summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/TextureConverterShaderGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/TextureConverterShaderGen.cpp')
-rw-r--r--Source/Core/VideoCommon/TextureConverterShaderGen.cpp119
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: