From 252550fbd2d4c425bcab058cdc876ff0fd60056b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 7 Aug 2022 13:19:27 +0200 Subject: [PATCH] Enable framebuffer depth blits through raster. Fixes games like Jeanne D'Arc on D3D9. --- Common/GPU/ShaderWriter.cpp | 45 ++++++++++++++++--- Common/GPU/ShaderWriter.h | 9 +++- GPU/Common/DepalettizeShaderCommon.cpp | 4 +- GPU/Common/Draw2D.cpp | 55 +++++++++++++++++------ GPU/Common/FramebufferManagerCommon.cpp | 58 +++++++++++++++++-------- GPU/Common/FramebufferManagerCommon.h | 10 +++-- GPU/Common/ReinterpretFramebuffer.cpp | 4 +- GPU/Common/StencilCommon.cpp | 4 +- 8 files changed, 140 insertions(+), 49 deletions(-) diff --git a/Common/GPU/ShaderWriter.cpp b/Common/GPU/ShaderWriter.cpp index 1671d5d6a5..d57a855ac7 100644 --- a/Common/GPU/ShaderWriter.cpp +++ b/Common/GPU/ShaderWriter.cpp @@ -212,7 +212,7 @@ void ShaderWriter::BeginVSMain(Slice inputs, Slice uniform } } -void ShaderWriter::BeginFSMain(Slice uniforms, Slice varyings) { +void ShaderWriter::BeginFSMain(Slice uniforms, Slice varyings, FSFlags flags) { _assert_(this->stage_ == ShaderStage::Fragment); switch (lang_.shaderLanguage) { case HLSL_D3D11: @@ -226,29 +226,56 @@ void ShaderWriter::BeginFSMain(Slice uniforms, Slice var C("};\n"); } + if (flags & FSFLAG_WRITEDEPTH) { + C("float gl_FragDepth;\n"); + } + + C("struct PS_OUT {\n"); + C(" vec4 target : SV_Target0;\n"); + if (flags & FSFLAG_WRITEDEPTH) { + C(" float depth : SV_Depth;\n"); + } + C("};\n"); + // Let's do the varyings as parameters to main, no struct. - C("vec4 main("); + C("PS_OUT main("); for (auto &varying : varyings) { F(" %s %s : %s, ", varying.type, varying.name, semanticNames[varying.semantic]); } // Erase the last comma Rewind(2); - F(") : SV_Target0 {\n"); + F(") {\n"); + C(" PS_OUT ps_out;\n"); + if (flags & FSFLAG_WRITEDEPTH) { + C(" float gl_FragDepth;\n"); + } break; case HLSL_D3D9: + C("struct PS_OUT {\n"); + C(" vec4 target : SV_Target0;\n"); + if (flags & FSFLAG_WRITEDEPTH) { + C(" float depth : DEPTH;\n"); + } + C("};\n"); + for (auto &uniform : uniforms) { F(" %s %s : register(c%d);\n", uniform.type, uniform.name, uniform.index); } // Let's do the varyings as parameters to main, no struct. - C("vec4 main("); + C("PS_OUT main("); for (auto &varying : varyings) { F(" %s %s : %s, ", varying.type, varying.name, semanticNames[varying.semantic]); } // Erase the last comma Rewind(2); - F(") : COLOR {\n"); + F(") {\n"); + C(" PS_OUT ps_out;\n"); + if (flags & FSFLAG_WRITEDEPTH) { + C(" float gl_FragDepth;\n"); + } + break; case GLSL_VULKAN: for (auto &varying : varyings) { @@ -299,12 +326,16 @@ void ShaderWriter::EndVSMain(Slice varyings) { C("}\n"); } -void ShaderWriter::EndFSMain(const char *vec4_color_variable) { +void ShaderWriter::EndFSMain(const char *vec4_color_variable, FSFlags flags) { _assert_(this->stage_ == ShaderStage::Fragment); switch (lang_.shaderLanguage) { case HLSL_D3D11: case HLSL_D3D9: - F(" return %s;\n", vec4_color_variable); + F(" ps_out.target = %s;\n", vec4_color_variable); + if (flags & FSFLAG_WRITEDEPTH) { + C(" ps_out.depth = gl_FragDepth;\n"); + } + C(" return ps_out;\n"); break; case GLSL_VULKAN: default: // OpenGL diff --git a/Common/GPU/ShaderWriter.h b/Common/GPU/ShaderWriter.h index 0624a8aca9..9d16f2bf9a 100644 --- a/Common/GPU/ShaderWriter.h +++ b/Common/GPU/ShaderWriter.h @@ -36,6 +36,11 @@ struct VaryingDef { const char *precision; }; +enum FSFlags { + FSFLAG_NONE = 0, + FSFLAG_WRITEDEPTH = 1, +}; + class ShaderWriter { public: ShaderWriter(char *buffer, const ShaderLanguageDesc &lang, ShaderStage stage, const char **gl_extensions, size_t num_gl_extensions) : p_(buffer), lang_(lang), stage_(stage) { @@ -82,11 +87,11 @@ public: // Simple shaders with no special tricks. void BeginVSMain(Slice inputs, Slice uniforms, Slice varyings); - void BeginFSMain(Slice uniforms, Slice varyings); + void BeginFSMain(Slice uniforms, Slice varyings, FSFlags flags); // For simple shaders that output a single color, we can deal with this generically. void EndVSMain(Slice varyings); - void EndFSMain(const char *vec4_color_variable); + void EndFSMain(const char *vec4_color_variable, FSFlags flags); void Rewind(size_t offset) { diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index 45e6dba76e..c35cc0e41f 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -267,7 +267,7 @@ void GenerateDepalFs(char *buffer, const DepalConfig &config, const ShaderLangua ShaderWriter writer(buffer, lang, ShaderStage::Fragment, nullptr, 0); writer.DeclareSamplers(samplers); writer.HighPrecisionFloat(); - writer.BeginFSMain(Slice::empty(), varyings); + writer.BeginFSMain(Slice::empty(), varyings, FSFLAG_NONE); switch (lang.shaderLanguage) { case HLSL_D3D9: case GLSL_1xx: @@ -281,7 +281,7 @@ void GenerateDepalFs(char *buffer, const DepalConfig &config, const ShaderLangua default: _assert_msg_(false, "Depal shader language not supported: %d", (int)lang.shaderLanguage); } - writer.EndFSMain("outColor"); + writer.EndFSMain("outColor", FSFLAG_NONE); } void GenerateDepalVs(char *buffer, const ShaderLanguageDesc &lang) { diff --git a/GPU/Common/Draw2D.cpp b/GPU/Common/Draw2D.cpp index 9dedfd2782..1ea143bd8a 100644 --- a/GPU/Common/Draw2D.cpp +++ b/GPU/Common/Draw2D.cpp @@ -39,12 +39,21 @@ static const SamplerDef samplers[1] = { { "tex" }, }; -void GenerateDraw2DFs(char *buffer, const ShaderLanguageDesc &lang, const Draw::Bugs &bugs) { +void GenerateDraw2DFs(char *buffer, const ShaderLanguageDesc &lang) { ShaderWriter writer(buffer, lang, ShaderStage::Fragment, nullptr, 0); writer.DeclareSamplers(samplers); - writer.BeginFSMain(Slice::empty(), varyings); + writer.BeginFSMain(Slice::empty(), varyings, FSFLAG_NONE); writer.C(" vec4 outColor = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n"); - writer.EndFSMain("outColor"); + writer.EndFSMain("outColor", FSFLAG_NONE); +} + +void GenerateDraw2DDepthFs(char *buffer, const ShaderLanguageDesc &lang) { + ShaderWriter writer(buffer, lang, ShaderStage::Fragment, nullptr, 0); + writer.DeclareSamplers(samplers); + writer.BeginFSMain(Slice::empty(), varyings, FSFLAG_WRITEDEPTH); + writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n"); + writer.C(" gl_FragDepth = ").SampleTexture2D("tex", "v_texcoord.xy").C(".x;\n"); + writer.EndFSMain("outColor", FSFLAG_WRITEDEPTH); } void GenerateDraw2DVS(char *buffer, const ShaderLanguageDesc &lang) { @@ -60,21 +69,24 @@ void GenerateDraw2DVS(char *buffer, const ShaderLanguageDesc &lang) { } // verts have positions in clip coordinates. -void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter) { +void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter, RasterChannel channel) { using namespace Draw; - if (!draw2DPipelineLinear_) { + if (!draw2DPipelineColor_) { const ShaderLanguageDesc &shaderLanguageDesc = draw_->GetShaderLanguageDesc(); char *fsCode = new char[4000]; + char *fsDepthCode = new char[4000]; char *vsCode = new char[4000]; - GenerateDraw2DFs(fsCode, shaderLanguageDesc, draw_->GetBugs()); + GenerateDraw2DFs(fsCode, shaderLanguageDesc); + GenerateDraw2DDepthFs(fsDepthCode, shaderLanguageDesc); GenerateDraw2DVS(vsCode, shaderLanguageDesc); draw2DFs_ = draw_->CreateShaderModule(ShaderStage::Fragment, shaderLanguageDesc.shaderLanguage, (const uint8_t *)fsCode, strlen(fsCode), "draw2d_fs"); + draw2DFsDepth_ = draw_->CreateShaderModule(ShaderStage::Fragment, shaderLanguageDesc.shaderLanguage, (const uint8_t *)fsDepthCode, strlen(fsDepthCode), "draw2d_depth_fs"); draw2DVs_ = draw_->CreateShaderModule(ShaderStage::Vertex, shaderLanguageDesc.shaderLanguage, (const uint8_t *)vsCode, strlen(vsCode), "draw2d_vs"); - _assert_(draw2DFs_ && draw2DVs_); + _assert_(draw2DFs_ && draw2DVs_ && draw2DFsDepth_); InputLayoutDesc desc = { { @@ -88,24 +100,41 @@ void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *ver InputLayout *inputLayout = draw_->CreateInputLayout(desc); BlendState *blendOff = draw_->CreateBlendState({ false, 0xF }); - DepthStencilStateDesc dsDesc{}; - DepthStencilState *noDepthStencil = draw_->CreateDepthStencilState(dsDesc); + BlendState *blendDiscard = draw_->CreateBlendState({ false, 0x0 }); + + DepthStencilState *noDepthStencil = draw_->CreateDepthStencilState(DepthStencilStateDesc{}); RasterState *rasterNoCull = draw_->CreateRasterState({}); - PipelineDesc stencilWriteDesc{ + DepthStencilStateDesc dsWriteDesc{}; + dsWriteDesc.depthTestEnabled = true; + dsWriteDesc.depthWriteEnabled = true; + dsWriteDesc.depthCompare = Draw::Comparison::ALWAYS; + DepthStencilState *depthWriteAlways = draw_->CreateDepthStencilState(dsWriteDesc); + + PipelineDesc draw2DColorPipelineDesc{ Primitive::TRIANGLE_STRIP, { draw2DVs_, draw2DFs_ }, inputLayout, noDepthStencil, blendOff, rasterNoCull, nullptr, }; - draw2DPipelineLinear_ = draw_->CreateGraphicsPipeline(stencilWriteDesc); - _assert_(draw2DPipelineLinear_); + + draw2DPipelineColor_ = draw_->CreateGraphicsPipeline(draw2DColorPipelineDesc); + + PipelineDesc draw2DDepthPipelineDesc{ + Primitive::TRIANGLE_STRIP, + { draw2DVs_, draw2DFsDepth_ }, + inputLayout, depthWriteAlways, blendDiscard, rasterNoCull, nullptr, + }; + draw2DPipelineDepth_ = draw_->CreateGraphicsPipeline(draw2DDepthPipelineDesc); + _assert_(draw2DPipelineDepth_); delete[] fsCode; delete[] vsCode; rasterNoCull->Release(); blendOff->Release(); + blendDiscard->Release(); noDepthStencil->Release(); + depthWriteAlways->Release(); inputLayout->Release(); SamplerStateDesc descLinear{}; @@ -125,7 +154,7 @@ void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *ver draw2DSamplerNearest_ = draw_->CreateSamplerState(descNearest); } - draw_->BindPipeline(draw2DPipelineLinear_); + draw_->BindPipeline(channel == RASTER_COLOR ? draw2DPipelineColor_ : draw2DPipelineDepth_); if (tex) { draw_->BindTextures(TEX_SLOT_PSP_TEXTURE, 1, &tex); } diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 7d5077b298..42603951c7 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -564,6 +564,8 @@ void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { _dbg_assert_(src && dst); + _dbg_assert_(src != dst); + // Check that the depth address is even the same before actually blitting. bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = (src->width == dst->width || (src->width == 512 && dst->width == 480) || (src->width == 480 && dst->width == 512)) && src->height == dst->height; @@ -579,7 +581,14 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir return; } - gpuStats.numDepthCopies++; + bool useCopy = draw_->GetDeviceCaps().framebufferSeparateDepthCopySupported || (!draw_->GetDeviceCaps().framebufferDepthBlitSupported && draw_->GetDeviceCaps().framebufferCopySupported); + bool useBlit = draw_->GetDeviceCaps().framebufferDepthBlitSupported; + + // Attempt at optimization - if destination already bound, draw depth using raster + if (true || currentRenderVfb_ == dst) { + useCopy = false; + useBlit = false; + } int w = std::min(src->renderWidth, dst->renderWidth); int h = std::min(src->renderHeight, dst->renderHeight); @@ -587,14 +596,20 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir // TODO: It might even be advantageous on some GPUs to do this copy using a fragment shader that writes to Z, that way upcoming commands can just continue that render pass. // Some GPUs can copy depth but only if stencil gets to come along for the ride. We only want to use this if there is no blit functionality. - if (draw_->GetDeviceCaps().framebufferSeparateDepthCopySupported || (!draw_->GetDeviceCaps().framebufferDepthBlitSupported && draw_->GetDeviceCaps().framebufferCopySupported)) { + if (useCopy) { draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); RebindFramebuffer("After BlitFramebufferDepth"); - } else if (draw_->GetDeviceCaps().framebufferDepthBlitSupported) { + } else if (useBlit) { // We'll accept whether we get a separate depth blit or not... draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); RebindFramebuffer("After BlitFramebufferDepth"); + } else { + BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, RasterChannel::RASTER_DEPTH); } + + draw_->InvalidateCachedState(); + + gpuStats.numDepthCopies++; dst->last_frame_depth_updated = gpuStats.numFlips; } @@ -2495,11 +2510,13 @@ void FramebufferManagerCommon::DeviceLost() { DoRelease(stencilUploadVs_); DoRelease(stencilUploadSampler_); DoRelease(stencilUploadPipeline_); - DoRelease(draw2DPipelineLinear_); + DoRelease(draw2DPipelineColor_); + DoRelease(draw2DPipelineDepth_); DoRelease(draw2DSamplerNearest_); DoRelease(draw2DSamplerLinear_); DoRelease(draw2DVs_); DoRelease(draw2DFs_); + DoRelease(draw2DFsDepth_); presentation_->DeviceLost(); draw_ = nullptr; } @@ -2557,15 +2574,18 @@ void FramebufferManagerCommon::DrawActiveTexture(float x, float y, float w, floa // Rearrange to strip form. std::swap(coord[2], coord[3]); - DrawStrip2D(nullptr, coord, 4, (flags & DRAWTEX_LINEAR) != 0); + DrawStrip2D(nullptr, coord, 4, (flags & DRAWTEX_LINEAR) != 0, RASTER_COLOR); gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE); } void FramebufferManagerCommon::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) { + RasterChannel channel = RASTER_COLOR; + if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if they recently switched from non-buffered. if (useBufferedRendering_) { + // Just bind the back buffer for rendering, forget about doing anything else as we're in a weird state. draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitFramebuffer"); } return; @@ -2638,30 +2658,35 @@ void FramebufferManagerCommon::BlitFramebuffer(VirtualFramebuffer *dst, int dstX const bool xOverlap = src == dst && srcX2 > dstX1 && srcX1 < dstX2; const bool yOverlap = src == dst && srcY2 > dstY1 && srcY1 < dstY2; if (sameSize && srcInsideBounds && dstInsideBounds && !(xOverlap && yOverlap)) { - draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1, Draw::FB_COLOR_BIT, tag); + draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1, + channel == RASTER_COLOR ? Draw::FB_COLOR_BIT : Draw::FB_DEPTH_BIT, tag); return; } } if (useBlit) { - draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST, tag); + draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, + channel == RASTER_COLOR ? Draw::FB_COLOR_BIT : Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, tag); } else { Draw::Framebuffer *srcFBO = src->fbo; if (src == dst) { Draw::Framebuffer *tempFBO = GetTempFBO(TempFBO::BLIT, src->renderWidth, src->renderHeight); - BlitUsingRaster(src->fbo, srcX1, srcY1, srcX2, srcY2, tempFBO, dstX1, dstY1, dstX2, dstY2, false); + BlitUsingRaster(src->fbo, srcX1, srcY1, srcX2, srcY2, tempFBO, dstX1, dstY1, dstX2, dstY2, false, channel); srcFBO = tempFBO; } - BlitUsingRaster(srcFBO, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, false); + BlitUsingRaster(srcFBO, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, false, channel); } + draw_->InvalidateCachedState(); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE); } void FramebufferManagerCommon::BlitUsingRaster( Draw::Framebuffer *src, float srcX1, float srcY1, float srcX2, float srcY2, Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2, - bool linearFilter) { + bool linearFilter, + RasterChannel channel) { int destW, destH, srcW, srcH; draw_->GetFramebufferDimensions(src, &srcW, &srcH); @@ -2678,17 +2703,16 @@ void FramebufferManagerCommon::BlitUsingRaster( { -1.0f + 2.0f * dX * destX2, -(1.0f - 2.0f * dY * destY2), sX * srcX2, sY * srcY2 }, }; - if (dest != currentRenderVfb_->fbo) { - // Unbind the texture first to avoid the D3D11 hazard check (can't set render target to things bound as textures and vice versa, not even temporarily). - draw_->BindTexture(0, nullptr); - draw_->BindFramebufferAsRenderTarget(dest, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitUsingRaster"); - } - draw_->BindFramebufferAsTexture(src, 0, Draw::FB_COLOR_BIT, 0); + // Unbind the texture first to avoid the D3D11 hazard check (can't set render target to things bound as textures and vice versa, not even temporarily). + draw_->BindTexture(0, nullptr); + // This will get optimized away in case it's already bound (in VK and GL at least..) + draw_->BindFramebufferAsRenderTarget(dest, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitUsingRaster"); + draw_->BindFramebufferAsTexture(src, 0, channel == RASTER_COLOR ? Draw::FB_COLOR_BIT : Draw::FB_DEPTH_BIT, 0); Draw::Viewport vp{ 0.0f, 0.0f, (float)dest->Width(), (float)dest->Height(), 0.0f, 1.0f }; draw_->SetViewports(1, &vp); draw_->SetScissorRect(0, 0, (int)dest->Width(), (int)dest->Height()); - DrawStrip2D(nullptr, vtx, 4, linearFilter); + DrawStrip2D(nullptr, vtx, 4, linearFilter, channel); gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE); } diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index a1557cfed8..5277d6a03e 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -359,7 +359,7 @@ protected: Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height); void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags); - void DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter); + void DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter, RasterChannel channel); bool UpdateSize(); @@ -367,11 +367,11 @@ protected: virtual void DecimateFBOs(); // keeping it virtual to let D3D do a little extra // Used by ReadFramebufferToMemory and later framebuffer block copies - virtual void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag); + void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag); void BlitUsingRaster( Draw::Framebuffer *src, float srcX1, float srcY1, float srcX2, float srcY2, - Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2, bool linearFilter); + Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2, bool linearFilter, RasterChannel channel); void CopyFramebufferForColorTexture(VirtualFramebuffer *dst, VirtualFramebuffer *src, int flags); @@ -485,9 +485,11 @@ protected: Draw::SamplerState *stencilUploadSampler_ = nullptr; // Draw2D pipelines - Draw::Pipeline *draw2DPipelineLinear_ = nullptr; + Draw::Pipeline *draw2DPipelineColor_ = nullptr; + Draw::Pipeline *draw2DPipelineDepth_ = nullptr; Draw::SamplerState *draw2DSamplerLinear_ = nullptr; Draw::SamplerState *draw2DSamplerNearest_ = nullptr; Draw::ShaderModule *draw2DVs_ = nullptr; Draw::ShaderModule *draw2DFs_ = nullptr; + Draw::ShaderModule *draw2DFsDepth_ = nullptr; }; diff --git a/GPU/Common/ReinterpretFramebuffer.cpp b/GPU/Common/ReinterpretFramebuffer.cpp index f0066e0313..71b0b24910 100644 --- a/GPU/Common/ReinterpretFramebuffer.cpp +++ b/GPU/Common/ReinterpretFramebuffer.cpp @@ -28,7 +28,7 @@ bool GenerateReinterpretFragmentShader(char *buffer, GEBufferFormat from, GEBuff writer.DeclareSamplers(samplers); - writer.BeginFSMain(Slice::empty(), varyings); + writer.BeginFSMain(Slice::empty(), varyings, FSFLAG_NONE); writer.C(" vec4 val = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n"); @@ -68,7 +68,7 @@ bool GenerateReinterpretFragmentShader(char *buffer, GEBufferFormat from, GEBuff break; } - writer.EndFSMain("outColor"); + writer.EndFSMain("outColor", FSFLAG_NONE); return true; } diff --git a/GPU/Common/StencilCommon.cpp b/GPU/Common/StencilCommon.cpp index 0881771ce3..950c84dd35 100644 --- a/GPU/Common/StencilCommon.cpp +++ b/GPU/Common/StencilCommon.cpp @@ -94,7 +94,7 @@ void GenerateStencilFs(char *buffer, const ShaderLanguageDesc &lang, const Draw: writer.C("float roundAndScaleTo255f(in float x) { return floor(x * 255.99); }\n"); - writer.BeginFSMain(uniforms, varyings); + writer.BeginFSMain(uniforms, varyings, FSFLAG_NONE); writer.C(" vec4 index = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n"); writer.C(" vec4 outColor = index.aaaa;\n"); // Only care about a. @@ -106,7 +106,7 @@ void GenerateStencilFs(char *buffer, const ShaderLanguageDesc &lang, const Draw: writer.C(" gl_FragDepth = gl_FragCoord.z;\n"); } - writer.EndFSMain("outColor"); + writer.EndFSMain("outColor", FSFLAG_NONE); } // This can probably be shared with some other shaders, like reinterpret or the future depth upload.