diff --git a/Source/Core/VideoCommon/FramebufferShaderGen.cpp b/Source/Core/VideoCommon/FramebufferShaderGen.cpp index ca00f2c332..a4a5219126 100644 --- a/Source/Core/VideoCommon/FramebufferShaderGen.cpp +++ b/Source/Core/VideoCommon/FramebufferShaderGen.cpp @@ -1,17 +1,26 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + #include "VideoCommon/FramebufferShaderGen.h" + #include +#include + #include "VideoCommon/FramebufferManager.h" #include "VideoCommon/TextureDecoder.h" #include "VideoCommon/VertexShaderGen.h" namespace FramebufferShaderGen { -static APIType GetAPIType() +namespace +{ +APIType GetAPIType() { return g_ActiveConfig.backend_info.api_type; } -static void EmitUniformBufferDeclaration(std::stringstream& ss) +void EmitUniformBufferDeclaration(std::ostringstream& ss) { if (GetAPIType() == APIType::D3D) ss << "cbuffer PSBlock : register(b0)\n"; @@ -19,8 +28,8 @@ static void EmitUniformBufferDeclaration(std::stringstream& ss) ss << "UBO_BINDING(std140, 1) uniform PSBlock\n"; } -static void EmitSamplerDeclarations(std::stringstream& ss, u32 start = 0, u32 end = 1, - bool multisampled = false) +void EmitSamplerDeclarations(std::ostringstream& ss, u32 start = 0, u32 end = 1, + bool multisampled = false) { switch (GetAPIType()) { @@ -51,17 +60,17 @@ static void EmitSamplerDeclarations(std::stringstream& ss, u32 start = 0, u32 en } } -static void EmitSampleTexture(std::stringstream& ss, u32 n, const char* coords) +void EmitSampleTexture(std::ostringstream& ss, u32 n, std::string_view coords) { switch (GetAPIType()) { case APIType::D3D: - ss << "tex" << n << ".Sample(samp" << n << ", " << coords << ")"; + ss << "tex" << n << ".Sample(samp" << n << ", " << coords << ')'; break; case APIType::OpenGL: case APIType::Vulkan: - ss << "texture(samp" << n << ", " << coords << ")"; + ss << "texture(samp" << n << ", " << coords << ')'; break; default: @@ -71,12 +80,12 @@ static void EmitSampleTexture(std::stringstream& ss, u32 n, const char* coords) // Emits a texel fetch/load instruction. Assumes that "coords" is a 4-element vector, with z // containing the layer, and w containing the mipmap level. -static void EmitTextureLoad(std::stringstream& ss, u32 n, const char* coords) +void EmitTextureLoad(std::ostringstream& ss, u32 n, std::string_view coords) { switch (GetAPIType()) { case APIType::D3D: - ss << "tex" << n << ".Load(" << coords << ")"; + ss << "tex" << n << ".Load(" << coords << ')'; break; case APIType::OpenGL: @@ -89,10 +98,9 @@ static void EmitTextureLoad(std::stringstream& ss, u32 n, const char* coords) } } -static void EmitVertexMainDeclaration(std::stringstream& ss, u32 num_tex_inputs, - u32 num_color_inputs, bool position_input, - u32 num_tex_outputs, u32 num_color_outputs, - const char* extra_inputs = "") +void EmitVertexMainDeclaration(std::ostringstream& ss, u32 num_tex_inputs, u32 num_color_inputs, + bool position_input, u32 num_tex_outputs, u32 num_color_outputs, + std::string_view extra_inputs = {}) { switch (GetAPIType()) { @@ -118,11 +126,15 @@ static void EmitVertexMainDeclaration(std::stringstream& ss, u32 num_tex_inputs, case APIType::Vulkan: { for (u32 i = 0; i < num_tex_inputs; i++) + { ss << "ATTRIBUTE_LOCATION(" << (SHADER_TEXTURE0_ATTRIB + i) << ") in float3 rawtex" << i << ";\n"; + } for (u32 i = 0; i < num_color_inputs; i++) + { ss << "ATTRIBUTE_LOCATION(" << (SHADER_COLOR0_ATTRIB + i) << ") in float4 rawcolor" << i << ";\n"; + } if (position_input) ss << "ATTRIBUTE_LOCATION(" << SHADER_POSITION_ATTRIB << ") in float4 rawpos;\n"; @@ -143,7 +155,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 << "#define opos gl_Position\n"; - ss << extra_inputs << "\n"; + ss << extra_inputs << '\n'; ss << "void main()\n"; } break; @@ -152,9 +164,9 @@ static void EmitVertexMainDeclaration(std::stringstream& ss, u32 num_tex_inputs, } } -static void EmitPixelMainDeclaration(std::stringstream& ss, u32 num_tex_inputs, - u32 num_color_inputs, const char* output_type = "float4", - const char* extra_vars = "", bool emit_frag_coord = false) +void EmitPixelMainDeclaration(std::ostringstream& ss, u32 num_tex_inputs, u32 num_color_inputs, + std::string_view output_type = "float4", + std::string_view extra_vars = {}, bool emit_frag_coord = false) { switch (GetAPIType()) { @@ -203,16 +215,17 @@ static void EmitPixelMainDeclaration(std::stringstream& ss, u32 num_tex_inputs, break; } } +} // Anonymous namespace std::string GenerateScreenQuadVertexShader() { - std::stringstream ss; + std::ostringstream ss; EmitVertexMainDeclaration(ss, 0, 0, false, 1, 0, GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " : "#define id gl_VertexID\n"); - ss << "{\n"; - ss << " 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"; + ss << "{\n" + " v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.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. if (GetAPIType() == APIType::Vulkan || GetAPIType() == APIType::OpenGL) @@ -225,50 +238,52 @@ std::string GenerateScreenQuadVertexShader() std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors) { - std::stringstream ss; + std::ostringstream ss; if (GetAPIType() == APIType::D3D) { - ss << "struct VS_OUTPUT\n"; - ss << "{\n"; + ss << "struct VS_OUTPUT\n" + "{\n"; for (u32 i = 0; i < num_tex; i++) ss << " float3 tex" << i << " : TEXCOORD" << i << ";\n"; for (u32 i = 0; i < num_colors; i++) ss << " float4 color" << i << " : COLOR" << i << ";\n"; - ss << " float4 position : SV_Position;\n"; - ss << "};\n"; - ss << "struct GS_OUTPUT\n"; - ss << "{"; + ss << " float4 position : SV_Position;\n" + "};\n"; + + ss << "struct GS_OUTPUT\n" + "{"; for (u32 i = 0; i < num_tex; i++) ss << " float3 tex" << i << " : TEXCOORD" << i << ";\n"; for (u32 i = 0; i < num_colors; i++) ss << " float4 color" << i << " : COLOR" << i << ";\n"; - ss << " float4 position : SV_Position;\n"; - ss << " uint slice : SV_RenderTargetArrayIndex;\n"; - ss << "};\n\n"; - ss << "[maxvertexcount(6)]\n"; - ss << "void main(triangle VS_OUTPUT vso[3], inout TriangleStream output)\n"; - ss << "{\n"; - ss << " for (uint slice = 0; slice < 2u; slice++)\n"; - ss << " {\n"; - ss << " for (int i = 0; i < 3; i++)\n"; - ss << " {\n"; - ss << " GS_OUTPUT gso;\n"; - ss << " gso.position = vso[i].position;\n"; + ss << " float4 position : SV_Position;\n" + " uint slice : SV_RenderTargetArrayIndex;\n" + "};\n\n"; + + ss << "[maxvertexcount(6)]\n" + "void main(triangle VS_OUTPUT vso[3], inout TriangleStream output)\n" + "{\n" + " for (uint slice = 0; slice < 2u; slice++)\n" + " {\n" + " for (int i = 0; i < 3; i++)\n" + " {\n" + " GS_OUTPUT gso;\n" + " gso.position = vso[i].position;\n"; for (u32 i = 0; i < num_tex; i++) ss << " gso.tex" << i << " = float3(vso[i].tex" << i << ".xy, float(slice));\n"; for (u32 i = 0; i < num_colors; i++) ss << " gso.color" << i << " = vso[i].color" << i << ";\n"; - ss << " gso.slice = slice;\n"; - ss << " output.Append(gso);\n"; - ss << " }\n"; - ss << " output.RestartStrip();\n"; - ss << " }\n"; - ss << "}\n"; + ss << " gso.slice = slice;\n" + " output.Append(gso);\n" + " }\n" + " output.RestartStrip();\n" + " }\n" + "}\n"; } else if (GetAPIType() == APIType::OpenGL || GetAPIType() == APIType::Vulkan) { - ss << "layout(triangles) in;\n"; - ss << "layout(triangle_strip, max_vertices = 6) out;\n"; + ss << "layout(triangles) in;\n" + "layout(triangle_strip, max_vertices = 6) out;\n"; if (num_tex > 0 || num_colors > 0) { ss << "VARYING_LOCATION(0) in VertexData {\n"; @@ -277,6 +292,7 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors) for (u32 i = 0; i < num_colors; i++) ss << " float4 v_col" << i << ";\n"; ss << "} v_in[];\n"; + ss << "VARYING_LOCATION(0) out VertexData {\n"; for (u32 i = 0; i < num_tex; i++) ss << " float3 v_tex" << i << ";\n"; @@ -284,12 +300,12 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors) ss << " float4 v_col" << i << ";\n"; ss << "} v_out;\n"; } - ss << "\n"; - ss << "void main()\n"; - ss << "{\n"; - ss << " for (int j = 0; j < 2; j++)\n"; - ss << " {\n"; - ss << " gl_Layer = j;\n"; + ss << "\n" + "void main()\n" + "{\n" + " for (int j = 0; j < 2; j++)\n" + " {\n" + " gl_Layer = j;\n"; // We have to explicitly unroll this loop otherwise the GL compiler gets cranky. for (u32 v = 0; v < 3; v++) @@ -302,9 +318,9 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors) ss << " v_out.v_col" << i << " = v_in[" << v << "].v_col" << i << ";\n"; ss << " EmitVertex();\n\n"; } - ss << " EndPrimitive();\n"; - ss << " }\n"; - ss << "}\n"; + ss << " EndPrimitive();\n" + " }\n" + "}\n"; } return ss.str(); @@ -312,20 +328,20 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors) std::string GenerateTextureCopyVertexShader() { - std::stringstream ss; + std::ostringstream ss; EmitUniformBufferDeclaration(ss); - ss << "{"; - ss << " float2 src_offset;\n"; - ss << " float2 src_size;\n"; - ss << "};\n\n"; + ss << "{" + " float2 src_offset;\n" + " float2 src_size;\n" + "};\n\n"; EmitVertexMainDeclaration(ss, 0, 0, false, 1, 0, GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " : "#define id gl_VertexID"); - ss << "{\n"; - ss << " 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"; - ss << " v_tex0 = float3(src_offset + (src_size * v_tex0.xy), 0.0f);\n"; + ss << "{\n" + " v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n" + " opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.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. if (GetAPIType() == APIType::Vulkan || GetAPIType() == APIType::OpenGL) @@ -338,35 +354,35 @@ std::string GenerateTextureCopyVertexShader() std::string GenerateTextureCopyPixelShader() { - std::stringstream ss; + std::ostringstream ss; EmitSamplerDeclarations(ss, 0, 1, false); EmitPixelMainDeclaration(ss, 1, 0); - ss << "{\n"; - ss << " ocol0 = "; + ss << "{\n" + " ocol0 = "; EmitSampleTexture(ss, 0, "v_tex0"); - ss << ";\n"; - ss << "}\n"; + ss << ";\n" + "}\n"; return ss.str(); } std::string GenerateColorPixelShader() { - std::stringstream ss; + std::ostringstream ss; EmitPixelMainDeclaration(ss, 0, 1); - ss << "{\n"; - ss << " ocol0 = v_col0;\n"; - ss << "}\n"; + ss << "{\n" + " ocol0 = v_col0;\n" + "}\n"; return ss.str(); } std::string GenerateResolveDepthPixelShader(u32 samples) { - std::stringstream ss; + std::ostringstream ss; EmitSamplerDeclarations(ss, 0, 1, true); EmitPixelMainDeclaration(ss, 1, 0, "float", GetAPIType() == APIType::D3D ? "in float4 ipos : SV_Position, " : ""); - ss << "{\n"; - ss << " int layer = int(v_tex0.z);\n"; + ss << "{\n" + " int layer = int(v_tex0.z);\n"; if (GetAPIType() == APIType::D3D) ss << " int3 coords = int3(int2(ipos.xy), layer);\n"; else @@ -389,20 +405,20 @@ std::string GenerateResolveDepthPixelShader(u32 samples) std::string GenerateClearVertexShader() { - std::stringstream ss; + std::ostringstream ss; EmitUniformBufferDeclaration(ss); - ss << "{\n"; - ss << " float4 clear_color;\n"; - ss << " float clear_depth;\n"; - ss << "};\n"; + ss << "{\n" + " float4 clear_color;\n" + " float clear_depth;\n" + "};\n"; EmitVertexMainDeclaration(ss, 0, 0, false, 0, 1, GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " : "#define id gl_VertexID\n"); - ss << "{\n"; - ss << " 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"; - ss << " v_col0 = clear_color;\n"; + ss << "{\n" + " float2 coord = float2(float((id << 1) & 2), float(id & 2));\n" + " opos = float4(coord * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), clear_depth, 1.0f);\n" + " v_col0 = clear_color;\n"; // NDC space is flipped in Vulkan if (GetAPIType() == APIType::Vulkan) @@ -415,11 +431,11 @@ std::string GenerateClearVertexShader() std::string GenerateEFBPokeVertexShader() { - std::stringstream ss; + std::ostringstream ss; EmitVertexMainDeclaration(ss, 0, 1, true, 0, 1); - ss << "{\n"; - ss << " v_col0 = rawcolor0;\n"; - ss << " opos = float4(rawpos.xyz, 1.0f);\n"; + ss << "{\n" + " v_col0 = rawcolor0;\n" + " opos = float4(rawpos.xyz, 1.0f);\n"; if (g_ActiveConfig.backend_info.bSupportsLargePoints) ss << " gl_PointSize = rawpos.w;\n"; @@ -433,7 +449,7 @@ std::string GenerateEFBPokeVertexShader() std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samples) { - std::stringstream ss; + std::ostringstream ss; EmitSamplerDeclarations(ss, 0, 1, samples > 1); EmitPixelMainDeclaration( ss, 1, 0, "float4", @@ -442,8 +458,8 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp "in float4 ipos : SV_Position, in uint isample : SV_SampleIndex, " : "in float4 ipos : SV_Position, ") : ""); - ss << "{\n"; - ss << " int layer = int(v_tex0.z);\n"; + ss << "{\n" + " int layer = int(v_tex0.z);\n"; if (GetAPIType() == APIType::D3D) ss << " int3 coords = int3(int2(ipos.xy), layer);\n"; else @@ -480,13 +496,13 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp switch (convtype) { case EFBReinterpretType::RGB8ToRGBA6: - ss << " int4 src8 = int4(round(val * 255.f));\n"; - ss << " int4 dst6;\n"; - ss << " dst6.r = src8.r >> 2;\n"; - ss << " dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n"; - ss << " dst6.b = ((src8.g & 0xF) << 2) | (src8.b >> 6);\n"; - ss << " dst6.a = src8.b & 0x3F;\n"; - ss << " ocol0 = float4(dst6) / 63.f;\n"; + ss << " int4 src8 = int4(round(val * 255.f));\n" + " int4 dst6;\n" + " dst6.r = src8.r >> 2;\n" + " dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n" + " dst6.b = ((src8.g & 0xF) << 2) | (src8.b >> 6);\n" + " dst6.a = src8.b & 0x3F;\n" + " ocol0 = float4(dst6) / 63.f;\n"; break; case EFBReinterpretType::RGB8ToRGB565: @@ -494,13 +510,13 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp break; case EFBReinterpretType::RGBA6ToRGB8: - ss << " int4 src6 = int4(round(val * 63.f));\n"; - ss << " int4 dst8;\n"; - ss << " dst8.r = (src6.r << 2) | (src6.g >> 4);\n"; - ss << " dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n"; - ss << " dst8.b = ((src6.b & 0x3) << 6) | src6.a;\n"; - ss << " dst8.a = 255;\n"; - ss << " ocol0 = float4(dst8) / 255.f;\n"; + ss << " int4 src6 = int4(round(val * 63.f));\n" + " int4 dst8;\n" + " dst8.r = (src6.r << 2) | (src6.g >> 4);\n" + " dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n" + " dst8.b = ((src6.b & 0x3) << 6) | src6.a;\n" + " dst8.a = 255;\n" + " ocol0 = float4(dst8) / 255.f;\n"; break; case EFBReinterpretType::RGBA6ToRGB565: @@ -523,12 +539,12 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureFormat to_format) { - std::stringstream ss; + std::ostringstream ss; EmitSamplerDeclarations(ss, 0, 1, false); EmitPixelMainDeclaration(ss, 1, 0, "float4", "", true); - ss << "{\n"; - ss << " int layer = int(v_tex0.z);\n"; - ss << " int4 coords = int4(int2(frag_coord.xy), layer, 0);\n"; + ss << "{\n" + " int layer = int(v_tex0.z);\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 // zeroes. @@ -540,8 +556,8 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF { ss << " float4 temp_value = "; EmitTextureLoad(ss, 0, "coords"); - ss << ";\n"; - ss << " raw_value = uint(temp_value.r * 255.0);\n"; + ss << ";\n" + " raw_value = uint(temp_value.r * 255.0);\n"; } break; @@ -549,8 +565,8 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF { ss << " float4 temp_value = "; EmitTextureLoad(ss, 0, "coords"); - ss << ";\n"; - ss << " raw_value = uint(temp_value.r * 255.0) | (uint(temp_value.a * 255.0) << 8);\n"; + ss << ";\n" + " raw_value = uint(temp_value.r * 255.0) | (uint(temp_value.a * 255.0) << 8);\n"; } break; @@ -558,8 +574,8 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF { ss << " float4 temp_value = "; EmitTextureLoad(ss, 0, "coords"); - ss << ";\n"; - ss << " raw_value = uint(temp_value.r * 15.0) | (uint(temp_value.a * 15.0) << 4);\n"; + ss << ";\n" + " raw_value = uint(temp_value.r * 15.0) | (uint(temp_value.a * 15.0) << 4);\n"; } break; @@ -567,9 +583,9 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF { ss << " float4 temp_value = "; EmitTextureLoad(ss, 0, "coords"); - ss << ";\n"; - ss << " 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"; + ss << ";\n" + " raw_value = uint(temp_value.b * 31.0) | (uint(temp_value.g * 63.0) << 5) |\n" + " (uint(temp_value.r * 31.0) << 11);\n"; } break; @@ -580,13 +596,13 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF ss << ";\n"; // 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 << " 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"; - ss << " } else {\n"; - ss << " 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"; - ss << " }\n"; + ss << " if (temp_value.a > 0.878f) {\n" + " raw_value = (uint(temp_value.b * 31.0)) | (uint(temp_value.g * 31.0) << 5) |\n" + " (uint(temp_value.r * 31.0) << 10) | 0x8000u;\n" + " } else {\n" + " raw_value = (uint(temp_value.b * 15.0)) | (uint(temp_value.g * 15.0) << 4) |\n" + " (uint(temp_value.r * 15.0) << 8) | (uint(temp_value.a * 7.0) << 12);\n" + " }\n"; } break; } @@ -597,45 +613,45 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF case TextureFormat::I8: case TextureFormat::C8: { - ss << " float orgba = float(raw_value & 0xFFu) / 255.0;\n"; - ss << " ocol0 = float4(orgba, orgba, orgba, orgba);\n"; + ss << " float orgba = float(raw_value & 0xFFu) / 255.0;\n" + " ocol0 = float4(orgba, orgba, orgba, orgba);\n"; } break; case TextureFormat::IA8: { - ss << " float orgb = float(raw_value & 0xFFu) / 255.0;\n"; - ss << " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 8) & 0xFFu) / 255.0);\n"; + ss << " float orgb = float(raw_value & 0xFFu) / 255.0;\n" + " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 8) & 0xFFu) / 255.0);\n"; } break; case TextureFormat::IA4: { - ss << " float orgb = float(raw_value & 0xFu) / 15.0;\n"; - ss << " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 4) & 0xFu) / 15.0);\n"; + ss << " float orgb = float(raw_value & 0xFu) / 15.0;\n" + " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 4) & 0xFu) / 15.0);\n"; } break; case TextureFormat::RGB565: { - ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n"; - ss << " float((raw_value >> 5) & 0x1Fu) / 31.0,\n"; - ss << " float(raw_value & 0x1Fu) / 31.0, 1.0);\n"; + ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n" + " float((raw_value >> 5) & 0x1Fu) / 31.0,\n" + " float(raw_value & 0x1Fu) / 31.0, 1.0);\n"; } break; case TextureFormat::RGB5A3: { - ss << " if ((raw_value & 0x8000u) != 0u) {\n"; - ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n"; - ss << " float((raw_value >> 5) & 0x1Fu) / 31.0,\n"; - ss << " float(raw_value & 0x1Fu) / 31.0, 1.0);\n"; - ss << " } else {\n"; - ss << " ocol0 = float4(float((raw_value >> 8) & 0x0Fu) / 15.0,\n"; - ss << " float((raw_value >> 4) & 0x0Fu) / 15.0,\n"; - ss << " float(raw_value & 0x0Fu) / 15.0,\n"; - ss << " float((raw_value >> 12) & 0x07u) / 7.0);\n"; - ss << " }\n"; + ss << " if ((raw_value & 0x8000u) != 0u) {\n" + " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n" + " float((raw_value >> 5) & 0x1Fu) / 31.0,\n" + " float(raw_value & 0x1Fu) / 31.0, 1.0);\n" + " } else {\n" + " ocol0 = float4(float((raw_value >> 8) & 0x0Fu) / 15.0,\n" + " float((raw_value >> 4) & 0x0Fu) / 15.0,\n" + " float(raw_value & 0x0Fu) / 15.0,\n" + " float((raw_value >> 12) & 0x07u) / 7.0);\n" + " }\n"; } break; } @@ -646,37 +662,37 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF std::string GenerateEFBRestorePixelShader() { - std::stringstream ss; + std::ostringstream ss; EmitSamplerDeclarations(ss, 0, 2, false); EmitPixelMainDeclaration(ss, 1, 0, "float4", GetAPIType() == APIType::D3D ? "out float depth : SV_Depth, " : ""); - ss << "{\n"; - ss << " ocol0 = "; + ss << "{\n" + " ocol0 = "; EmitSampleTexture(ss, 0, "v_tex0"); ss << ";\n"; ss << " " << (GetAPIType() == APIType::D3D ? "depth" : "gl_FragDepth") << " = "; EmitSampleTexture(ss, 1, "v_tex0"); - ss << ".r;\n"; - ss << "}\n"; + ss << ".r;\n" + "}\n"; return ss.str(); } std::string GenerateImGuiVertexShader() { - std::stringstream ss; + std::ostringstream ss; // Uniform buffer contains the viewport size, and we transform in the vertex shader. EmitUniformBufferDeclaration(ss); - ss << "{\n"; - ss << "float2 u_rcp_viewport_size_mul2;\n"; - ss << "};\n\n"; + ss << "{\n" + "float2 u_rcp_viewport_size_mul2;\n" + "};\n\n"; EmitVertexMainDeclaration(ss, 1, 1, true, 1, 1); ss << "{\n" - << " v_tex0 = float3(rawtex0.xy, 0.0);\n" - << " v_col0 = rawcolor0;\n" - << " 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"; + " v_tex0 = float3(rawtex0.xy, 0.0);\n" + " v_col0 = rawcolor0;\n" + " 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"; // NDC space is flipped in Vulkan. if (GetAPIType() == APIType::Vulkan) @@ -688,14 +704,14 @@ std::string GenerateImGuiVertexShader() std::string GenerateImGuiPixelShader() { - std::stringstream ss; + std::ostringstream ss; EmitSamplerDeclarations(ss, 0, 1, false); EmitPixelMainDeclaration(ss, 1, 1); - ss << "{\n"; - ss << " ocol0 = "; + ss << "{\n" + " ocol0 = "; EmitSampleTexture(ss, 0, "float3(v_tex0.xy, 0.0)"); - ss << " * v_col0;\n"; - ss << "}\n"; + ss << " * v_col0;\n" + "}\n"; return ss.str(); } diff --git a/Source/Core/VideoCommon/FramebufferShaderGen.h b/Source/Core/VideoCommon/FramebufferShaderGen.h index c6186a4aa3..eed3066fbb 100644 --- a/Source/Core/VideoCommon/FramebufferShaderGen.h +++ b/Source/Core/VideoCommon/FramebufferShaderGen.h @@ -1,25 +1,17 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + #pragma once + #include -#include "VideoCommon/VideoCommon.h" +#include "Common/CommonTypes.h" enum class EFBReinterpretType; enum class TextureFormat; namespace FramebufferShaderGen { -struct Config -{ - Config(APIType api_type_, u32 efb_samples_, u32 efb_layers_, bool ssaa_) - : api_type(api_type_), efb_samples(efb_samples_), efb_layers(efb_layers_), ssaa(ssaa_) - { - } - - APIType api_type; - u32 efb_samples; - u32 efb_layers; - bool ssaa; -}; - std::string GenerateScreenQuadVertexShader(); std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors); std::string GenerateTextureCopyVertexShader();