From 3355d8086dc449c7d0325273eafcc999cfc649ee Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 23 Nov 2014 02:13:25 +0100 Subject: [PATCH] D3DUtil: Use a geometry shader to clear all slices. --- Source/Core/VideoBackends/D3D/D3DUtil.cpp | 15 +++++-- Source/Core/VideoBackends/D3D/D3DUtil.h | 2 +- .../VideoBackends/D3D/GeometryShaderCache.cpp | 41 +++++++++++++++++++ .../VideoBackends/D3D/GeometryShaderCache.h | 2 + Source/Core/VideoBackends/D3D/Render.cpp | 2 +- 5 files changed, 56 insertions(+), 6 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/D3DUtil.cpp b/Source/Core/VideoBackends/D3D/D3DUtil.cpp index 89bdbcee97..28b9850902 100644 --- a/Source/Core/VideoBackends/D3D/D3DUtil.cpp +++ b/Source/Core/VideoBackends/D3D/D3DUtil.cpp @@ -10,6 +10,7 @@ #include "VideoBackends/D3D/D3DShader.h" #include "VideoBackends/D3D/D3DState.h" #include "VideoBackends/D3D/D3DUtil.h" +#include "VideoBackends/D3D/GeometryShaderCache.h" #include "VideoBackends/D3D/PixelShaderCache.h" #include "VideoBackends/D3D/VertexShaderCache.h" @@ -653,6 +654,7 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2) } stateman->SetVertexShader(VertexShaderCache::GetClearVertexShader()); + stateman->SetGeometryShader(g_ActiveConfig.iStereoMode > 0 ? GeometryShaderCache::GetClearGeometryShader() : nullptr); stateman->SetPixelShader(PixelShaderCache::GetClearProgram()); stateman->SetInputLayout(VertexShaderCache::GetClearInputLayout()); @@ -663,9 +665,11 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2) stateman->Apply(); context->Draw(4, cq_offset); + + stateman->SetGeometryShader(nullptr); } -void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout) +void drawClearQuad(u32 Color, float z) { ClearVertex coords[4] = { {-1.0f, 1.0f, z, Color}, @@ -683,9 +687,10 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS clear_quad_data.z = z; } - stateman->SetVertexShader(Vshader); - stateman->SetPixelShader(PShader); - stateman->SetInputLayout(layout); + stateman->SetVertexShader(VertexShaderCache::GetClearVertexShader()); + stateman->SetGeometryShader(g_ActiveConfig.iStereoMode > 0 ? GeometryShaderCache::GetClearGeometryShader() : nullptr); + stateman->SetPixelShader(PixelShaderCache::GetClearProgram()); + stateman->SetInputLayout(VertexShaderCache::GetClearInputLayout()); UINT stride = sizeof(ClearVertex); UINT offset = 0; @@ -694,6 +699,8 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS stateman->Apply(); context->Draw(4, clearq_offset); + + stateman->SetGeometryShader(nullptr); } } // namespace D3D diff --git a/Source/Core/VideoBackends/D3D/D3DUtil.h b/Source/Core/VideoBackends/D3D/D3DUtil.h index 53706847c2..0f2dd72adb 100644 --- a/Source/Core/VideoBackends/D3D/D3DUtil.h +++ b/Source/Core/VideoBackends/D3D/D3DUtil.h @@ -74,7 +74,7 @@ namespace D3D ID3D11InputLayout* layout, float Gamma = 1.0f, u32 slice = 0); - void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout); + void drawClearQuad(u32 Color, float z); void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2); } diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp index a7bc1a470e..087428a200 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp @@ -27,8 +27,12 @@ const GeometryShaderCache::GSCacheEntry* GeometryShaderCache::last_entry; GeometryShaderUid GeometryShaderCache::last_uid; UidChecker GeometryShaderCache::geometry_uid_checker; +ID3D11GeometryShader* ClearGeometryShader = nullptr; + LinearDiskCache g_gs_disk_cache; +ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader() { return ClearGeometryShader; } + ID3D11Buffer* gscbuf = nullptr; // this class will load the precompiled shaders into our cache @@ -41,8 +45,43 @@ public: } }; +const char clear_shader_code[] = { + "struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vColor0 : COLOR0;\n" + "};\n" + "struct GSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vColor0 : COLOR0;\n" + "uint slice : SV_RenderTargetArrayIndex;\n" + "};\n" + "[maxvertexcount(6)]\n" + "void main(triangle VSOUTPUT o[3], inout TriangleStream Output)\n" + "{\n" + "for(int slice = 0; slice < 2; slice++)\n" + "{\n" + "for(int i = 0; i < 3; i++)\n" + "{\n" + "GSOUTPUT OUT;\n" + "OUT.vPosition = o[i].vPosition;\n" + "OUT.vColor0 = o[i].vColor0;\n" + "OUT.slice = slice;\n" + "Output.Append(OUT);\n" + "}\n" + "Output.RestartStrip();\n" + "}\n" + "}\n" +}; + void GeometryShaderCache::Init() { + // used when drawing clear quads + ClearGeometryShader = D3D::CompileAndCreateGeometryShader(clear_shader_code); + CHECK(ClearGeometryShader != nullptr, "Create clear geometry shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearGeometryShader, "clear geometry shader"); + Clear(); if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) @@ -72,6 +111,8 @@ void GeometryShaderCache::Clear() void GeometryShaderCache::Shutdown() { + SAFE_RELEASE(ClearGeometryShader); + Clear(); g_gs_disk_cache.Sync(); g_gs_disk_cache.Close(); diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.h b/Source/Core/VideoBackends/D3D/GeometryShaderCache.h index b200323be8..38a524c596 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.h +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.h @@ -21,6 +21,8 @@ public: static bool SetShader(u32 components); // TODO: Should be renamed to LoadShader static bool InsertByteCode(const GeometryShaderUid &uid, const void* bytecode, unsigned int bytecodelen); + static ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader(); + static ID3D11GeometryShader* GetActiveShader() { return last_entry->shader; } private: diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 0cd5835b60..3d0b365242 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -547,7 +547,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE // Color is passed in bgra mode so we need to convert it to rgba u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000); - D3D::drawClearQuad(rgbaColor, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader(), VertexShaderCache::GetClearInputLayout()); + D3D::drawClearQuad(rgbaColor, (z & 0xFFFFFF) / float(0xFFFFFF)); D3D::stateman->PopDepthState(); D3D::stateman->PopBlendState();