VideoCommon/FramebufferShaderGen: Collapse stream insertions

No behavioral change. This is intended to make the transition to fmt
less noisy in subsequent changes by combining insertions of multiple
string literals into one where applicable.
This commit is contained in:
Lioncash 2019-12-04 23:29:11 -05:00
parent 15fc71cfcf
commit f8c90f0484
1 changed files with 146 additions and 139 deletions

View File

@ -56,12 +56,12 @@ static void EmitSampleTexture(std::stringstream& ss, u32 n, const char* coords)
switch (GetAPIType()) switch (GetAPIType())
{ {
case APIType::D3D: case APIType::D3D:
ss << "tex" << n << ".Sample(samp" << n << ", " << coords << ")"; ss << "tex" << n << ".Sample(samp" << n << ", " << coords << ')';
break; break;
case APIType::OpenGL: case APIType::OpenGL:
case APIType::Vulkan: case APIType::Vulkan:
ss << "texture(samp" << n << ", " << coords << ")"; ss << "texture(samp" << n << ", " << coords << ')';
break; break;
default: default:
@ -76,7 +76,7 @@ static void EmitTextureLoad(std::stringstream& ss, u32 n, const char* coords)
switch (GetAPIType()) switch (GetAPIType())
{ {
case APIType::D3D: case APIType::D3D:
ss << "tex" << n << ".Load(" << coords << ")"; ss << "tex" << n << ".Load(" << coords << ')';
break; break;
case APIType::OpenGL: case APIType::OpenGL:
@ -118,11 +118,15 @@ static void EmitVertexMainDeclaration(std::stringstream& ss, u32 num_tex_inputs,
case APIType::Vulkan: case APIType::Vulkan:
{ {
for (u32 i = 0; i < num_tex_inputs; i++) for (u32 i = 0; i < num_tex_inputs; i++)
{
ss << "ATTRIBUTE_LOCATION(" << (SHADER_TEXTURE0_ATTRIB + i) << ") in float3 rawtex" << i ss << "ATTRIBUTE_LOCATION(" << (SHADER_TEXTURE0_ATTRIB + i) << ") in float3 rawtex" << i
<< ";\n"; << ";\n";
}
for (u32 i = 0; i < num_color_inputs; i++) for (u32 i = 0; i < num_color_inputs; i++)
{
ss << "ATTRIBUTE_LOCATION(" << (SHADER_COLOR0_ATTRIB + i) << ") in float4 rawcolor" << i ss << "ATTRIBUTE_LOCATION(" << (SHADER_COLOR0_ATTRIB + i) << ") in float4 rawcolor" << i
<< ";\n"; << ";\n";
}
if (position_input) if (position_input)
ss << "ATTRIBUTE_LOCATION(" << SHADER_POSITION_ATTRIB << ") in float4 rawpos;\n"; ss << "ATTRIBUTE_LOCATION(" << SHADER_POSITION_ATTRIB << ") in float4 rawpos;\n";
@ -143,7 +147,7 @@ static void EmitVertexMainDeclaration(std::stringstream& ss, u32 num_tex_inputs,
ss << "VARYING_LOCATION(" << (num_tex_inputs + i) << ") out float4 v_col" << i << ";\n"; ss << "VARYING_LOCATION(" << (num_tex_inputs + i) << ") out float4 v_col" << i << ";\n";
} }
ss << "#define opos gl_Position\n"; ss << "#define opos gl_Position\n";
ss << extra_inputs << "\n"; ss << extra_inputs << '\n';
ss << "void main()\n"; ss << "void main()\n";
} }
break; break;
@ -210,9 +214,9 @@ std::string GenerateScreenQuadVertexShader()
EmitVertexMainDeclaration(ss, 0, 0, false, 1, 0, EmitVertexMainDeclaration(ss, 0, 0, false, 1, 0,
GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " : GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " :
"#define id gl_VertexID\n"); "#define id gl_VertexID\n");
ss << "{\n"; ss << "{\n"
ss << " v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n"; " v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n"
ss << " opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n"; " opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n";
// NDC space is flipped in Vulkan. We also flip in GL so that (0,0) is in the lower-left. // NDC space is flipped in Vulkan. We also flip in GL so that (0,0) is in the lower-left.
if (GetAPIType() == APIType::Vulkan || GetAPIType() == APIType::OpenGL) if (GetAPIType() == APIType::Vulkan || GetAPIType() == APIType::OpenGL)
@ -228,47 +232,49 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors)
std::stringstream ss; std::stringstream ss;
if (GetAPIType() == APIType::D3D) if (GetAPIType() == APIType::D3D)
{ {
ss << "struct VS_OUTPUT\n"; ss << "struct VS_OUTPUT\n"
ss << "{\n"; "{\n";
for (u32 i = 0; i < num_tex; i++) for (u32 i = 0; i < num_tex; i++)
ss << " float3 tex" << i << " : TEXCOORD" << i << ";\n"; ss << " float3 tex" << i << " : TEXCOORD" << i << ";\n";
for (u32 i = 0; i < num_colors; i++) for (u32 i = 0; i < num_colors; i++)
ss << " float4 color" << i << " : COLOR" << i << ";\n"; ss << " float4 color" << i << " : COLOR" << i << ";\n";
ss << " float4 position : SV_Position;\n"; ss << " float4 position : SV_Position;\n"
ss << "};\n"; "};\n";
ss << "struct GS_OUTPUT\n";
ss << "{"; ss << "struct GS_OUTPUT\n"
"{";
for (u32 i = 0; i < num_tex; i++) for (u32 i = 0; i < num_tex; i++)
ss << " float3 tex" << i << " : TEXCOORD" << i << ";\n"; ss << " float3 tex" << i << " : TEXCOORD" << i << ";\n";
for (u32 i = 0; i < num_colors; i++) for (u32 i = 0; i < num_colors; i++)
ss << " float4 color" << i << " : COLOR" << i << ";\n"; ss << " float4 color" << i << " : COLOR" << i << ";\n";
ss << " float4 position : SV_Position;\n"; ss << " float4 position : SV_Position;\n"
ss << " uint slice : SV_RenderTargetArrayIndex;\n"; " uint slice : SV_RenderTargetArrayIndex;\n"
ss << "};\n\n"; "};\n\n";
ss << "[maxvertexcount(6)]\n";
ss << "void main(triangle VS_OUTPUT vso[3], inout TriangleStream<GS_OUTPUT> output)\n"; ss << "[maxvertexcount(6)]\n"
ss << "{\n"; "void main(triangle VS_OUTPUT vso[3], inout TriangleStream<GS_OUTPUT> output)\n"
ss << " for (uint slice = 0; slice < 2u; slice++)\n"; "{\n"
ss << " {\n"; " for (uint slice = 0; slice < 2u; slice++)\n"
ss << " for (int i = 0; i < 3; i++)\n"; " {\n"
ss << " {\n"; " for (int i = 0; i < 3; i++)\n"
ss << " GS_OUTPUT gso;\n"; " {\n"
ss << " gso.position = vso[i].position;\n"; " GS_OUTPUT gso;\n"
" gso.position = vso[i].position;\n";
for (u32 i = 0; i < num_tex; i++) for (u32 i = 0; i < num_tex; i++)
ss << " gso.tex" << i << " = float3(vso[i].tex" << i << ".xy, float(slice));\n"; ss << " gso.tex" << i << " = float3(vso[i].tex" << i << ".xy, float(slice));\n";
for (u32 i = 0; i < num_colors; i++) for (u32 i = 0; i < num_colors; i++)
ss << " gso.color" << i << " = vso[i].color" << i << ";\n"; ss << " gso.color" << i << " = vso[i].color" << i << ";\n";
ss << " gso.slice = slice;\n"; ss << " gso.slice = slice;\n"
ss << " output.Append(gso);\n"; " output.Append(gso);\n"
ss << " }\n"; " }\n"
ss << " output.RestartStrip();\n"; " output.RestartStrip();\n"
ss << " }\n"; " }\n"
ss << "}\n"; "}\n";
} }
else if (GetAPIType() == APIType::OpenGL || GetAPIType() == APIType::Vulkan) else if (GetAPIType() == APIType::OpenGL || GetAPIType() == APIType::Vulkan)
{ {
ss << "layout(triangles) in;\n"; ss << "layout(triangles) in;\n"
ss << "layout(triangle_strip, max_vertices = 6) out;\n"; "layout(triangle_strip, max_vertices = 6) out;\n";
if (num_tex > 0 || num_colors > 0) if (num_tex > 0 || num_colors > 0)
{ {
ss << "VARYING_LOCATION(0) in VertexData {\n"; ss << "VARYING_LOCATION(0) in VertexData {\n";
@ -277,6 +283,7 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors)
for (u32 i = 0; i < num_colors; i++) for (u32 i = 0; i < num_colors; i++)
ss << " float4 v_col" << i << ";\n"; ss << " float4 v_col" << i << ";\n";
ss << "} v_in[];\n"; ss << "} v_in[];\n";
ss << "VARYING_LOCATION(0) out VertexData {\n"; ss << "VARYING_LOCATION(0) out VertexData {\n";
for (u32 i = 0; i < num_tex; i++) for (u32 i = 0; i < num_tex; i++)
ss << " float3 v_tex" << i << ";\n"; ss << " float3 v_tex" << i << ";\n";
@ -284,12 +291,12 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors)
ss << " float4 v_col" << i << ";\n"; ss << " float4 v_col" << i << ";\n";
ss << "} v_out;\n"; ss << "} v_out;\n";
} }
ss << "\n"; ss << "\n"
ss << "void main()\n"; "void main()\n"
ss << "{\n"; "{\n"
ss << " for (int j = 0; j < 2; j++)\n"; " for (int j = 0; j < 2; j++)\n"
ss << " {\n"; " {\n"
ss << " gl_Layer = j;\n"; " gl_Layer = j;\n";
// We have to explicitly unroll this loop otherwise the GL compiler gets cranky. // We have to explicitly unroll this loop otherwise the GL compiler gets cranky.
for (u32 v = 0; v < 3; v++) for (u32 v = 0; v < 3; v++)
@ -302,9 +309,9 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors)
ss << " v_out.v_col" << i << " = v_in[" << v << "].v_col" << i << ";\n"; ss << " v_out.v_col" << i << " = v_in[" << v << "].v_col" << i << ";\n";
ss << " EmitVertex();\n\n"; ss << " EmitVertex();\n\n";
} }
ss << " EndPrimitive();\n"; ss << " EndPrimitive();\n"
ss << " }\n"; " }\n"
ss << "}\n"; "}\n";
} }
return ss.str(); return ss.str();
@ -314,18 +321,18 @@ std::string GenerateTextureCopyVertexShader()
{ {
std::stringstream ss; std::stringstream ss;
EmitUniformBufferDeclaration(ss); EmitUniformBufferDeclaration(ss);
ss << "{"; ss << "{"
ss << " float2 src_offset;\n"; " float2 src_offset;\n"
ss << " float2 src_size;\n"; " float2 src_size;\n"
ss << "};\n\n"; "};\n\n";
EmitVertexMainDeclaration(ss, 0, 0, false, 1, 0, EmitVertexMainDeclaration(ss, 0, 0, false, 1, 0,
GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " : GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " :
"#define id gl_VertexID"); "#define id gl_VertexID");
ss << "{\n"; ss << "{\n"
ss << " v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n"; " v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n"
ss << " opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n"; " opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n"
ss << " v_tex0 = float3(src_offset + (src_size * v_tex0.xy), 0.0f);\n"; " v_tex0 = float3(src_offset + (src_size * v_tex0.xy), 0.0f);\n";
// NDC space is flipped in Vulkan. We also flip in GL so that (0,0) is in the lower-left. // NDC space is flipped in Vulkan. We also flip in GL so that (0,0) is in the lower-left.
if (GetAPIType() == APIType::Vulkan || GetAPIType() == APIType::OpenGL) if (GetAPIType() == APIType::Vulkan || GetAPIType() == APIType::OpenGL)
@ -341,11 +348,11 @@ std::string GenerateTextureCopyPixelShader()
std::stringstream ss; std::stringstream ss;
EmitSamplerDeclarations(ss, 0, 1, false); EmitSamplerDeclarations(ss, 0, 1, false);
EmitPixelMainDeclaration(ss, 1, 0); EmitPixelMainDeclaration(ss, 1, 0);
ss << "{\n"; ss << "{\n"
ss << " ocol0 = "; " ocol0 = ";
EmitSampleTexture(ss, 0, "v_tex0"); EmitSampleTexture(ss, 0, "v_tex0");
ss << ";\n"; ss << ";\n"
ss << "}\n"; "}\n";
return ss.str(); return ss.str();
} }
@ -353,9 +360,9 @@ std::string GenerateColorPixelShader()
{ {
std::stringstream ss; std::stringstream ss;
EmitPixelMainDeclaration(ss, 0, 1); EmitPixelMainDeclaration(ss, 0, 1);
ss << "{\n"; ss << "{\n"
ss << " ocol0 = v_col0;\n"; " ocol0 = v_col0;\n"
ss << "}\n"; "}\n";
return ss.str(); return ss.str();
} }
@ -365,8 +372,8 @@ std::string GenerateResolveDepthPixelShader(u32 samples)
EmitSamplerDeclarations(ss, 0, 1, true); EmitSamplerDeclarations(ss, 0, 1, true);
EmitPixelMainDeclaration(ss, 1, 0, "float", EmitPixelMainDeclaration(ss, 1, 0, "float",
GetAPIType() == APIType::D3D ? "in float4 ipos : SV_Position, " : ""); GetAPIType() == APIType::D3D ? "in float4 ipos : SV_Position, " : "");
ss << "{\n"; ss << "{\n"
ss << " int layer = int(v_tex0.z);\n"; " int layer = int(v_tex0.z);\n";
if (GetAPIType() == APIType::D3D) if (GetAPIType() == APIType::D3D)
ss << " int3 coords = int3(int2(ipos.xy), layer);\n"; ss << " int3 coords = int3(int2(ipos.xy), layer);\n";
else else
@ -391,18 +398,18 @@ std::string GenerateClearVertexShader()
{ {
std::stringstream ss; std::stringstream ss;
EmitUniformBufferDeclaration(ss); EmitUniformBufferDeclaration(ss);
ss << "{\n"; ss << "{\n"
ss << " float4 clear_color;\n"; " float4 clear_color;\n"
ss << " float clear_depth;\n"; " float clear_depth;\n"
ss << "};\n"; "};\n";
EmitVertexMainDeclaration(ss, 0, 0, false, 0, 1, EmitVertexMainDeclaration(ss, 0, 0, false, 0, 1,
GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " : GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " :
"#define id gl_VertexID\n"); "#define id gl_VertexID\n");
ss << "{\n"; ss << "{\n"
ss << " float2 coord = float2(float((id << 1) & 2), float(id & 2));\n"; " float2 coord = float2(float((id << 1) & 2), float(id & 2));\n"
ss << " opos = float4(coord * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), clear_depth, 1.0f);\n"; " opos = float4(coord * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), clear_depth, 1.0f);\n"
ss << " v_col0 = clear_color;\n"; " v_col0 = clear_color;\n";
// NDC space is flipped in Vulkan // NDC space is flipped in Vulkan
if (GetAPIType() == APIType::Vulkan) if (GetAPIType() == APIType::Vulkan)
@ -417,9 +424,9 @@ std::string GenerateEFBPokeVertexShader()
{ {
std::stringstream ss; std::stringstream ss;
EmitVertexMainDeclaration(ss, 0, 1, true, 0, 1); EmitVertexMainDeclaration(ss, 0, 1, true, 0, 1);
ss << "{\n"; ss << "{\n"
ss << " v_col0 = rawcolor0;\n"; " v_col0 = rawcolor0;\n"
ss << " opos = float4(rawpos.xyz, 1.0f);\n"; " opos = float4(rawpos.xyz, 1.0f);\n";
if (g_ActiveConfig.backend_info.bSupportsLargePoints) if (g_ActiveConfig.backend_info.bSupportsLargePoints)
ss << " gl_PointSize = rawpos.w;\n"; ss << " gl_PointSize = rawpos.w;\n";
@ -442,8 +449,8 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp
"in float4 ipos : SV_Position, in uint isample : SV_SampleIndex, " : "in float4 ipos : SV_Position, in uint isample : SV_SampleIndex, " :
"in float4 ipos : SV_Position, ") : "in float4 ipos : SV_Position, ") :
""); "");
ss << "{\n"; ss << "{\n"
ss << " int layer = int(v_tex0.z);\n"; " int layer = int(v_tex0.z);\n";
if (GetAPIType() == APIType::D3D) if (GetAPIType() == APIType::D3D)
ss << " int3 coords = int3(int2(ipos.xy), layer);\n"; ss << " int3 coords = int3(int2(ipos.xy), layer);\n";
else else
@ -480,13 +487,13 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp
switch (convtype) switch (convtype)
{ {
case EFBReinterpretType::RGB8ToRGBA6: case EFBReinterpretType::RGB8ToRGBA6:
ss << " int4 src8 = int4(round(val * 255.f));\n"; ss << " int4 src8 = int4(round(val * 255.f));\n"
ss << " int4 dst6;\n"; " int4 dst6;\n"
ss << " dst6.r = src8.r >> 2;\n"; " dst6.r = src8.r >> 2;\n"
ss << " dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n"; " dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n"
ss << " dst6.b = ((src8.g & 0xF) << 2) | (src8.b >> 6);\n"; " dst6.b = ((src8.g & 0xF) << 2) | (src8.b >> 6);\n"
ss << " dst6.a = src8.b & 0x3F;\n"; " dst6.a = src8.b & 0x3F;\n"
ss << " ocol0 = float4(dst6) / 63.f;\n"; " ocol0 = float4(dst6) / 63.f;\n";
break; break;
case EFBReinterpretType::RGB8ToRGB565: case EFBReinterpretType::RGB8ToRGB565:
@ -494,13 +501,13 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp
break; break;
case EFBReinterpretType::RGBA6ToRGB8: case EFBReinterpretType::RGBA6ToRGB8:
ss << " int4 src6 = int4(round(val * 63.f));\n"; ss << " int4 src6 = int4(round(val * 63.f));\n"
ss << " int4 dst8;\n"; " int4 dst8;\n"
ss << " dst8.r = (src6.r << 2) | (src6.g >> 4);\n"; " dst8.r = (src6.r << 2) | (src6.g >> 4);\n"
ss << " dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n"; " dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n"
ss << " dst8.b = ((src6.b & 0x3) << 6) | src6.a;\n"; " dst8.b = ((src6.b & 0x3) << 6) | src6.a;\n"
ss << " dst8.a = 255;\n"; " dst8.a = 255;\n"
ss << " ocol0 = float4(dst8) / 255.f;\n"; " ocol0 = float4(dst8) / 255.f;\n";
break; break;
case EFBReinterpretType::RGBA6ToRGB565: case EFBReinterpretType::RGBA6ToRGB565:
@ -526,9 +533,9 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
std::stringstream ss; std::stringstream ss;
EmitSamplerDeclarations(ss, 0, 1, false); EmitSamplerDeclarations(ss, 0, 1, false);
EmitPixelMainDeclaration(ss, 1, 0, "float4", "", true); EmitPixelMainDeclaration(ss, 1, 0, "float4", "", true);
ss << "{\n"; ss << "{\n"
ss << " int layer = int(v_tex0.z);\n"; " int layer = int(v_tex0.z);\n"
ss << " int4 coords = int4(int2(frag_coord.xy), layer, 0);\n"; " int4 coords = int4(int2(frag_coord.xy), layer, 0);\n";
// Convert to a 32-bit value encompassing all channels, filling the most significant bits with // Convert to a 32-bit value encompassing all channels, filling the most significant bits with
// zeroes. // zeroes.
@ -540,8 +547,8 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
{ {
ss << " float4 temp_value = "; ss << " float4 temp_value = ";
EmitTextureLoad(ss, 0, "coords"); EmitTextureLoad(ss, 0, "coords");
ss << ";\n"; ss << ";\n"
ss << " raw_value = uint(temp_value.r * 255.0);\n"; " raw_value = uint(temp_value.r * 255.0);\n";
} }
break; break;
@ -549,8 +556,8 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
{ {
ss << " float4 temp_value = "; ss << " float4 temp_value = ";
EmitTextureLoad(ss, 0, "coords"); EmitTextureLoad(ss, 0, "coords");
ss << ";\n"; ss << ";\n"
ss << " raw_value = uint(temp_value.r * 255.0) | (uint(temp_value.a * 255.0) << 8);\n"; " raw_value = uint(temp_value.r * 255.0) | (uint(temp_value.a * 255.0) << 8);\n";
} }
break; break;
@ -558,8 +565,8 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
{ {
ss << " float4 temp_value = "; ss << " float4 temp_value = ";
EmitTextureLoad(ss, 0, "coords"); EmitTextureLoad(ss, 0, "coords");
ss << ";\n"; ss << ";\n"
ss << " raw_value = uint(temp_value.r * 15.0) | (uint(temp_value.a * 15.0) << 4);\n"; " raw_value = uint(temp_value.r * 15.0) | (uint(temp_value.a * 15.0) << 4);\n";
} }
break; break;
@ -567,9 +574,9 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
{ {
ss << " float4 temp_value = "; ss << " float4 temp_value = ";
EmitTextureLoad(ss, 0, "coords"); EmitTextureLoad(ss, 0, "coords");
ss << ";\n"; ss << ";\n"
ss << " raw_value = uint(temp_value.b * 31.0) | (uint(temp_value.g * 63.0) << 5) |\n"; " raw_value = uint(temp_value.b * 31.0) | (uint(temp_value.g * 63.0) << 5) |\n"
ss << " (uint(temp_value.r * 31.0) << 11);\n"; " (uint(temp_value.r * 31.0) << 11);\n";
} }
break; break;
@ -580,13 +587,13 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
ss << ";\n"; ss << ";\n";
// 0.8784 = 224 / 255 which is the maximum alpha value that can be represented in 3 bits // 0.8784 = 224 / 255 which is the maximum alpha value that can be represented in 3 bits
ss << " if (temp_value.a > 0.878f) {\n"; ss << " if (temp_value.a > 0.878f) {\n"
ss << " raw_value = (uint(temp_value.b * 31.0)) | (uint(temp_value.g * 31.0) << 5) |\n"; " raw_value = (uint(temp_value.b * 31.0)) | (uint(temp_value.g * 31.0) << 5) |\n"
ss << " (uint(temp_value.r * 31.0) << 10) | 0x8000u;\n"; " (uint(temp_value.r * 31.0) << 10) | 0x8000u;\n"
ss << " } else {\n"; " } else {\n"
ss << " raw_value = (uint(temp_value.b * 15.0)) | (uint(temp_value.g * 15.0) << 4) |\n"; " raw_value = (uint(temp_value.b * 15.0)) | (uint(temp_value.g * 15.0) << 4) |\n"
ss << " (uint(temp_value.r * 15.0) << 8) | (uint(temp_value.a * 7.0) << 12);\n"; " (uint(temp_value.r * 15.0) << 8) | (uint(temp_value.a * 7.0) << 12);\n"
ss << " }\n"; " }\n";
} }
break; break;
} }
@ -597,45 +604,45 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
case TextureFormat::I8: case TextureFormat::I8:
case TextureFormat::C8: case TextureFormat::C8:
{ {
ss << " float orgba = float(raw_value & 0xFFu) / 255.0;\n"; ss << " float orgba = float(raw_value & 0xFFu) / 255.0;\n"
ss << " ocol0 = float4(orgba, orgba, orgba, orgba);\n"; " ocol0 = float4(orgba, orgba, orgba, orgba);\n";
} }
break; break;
case TextureFormat::IA8: case TextureFormat::IA8:
{ {
ss << " float orgb = float(raw_value & 0xFFu) / 255.0;\n"; ss << " float orgb = float(raw_value & 0xFFu) / 255.0;\n"
ss << " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 8) & 0xFFu) / 255.0);\n"; " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 8) & 0xFFu) / 255.0);\n";
} }
break; break;
case TextureFormat::IA4: case TextureFormat::IA4:
{ {
ss << " float orgb = float(raw_value & 0xFu) / 15.0;\n"; ss << " float orgb = float(raw_value & 0xFu) / 15.0;\n"
ss << " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 4) & 0xFu) / 15.0);\n"; " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 4) & 0xFu) / 15.0);\n";
} }
break; break;
case TextureFormat::RGB565: case TextureFormat::RGB565:
{ {
ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n"; ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n"
ss << " float((raw_value >> 5) & 0x1Fu) / 31.0,\n"; " float((raw_value >> 5) & 0x1Fu) / 31.0,\n"
ss << " float(raw_value & 0x1Fu) / 31.0, 1.0);\n"; " float(raw_value & 0x1Fu) / 31.0, 1.0);\n";
} }
break; break;
case TextureFormat::RGB5A3: case TextureFormat::RGB5A3:
{ {
ss << " if ((raw_value & 0x8000u) != 0u) {\n"; ss << " if ((raw_value & 0x8000u) != 0u) {\n"
ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n"; " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n"
ss << " float((raw_value >> 5) & 0x1Fu) / 31.0,\n"; " float((raw_value >> 5) & 0x1Fu) / 31.0,\n"
ss << " float(raw_value & 0x1Fu) / 31.0, 1.0);\n"; " float(raw_value & 0x1Fu) / 31.0, 1.0);\n"
ss << " } else {\n"; " } else {\n"
ss << " ocol0 = float4(float((raw_value >> 8) & 0x0Fu) / 15.0,\n"; " ocol0 = float4(float((raw_value >> 8) & 0x0Fu) / 15.0,\n"
ss << " float((raw_value >> 4) & 0x0Fu) / 15.0,\n"; " float((raw_value >> 4) & 0x0Fu) / 15.0,\n"
ss << " float(raw_value & 0x0Fu) / 15.0,\n"; " float(raw_value & 0x0Fu) / 15.0,\n"
ss << " float((raw_value >> 12) & 0x07u) / 7.0);\n"; " float((raw_value >> 12) & 0x07u) / 7.0);\n"
ss << " }\n"; " }\n";
} }
break; break;
} }
@ -650,14 +657,14 @@ std::string GenerateEFBRestorePixelShader()
EmitSamplerDeclarations(ss, 0, 2, false); EmitSamplerDeclarations(ss, 0, 2, false);
EmitPixelMainDeclaration(ss, 1, 0, "float4", EmitPixelMainDeclaration(ss, 1, 0, "float4",
GetAPIType() == APIType::D3D ? "out float depth : SV_Depth, " : ""); GetAPIType() == APIType::D3D ? "out float depth : SV_Depth, " : "");
ss << "{\n"; ss << "{\n"
ss << " ocol0 = "; " ocol0 = ";
EmitSampleTexture(ss, 0, "v_tex0"); EmitSampleTexture(ss, 0, "v_tex0");
ss << ";\n"; ss << ";\n";
ss << " " << (GetAPIType() == APIType::D3D ? "depth" : "gl_FragDepth") << " = "; ss << " " << (GetAPIType() == APIType::D3D ? "depth" : "gl_FragDepth") << " = ";
EmitSampleTexture(ss, 1, "v_tex0"); EmitSampleTexture(ss, 1, "v_tex0");
ss << ".r;\n"; ss << ".r;\n"
ss << "}\n"; "}\n";
return ss.str(); return ss.str();
} }
@ -667,16 +674,16 @@ std::string GenerateImGuiVertexShader()
// Uniform buffer contains the viewport size, and we transform in the vertex shader. // Uniform buffer contains the viewport size, and we transform in the vertex shader.
EmitUniformBufferDeclaration(ss); EmitUniformBufferDeclaration(ss);
ss << "{\n"; ss << "{\n"
ss << "float2 u_rcp_viewport_size_mul2;\n"; "float2 u_rcp_viewport_size_mul2;\n"
ss << "};\n\n"; "};\n\n";
EmitVertexMainDeclaration(ss, 1, 1, true, 1, 1); EmitVertexMainDeclaration(ss, 1, 1, true, 1, 1);
ss << "{\n" ss << "{\n"
<< " v_tex0 = float3(rawtex0.xy, 0.0);\n" " v_tex0 = float3(rawtex0.xy, 0.0);\n"
<< " v_col0 = rawcolor0;\n" " v_col0 = rawcolor0;\n"
<< " opos = float4(rawpos.x * u_rcp_viewport_size_mul2.x - 1.0," " opos = float4(rawpos.x * u_rcp_viewport_size_mul2.x - 1.0,"
<< " 1.0 - rawpos.y * u_rcp_viewport_size_mul2.y, 0.0, 1.0);\n"; " 1.0 - rawpos.y * u_rcp_viewport_size_mul2.y, 0.0, 1.0);\n";
// NDC space is flipped in Vulkan. // NDC space is flipped in Vulkan.
if (GetAPIType() == APIType::Vulkan) if (GetAPIType() == APIType::Vulkan)
@ -691,11 +698,11 @@ std::string GenerateImGuiPixelShader()
std::stringstream ss; std::stringstream ss;
EmitSamplerDeclarations(ss, 0, 1, false); EmitSamplerDeclarations(ss, 0, 1, false);
EmitPixelMainDeclaration(ss, 1, 1); EmitPixelMainDeclaration(ss, 1, 1);
ss << "{\n"; ss << "{\n"
ss << " ocol0 = "; " ocol0 = ";
EmitSampleTexture(ss, 0, "float3(v_tex0.xy, 0.0)"); EmitSampleTexture(ss, 0, "float3(v_tex0.xy, 0.0)");
ss << " * v_col0;\n"; ss << " * v_col0;\n"
ss << "}\n"; "}\n";
return ss.str(); return ss.str();
} }