mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Move most backend functionality to VideoCommon
This commit is contained in:
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
"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("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)
|
||||
{
|
||||
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"
|
||||
" return tex0.Sample(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"
|
||||
|
Reference in New Issue
Block a user