From ba242d27c8318b0d902383de4ddf43e7c6c9e9ae Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 21 Dec 2014 15:21:43 +0100 Subject: [PATCH 1/4] FramebufferManager: Support stereoscopic EFB format changes. --- .../VideoBackends/OGL/FramebufferManager.cpp | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp index e9d2ba7294..63ef72b083 100644 --- a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp @@ -207,8 +207,8 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms // non-msaa, so just fetch the pixel sampler = "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n" - "vec4 sampleEFB(ivec2 pos) {\n" - " return texelFetch(samp9, ivec3(pos, 0), 0);\n" + "vec4 sampleEFB(ivec3 pos) {\n" + " return texelFetch(samp9, pos, 0);\n" "}\n"; } else if (g_ogl_config.bSupportSampleShading) @@ -220,16 +220,16 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms { sampler = "SAMPLER_BINDING(9) uniform sampler2DMSArray samp9;\n" - "vec4 sampleEFB(ivec2 pos) {\n" - " return texelFetch(samp9, ivec3(pos, 0), gl_SampleID);\n" + "vec4 sampleEFB(ivec3 pos) {\n" + " return texelFetch(samp9, pos, gl_SampleID);\n" "}\n"; } else { sampler = "SAMPLER_BINDING(9) uniform sampler2DMS samp9;\n" - "vec4 sampleEFB(ivec2 pos) {\n" - " return texelFetch(samp9, pos, gl_SampleID);\n" + "vec4 sampleEFB(ivec3 pos) {\n" + " return texelFetch(samp9, pos.xy, gl_SampleID);\n" "}\n"; } } @@ -242,10 +242,10 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms { sampler = "SAMPLER_BINDING(9) uniform sampler2DMSArray samp9;\n" - "vec4 sampleEFB(ivec2 pos) {\n" + "vec4 sampleEFB(ivec3 pos) {\n" " vec4 color = vec4(0.0, 0.0, 0.0, 0.0);\n" " for(int i=0; i<" + samples.str() + "; i++)\n" - " color += texelFetch(samp9, ivec3(pos, 0), i);\n" + " color += texelFetch(samp9, pos, 0), i);\n" " return color / " + samples.str() + ";\n" "}\n"; } @@ -253,10 +253,10 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms { sampler = "SAMPLER_BINDING(9) uniform sampler2DMS samp9;\n" - "vec4 sampleEFB(ivec2 pos) {\n" + "vec4 sampleEFB(ivec3 pos) {\n" " vec4 color = vec4(0.0, 0.0, 0.0, 0.0);\n" " for(int i=0; i<" + samples.str() + "; i++)\n" - " color += texelFetch(samp9, pos, i);\n" + " color += texelFetch(samp9, pos.xy, i);\n" " return color / " + samples.str() + ";\n" "}\n"; } @@ -266,7 +266,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms "out vec4 ocol0;\n" "void main()\n" "{\n" - " ivec4 src6 = ivec4(round(sampleEFB(ivec2(gl_FragCoord.xy)) * 63.f));\n" + " ivec4 src6 = ivec4(round(sampleEFB(ivec3(gl_FragCoord.xyz)) * 63.f));\n" " ivec4 dst8;\n" " dst8.r = (src6.r << 2) | (src6.g >> 4);\n" " dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n" @@ -279,7 +279,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms "out vec4 ocol0;\n" "void main()\n" "{\n" - " ivec4 src8 = ivec4(round(sampleEFB(ivec2(gl_FragCoord.xy)) * 255.f));\n" + " ivec4 src8 = ivec4(round(sampleEFB(ivec3(gl_FragCoord.xyz)) * 255.f));\n" " ivec4 dst6;\n" " dst6.r = src8.r >> 2;\n" " dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n" @@ -288,8 +288,26 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms " ocol0 = float4(dst6) / 63.f;\n" "}"; - ProgramShaderCache::CompileShader(m_pixel_format_shaders[0], vs, ps_rgb8_to_rgba6.c_str()); - ProgramShaderCache::CompileShader(m_pixel_format_shaders[1], vs, ps_rgba6_to_rgb8.c_str()); + std::stringstream vertices; + vertices << m_EFBLayers * 3; + std::string gs = sampler + + "layout(triangles) in;\n" + "layout(triangle_strip, max_vertices = " + vertices.str() + ") out;\n" + "void main()\n" + "{\n" + " int layers = textureSize(samp9, 0).z;\n" + " for (int layer = 0; layer < layers; ++layer) {\n" + " for (int i = 0; i < 3; ++i) {\n" + " gl_Position = vec4(gl_in[i].gl_Position.xy, layer, 1.0);\n" + " gl_Layer = layer;\n" + " EmitVertex();\n" + " }\n" + " EndPrimitive();\n" + " }\n" + "}\n"; + + ProgramShaderCache::CompileShader(m_pixel_format_shaders[0], vs, ps_rgb8_to_rgba6.c_str(), (m_EFBLayers > 1) ? gs.c_str() : nullptr); + ProgramShaderCache::CompileShader(m_pixel_format_shaders[1], vs, ps_rgba6_to_rgb8.c_str(), (m_EFBLayers > 1) ? gs.c_str() : nullptr); } FramebufferManager::~FramebufferManager() From 737bc0e7ad7bbd22887b108d0d164aef955e73f0 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 21 Dec 2014 15:37:05 +0100 Subject: [PATCH 2/4] PixelShaderCache: Support stereoscopic EFB format changes. --- Source/Core/VideoBackends/D3D/D3DUtil.cpp | 2 +- .../VideoBackends/D3D/GeometryShaderCache.cpp | 5 ++-- .../VideoBackends/D3D/PixelShaderCache.cpp | 28 +++++++++---------- Source/Core/VideoBackends/D3D/Render.cpp | 2 +- .../Core/VideoBackends/D3D/TextureCache.cpp | 3 +- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/D3DUtil.cpp b/Source/Core/VideoBackends/D3D/D3DUtil.cpp index ad9acc809f..020045d687 100644 --- a/Source/Core/VideoBackends/D3D/D3DUtil.cpp +++ b/Source/Core/VideoBackends/D3D/D3DUtil.cpp @@ -697,7 +697,7 @@ void drawClearQuad(u32 Color, float z) } stateman->SetVertexShader(VertexShaderCache::GetClearVertexShader()); - stateman->SetGeometryShader(g_ActiveConfig.iStereoMode > 0 ? GeometryShaderCache::GetClearGeometryShader() : nullptr); + stateman->SetGeometryShader(GeometryShaderCache::GetClearGeometryShader()); stateman->SetPixelShader(PixelShaderCache::GetClearProgram()); stateman->SetInputLayout(VertexShaderCache::GetClearInputLayout()); diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp index 59b0e3ff65..a5cfcd235f 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp @@ -12,6 +12,7 @@ #include "VideoBackends/D3D/D3DBase.h" #include "VideoBackends/D3D/D3DShader.h" +#include "VideoBackends/D3D/FramebufferManager.h" #include "VideoBackends/D3D/GeometryShaderCache.h" #include "VideoBackends/D3D/Globals.h" @@ -35,8 +36,8 @@ ID3D11GeometryShader* CopyGeometryShader = nullptr; LinearDiskCache g_gs_disk_cache; -ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader() { return ClearGeometryShader; } -ID3D11GeometryShader* GeometryShaderCache::GetCopyGeometryShader() { return CopyGeometryShader; } +ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader() { return (FramebufferManager::GetEFBLayers() > 1) ? ClearGeometryShader: nullptr; } +ID3D11GeometryShader* GeometryShaderCache::GetCopyGeometryShader() { return (FramebufferManager::GetEFBLayers() > 1) ? CopyGeometryShader : nullptr; } ID3D11Buffer* gscbuf = nullptr; diff --git a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp index ae1919c91e..a94d113c4f 100644 --- a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp @@ -201,11 +201,11 @@ const char depth_matrix_program_msaa[] = { const char reint_rgba6_to_rgb8[] = { "sampler samp0 : register(s0);\n" - "Texture2D Tex0 : register(t0);\n" + "Texture2DArray Tex0 : register(t0);\n" "void main(\n" " out float4 ocol0 : SV_Target,\n" " in float4 pos : SV_Position,\n" - " in float2 uv0 : TEXCOORD0)\n" + " in float3 uv0 : TEXCOORD0)\n" "{\n" " int4 src6 = round(Tex0.Sample(samp0,uv0) * 63.f);\n" " int4 dst8;\n" @@ -219,17 +219,17 @@ const char reint_rgba6_to_rgb8[] = { const char reint_rgba6_to_rgb8_msaa[] = { "sampler samp0 : register(s0);\n" - "Texture2DMS Tex0 : register(t0);\n" + "Texture2DMSArray Tex0 : register(t0);\n" "void main(\n" " out float4 ocol0 : SV_Target,\n" " in float4 pos : SV_Position,\n" - " in float2 uv0 : TEXCOORD0)\n" + " in float3 uv0 : TEXCOORD0)\n" "{\n" - " int width, height, samples;\n" - " Tex0.GetDimensions(width, height, samples);\n" + " int width, height, slices, samples;\n" + " Tex0.GetDimensions(width, height, slices, samples);\n" " float4 texcol = 0;\n" " for (int i = 0; i < samples; ++i)\n" - " texcol += Tex0.Load(int2(uv0.x*(width), uv0.y*(height)), i);\n" + " texcol += Tex0.Load(int3(uv0.x*(width), uv0.y*(height), uv0.z), i);\n" " texcol /= samples;\n" " int4 src6 = round(texcol * 63.f);\n" " int4 dst8;\n" @@ -243,11 +243,11 @@ const char reint_rgba6_to_rgb8_msaa[] = { const char reint_rgb8_to_rgba6[] = { "sampler samp0 : register(s0);\n" - "Texture2D Tex0 : register(t0);\n" + "Texture2DArray Tex0 : register(t0);\n" "void main(\n" " out float4 ocol0 : SV_Target,\n" " in float4 pos : SV_Position,\n" - " in float2 uv0 : TEXCOORD0)\n" + " in float3 uv0 : TEXCOORD0)\n" "{\n" " int4 src8 = round(Tex0.Sample(samp0,uv0) * 255.f);\n" " int4 dst6;\n" @@ -261,17 +261,17 @@ const char reint_rgb8_to_rgba6[] = { const char reint_rgb8_to_rgba6_msaa[] = { "sampler samp0 : register(s0);\n" - "Texture2DMS Tex0 : register(t0);\n" + "Texture2DMSArray Tex0 : register(t0);\n" "void main(\n" " out float4 ocol0 : SV_Target,\n" " in float4 pos : SV_Position,\n" - " in float2 uv0 : TEXCOORD0)\n" + " in float3 uv0 : TEXCOORD0)\n" "{\n" - " int width, height, samples;\n" - " Tex0.GetDimensions(width, height, samples);\n" + " int width, height, slices, samples;\n" + " Tex0.GetDimensions(width, height, slices, samples);\n" " float4 texcol = 0;\n" " for (int i = 0; i < samples; ++i)\n" - " texcol += Tex0.Load(int2(uv0.x*(width), uv0.y*(height)), i);\n" + " texcol += Tex0.Load(int3(uv0.x*(width), uv0.y*(height), uv0.z), i);\n" " texcol /= samples;\n" " int4 src8 = round(texcol * 255.f);\n" " int4 dst6;\n" diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 84b83ef1f0..3f411bdd3f 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -577,7 +577,7 @@ void Renderer::ReinterpretPixelData(unsigned int convtype) D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTempTexture()->GetRTV(), nullptr); D3D::SetPointCopySampler(); - D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &source, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), pixel_shader, VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); + D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &source, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), pixel_shader, VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); g_renderer->RestoreAPIState(); diff --git a/Source/Core/VideoBackends/D3D/TextureCache.cpp b/Source/Core/VideoBackends/D3D/TextureCache.cpp index b251a30682..af1267c1de 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D/TextureCache.cpp @@ -168,8 +168,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo (srcFormat == PEControl::Z24) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(), &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), (srcFormat == PEControl::Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), - VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), - (g_Config.iStereoMode > 0) ? GeometryShaderCache::GetCopyGeometryShader() : nullptr); + VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); From 01718eafa629b79719a606d0b2719a35267d263a Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Tue, 23 Dec 2014 12:32:01 +0100 Subject: [PATCH 3/4] FramebufferManager: Use a separate layer variable. --- .../VideoBackends/OGL/FramebufferManager.cpp | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp index 63ef72b083..731cf389d2 100644 --- a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp @@ -192,10 +192,16 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // reinterpret pixel format - char vs[] = + const char* vs = m_EFBLayers > 1 ? "void main(void) {\n" " vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);\n" " gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n" + "}\n" : + "flat out int layer;\n" + "void main(void) {\n" + " layer = 0;\n" + " vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);\n" + " gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n" "}\n"; // The way to sample the EFB is based on the on the current configuration. @@ -263,10 +269,11 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms } std::string ps_rgba6_to_rgb8 = sampler + + "flat in int layer;\n" "out vec4 ocol0;\n" "void main()\n" "{\n" - " ivec4 src6 = ivec4(round(sampleEFB(ivec3(gl_FragCoord.xyz)) * 63.f));\n" + " ivec4 src6 = ivec4(round(sampleEFB(ivec3(gl_FragCoord.xy, layer)) * 63.f));\n" " ivec4 dst8;\n" " dst8.r = (src6.r << 2) | (src6.g >> 4);\n" " dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n" @@ -276,10 +283,11 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms "}"; std::string ps_rgb8_to_rgba6 = sampler + + "flat in int layer;\n" "out vec4 ocol0;\n" "void main()\n" "{\n" - " ivec4 src8 = ivec4(round(sampleEFB(ivec3(gl_FragCoord.xyz)) * 255.f));\n" + " ivec4 src8 = ivec4(round(sampleEFB(ivec3(gl_FragCoord.xy, layer)) * 255.f));\n" " ivec4 dst6;\n" " dst6.r = src8.r >> 2;\n" " dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n" @@ -288,18 +296,20 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms " ocol0 = float4(dst6) / 63.f;\n" "}"; - std::stringstream vertices; + std::stringstream vertices, layers; vertices << m_EFBLayers * 3; + layers << m_EFBLayers; std::string gs = sampler + "layout(triangles) in;\n" "layout(triangle_strip, max_vertices = " + vertices.str() + ") out;\n" + "flat out int layer;\n" "void main()\n" "{\n" - " int layers = textureSize(samp9, 0).z;\n" - " for (int layer = 0; layer < layers; ++layer) {\n" + " for (int j = 0; j < " + layers.str() + "; ++j) {\n" " for (int i = 0; i < 3; ++i) {\n" - " gl_Position = vec4(gl_in[i].gl_Position.xy, layer, 1.0);\n" - " gl_Layer = layer;\n" + " layer = j;\n" + " gl_Layer = j;\n" + " gl_Position = gl_in[i].gl_Position;\n" " EmitVertex();\n" " }\n" " EndPrimitive();\n" From b2efbdaf44b6ad7d05caa0be4ba23756a5f7b6b5 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Tue, 23 Dec 2014 12:33:45 +0100 Subject: [PATCH 4/4] Cosmetics. --- Source/Core/VideoBackends/D3D/Render.cpp | 3 ++- Source/Core/VideoBackends/OGL/TextureCache.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 3f411bdd3f..c309882e75 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -577,7 +577,8 @@ void Renderer::ReinterpretPixelData(unsigned int convtype) D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTempTexture()->GetRTV(), nullptr); D3D::SetPointCopySampler(); - D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &source, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), pixel_shader, VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); + D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &source, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), + pixel_shader, VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); g_renderer->RestoreAPIState(); diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp index f697d51c73..97bc487675 100644 --- a/Source/Core/VideoBackends/OGL/TextureCache.cpp +++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp @@ -400,7 +400,7 @@ void TextureCache::CompileShaders() " gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n" "}\n"; - const char *GProgram = (g_ActiveConfig.iStereoMode > 0) ? + const char *GProgram = FramebufferManager::GetEFBLayers() > 1 ? "layout(triangles) in;\n" "layout(triangle_strip, max_vertices = 6) out;\n" "in vec3 v_uv0[3];\n" @@ -421,7 +421,7 @@ void TextureCache::CompileShaders() "}\n" : nullptr; const char* prefix = (GProgram == nullptr) ? "f" : "v"; - const char* depth_layer = (g_ActiveConfig.bStereoMonoEFBDepth) ? "0" : "f_uv0.z"; + const char* depth_layer = (g_ActiveConfig.bStereoMonoEFBDepth) ? "0.0" : "f_uv0.z"; ProgramShaderCache::CompileShader(s_ColorMatrixProgram, StringFromFormat(VProgram, prefix, prefix).c_str(), pColorMatrixProg, GProgram); ProgramShaderCache::CompileShader(s_DepthMatrixProgram, StringFromFormat(VProgram, prefix, prefix).c_str(), StringFromFormat(pDepthMatrixProg, depth_layer).c_str(), GProgram);