From af849126b37b3a9adb9542437b134aca947b8f5a Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 2 Oct 2019 12:52:45 +1000 Subject: [PATCH] Renderer: Use interface blocks for ImGui shaders --- .../Core/VideoCommon/FramebufferShaderGen.cpp | 43 ++++++++- .../Core/VideoCommon/FramebufferShaderGen.h | 2 + Source/Core/VideoCommon/RenderBase.cpp | 90 +------------------ 3 files changed, 46 insertions(+), 89 deletions(-) diff --git a/Source/Core/VideoCommon/FramebufferShaderGen.cpp b/Source/Core/VideoCommon/FramebufferShaderGen.cpp index 4917b2dba7..ca00f2c332 100644 --- a/Source/Core/VideoCommon/FramebufferShaderGen.cpp +++ b/Source/Core/VideoCommon/FramebufferShaderGen.cpp @@ -14,9 +14,9 @@ static APIType GetAPIType() static void EmitUniformBufferDeclaration(std::stringstream& ss) { if (GetAPIType() == APIType::D3D) - ss << "cbuffer UBO : register(b0)\n"; + ss << "cbuffer PSBlock : register(b0)\n"; else - ss << "UBO_BINDING(std140, 1) uniform UBO\n"; + ss << "UBO_BINDING(std140, 1) uniform PSBlock\n"; } static void EmitSamplerDeclarations(std::stringstream& ss, u32 start = 0, u32 end = 1, @@ -661,4 +661,43 @@ std::string GenerateEFBRestorePixelShader() return ss.str(); } +std::string GenerateImGuiVertexShader() +{ + std::stringstream 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"; + + 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"; + + // NDC space is flipped in Vulkan. + if (GetAPIType() == APIType::Vulkan) + ss << " opos.y = -opos.y;\n"; + + ss << "}\n"; + return ss.str(); +} + +std::string GenerateImGuiPixelShader() +{ + std::stringstream ss; + EmitSamplerDeclarations(ss, 0, 1, false); + EmitPixelMainDeclaration(ss, 1, 1); + ss << "{\n"; + ss << " ocol0 = "; + EmitSampleTexture(ss, 0, "float3(v_tex0.xy, 0.0)"); + ss << " * v_col0;\n"; + ss << "}\n"; + + return ss.str(); +} + } // namespace FramebufferShaderGen diff --git a/Source/Core/VideoCommon/FramebufferShaderGen.h b/Source/Core/VideoCommon/FramebufferShaderGen.h index 2ec50b4d76..c6186a4aa3 100644 --- a/Source/Core/VideoCommon/FramebufferShaderGen.h +++ b/Source/Core/VideoCommon/FramebufferShaderGen.h @@ -31,5 +31,7 @@ std::string GenerateColorPixelShader(); std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samples); std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureFormat to_format); std::string GenerateEFBRestorePixelShader(); +std::string GenerateImGuiVertexShader(); +std::string GenerateImGuiPixelShader(); } // namespace FramebufferShaderGen diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index c533814fc8..8559ca86b6 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -910,90 +910,6 @@ void Renderer::RecordVideoMemory() texMem); } -static std::string GenerateImGuiVertexShader() -{ - const APIType api_type = g_ActiveConfig.backend_info.api_type; - std::stringstream ss; - - // Uniform buffer contains the viewport size, and we transform in the vertex shader. - if (api_type == APIType::D3D) - ss << "cbuffer PSBlock : register(b0) {\n"; - else if (api_type == APIType::OpenGL) - ss << "UBO_BINDING(std140, 1) uniform PSBlock {\n"; - else if (api_type == APIType::Vulkan) - ss << "UBO_BINDING(std140, 1) uniform PSBlock {\n"; - ss << "float2 u_rcp_viewport_size_mul2;\n"; - ss << "};\n"; - - if (api_type == APIType::D3D) - { - ss << "void main(in float2 rawpos : POSITION,\n" - << " in float2 rawtex0 : TEXCOORD,\n" - << " in float4 rawcolor0 : COLOR,\n" - << " out float3 v_tex0 : TEXCOORD,\n" - << " out float4 v_col0 : COLOR,\n" - << " out float4 out_pos : SV_Position)\n"; - } - else - { - ss << "ATTRIBUTE_LOCATION(" << SHADER_POSITION_ATTRIB << ") in float2 rawpos;\n" - << "ATTRIBUTE_LOCATION(" << SHADER_TEXTURE0_ATTRIB << ") in float2 rawtex0;\n" - << "ATTRIBUTE_LOCATION(" << SHADER_COLOR0_ATTRIB << ") in float4 rawcolor0;\n" - << "VARYING_LOCATION(0) out float3 v_tex0;\n" - << "VARYING_LOCATION(1) out float4 v_col0;\n" - << "void main()\n"; - } - - ss << "{\n" - << " v_tex0 = float3(rawtex0, 0.0);\n" - << " v_col0 = rawcolor0;\n"; - - ss << " " << (api_type == APIType::D3D ? "out_pos" : "gl_Position") - << "= 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"; - - // Clip-space is flipped in Vulkan - if (api_type == APIType::Vulkan) - ss << " gl_Position.y = -gl_Position.y;\n"; - - ss << "}\n"; - return ss.str(); -} - -static std::string GenerateImGuiPixelShader() -{ - const APIType api_type = g_ActiveConfig.backend_info.api_type; - - std::stringstream ss; - if (api_type == APIType::D3D) - { - ss << "Texture2DArray tex0 : register(t0);\n" - << "SamplerState samp0 : register(s0);\n" - << "void main(in float3 v_tex0 : TEXCOORD,\n" - << " in float4 v_col0 : COLOR,\n" - << " out float4 ocol0 : SV_Target)\n"; - } - else - { - ss << "SAMPLER_BINDING(0) uniform sampler2DArray samp0;\n" - << "VARYING_LOCATION(0) in float3 v_tex0; \n" - << "VARYING_LOCATION(1) in float4 v_col0;\n" - << "FRAGMENT_OUTPUT_LOCATION(0) out float4 ocol0;\n" - << "void main()\n"; - } - - ss << "{\n"; - - if (api_type == APIType::D3D) - ss << " ocol0 = tex0.Sample(samp0, float3(v_tex0.xy, 0.0)) * v_col0;\n"; - else - ss << " ocol0 = texture(samp0, float3(v_tex0.xy, 0.0)) * v_col0;\n"; - - ss << "}\n"; - - return ss.str(); -} - bool Renderer::InitializeImGui() { if (!ImGui::CreateContext()) @@ -1054,10 +970,10 @@ bool Renderer::InitializeImGui() bool Renderer::RecompileImGuiPipeline() { - std::unique_ptr vertex_shader = - CreateShaderFromSource(ShaderStage::Vertex, GenerateImGuiVertexShader()); + std::unique_ptr vertex_shader = CreateShaderFromSource( + ShaderStage::Vertex, FramebufferShaderGen::GenerateImGuiVertexShader()); std::unique_ptr pixel_shader = - CreateShaderFromSource(ShaderStage::Pixel, GenerateImGuiPixelShader()); + CreateShaderFromSource(ShaderStage::Pixel, FramebufferShaderGen::GenerateImGuiPixelShader()); if (!vertex_shader || !pixel_shader) { PanicAlert("Failed to compile imgui shaders");