diff --git a/Source/Core/VideoBackends/D3D/D3DUtil.cpp b/Source/Core/VideoBackends/D3D/D3DUtil.cpp index 28b9850902..50eac8665b 100644 --- a/Source/Core/VideoBackends/D3D/D3DUtil.cpp +++ b/Source/Core/VideoBackends/D3D/D3DUtil.cpp @@ -511,8 +511,9 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture, int SourceWidth, int SourceHeight, ID3D11PixelShader* PShader, - ID3D11VertexShader* Vshader, + ID3D11VertexShader* VShader, ID3D11InputLayout* layout, + ID3D11GeometryShader* GShader, float Gamma, u32 slice) { @@ -556,13 +557,16 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture, D3D::stateman->SetVertexBuffer(util_vbuf->GetBuffer(), stride, offset); D3D::stateman->SetPixelShader(PShader); D3D::stateman->SetTexture(0, texture); - D3D::stateman->SetVertexShader(Vshader); + D3D::stateman->SetVertexShader(VShader); + D3D::stateman->SetGeometryShader(GShader); D3D::stateman->Apply(); D3D::context->Draw(4, stq_offset); D3D::stateman->SetTexture(0, nullptr); // immediately unbind the texture D3D::stateman->Apply(); + + D3D::stateman->SetGeometryShader(nullptr); } void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, @@ -571,8 +575,9 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, int SourceHeight, const MathUtil::Rectangle* rDest, ID3D11PixelShader* PShader, - ID3D11VertexShader* Vshader, + ID3D11VertexShader* VShader, ID3D11InputLayout* layout, + ID3D11GeometryShader* GShader, float Gamma, u32 slice) { @@ -618,13 +623,16 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, stateman->SetInputLayout(layout); stateman->SetTexture(0, texture); stateman->SetPixelShader(PShader); - stateman->SetVertexShader(Vshader); + stateman->SetVertexShader(VShader); + stateman->SetGeometryShader(GShader); stateman->Apply(); context->Draw(4, stsq_offset); stateman->SetTexture(0, nullptr); // immediately unbind the texture stateman->Apply(); + + stateman->SetGeometryShader(nullptr); } // Fills a certain area of the current render target with the specified color diff --git a/Source/Core/VideoBackends/D3D/D3DUtil.h b/Source/Core/VideoBackends/D3D/D3DUtil.h index 0f2dd72adb..883f232b28 100644 --- a/Source/Core/VideoBackends/D3D/D3DUtil.h +++ b/Source/Core/VideoBackends/D3D/D3DUtil.h @@ -62,6 +62,7 @@ namespace D3D ID3D11PixelShader* PShader, ID3D11VertexShader* VShader, ID3D11InputLayout* layout, + ID3D11GeometryShader* GShader = nullptr, float Gamma = 1.0f, u32 slice = 0); void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, @@ -70,8 +71,9 @@ namespace D3D int SourceHeight, const MathUtil::Rectangle* rDest, ID3D11PixelShader* PShader, - ID3D11VertexShader* Vshader, + ID3D11VertexShader* VShader, ID3D11InputLayout* layout, + ID3D11GeometryShader* GShader = nullptr, float Gamma = 1.0f, u32 slice = 0); void drawClearQuad(u32 Color, float z); diff --git a/Source/Core/VideoBackends/D3D/FramebufferManager.cpp b/Source/Core/VideoBackends/D3D/FramebufferManager.cpp index dc2bb0c5cb..a1b66dc3e7 100644 --- a/Source/Core/VideoBackends/D3D/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/D3D/FramebufferManager.cpp @@ -208,7 +208,7 @@ void XFBSource::CopyEFB(float Gamma) D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(), - VertexShaderCache::GetSimpleInputLayout(),Gamma); + VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp index 087428a200..03facfb674 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp @@ -28,10 +28,12 @@ GeometryShaderUid GeometryShaderCache::last_uid; UidChecker GeometryShaderCache::geometry_uid_checker; ID3D11GeometryShader* ClearGeometryShader = nullptr; +ID3D11GeometryShader* CopyGeometryShader = nullptr; LinearDiskCache g_gs_disk_cache; ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader() { return ClearGeometryShader; } +ID3D11GeometryShader* GeometryShaderCache::GetCopyGeometryShader() { return CopyGeometryShader; } ID3D11Buffer* gscbuf = nullptr; @@ -75,6 +77,40 @@ const char clear_shader_code[] = { "}\n" }; +const char copy_shader_code[] = { + "struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float3 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "};\n" + "struct GSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float3 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\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.vTexCoord = o[i].vTexCoord;\n" + "OUT.vTexCoord.z = slice;\n" + "OUT.vTexCoord1 = o[i].vTexCoord1;\n" + "OUT.slice = slice;\n" + "Output.Append(OUT);\n" + "}\n" + "Output.RestartStrip();\n" + "}\n" + "}\n" +}; + void GeometryShaderCache::Init() { // used when drawing clear quads @@ -82,6 +118,11 @@ void GeometryShaderCache::Init() CHECK(ClearGeometryShader != nullptr, "Create clear geometry shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearGeometryShader, "clear geometry shader"); + // used for buffer copy + CopyGeometryShader = D3D::CompileAndCreateGeometryShader(copy_shader_code); + CHECK(CopyGeometryShader != nullptr, "Create copy geometry shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)CopyGeometryShader, "copy geometry shader"); + Clear(); if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) @@ -112,6 +153,7 @@ void GeometryShaderCache::Clear() void GeometryShaderCache::Shutdown() { SAFE_RELEASE(ClearGeometryShader); + SAFE_RELEASE(CopyGeometryShader); Clear(); g_gs_disk_cache.Sync(); diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.h b/Source/Core/VideoBackends/D3D/GeometryShaderCache.h index 38a524c596..95672a0087 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.h +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.h @@ -22,6 +22,7 @@ public: static bool InsertByteCode(const GeometryShaderUid &uid, const void* bytecode, unsigned int bytecodelen); static ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader(); + static ID3D11GeometryShader* GeometryShaderCache::GetCopyGeometryShader(); static ID3D11GeometryShader* GetActiveShader() { return last_entry->shader; } diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 3d0b365242..2dcb8ee6b7 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -804,10 +804,10 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co D3D11_VIEWPORT rightVp = CD3D11_VIEWPORT((float)rightRc.left, (float)rightRc.top, (float)rightRc.GetWidth(), (float)rightRc.GetHeight()); D3D::context->RSSetViewports(1, &leftVp); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), Gamma, 0); + D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 0); D3D::context->RSSetViewports(1, &rightVp); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), Gamma, 1); + D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 1); D3D::context->RSSetViewports(1, &vp); } @@ -823,10 +823,10 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co D3D::context->OMSetRenderTargets(1, &s_3d_vision_texture->GetRTV(), nullptr); D3D::context->RSSetViewports(1, &leftVp); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), Gamma, 0); + D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 0); D3D::context->RSSetViewports(1, &rightVp); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), Gamma, 1); + D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 1); // Copy the left eye to the backbuffer, if Nvidia 3D Vision is enabled it should // recognize the signature and automatically include the right eye frame. @@ -838,7 +838,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co } else { - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), Gamma); + D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma); } } diff --git a/Source/Core/VideoBackends/D3D/TextureCache.cpp b/Source/Core/VideoBackends/D3D/TextureCache.cpp index 24ee1c9aa9..bef632e4fd 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D/TextureCache.cpp @@ -7,6 +7,7 @@ #include "VideoBackends/D3D/D3DState.h" #include "VideoBackends/D3D/D3DUtil.h" #include "VideoBackends/D3D/FramebufferManager.h" +#include "VideoBackends/D3D/GeometryShaderCache.h" #include "VideoBackends/D3D/PixelShaderCache.h" #include "VideoBackends/D3D/PSTextureEncoder.h" #include "VideoBackends/D3D/TextureCache.h" @@ -163,7 +164,8 @@ 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()); + VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), + (g_Config.iStereoMode > 0) ? GeometryShaderCache::GetCopyGeometryShader() : nullptr); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());