diff --git a/GPU/Common/Draw2D.cpp b/GPU/Common/Draw2D.cpp index f1e6c187ef..78086bd682 100644 --- a/GPU/Common/Draw2D.cpp +++ b/GPU/Common/Draw2D.cpp @@ -57,26 +57,32 @@ const UniformBufferDesc draw2DUBDesc{ sizeof(Draw2DUB), { } }; -RasterChannel GenerateDraw2DFs(ShaderWriter &writer) { +Draw2DPipelineInfo GenerateDraw2DCopyColorFs(ShaderWriter &writer) { writer.DeclareSamplers(samplers); writer.BeginFSMain(Slice::empty(), varyings, FSFLAG_NONE); writer.C(" vec4 outColor = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n"); writer.EndFSMain("outColor", FSFLAG_NONE); - return RASTER_COLOR; + return Draw2DPipelineInfo{ + RASTER_COLOR, + RASTER_COLOR, + }; } -RasterChannel GenerateDraw2DDepthFs(ShaderWriter &writer) { +Draw2DPipelineInfo GenerateDraw2DCopyDepthFs(ShaderWriter &writer) { 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); - return RASTER_DEPTH; + return Draw2DPipelineInfo{ + RASTER_DEPTH, + RASTER_DEPTH, + }; } -RasterChannel GenerateDraw2D565ToDepthFs(ShaderWriter &writer) { +Draw2DPipelineInfo GenerateDraw2D565ToDepthFs(ShaderWriter &writer) { writer.DeclareSamplers(samplers); writer.BeginFSMain(Slice::empty(), varyings, FSFLAG_WRITEDEPTH); writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n"); @@ -88,10 +94,13 @@ RasterChannel GenerateDraw2D565ToDepthFs(ShaderWriter &writer) { writer.F(" gl_FragDepth = (depthValue / %f) + %f;\n", factors.scale, factors.offset); writer.EndFSMain("outColor", FSFLAG_WRITEDEPTH); - return RASTER_DEPTH; + return Draw2DPipelineInfo{ + RASTER_COLOR, + RASTER_DEPTH, + }; } -RasterChannel GenerateDraw2D565ToDepthDeswizzleFs(ShaderWriter &writer) { +Draw2DPipelineInfo GenerateDraw2D565ToDepthDeswizzleFs(ShaderWriter &writer) { writer.DeclareSamplers(samplers); writer.BeginFSMain(uniforms, varyings, FSFLAG_WRITEDEPTH); writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n"); @@ -108,7 +117,11 @@ RasterChannel GenerateDraw2D565ToDepthDeswizzleFs(ShaderWriter &writer) { 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.scale, factors.offset); writer.EndFSMain("outColor", FSFLAG_WRITEDEPTH); - return RASTER_DEPTH; + + return Draw2DPipelineInfo{ + RASTER_COLOR, + RASTER_DEPTH + }; } void GenerateDraw2DVS(ShaderWriter &writer) { @@ -155,7 +168,7 @@ void FramebufferManagerCommon::Ensure2DResources() { } } -Draw::Pipeline *FramebufferManagerCommon::Create2DPipeline(std::function generate) { +Draw2DPipeline *FramebufferManagerCommon::Create2DPipeline(std::function generate) { Ensure2DResources(); using namespace Draw; @@ -163,7 +176,7 @@ Draw::Pipeline *FramebufferManagerCommon::Create2DPipeline(std::functionCreateShaderModule(ShaderStage::Fragment, shaderLanguageDesc.shaderLanguage, (const uint8_t *)fsCode, strlen(fsCode), "draw2d_fs"); delete[] fsCode; @@ -182,10 +195,10 @@ Draw::Pipeline *FramebufferManagerCommon::Create2DPipeline(std::functionCreateInputLayout(desc); - BlendState *blend = draw_->CreateBlendState({ false, channel == RASTER_COLOR ? 0xF : 0 }); + BlendState *blend = draw_->CreateBlendState({ false, info.writeChannel == RASTER_COLOR ? 0xF : 0 }); DepthStencilStateDesc dsDesc{}; - if (channel == RASTER_DEPTH) { + if (info.writeChannel == RASTER_DEPTH) { dsDesc.depthTestEnabled = true; dsDesc.depthWriteEnabled = true; dsDesc.depthCompare = Draw::Comparison::ALWAYS; @@ -211,19 +224,31 @@ Draw::Pipeline *FramebufferManagerCommon::Create2DPipeline(std::functionRelease(); inputLayout->Release(); - return pipeline; + return new Draw2DPipeline { + pipeline, + info + }; } -void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter, Draw::Pipeline *pipeline, float texW, float texH) { +void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter, Draw2DPipeline *pipeline, float texW, float texH) { using namespace Draw; + _dbg_assert_(pipeline); + + if (pipeline->info.writeChannel == RASTER_DEPTH) { + _dbg_assert_(draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported); + + // We don't filter inputs when writing depth, results will be bad. + linearFilter = false; + } + Draw2DUB ub; ub.texSizeX = tex ? tex->Width() : texW; ub.texSizeY = tex ? tex->Height() : texH; ub.scaleFactor = (float)renderScaleFactor_; - draw_->BindPipeline(pipeline); + draw_->BindPipeline(pipeline->pipeline); draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub)); if (tex) { @@ -237,17 +262,17 @@ void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *ver gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE | DIRTY_VERTEXSHADER_STATE); } -void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter, Draw2DShader shader, float texW, float texH) { +Draw2DPipeline *FramebufferManagerCommon::Get2DPipeline(Draw2DShader shader) { using namespace Draw; const ShaderLanguageDesc &shaderLanguageDesc = draw_->GetShaderLanguageDesc(); - Draw::Pipeline *pipeline = nullptr; + Draw2DPipeline *pipeline = nullptr; switch (shader) { case DRAW2D_COPY_COLOR: if (!draw2DPipelineColor_) { - draw2DPipelineColor_ = Create2DPipeline(&GenerateDraw2DFs); + draw2DPipelineColor_ = Create2DPipeline(&GenerateDraw2DCopyColorFs); } pipeline = draw2DPipelineColor_; break; @@ -255,41 +280,36 @@ void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *ver case DRAW2D_COPY_DEPTH: if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) { // Can't do it - return; + return nullptr; } if (!draw2DPipelineDepth_) { - draw2DPipelineDepth_ = Create2DPipeline(&GenerateDraw2DDepthFs); + draw2DPipelineDepth_ = Create2DPipeline(&GenerateDraw2DCopyDepthFs); } - linearFilter = false; pipeline = draw2DPipelineDepth_; break; case DRAW2D_565_TO_DEPTH: if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) { // Can't do it - return; + return nullptr; } if (!draw2DPipeline565ToDepth_) { draw2DPipeline565ToDepth_ = Create2DPipeline(&GenerateDraw2D565ToDepthFs); } - linearFilter = false; pipeline = draw2DPipeline565ToDepth_; break; case DRAW2D_565_TO_DEPTH_DESWIZZLE: if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) { // Can't do it - return; + return nullptr; } if (!draw2DPipeline565ToDepthDeswizzle_) { draw2DPipeline565ToDepthDeswizzle_ = Create2DPipeline(&GenerateDraw2D565ToDepthDeswizzleFs); } - linearFilter = false; pipeline = draw2DPipeline565ToDepthDeswizzle_; break; } - if (pipeline) { - DrawStrip2D(tex, verts, vertexCount, linearFilter, pipeline, texW, texH); - } + return pipeline; } diff --git a/GPU/Common/Draw2D.h b/GPU/Common/Draw2D.h index e1ed615ba8..332c2c707d 100644 --- a/GPU/Common/Draw2D.h +++ b/GPU/Common/Draw2D.h @@ -28,3 +28,17 @@ inline RasterChannel Draw2DSourceChannel(Draw2DShader shader) { return RASTER_COLOR; } } + +struct Draw2DPipelineInfo { + RasterChannel readChannel; + RasterChannel writeChannel; +}; + +struct Draw2DPipeline { + Draw::Pipeline *pipeline; + Draw2DPipelineInfo info; + void Release() { + pipeline->Release(); + delete this; + } +}; diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 4e7e9a07ee..a3bce4e3fc 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -573,7 +573,7 @@ void FramebufferManagerCommon::CopyToDepthFromOverlappingFramebuffers(VirtualFra BlitUsingRaster( src->fbo, 0.0f, 0.0f, src->renderWidth, src->renderHeight, dest->fbo, 0.0f, 0.0f, src->renderWidth, src->renderHeight, - false, shader, "565_to_depth"); + false, Get2DPipeline(shader), "565_to_depth"); } } @@ -656,7 +656,7 @@ void FramebufferManagerCommon::CopyToColorFromOverlappingFramebuffers(VirtualFra int dstY2 = dstY1 + dstHeight; BlitUsingRaster(src->fbo, 0.0f, 0.0f, srcWidth, srcHeight, - dst->fbo, dstX1, dstY1, dstX2, dstY2, false, DRAW2D_COPY_COLOR, "copy_color"); + dst->fbo, dstX1, dstY1, dstX2, dstY2, false, Get2DPipeline(DRAW2D_COPY_COLOR), "copy_color"); } } @@ -731,7 +731,7 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir 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 if (useRaster) { - BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, Draw2DShader::DRAW2D_COPY_DEPTH, "BlitDepthRaster"); + BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, Get2DPipeline(Draw2DShader::DRAW2D_COPY_DEPTH), "BlitDepthRaster"); } draw_->InvalidateCachedState(); @@ -2491,7 +2491,7 @@ 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, DRAW2D_COPY_COLOR); + DrawStrip2D(nullptr, coord, 4, (flags & DRAWTEX_LINEAR) != 0, Get2DPipeline(DRAW2D_COPY_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); } @@ -2587,14 +2587,14 @@ 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 { - Draw2DShader shader = channel == RASTER_COLOR ? DRAW2D_COPY_COLOR : DRAW2D_COPY_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); - BlitUsingRaster(src->fbo, srcX1, srcY1, srcX2, srcY2, tempFBO, dstX1, dstY1, dstX2, dstY2, false, shader, tag); + BlitUsingRaster(src->fbo, srcX1, srcY1, srcX2, srcY2, tempFBO, dstX1, dstY1, dstX2, dstY2, false, pipeline, tag); srcFBO = tempFBO; } - BlitUsingRaster(srcFBO, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, false, shader, tag); + BlitUsingRaster(srcFBO, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, false, pipeline, tag); } draw_->InvalidateCachedState(); @@ -2607,9 +2607,9 @@ 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, - Draw2DShader shader, const char *tag) { + Draw2DPipeline *pipeline, const char *tag) { - if (shader == DRAW2D_COPY_DEPTH || shader == DRAW2D_565_TO_DEPTH) { + if (pipeline->info.writeChannel == RASTER_DEPTH) { _dbg_assert_(draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported); } @@ -2632,12 +2632,12 @@ void FramebufferManagerCommon::BlitUsingRaster( 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 }, tag ? tag : "BlitUsingRaster"); - draw_->BindFramebufferAsTexture(src, 0, Draw2DSourceChannel(shader) == RASTER_COLOR ? Draw::FB_COLOR_BIT : Draw::FB_DEPTH_BIT, 0); + draw_->BindFramebufferAsTexture(src, 0, pipeline->info.readChannel == 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, shader, src->Width(), src->Height()); + DrawStrip2D(nullptr, vtx, 4, linearFilter, pipeline, src->Width(), src->Height()); 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 fab01b9ceb..6913839797 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -375,11 +375,11 @@ 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, Draw2DShader channel, float texW = 0.0f, float texH = 0.0f); - void DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter, Draw::Pipeline *pipeline, float texW = 0.0f, float texH = 0.0f); + Draw2DPipeline *FramebufferManagerCommon::Get2DPipeline(Draw2DShader shader); + void DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter, Draw2DPipeline *pipeline, float texW = 0.0f, float texH = 0.0f); void Ensure2DResources(); - Draw::Pipeline *Create2DPipeline(std::function generate); + Draw2DPipeline *Create2DPipeline(std::function generate); void CopyToColorFromOverlappingFramebuffers(VirtualFramebuffer *dest); void CopyToDepthFromOverlappingFramebuffers(VirtualFramebuffer *dest); @@ -394,7 +394,7 @@ protected: 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, Draw2DShader shader, const char *tag); + Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2, bool linearFilter, Draw2DPipeline *pipeline, const char *tag); void CopyFramebufferForColorTexture(VirtualFramebuffer *dst, VirtualFramebuffer *src, int flags); @@ -511,10 +511,10 @@ protected: Draw::SamplerState *stencilUploadSampler_ = nullptr; // Draw2D pipelines - Draw::Pipeline *draw2DPipelineColor_ = nullptr; - Draw::Pipeline *draw2DPipelineDepth_ = nullptr; - Draw::Pipeline *draw2DPipeline565ToDepth_ = nullptr; - Draw::Pipeline *draw2DPipeline565ToDepthDeswizzle_ = nullptr; + Draw2DPipeline *draw2DPipelineColor_ = nullptr; + Draw2DPipeline *draw2DPipelineDepth_ = nullptr; + Draw2DPipeline *draw2DPipeline565ToDepth_ = nullptr; + Draw2DPipeline *draw2DPipeline565ToDepthDeswizzle_ = nullptr; Draw::SamplerState *draw2DSamplerLinear_ = nullptr; Draw::SamplerState *draw2DSamplerNearest_ = nullptr; Draw::ShaderModule *draw2DVs_ = nullptr;