Move most backend functionality to VideoCommon

This commit is contained in:
Stenzek
2019-02-15 11:59:50 +10:00
parent 933f3ba008
commit f039149198
182 changed files with 8334 additions and 15917 deletions

View File

@ -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"