diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index bca9e5c8dd..1d3630919c 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -114,7 +114,7 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config) { break; case GE_FORMAT_DEPTH16: // Decode depth buffer. - writer.C(" float depth = (color.x - z_offset) * z_scale;\n"); + writer.C(" float depth = (color.x - z_offset) * z_scale * 65535.0f;\n"); if (config.bufferFormat == GE_FORMAT_DEPTH16 && config.textureFormat == GE_TFMT_5650) { // Convert depth to 565, without going through a CLUT. diff --git a/GPU/Common/Draw2D.cpp b/GPU/Common/Draw2D.cpp index 0ffb2a0722..4f19277956 100644 --- a/GPU/Common/Draw2D.cpp +++ b/GPU/Common/Draw2D.cpp @@ -39,11 +39,12 @@ static const SamplerDef samplers[1] = { { 0, "tex", SamplerFlags::ARRAY_ON_VULKAN }, }; -const UniformDef g_draw2Duniforms[4] = { +const UniformDef g_draw2Duniforms[5] = { { "vec2", "texSize", 0 }, { "float", "scaleFactor", 1}, { "float", "z_scale", 2 }, - { "float", "z_offset", 3 }, + { "float", "z_scale_inv", 3 }, + { "float", "z_offset", 4 }, }; struct Draw2DUB { @@ -51,6 +52,7 @@ struct Draw2DUB { float texSizeY; float scaleFactor; float zScale; + float zScaleInv; float zOffset; }; @@ -58,7 +60,8 @@ const UniformBufferDesc draw2DUBDesc{ sizeof(Draw2DUB), { { "texSize", -1, 0, UniformType::FLOAT2, 0 }, { "scaleFactor", -1, 1, UniformType::FLOAT1, 8 }, { "z_scale", -1, 1, UniformType::FLOAT1, 12 }, - { "z_offset", -1, 1, UniformType::FLOAT1, 16 }, + { "z_scale_inv", -1, 1, UniformType::FLOAT1, 16 }, + { "z_offset", -1, 1, UniformType::FLOAT1, 20 }, } }; Draw2DPipelineInfo GenerateDraw2DCopyColorFs(ShaderWriter &writer) { @@ -100,23 +103,41 @@ Draw2DPipelineInfo GenerateDraw2DCopyDepthFs(ShaderWriter &writer) { writer.EndFSMain("outColor"); return Draw2DPipelineInfo{ - "draw2d_copy_r16_to_depth", + "draw2d_copy_depth", RASTER_DEPTH, // Unused in this case, I think. RASTER_DEPTH, }; } +Draw2DPipelineInfo GenerateDraw2DEncodeDepthFs(ShaderWriter &writer) { + writer.SetFlags(ShaderWriterFlags::FS_WRITE_DEPTH); + writer.HighPrecisionFloat(); + writer.DeclareSamplers(samplers); + writer.BeginFSMain(g_draw2Duniforms, varyings); + writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n"); + writer.C(" float depthValue = ").SampleTexture2D("tex", "v_texcoord.xy").C(".x;\n"); + writer.C(" gl_FragDepth = (depthValue * z_scale_inv) + z_offset;\n"); + writer.EndFSMain("outColor"); + + return Draw2DPipelineInfo{ + "draw2d_copy_r16_to_depth", + RASTER_COLOR, + RASTER_DEPTH, + }; +} + Draw2DPipelineInfo GenerateDraw2D565ToDepthFs(ShaderWriter &writer) { writer.SetFlags(ShaderWriterFlags::FS_WRITE_DEPTH); + writer.HighPrecisionFloat(); writer.DeclareSamplers(samplers); - writer.BeginFSMain(Slice::empty(), varyings); + writer.BeginFSMain(g_draw2Duniforms, varyings); writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n"); // Unlike when just copying a depth buffer, here we're generating new depth values so we'll // have to apply the scaling. DepthScaleFactors factors = GetDepthScaleFactors(gstate_c.UseFlags()); writer.C(" vec3 rgb = ").SampleTexture2D("tex", "v_texcoord.xy").C(".xyz;\n"); - writer.F(" highp float depthValue = (floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0); \n"); - writer.F(" gl_FragDepth = (depthValue / %f) + %f;\n", factors.ScaleU16(), factors.Offset()); + writer.F(" float depthValue = ((floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0)) / 65535.0; \n"); + writer.C(" gl_FragDepth = (depthValue * z_scale_inv) + z_offset;\n"); writer.EndFSMain("outColor"); return Draw2DPipelineInfo{ @@ -128,6 +149,7 @@ Draw2DPipelineInfo GenerateDraw2D565ToDepthFs(ShaderWriter &writer) { Draw2DPipelineInfo GenerateDraw2D565ToDepthDeswizzleFs(ShaderWriter &writer) { writer.SetFlags(ShaderWriterFlags::FS_WRITE_DEPTH); + writer.HighPrecisionFloat(); writer.DeclareSamplers(samplers); writer.BeginFSMain(g_draw2Duniforms, varyings); writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n"); @@ -140,11 +162,11 @@ Draw2DPipelineInfo GenerateDraw2D565ToDepthDeswizzleFs(ShaderWriter &writer) { writer.C(" float in_strip = mod(coord.y, strip);\n"); writer.C(" coord.y = coord.y - in_strip + strip - in_strip;\n"); writer.C(" coord /= tsize;\n"); - writer.C(" vec3 rgb = ").SampleTexture2D("tex", "coord").C(".xyz;\n"); - writer.F(" highp float depthValue = (floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0); \n"); - writer.F(" gl_FragDepth = (depthValue / %f) + %f;\n", factors.ScaleU16(), factors.Offset()); + writer.C(" highp vec3 rgb = ").SampleTexture2D("tex", "coord").C(".xyz;\n"); + writer.F(" highp float depthValue = floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0; \n"); + writer.C(" gl_FragDepth = z_offset + ((depthValue / 65535.0) * z_scale_inv);\n"); writer.EndFSMain("outColor"); - + return Draw2DPipelineInfo{ "draw2d_565_to_depth_deswizzle", RASTER_COLOR, @@ -253,7 +275,7 @@ Draw2DPipeline *Draw2D::Create2DPipeline(std::functionCreateInputLayout(desc); - BlendState *blend = draw_->CreateBlendState({ false, info.writeChannel == RASTER_COLOR ? 0xF : 0 }); + BlendState *blend = draw_->CreateBlendState({ false, info.writeChannel == RASTER_COLOR ? 0xF : 0x0 }); DepthStencilStateDesc dsDesc{}; if (info.writeChannel == RASTER_DEPTH) { @@ -326,6 +348,7 @@ void Draw2D::DrawStrip2D(Draw::Texture *tex, const Draw2DVertex *verts, int vert DepthScaleFactors zScaleFactors = GetDepthScaleFactors(gstate_c.UseFlags()); ub.zScale = zScaleFactors.Scale(); + ub.zScaleInv = 1.0f / ub.zScale; ub.zOffset = zScaleFactors.Offset(); draw_->BindPipeline(pipeline->pipeline); @@ -352,10 +375,10 @@ Draw2DPipeline *FramebufferManagerCommon::Get2DPipeline(Draw2DShader shader) { switch (shader) { case DRAW2D_COPY_COLOR: - if (!draw2DPipelineColor_) { - draw2DPipelineColor_ = draw2D_.Create2DPipeline(&GenerateDraw2DCopyColorFs); + if (!draw2DPipelineCopyColor_) { + draw2DPipelineCopyColor_ = draw2D_.Create2DPipeline(&GenerateDraw2DCopyColorFs); } - pipeline = draw2DPipelineColor_; + pipeline = draw2DPipelineCopyColor_; break; case DRAW2D_COPY_COLOR_RECT2LIN: @@ -364,16 +387,26 @@ Draw2DPipeline *FramebufferManagerCommon::Get2DPipeline(Draw2DShader shader) { } pipeline = draw2DPipelineColorRect2Lin_; break; - - case DRAW2D_COPY_R16_TO_DEPTH: + case DRAW2D_COPY_DEPTH: if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) { // Can't do it return nullptr; } - if (!draw2DPipelineDepth_) { - draw2DPipelineDepth_ = draw2D_.Create2DPipeline(&GenerateDraw2DCopyDepthFs); + if (!draw2DPipelineCopyDepth_) { + draw2DPipelineCopyDepth_ = draw2D_.Create2DPipeline(&GenerateDraw2DCopyDepthFs); } - pipeline = draw2DPipelineDepth_; + pipeline = draw2DPipelineCopyDepth_; + break; + + case DRAW2D_ENCODE_R16_TO_DEPTH: + if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) { + // Can't do it + return nullptr; + } + if (!draw2DPipelineEncodeDepth_) { + draw2DPipelineEncodeDepth_ = draw2D_.Create2DPipeline(&GenerateDraw2DEncodeDepthFs); + } + pipeline = draw2DPipelineEncodeDepth_; break; case DRAW2D_565_TO_DEPTH: diff --git a/GPU/Common/Draw2D.h b/GPU/Common/Draw2D.h index 4302a3fa2e..5df67f7493 100644 --- a/GPU/Common/Draw2D.h +++ b/GPU/Common/Draw2D.h @@ -13,7 +13,8 @@ struct Draw2DVertex { enum Draw2DShader { DRAW2D_COPY_COLOR, - DRAW2D_COPY_R16_TO_DEPTH, + DRAW2D_COPY_DEPTH, + DRAW2D_ENCODE_R16_TO_DEPTH, DRAW2D_565_TO_DEPTH, DRAW2D_565_TO_DEPTH_DESWIZZLE, DRAW2D_COPY_COLOR_RECT2LIN, @@ -21,9 +22,10 @@ enum Draw2DShader { inline RasterChannel Draw2DSourceChannel(Draw2DShader shader) { switch (shader) { - case DRAW2D_COPY_R16_TO_DEPTH: + case DRAW2D_COPY_DEPTH: return RASTER_DEPTH; case DRAW2D_COPY_COLOR: + case DRAW2D_ENCODE_R16_TO_DEPTH: case DRAW2D_565_TO_DEPTH: case DRAW2D_565_TO_DEPTH_DESWIZZLE: default: @@ -38,7 +40,7 @@ struct Draw2DPipelineInfo { Slice samplers; }; -extern const UniformDef g_draw2Duniforms[4]; +extern const UniformDef g_draw2Duniforms[5]; struct Draw2DPipeline { Draw::Pipeline *pipeline; diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 9768449970..05289365e8 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -974,7 +974,7 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir // 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 (useRaster) { - BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, dst->renderScaleFactor, Get2DPipeline(Draw2DShader::DRAW2D_COPY_R16_TO_DEPTH), "BlitDepthRaster"); + BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, dst->renderScaleFactor, Get2DPipeline(Draw2DShader::DRAW2D_COPY_DEPTH), "BlitDepthRaster"); } else if (useCopy) { draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "CopyFramebufferDepth"); RebindFramebuffer("After BlitFramebufferDepth"); @@ -2964,9 +2964,10 @@ void FramebufferManagerCommon::ReleasePipelines() { DoRelease(stencilReadbackPipeline_); DoRelease(depthReadbackSampler_); DoRelease(depthReadbackPipeline_); - DoRelease(draw2DPipelineColor_); + DoRelease(draw2DPipelineCopyColor_); DoRelease(draw2DPipelineColorRect2Lin_); - DoRelease(draw2DPipelineDepth_); + DoRelease(draw2DPipelineCopyDepth_); + DoRelease(draw2DPipelineEncodeDepth_); DoRelease(draw2DPipeline565ToDepth_); DoRelease(draw2DPipeline565ToDepthDeswizzle_); } @@ -3036,7 +3037,7 @@ void FramebufferManagerCommon::DrawActiveTexture(float x, float y, float w, floa // Rearrange to strip form. std::swap(coord[2], coord[3]); - draw2D_.DrawStrip2D(nullptr, coord, 4, (flags & DRAWTEX_LINEAR) != 0, Get2DPipeline((flags & DRAWTEX_DEPTH) ? DRAW2D_COPY_R16_TO_DEPTH : DRAW2D_COPY_COLOR)); + draw2D_.DrawStrip2D(nullptr, coord, 4, (flags & DRAWTEX_LINEAR) != 0, Get2DPipeline((flags & DRAWTEX_DEPTH) ? DRAW2D_ENCODE_R16_TO_DEPTH : DRAW2D_COPY_COLOR)); gstate_c.Dirty(DIRTY_ALL_RENDER_STATE); } @@ -3135,7 +3136,7 @@ void FramebufferManagerCommon::BlitFramebuffer(VirtualFramebuffer *dst, int dstX 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 { - Draw2DPipeline *pipeline = Get2DPipeline(channel == RASTER_COLOR ? DRAW2D_COPY_COLOR : DRAW2D_COPY_R16_TO_DEPTH); + Draw2DPipeline *pipeline = Get2DPipeline(channel == RASTER_COLOR ? DRAW2D_COPY_COLOR : DRAW2D_COPY_DEPTH); Draw::Framebuffer *srcFBO = src->fbo; if (src == dst) { Draw::Framebuffer *tempFBO = GetTempFBO(TempFBO::BLIT, src->renderWidth, src->renderHeight); diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index df33d549b4..ea4565e6c0 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -605,9 +605,10 @@ protected: Draw::SamplerState *depthReadbackSampler_ = nullptr; // Draw2D pipelines - Draw2DPipeline *draw2DPipelineColor_ = nullptr; + Draw2DPipeline *draw2DPipelineCopyColor_ = nullptr; Draw2DPipeline *draw2DPipelineColorRect2Lin_ = nullptr; - Draw2DPipeline *draw2DPipelineDepth_ = nullptr; + Draw2DPipeline *draw2DPipelineCopyDepth_ = nullptr; + Draw2DPipeline *draw2DPipelineEncodeDepth_ = nullptr; Draw2DPipeline *draw2DPipeline565ToDepth_ = nullptr; Draw2DPipeline *draw2DPipeline565ToDepthDeswizzle_ = nullptr;