From 2f700aa495706301d90fbb3157cf84d37ff361af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Dec 2020 00:19:39 +0100 Subject: [PATCH 1/3] Fix DiRT 2's car reflections. --- GPU/Common/FramebufferManagerCommon.cpp | 11 +++++++++-- assets/compat.ini | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 019cb8b860..20566b0cb2 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -536,10 +536,14 @@ void FramebufferManagerCommon::ReinterpretFramebufferFrom(VirtualFramebuffer *vf // Fixes #13717. if (!PSP_CoreParameter().compat.flags().ReinterpretFramebuffers) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "FakeReinterpret"); - currentRenderVfb_ = vfb; // Need to dirty anything that has command buffer dynamic state, in case we started a new pass above. // Should find a way to feed that information back, maybe... Or simply correct the issue in the rendermanager. gstate_c.Dirty(DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE); + + if (currentRenderVfb_ != vfb) { + // In case ReinterpretFramebuffer was called from the texture manager. + draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "After FakeReinterpret"); + } } } return; @@ -626,13 +630,16 @@ void FramebufferManagerCommon::ReinterpretFramebufferFrom(VirtualFramebuffer *vf // Unbind. draw_->BindTexture(0, nullptr); - RebindFramebuffer("After reinterpret"); shaderManager_->DirtyLastShader(); textureCache_->ForgetLastTexture(); gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_VERTEXSHADER_STATE); + if (currentRenderVfb_ != vfb) { + // In case ReinterpretFramebuffer was called from the texture manager. + draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "After reinterpret"); + } delete[] vsCode; delete[] fsCode; } diff --git a/assets/compat.ini b/assets/compat.ini index c7c41e5d63..4e93373a96 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -819,15 +819,16 @@ NPEZ00198 = true # This setting will go away in the near future, hopefully we can enable it # for all or most games. [ReinterpretFramebuffers] -# Outrun 2006: Coast to Coast - issue #11358 +# Outrun 2006: Coast to Coast - issue #11358 (car reflections) ULES00262 = true ULUS10064 = true ULKS46087 = true -# Colin McRae's DiRT 2? -# ULUS10471 = true -# ULJM05533 = true -# NPJH50006 = true +# Colin McRae's DiRT 2 - issue #13012 (car lighting) +ULUS10471 = true +ULJM05533 = true +NPJH50006 = true +ULES01301 = true # Ultimate Ghosts & Goblins ULJM05147 = true @@ -845,6 +846,12 @@ ULES00262 = true ULUS10064 = true ULKS46087 = true +# Colin McRae's DiRT 2 - issue #13012 (car lighting) +ULUS10471 = true +ULJM05533 = true +NPJH50006 = true +ULES01301 = true + [DoublePrecisionSinCos] # Hitman Reborn Battle Arena 2 (#12900) ULJS00218 = true From 6a5522b185c2698ab1e2809f7a0fcd2ba743eb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Dec 2020 00:20:13 +0100 Subject: [PATCH 2/3] thin3d: Add a way to query the current render target for debugging. --- Common/GPU/D3D11/thin3d_d3d11.cpp | 9 +++++++-- Common/GPU/D3D9/thin3d_d3d9.cpp | 7 ++++++- Common/GPU/OpenGL/thin3d_gl.cpp | 6 +++++- Common/GPU/Vulkan/VulkanQueueRunner.cpp | 4 ++-- Common/GPU/Vulkan/thin3d_vulkan.cpp | 7 ++++--- Common/GPU/thin3d.h | 1 + 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index e961bebf57..423e1ff868 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -35,6 +35,7 @@ class D3D11BlendState; class D3D11DepthStencilState; class D3D11SamplerState; class D3D11RasterState; +class D3D11Framebuffer; class D3D11DrawContext : public DrawContext { public: @@ -71,7 +72,9 @@ public: // These functions should be self explanatory. void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; - // color must be 0, for now. + Framebuffer *GetCurrentRenderTarget() override { + return curRenderTarget_; + } void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override; uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) override; @@ -182,6 +185,7 @@ private: ID3D11Texture2D *bbDepthStencilTex_ = nullptr; ID3D11DepthStencilView *bbDepthStencilView_ = nullptr; + Framebuffer *curRenderTarget_ = nullptr; ID3D11RenderTargetView *curRenderTargetView_ = nullptr; ID3D11DepthStencilView *curDepthStencilView_ = nullptr; // Needed to rotate stencil/viewport rectangles properly @@ -1585,6 +1589,7 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren curRTWidth_ = fb->Width(); curRTHeight_ = fb->Height(); } + curRenderTarget_ = fb; } else { if (curRenderTargetView_ == bbRenderTargetView_ && curDepthStencilView_ == bbDepthStencilView_) { // No need to switch, but let's fallthrough to clear! @@ -1595,6 +1600,7 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren curRTWidth_ = bbWidth_; curRTHeight_ = bbHeight_; } + curRenderTarget_ = nullptr; } if (rp.color == RPAction::CLEAR && curRenderTargetView_) { float cv[4]{}; @@ -1616,7 +1622,6 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren stepId_++; } -// color must be 0, for now. void D3D11DrawContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) { D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo; switch (channelBit) { diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index 44a559ee50..83a1ca2bdf 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -520,7 +520,9 @@ public: // These functions should be self explanatory. void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; - // color must be 0, for now. + Framebuffer *GetCurrentRenderTarget() override { + return curRenderTarget_; + } void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override; uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) override; @@ -615,6 +617,7 @@ private: int curVBufferOffsets_[4]{}; D3D9Buffer *curIBuffer_ = nullptr; int curIBufferOffset_ = 0; + Framebuffer *curRenderTarget_ = nullptr; // Framebuffer state LPDIRECT3DSURFACE9 deviceRTsurf = 0; @@ -1139,9 +1142,11 @@ void D3D9Context::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPa D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo; device_->SetRenderTarget(0, fb->surf); device_->SetDepthStencilSurface(fb->depthstencil); + curRenderTarget_ = fb; } else { device_->SetRenderTarget(0, deviceRTsurf); device_->SetDepthStencilSurface(deviceDSsurf); + curRenderTarget_ = nullptr; } int clearFlags = 0; diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index 05b27923c2..8b1f043473 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -361,7 +361,9 @@ public: // These functions should be self explanatory. void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; - // color must be 0, for now. + Framebuffer *GetCurrentRenderTarget() override { + return curRenderTarget_; + } void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override; void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override; @@ -487,6 +489,7 @@ private: int curVBufferOffsets_[4]{}; OpenGLBuffer *curIBuffer_ = nullptr; int curIBufferOffset_ = 0; + Framebuffer *curRenderTarget_ = nullptr; uint8_t stencilRef_ = 0; @@ -1320,6 +1323,7 @@ void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Render GLRRenderPassAction stencil = (GLRRenderPassAction)rp.stencil; renderManager_.BindFramebufferAsRenderTarget(fb ? fb->framebuffer_ : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil, tag); + curRenderTarget_ = fb; } void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) { diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.cpp b/Common/GPU/Vulkan/VulkanQueueRunner.cpp index cb3a07e03b..56fb09dea2 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.cpp +++ b/Common/GPU/Vulkan/VulkanQueueRunner.cpp @@ -1234,12 +1234,12 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c VKRFramebuffer *fb = step.render.framebuffer; - VkPipeline lastPipeline = VK_NULL_HANDLE; - auto &commands = step.commands; // We can do a little bit of state tracking here to eliminate some calls into the driver. // The stencil ones are very commonly mostly redundant so let's eliminate them where possible. + // Might also want to consider scissor and viewport. + VkPipeline lastPipeline = VK_NULL_HANDLE; int lastStencilWriteMask = -1; int lastStencilCompareMask = -1; int lastStencilReference = -1; diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index b5ac0fb8c1..ba3bc05897 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -392,7 +392,9 @@ public: // These functions should be self explanatory. void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; - // color must be 0, for now. + Framebuffer *GetCurrentRenderTarget() override { + return curFramebuffer_; + } void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override; uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) override; @@ -517,7 +519,7 @@ private: VkDescriptorSetLayout descriptorSetLayout_ = VK_NULL_HANDLE; VkPipelineLayout pipelineLayout_ = VK_NULL_HANDLE; VkPipelineCache pipelineCache_ = VK_NULL_HANDLE; - VKFramebuffer *curFramebuffer_ = nullptr; + Framebuffer *curFramebuffer_ = nullptr; VkDevice device_; VkQueue queue_; @@ -1539,7 +1541,6 @@ void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPass curFramebuffer_ = fb; } -// color must be 0, for now. void VKContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) { VKFramebuffer *fb = (VKFramebuffer *)fbo; diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index d29ac91842..757fccf770 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -578,6 +578,7 @@ public: // These functions should be self explanatory. // Binding a zero render target means binding the backbuffer. virtual void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) = 0; + virtual Framebuffer *GetCurrentRenderTarget() = 0; // binding must be < MAX_TEXTURE_SLOTS (0, 1 are okay if it's 2). virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) = 0; From 0c66f6c6d07ec43599d3e8bcce44006c06361eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Dec 2020 00:20:47 +0100 Subject: [PATCH 3/3] Assorted drive-by code cleanup --- GPU/Common/FramebufferManagerCommon.cpp | 32 ++++++++++++------------- GPU/Common/FramebufferManagerCommon.h | 14 ++++++++--- GPU/Common/TextureCacheCommon.cpp | 3 +-- GPU/D3D11/FramebufferManagerD3D11.cpp | 4 ---- GPU/D3D11/FramebufferManagerD3D11.h | 2 -- GPU/D3D11/TextureCacheD3D11.cpp | 6 ++--- GPU/Directx9/FramebufferManagerDX9.cpp | 4 ---- GPU/Directx9/FramebufferManagerDX9.h | 2 -- GPU/GPUCommon.cpp | 2 ++ GPU/Vulkan/DrawEngineVulkan.cpp | 7 +++--- GPU/Vulkan/FramebufferManagerVulkan.cpp | 12 ---------- GPU/Vulkan/FramebufferManagerVulkan.h | 3 --- 12 files changed, 36 insertions(+), 55 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 20566b0cb2..f7cdc5f765 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -471,10 +471,10 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir // Note: We prefer Blit ahead of Copy here, since at least on GL, Copy will always also copy stencil which we don't want. See #9740. if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT_TO_DEPTH)) { draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); - RebindFramebuffer("BlitFramebufferDepth"); + RebindFramebuffer("After BlitFramebufferDepth"); } else if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) { draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - RebindFramebuffer("BlitFramebufferDepth"); + RebindFramebuffer("After BlitFramebufferDepth"); } dst->last_frame_depth_updated = gpuStats.numFlips; } @@ -503,7 +503,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer if (vfbFormatChanged) { textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED); if (vfb->drawnFormat != vfb->format) { - ReinterpretFramebufferFrom(vfb, vfb->drawnFormat); + ReinterpretFramebuffer(vfb, vfb->drawnFormat, vfb->format); } } @@ -517,11 +517,15 @@ void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer } } -void FramebufferManagerCommon::ReinterpretFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat oldFormat) { +void FramebufferManagerCommon::ReinterpretFramebuffer(VirtualFramebuffer *vfb, GEBufferFormat oldFormat, GEBufferFormat newFormat) { if (!useBufferedRendering_ || !vfb->fbo) { return; } + _assert_(newFormat != oldFormat); + // The caller is responsible for updating the format. + _assert_(newFormat == vfb->format); + ShaderLanguage lang = draw_->GetShaderLanguageDesc().shaderLanguage; bool doReinterpret = PSP_CoreParameter().compat.flags().ReinterpretFramebuffers && @@ -549,10 +553,6 @@ void FramebufferManagerCommon::ReinterpretFramebufferFrom(VirtualFramebuffer *vf return; } - GEBufferFormat newFormat = vfb->format; - - _assert_(newFormat != oldFormat); - // We only reinterpret between 16 - bit formats, for now. if (!IsGeBufferFormat16BitColor(oldFormat) || !IsGeBufferFormat16BitColor(newFormat)) { // 16->32 and 32->16 will require some more specialized shaders. @@ -671,8 +671,9 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe } } } + if (vfb->drawnFormat != vfb->format) { - ReinterpretFramebufferFrom(vfb, vfb->drawnFormat); + ReinterpretFramebuffer(vfb, vfb->drawnFormat, vfb->format); } if (useBufferedRendering_) { @@ -839,10 +840,8 @@ bool FramebufferManagerCommon::BindFramebufferAsColorTexture(int stage, VirtualF // currentRenderVfb_ will always be set when this is called, except from the GE debugger. // Let's just not bother with the copy in that case. - bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; - if (GPUStepping::IsStepping()) { - skipCopy = true; - } + bool skipCopy = !(flags & BINDFBCOLOR_MAY_COPY) || GPUStepping::IsStepping(); + // Currently rendering to this framebuffer. Need to make a copy. if (!skipCopy && framebuffer == currentRenderVfb_) { // TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size. @@ -870,7 +869,6 @@ bool FramebufferManagerCommon::BindFramebufferAsColorTexture(int stage, VirtualF gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; return false; } - } void FramebufferManagerCommon::CopyFramebufferForColorTexture(VirtualFramebuffer *dst, VirtualFramebuffer *src, int flags) { @@ -996,6 +994,8 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu // PresentationCommon sets all kinds of state, we can't rely on anything. gstate_c.Dirty(DIRTY_ALL); + + currentRenderVfb_ = nullptr; } void FramebufferManagerCommon::DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb) { @@ -1747,10 +1747,10 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp, "Blit_IntraBufferBlockTransfer"); RebindFramebuffer("rebind after intra block transfer"); SetColorUpdated(dstBuffer, skipDrawReason); - return true; + return true; // Skip the memory copy. } else { // Ignore, nothing to do. Tales of Phantasia X does this by accident. - return true; + return true; // Skip the memory copy. } } else { WARN_LOG_N_TIMES(dstnotsrc, 100, G3D, "Inter-buffer block transfer %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index f20703df42..0b843b5bc4 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -15,6 +15,14 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// TODO: We now have the tools in thin3d to nearly eliminate the backend-specific framebuffer managers. +// Here's a list of functionality to unify into FramebufferManagerCommon: +// * DrawActiveTexture +// * BlitFramebuffer +// * StencilBuffer*.cpp +// +// Also, in TextureCache we should be able to unify texture-based depal. + #pragma once #include @@ -131,7 +139,7 @@ void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPU enum BindFramebufferColorFlags { BINDFBCOLOR_SKIP_COPY = 0, BINDFBCOLOR_MAY_COPY = 1, - BINDFBCOLOR_MAY_COPY_WITH_UV = 3, + BINDFBCOLOR_MAY_COPY_WITH_UV = 3, // includes BINDFBCOLOR_MAY_COPY BINDFBCOLOR_APPLY_TEX_OFFSET = 4, // Used when rendering to a temporary surface (e.g. not the current render target.) BINDFBCOLOR_FORCE_SELF = 8, @@ -322,7 +330,7 @@ public: const std::vector &Framebuffers() { return vfbs_; } - void ReinterpretFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old); + void ReinterpretFramebuffer(VirtualFramebuffer *vfb, GEBufferFormat oldFormat, GEBufferFormat newFormat); protected: virtual void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h); @@ -356,7 +364,7 @@ protected: void DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb); void FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer, VirtualFramebuffer *&srcBuffer, u32 dstBasePtr, int dstStride, int &dstX, int &dstY, u32 srcBasePtr, int srcStride, int &srcX, int &srcY, int &srcWidth, int &srcHeight, int &dstWidth, int &dstHeight, int bpp); VirtualFramebuffer *FindDownloadTempBuffer(VirtualFramebuffer *vfb); - virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) = 0; + virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) {} VirtualFramebuffer *CreateRAMFramebuffer(uint32_t fbAddress, int width, int height, int stride, GEBufferFormat format); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index a17565e41f..277ee17ece 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -958,10 +958,9 @@ void TextureCacheCommon::SetTextureFramebuffer(const AttachCandidate &candidate) FramebufferMatchInfo fbInfo = candidate.match; if (candidate.match.reinterpret) { - // TODO: Kinda ugly, maybe switch direction of the call? GEBufferFormat oldFormat = candidate.fb->format; candidate.fb->format = candidate.match.reinterpretTo; - framebufferManager_->ReinterpretFramebufferFrom(candidate.fb, oldFormat); + framebufferManager_->ReinterpretFramebuffer(candidate.fb, oldFormat, candidate.match.reinterpretTo); } _dbg_assert_msg_(framebuffer != nullptr, "Framebuffer must not be null."); diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 195b85b03b..a2bf163e34 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -277,10 +277,6 @@ static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { } } -void FramebufferManagerD3D11::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) { - // Nothing to do here. -} - void FramebufferManagerD3D11::SimpleBlit( Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2, Draw::Framebuffer *src, float srcX1, float srcY1, float srcX2, float srcY2, bool linearFilter) { diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index e762beb5f0..9f0f3e0ef8 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -54,8 +54,6 @@ protected: // Used by ReadFramebufferToMemory and later framebuffer block copies void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) override; - void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override; - private: void Bind2DShader() override; void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h); diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 044f5113c3..8e4aadfc0a 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -412,7 +412,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, shaderApply.Shade(); context_->PSSetShaderResources(0, 1, &nullTexture); // Make D3D11 validation happy. Really of no consequence since we rebind anyway. - framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); + framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0); const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16); @@ -422,8 +422,8 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL); } else { gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); - framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); - framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); + framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); + framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); } SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index adc54a5860..70db6442b1 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -259,10 +259,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { return offscreen; } - void FramebufferManagerDX9::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) { - // Nothing to do here. - } - void FramebufferManagerDX9::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) { if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if we recently switched from non-buffered. diff --git a/GPU/Directx9/FramebufferManagerDX9.h b/GPU/Directx9/FramebufferManagerDX9.h index 6f884d5f0e..385caf47c0 100644 --- a/GPU/Directx9/FramebufferManagerDX9.h +++ b/GPU/Directx9/FramebufferManagerDX9.h @@ -65,8 +65,6 @@ protected: // Used by ReadFramebufferToMemory and later framebuffer block copies void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) override; - void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override; - private: void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) override; void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h); diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index a86f7b9963..c57f026670 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -2721,6 +2721,8 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) { // Track stray copies of a framebuffer in RAM. MotoGP does this. if (framebufferManager_->MayIntersectFramebuffer(src) || framebufferManager_->MayIntersectFramebuffer(dest)) { if (!framebufferManager_->NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) { + // TODO: What? Why would a game copy between the mirrors? This check seems entirely + // superfluous. // We use a little hack for Download/Upload using a VRAM mirror. // Since they're identical we don't need to copy. if (!Memory::IsVRAMAddress(dest) || (dest ^ 0x00400000) != src) { diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index b2f86d23fd..da1fb1f52c 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -803,6 +803,7 @@ void DrawEngineVulkan::DoFlush() { } PROFILE_THIS_SCOPE("updatestate"); + if (textureNeedsApply) { textureCache_->ApplyTexture(); textureCache_->GetVulkanHandles(imageView, sampler); @@ -860,8 +861,6 @@ void DrawEngineVulkan::DoFlush() { UpdateUBOs(frame); VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, boneBuf, tess); - { - PROFILE_THIS_SCOPE("renderman_q"); const uint32_t dynamicUBOOffsets[3] = { baseUBOOffset, lightUBOOffset, boneUBOOffset, @@ -870,13 +869,13 @@ void DrawEngineVulkan::DoFlush() { int stride = dec_->GetDecVtxFmt().stride; if (useElements) { - if (!ibuf) + if (!ibuf) { ibOffset = (uint32_t)frame->pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &ibuf); + } renderManager->DrawIndexed(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, 1, VK_INDEX_TYPE_UINT16); } else { renderManager->Draw(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, vertexCount); } - } } else { PROFILE_THIS_SCOPE("soft"); // Decode to "decoded" diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 1abf4467ad..a9e2fb230b 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -234,18 +234,6 @@ void FramebufferManagerVulkan::Bind2DShader() { cur2DPipeline_ = vulkan2D_->GetPipeline(rp, vsBasicTex_, fsBasicTex_); } -int FramebufferManagerVulkan::GetLineWidth() { - if (g_Config.iInternalResolution == 0) { - return std::max(1, (int)(renderWidth_ / 480)); - } else { - return g_Config.iInternalResolution; - } -} - -void FramebufferManagerVulkan::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) { - // Nothing to do here. -} - void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) { if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if they recently switched from non-buffered. diff --git a/GPU/Vulkan/FramebufferManagerVulkan.h b/GPU/Vulkan/FramebufferManagerVulkan.h index 8cb3bb6ccf..0aed797361 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.h +++ b/GPU/Vulkan/FramebufferManagerVulkan.h @@ -52,8 +52,6 @@ public: void DeviceLost() override; void DeviceRestore(Draw::DrawContext *draw) override; - int GetLineWidth(); - bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; // If within a render pass, this will just issue a regular clear. If beginning a new render pass, @@ -65,7 +63,6 @@ protected: // Used by ReadFramebufferToMemory and later framebuffer block copies void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) override; - void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override; private: void InitDeviceObjects();