diff options
Diffstat (limited to 'Source/Core/VideoCommon/TextureConverterShaderGen.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/TextureConverterShaderGen.cpp | 119 |
1 files changed, 73 insertions, 46 deletions
diff --git a/Source/Core/VideoCommon/TextureConverterShaderGen.cpp b/Source/Core/VideoCommon/TextureConverterShaderGen.cpp index 5cfb3e7c76..15de7ba9a7 100644 --- a/Source/Core/VideoCommon/TextureConverterShaderGen.cpp +++ b/Source/Core/VideoCommon/TextureConverterShaderGen.cpp @@ -31,72 +31,99 @@ TCShaderUid GetShaderUid(EFBCopyFormat dst_format, bool is_depth_copy, bool is_i return out; } -ShaderCode GenerateShader(APIType api_type, const UidData* uid_data) +static void WriteHeader(APIType api_type, ShaderCode& out) { - const bool mono_depth = uid_data->is_depth_copy && g_ActiveConfig.bStereoEFBMonoDepth; - - ShaderCode out; - if (api_type == APIType::OpenGL) + if (api_type == APIType::D3D) { - out.Write("SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n" - "uniform float3 filter_coefficients;\n" - "uniform float gamma_rcp;\n" - "uniform float2 clamp_tb;\n" - "uniform float pixel_height;\n"); - out.Write("float4 SampleEFB(float3 uv, float y_offset) {\n" - " return texture(samp9, float3(uv.x, clamp(uv.y - (y_offset * pixel_height), " - "clamp_tb.x, clamp_tb.y), %s));\n" - "}\n", - mono_depth ? "0.0" : "uv.z"); - out.Write("#define uv0 f_uv0\n" - "in vec3 uv0;\n" - "out vec4 ocol0;\n" - "void main(){\n"); + out.Write("cbuffer PSBlock : register(b0) {\n" + " float2 src_offset, src_size;\n" + " float3 filter_coefficients;\n" + " float gamma_rcp;\n" + " float2 clamp_tb;\n" + " float pixel_height;\n" + "};\n\n"); } - else if (api_type == APIType::Vulkan) + else if (api_type == APIType::OpenGL || api_type == APIType::Vulkan) { out.Write("UBO_BINDING(std140, 1) uniform PSBlock {\n" + " float2 src_offset, src_size;\n" " float3 filter_coefficients;\n" " float gamma_rcp;\n" " float2 clamp_tb;\n" " float pixel_height;\n" "};\n"); - out.Write("SAMPLER_BINDING(0) uniform sampler2DArray samp0;\n"); - out.Write("float4 SampleEFB(float3 uv, float y_offset) {\n" - " return texture(samp0, float3(uv.x, clamp(uv.y + (y_offset * pixel_height), " - "clamp_tb.x, clamp_tb.y), %s));\n" - "}\n", - mono_depth ? "0.0" : "uv.z"); - out.Write("layout(location = 0) in vec3 uv0;\n" - "layout(location = 1) in vec4 col0;\n" - "layout(location = 0) out vec4 ocol0;" - "void main(){\n"); } - else if (api_type == APIType::D3D) +} + +ShaderCode GenerateVertexShader(APIType api_type) +{ + ShaderCode out; + WriteHeader(api_type, out); + + if (api_type == APIType::D3D) + { + out.Write("void main(in uint id : SV_VertexID, out float3 v_tex0 : TEXCOORD0,\n" + " out float4 opos : SV_Position) {\n"); + } + else if (api_type == APIType::OpenGL || api_type == APIType::Vulkan) + { + out.Write("VARYING_LOCATION(0) out float3 v_tex0;\n" + "#define id gl_VertexID\n" + "#define opos gl_Position\n" + "void main() {\n"); + } + out.Write(" v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n"); + out.Write( + " opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n"); + out.Write(" v_tex0 = float3(src_offset + (src_size * v_tex0.xy), 0.0f);\n"); + + // NDC space is flipped in Vulkan + if (api_type == APIType::Vulkan) + out.Write(" opos.y = -opos.y;\n"); + + out.Write("}\n"); + + return out; +} + +ShaderCode GeneratePixelShader(APIType api_type, const UidData* uid_data) +{ + const bool mono_depth = uid_data->is_depth_copy && g_ActiveConfig.bStereoEFBMonoDepth; + + ShaderCode out; + WriteHeader(api_type, out); + + if (api_type == APIType::D3D) { out.Write("Texture2DArray tex0 : register(t0);\n" "SamplerState samp0 : register(s0);\n" - "uniform float3 filter_coefficients;\n" - "uniform float gamma_rcp;\n" - "uniform float2 clamp_tb;\n" - "uniform float pixel_height;\n\n"); - out.Write("float4 SampleEFB(float3 uv, float y_offset) {\n" + "float4 SampleEFB(float3 uv, float y_offset) {\n" " return tex0.Sample(samp0, float3(uv.x, clamp(uv.y + (y_offset * pixel_height), " "clamp_tb.x, clamp_tb.y), %s));\n" + "}\n\n", + mono_depth ? "0.0" : "uv.z"); + out.Write("void main(in float3 v_tex0 : TEXCOORD0, out float4 ocol0 : SV_Target)\n{\n"); + } + else if (api_type == APIType::OpenGL || api_type == APIType::Vulkan) + { + out.Write("SAMPLER_BINDING(0) uniform sampler2DArray samp0;\n"); + out.Write("float4 SampleEFB(float3 uv, float y_offset) {\n" + " return texture(samp0, float3(uv.x, clamp(uv.y + (y_offset * pixel_height), " + "clamp_tb.x, clamp_tb.y), %s));\n" "}\n", mono_depth ? "0.0" : "uv.z"); - out.Write("void main(out float4 ocol0 : SV_Target,\n" - " in float4 pos : SV_Position,\n" - " in float3 uv0 : TEXCOORD0) {\n"); + out.Write("VARYING_LOCATION(0) in vec3 v_tex0;\n" + "FRAGMENT_OUTPUT_LOCATION(0) out vec4 ocol0;" + "void main()\n{\n"); } // The copy filter applies to both color and depth copies. This has been verified on hardware. // The filter is only applied to the RGB channels, the alpha channel is left intact. if (uid_data->copy_filter) { - out.Write(" float4 prev_row = SampleEFB(uv0, -1.0f);\n" - " float4 current_row = SampleEFB(uv0, 0.0f);\n" - " float4 next_row = SampleEFB(uv0, 1.0f);\n" + out.Write(" float4 prev_row = SampleEFB(v_tex0, -1.0f);\n" + " float4 current_row = SampleEFB(v_tex0, 0.0f);\n" + " float4 next_row = SampleEFB(v_tex0, 1.0f);\n" " float4 texcol = float4(min(prev_row.rgb * filter_coefficients[0] +\n" " current_row.rgb * filter_coefficients[1] +\n" " next_row.rgb * filter_coefficients[2], \n" @@ -105,14 +132,14 @@ ShaderCode GenerateShader(APIType api_type, const UidData* uid_data) else { out.Write( - " float4 current_row = SampleEFB(uv0, 0.0f);\n" + " float4 current_row = SampleEFB(v_tex0, 0.0f);\n" " float4 texcol = float4(min(current_row.rgb * filter_coefficients[1], float3(1, 1, 1)),\n" " current_row.a);\n"); } if (uid_data->is_depth_copy) { - if (api_type == APIType::D3D || api_type == APIType::Vulkan) + if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange) out.Write("texcol.x = 1.0 - texcol.x;\n"); out.Write(" int depth = int(texcol.x * 16777216.0);\n" @@ -268,8 +295,8 @@ ShaderCode GenerateShader(APIType api_type, const UidData* uid_data) break; case EFBCopyFormat::XFB: - out.Write(" ocol0 = float4(pow(texcol.rgb, float3(gamma_rcp, gamma_rcp, gamma_rcp)), " - "texcol.a);\n"); + out.Write( + " ocol0 = float4(pow(texcol.rgb, float3(gamma_rcp, gamma_rcp, gamma_rcp)), 1.0f);\n"); break; default: |
