From 94ae0fabfafbf28a6fd116a4f8d9a72deb380950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 21 Sep 2022 18:33:15 +0200 Subject: [PATCH 1/2] CLUTs can be loaded from small rectangular textures. Need to linearize. Fixes #8406, although technically, we should wrap by bufw, not the texture width. --- GPU/Common/Draw2D.cpp | 24 ++++++++++++++++++++++++ GPU/Common/Draw2D.h | 1 + GPU/Common/FramebufferManagerCommon.cpp | 1 + GPU/Common/FramebufferManagerCommon.h | 1 + GPU/Common/TextureCacheCommon.cpp | 5 +++-- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/GPU/Common/Draw2D.cpp b/GPU/Common/Draw2D.cpp index ff7aab316965..49aaa0bd5bcd 100644 --- a/GPU/Common/Draw2D.cpp +++ b/GPU/Common/Draw2D.cpp @@ -70,6 +70,23 @@ Draw2DPipelineInfo GenerateDraw2DCopyColorFs(ShaderWriter &writer) { }; } +Draw2DPipelineInfo GenerateDraw2DCopyColorRect2LinFs(ShaderWriter &writer) { + writer.DeclareSamplers(samplers); + writer.BeginFSMain(g_draw2Duniforms, varyings, FSFLAG_NONE); + writer.C(" vec2 tSize = texSize / scaleFactor;\n"); + writer.C(" vec2 pixels = v_texcoord * tSize;\n"); + writer.C(" float u = mod(floor(pixels.x), tSize.x);\n"); + writer.C(" float v = floor(pixels.x / tSize.x);\n"); + writer.C(" vec4 outColor = ").SampleTexture2D("tex", "vec2(u, v) / tSize").C(";\n"); + writer.EndFSMain("outColor", FSFLAG_NONE); + + return Draw2DPipelineInfo{ + "draw2d_copy_color_rect2lin", + RASTER_COLOR, + RASTER_COLOR, + }; +} + Draw2DPipelineInfo GenerateDraw2DCopyDepthFs(ShaderWriter &writer) { writer.DeclareSamplers(samplers); writer.BeginFSMain(Slice::empty(), varyings, FSFLAG_WRITEDEPTH); @@ -318,6 +335,13 @@ Draw2DPipeline *FramebufferManagerCommon::Get2DPipeline(Draw2DShader shader) { pipeline = draw2DPipelineColor_; break; + case DRAW2D_COPY_COLOR_RECT2LIN: + if (!draw2DPipelineColorRect2Lin_) { + draw2DPipelineColorRect2Lin_ = draw2D_.Create2DPipeline(&GenerateDraw2DCopyColorRect2LinFs); + } + pipeline = draw2DPipelineColorRect2Lin_; + break; + case DRAW2D_COPY_DEPTH: if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) { // Can't do it diff --git a/GPU/Common/Draw2D.h b/GPU/Common/Draw2D.h index d44f7ff6134e..bf156e6d3953 100644 --- a/GPU/Common/Draw2D.h +++ b/GPU/Common/Draw2D.h @@ -16,6 +16,7 @@ enum Draw2DShader { DRAW2D_COPY_DEPTH, DRAW2D_565_TO_DEPTH, DRAW2D_565_TO_DEPTH_DESWIZZLE, + DRAW2D_COPY_COLOR_RECT2LIN, }; inline RasterChannel Draw2DSourceChannel(Draw2DShader shader) { diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index dd01c3c499cc..8d17f2d9ff1a 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -2701,6 +2701,7 @@ void FramebufferManagerCommon::DeviceLost() { DoRelease(stencilUploadSampler_); DoRelease(stencilUploadPipeline_); DoRelease(draw2DPipelineColor_); + DoRelease(draw2DPipelineColorRect2Lin_); DoRelease(draw2DPipelineDepth_); DoRelease(draw2DPipeline565ToDepth_); DoRelease(draw2DPipeline565ToDepthDeswizzle_); diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index a38cc328d569..20fd15f87aab 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -569,6 +569,7 @@ class FramebufferManagerCommon { // Draw2D pipelines Draw2DPipeline *draw2DPipelineColor_ = nullptr; + Draw2DPipeline *draw2DPipelineColorRect2Lin_ = nullptr; Draw2DPipeline *draw2DPipelineDepth_ = nullptr; Draw2DPipeline *draw2DPipeline565ToDepth_ = nullptr; Draw2DPipeline *draw2DPipeline565ToDepthDeswizzle_ = nullptr; diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 97efd42cbe5f..8bc072114bb5 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -1259,11 +1259,12 @@ void TextureCacheCommon::LoadClut(u32 clutAddr, u32 loadBytes) { dynamicClutTemp_ = draw_->CreateFramebuffer(desc); } - // Download the pixels to our temp clut, scaling down if needed. + // Copy the pixels to our temp clut, scaling down if needed and wrapping. + // TODO: Take the clutRenderOffset_ into account here. framebufferManager_->BlitUsingRaster( chosenFramebuffer->fbo, 0.0f, 0.0f, 512.0f * chosenFramebuffer->renderScaleFactor, 1.0f, dynamicClutTemp_, 0.0f, 0.0f, 512.0f, 1.0f, - false, 1.0f, framebufferManager_->Get2DPipeline(DRAW2D_COPY_COLOR), "copy_clut_to_temp"); + false, chosenFramebuffer->renderScaleFactor, framebufferManager_->Get2DPipeline(DRAW2D_COPY_COLOR_RECT2LIN), "copy_clut_to_temp"); clutRenderFormat_ = chosenFramebuffer->fb_format; } NotifyMemInfo(MemBlockFlags::ALLOC, clutAddr, loadBytes, "CLUT"); From 78ab0139144df5fb3bfc5f29460650b1159945bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 21 Sep 2022 18:37:40 +0200 Subject: [PATCH 2/2] Shouldn't 'floor' there --- GPU/Common/Draw2D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/Draw2D.cpp b/GPU/Common/Draw2D.cpp index 49aaa0bd5bcd..83df3ee34d12 100644 --- a/GPU/Common/Draw2D.cpp +++ b/GPU/Common/Draw2D.cpp @@ -75,7 +75,7 @@ Draw2DPipelineInfo GenerateDraw2DCopyColorRect2LinFs(ShaderWriter &writer) { writer.BeginFSMain(g_draw2Duniforms, varyings, FSFLAG_NONE); writer.C(" vec2 tSize = texSize / scaleFactor;\n"); writer.C(" vec2 pixels = v_texcoord * tSize;\n"); - writer.C(" float u = mod(floor(pixels.x), tSize.x);\n"); + writer.C(" float u = mod(pixels.x, tSize.x);\n"); writer.C(" float v = floor(pixels.x / tSize.x);\n"); writer.C(" vec4 outColor = ").SampleTexture2D("tex", "vec2(u, v) / tSize").C(";\n"); writer.EndFSMain("outColor", FSFLAG_NONE);