From 49efaaef59665330e70a6f9d7ac3bda3cce49440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 3 Aug 2020 23:35:40 +0200 Subject: [PATCH 1/3] Clarify, but don't yet remove, a perf hack for ES devices. Remove a unused sync parameter from readbacks. --- GPU/Common/FramebufferManagerCommon.cpp | 30 +++++++++++++------------ GPU/Common/FramebufferManagerCommon.h | 5 +++-- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index c93f838e18e6..1ca924df1672 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -45,6 +45,10 @@ FramebufferManagerCommon::FramebufferManagerCommon(Draw::DrawContext *draw) : draw_(draw), displayFormat_(GE_FORMAT_565) { presentation_ = new PresentationCommon(draw); + + // See comment from where it's used below. + // As for the use of IsGLES, just the way it was. Scary to change it. + clearFramebufferOnFirstUseHack_ = gl_extensions.IsGLES; } FramebufferManagerCommon::~FramebufferManagerCommon() { @@ -500,7 +504,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) { if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) { - ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height); + ReadFramebufferToMemory(vfb, 0, 0, vfb->width, vfb->height); vfb->usageFlags = (vfb->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; vfb->firstFrameSaved = true; } else { @@ -527,13 +531,12 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe if (useBufferedRendering_) { if (vfb->fbo) { shaderManager_->DirtyLastShader(); - if (gl_extensions.IsGLES) { - // Some tiled mobile GPUs benefit IMMENSELY from clearing an FBO before rendering - // to it. This broke stuff before, so now it only clears on the first use of an - // FBO in a frame. This means that some games won't be able to avoid the on-some-GPUs - // performance-crushing framebuffer reloads from RAM, but we'll have to live with that. - - // Wait, can we even do this? Seems highly unsafe.. TODO: Remove + if (clearFramebufferOnFirstUseHack_) { + // HACK: Some tiled mobile GPUs benefit IMMENSELY from clearing an FBO before rendering + // to it (or in Vulkan, clear during framebuffer load). This is a hack to force this + // the first time a framebuffer is bound for rendering in a frame. + // + // Quite unsafe as it might kill some feedback effects. if (vfb->last_frame_render != gpuStats.numFlips) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "FramebufferSwitch"); } else { @@ -809,7 +812,7 @@ void FramebufferManagerCommon::DownloadFramebufferOnSwitch(VirtualFramebuffer *v // To support this, we save the first frame to memory when we have a safe w/h. // Saving each frame would be slow. if (!g_Config.bDisableSlowFramebufEffects) { - ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight); + ReadFramebufferToMemory(vfb, 0, 0, vfb->safeWidth, vfb->safeHeight); vfb->usageFlags = (vfb->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; vfb->firstFrameSaved = true; vfb->safeWidth = 0; @@ -975,8 +978,7 @@ void FramebufferManagerCommon::DecimateFBOs() { int age = frameLastFramebufUsed_ - std::max(vfb->last_frame_render, vfb->last_frame_used); if (ShouldDownloadFramebuffer(vfb) && age == 0 && !vfb->memoryUpdated) { - bool sync = gl_extensions.IsGLES; - ReadFramebufferToMemory(vfb, sync, 0, 0, vfb->width, vfb->height); + ReadFramebufferToMemory(vfb, 0, 0, vfb->width, vfb->height); vfb->usageFlags = (vfb->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; vfb->firstFrameSaved = true; } @@ -1187,7 +1189,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, if (srcH == 0 || srcY + srcH > srcBuffer->bufferHeight) { WARN_LOG_REPORT_ONCE(btdcpyheight, G3D, "Memcpy fbo download %08x -> %08x skipped, %d+%d is taller than %d", src, dst, srcY, srcH, srcBuffer->bufferHeight); } else if (g_Config.bBlockTransferGPU && !srcBuffer->memoryUpdated && !PSP_CoreParameter().compat.flags().DisableReadbacks) { - ReadFramebufferToMemory(srcBuffer, true, 0, srcY, srcBuffer->width, srcH); + ReadFramebufferToMemory(srcBuffer, 0, srcY, srcBuffer->width, srcH); srcBuffer->usageFlags = (srcBuffer->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; } return false; @@ -1587,7 +1589,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst } else { if (tooTall) WARN_LOG_ONCE(btdheight, G3D, "Block transfer download %08x -> %08x dangerous, %d+%d is taller than %d", srcBasePtr, dstBasePtr, srcY, srcHeight, srcBuffer->bufferHeight); - ReadFramebufferToMemory(srcBuffer, true, static_cast(srcX * srcXFactor), srcY, static_cast(srcWidth * srcXFactor), srcHeight); + ReadFramebufferToMemory(srcBuffer, static_cast(srcX * srcXFactor), srcY, static_cast(srcWidth * srcXFactor), srcHeight); srcBuffer->usageFlags = (srcBuffer->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; } } @@ -1971,7 +1973,7 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int gpuStats.numReadbacks++; } -void FramebufferManagerCommon::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) { +void FramebufferManagerCommon::ReadFramebufferToMemory(VirtualFramebuffer *vfb, int x, int y, int w, int h) { // Clamp to bufferWidth. Sometimes block transfers can cause this to hit. if (x + w >= vfb->bufferWidth) { w = vfb->bufferWidth - x; diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 07ee628d1efe..e1fbd2958c35 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -187,7 +187,7 @@ class TextureCacheCommon; class FramebufferManagerCommon { public: - FramebufferManagerCommon(Draw::DrawContext *draw); + explicit FramebufferManagerCommon(Draw::DrawContext *draw); virtual ~FramebufferManagerCommon(); virtual void Init(); @@ -231,7 +231,7 @@ class FramebufferManagerCommon { bool NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason); void NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason); - void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h); + void ReadFramebufferToMemory(VirtualFramebuffer *vfb, int x, int y, int w, int h); void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes); void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride); @@ -394,6 +394,7 @@ class FramebufferManagerCommon { std::vector bvfbs_; // blitting framebuffers (for download) bool gameUsesSequentialCopies_ = false; + bool clearFramebufferOnFirstUseHack_ = false; // Sampled in BeginFrame for safety. float renderWidth_ = 0.0f; From 58ef0c8e8096d4408cd44f72a60890bd25bf7dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 4 Aug 2020 14:45:14 +0200 Subject: [PATCH 2/3] Texture from framebuffer: Logging improvements --- CMakeLists.txt | 2 ++ GPU/Common/FramebufferManagerCommon.cpp | 2 +- GPU/Common/FramebufferManagerCommon.h | 4 ++- GPU/Common/TextureCacheCommon.cpp | 34 +++++++++++++++---------- GPU/Common/TextureCacheCommon.h | 3 ++- GPU/Directx9/TextureCacheDX9.cpp | 1 - GPU/GLES/TextureCacheGLES.cpp | 1 - GPU/GPU.vcxproj | 1 + GPU/GPU.vcxproj.filters | 9 ++++--- GPU/GeConstants.cpp | 28 ++++++++++++++++++++ GPU/Vulkan/TextureCacheVulkan.cpp | 1 - GPU/ge_constants.h | 10 ++++++++ UWP/GPU_UWP/GPU_UWP.vcxproj | 1 + UWP/GPU_UWP/GPU_UWP.vcxproj.filters | 1 + android/jni/Android.mk | 1 + libretro/Makefile.common | 1 + 16 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 GPU/GeConstants.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a6d488f2df1d..a1edc34f9e58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1402,6 +1402,8 @@ set(GPU_SOURCES GPU/Debugger/RecordFormat.h GPU/Debugger/Stepping.cpp GPU/Debugger/Stepping.h + GPU/ge_constants.h + GPU/GeConstants.cpp GPU/GPUInterface.h GPU/GeDisasm.cpp GPU/GeDisasm.h diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 1ca924df1672..5be05dfdedb7 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1304,7 +1304,7 @@ VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAd float renderWidthFactor = renderWidth_ / 480.0f; float renderHeightFactor = renderHeight_ / 272.0f; - DEBUG_LOG(G3D, "Creating RAM framebuffer at %08x (%dx%d, stride %d, format %d)", fbAddress, width, height, stride, format); + INFO_LOG(G3D, "Creating RAM framebuffer at %08x (%dx%d, stride %d, format %d)", fbAddress, width, height, stride, format); // A target for the destination is missing - so just create one! // Make sure this one would be found by the algorithm above so we wouldn't diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index e1fbd2958c35..66954c511c3e 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -68,13 +68,15 @@ struct VirtualFramebuffer { // There's also a top left of the drawing region, but meh... - // width/height: The detected size of the current framebuffer. + // width/height: The detected size of the current framebuffer, in original PSP pixels. u16 width; u16 height; + // renderWidth/renderHeight: The scaled size we render at. May be scaled to render at higher resolutions. // The physical buffer may be larger than renderWidth/renderHeight. u16 renderWidth; u16 renderHeight; + // bufferWidth/bufferHeight: The pre-scaling size of the buffer itself. May only be bigger than width/height. // Actual physical buffer is this size times the render resolution multiplier. // The buffer may be used to render a width or height from 0 to these values without being recreated. diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 462e72fc631d..e6e6666adb41 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -772,13 +772,13 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // If they match exactly, it's non-CLUT and from the top left. if (exactMatch) { - DEBUG_LOG(G3D, "Render to texture detected at %08x!", address); if (framebuffer->fb_stride != entry->bufw) { - WARN_LOG_REPORT_ONCE(diffStrides1, G3D, "Render to texture with different strides %d != %d", entry->bufw, framebuffer->fb_stride); + WARN_LOG_REPORT_ONCE(diffStrides1, G3D, "Texturing from framebuffer with different strides %d != %d", entry->bufw, framebuffer->fb_stride); } + // NOTE: This check is okay because the first texture formats are the same as the buffer formats. if (entry->format != (GETextureFormat)framebuffer->format) { - WARN_LOG_REPORT_ONCE(diffFormat1, G3D, "Render to texture with different formats %d != %d", entry->format, framebuffer->format); - // Let's avoid using it when we know the format is wrong. May be a video/etc. updating memory. + WARN_LOG_REPORT_ONCE(diffFormat1, G3D, "Texturing from framebuffer with different formats %d != %d", entry->format, framebuffer->format); + // Let's avoid using it when we know the format is wrong. May be a video/etc. updating memory. // However, some games use a different format to clear the buffer. if (framebuffer->last_frame_attached + 1 < gpuStats.numFlips) { DetachFramebuffer(entry, address, framebuffer); @@ -792,10 +792,12 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi if (!framebufferManager_->UseBufferedRendering()) return false; - const bool clutFormat = + const bool matchingClutFormat = (framebuffer->format == GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT32) || (framebuffer->format != GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT16); + const bool clutFormat = IsClutFormat((GETextureFormat)(entry->format)); + const u32 bitOffset = (texaddr - addr) * 8; const u32 pixelOffset = bitOffset / std::max(1U, (u32)textureBitsPerPixel[entry->format]); fbInfo.yOffset = entry->bufw == 0 ? 0 : pixelOffset / entry->bufw; @@ -803,7 +805,8 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi if (framebuffer->fb_stride != entry->bufw) { if (noOffset) { - WARN_LOG_REPORT_ONCE(diffStrides2, G3D, "Render to texture using CLUT with different strides %d != %d", entry->bufw, framebuffer->fb_stride); + // Not actually sure why we even try here. There's no way it'll go well if the strides are different. + WARN_LOG_ONCE(diffStrides2, G3D, "Texturing from framebuffer (matching_clut=%s) different strides %d != %d", matchingClutFormat ? "yes" : "no", entry->bufw, framebuffer->fb_stride); } else { // Assume any render-to-tex with different bufw + offset is a render from ram. DetachFramebuffer(entry, address, framebuffer); @@ -823,32 +826,34 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi DetachFramebuffer(entry, address, framebuffer); return false; } + // Trying to play it safe. Below 0x04110000 is almost always framebuffers. // TODO: Maybe we can reduce this check and find a better way above 0x04110000? if (fbInfo.yOffset > MAX_SUBAREA_Y_OFFSET_SAFE && addr > 0x04110000) { - WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible render to texture at %08x +%dx%d / %dx%d", address, fbInfo.xOffset, fbInfo.yOffset, framebuffer->width, framebuffer->height); + WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible texturing from framebuffer at %08x +%dx%d / %dx%d", address, fbInfo.xOffset, fbInfo.yOffset, framebuffer->width, framebuffer->height); DetachFramebuffer(entry, address, framebuffer); return false; } // Check for CLUT. The framebuffer is always RGB, but it can be interpreted as a CLUT texture. // 3rd Birthday (and a bunch of other games) render to a 16 bit clut texture. - if (clutFormat) { + if (matchingClutFormat) { if (!noOffset) { - WARN_LOG_REPORT_ONCE(subareaClut, G3D, "Render to texture using CLUT with offset at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); + WARN_LOG_REPORT_ONCE(subareaClut, G3D, "Texturing from framebuffer using CLUT with offset at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); } AttachFramebufferValid(entry, framebuffer, fbInfo); entry->status |= TexCacheEntry::STATUS_DEPALETTIZE; // We'll validate it compiles later. return true; - } else if (entry->format == GE_TFMT_CLUT8 || entry->format == GE_TFMT_CLUT4) { - ERROR_LOG_REPORT_ONCE(fourEightBit, G3D, "4 and 8-bit CLUT format not supported for framebuffers"); + } else if (IsClutFormat((GETextureFormat)(entry->format)) || IsDXTFormat((GETextureFormat)(entry->format))) { + WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffers", GeTextureFormatToString((GETextureFormat)entry->format)); } // This is either normal or we failed to generate a shader to depalettize - if (framebuffer->format == entry->format || clutFormat) { + if (framebuffer->format == entry->format || matchingClutFormat) { if (framebuffer->format != entry->format) { - WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Render to texture with different formats %d != %d at %08x", entry->format, framebuffer->format, address); + WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with different formats %s != %s at %08x", + GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); AttachFramebufferValid(entry, framebuffer, fbInfo); return true; } else { @@ -858,7 +863,8 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi return true; } } else { - WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Render to texture with incompatible formats %d != %d at %08x", entry->format, framebuffer->format, address); + WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with incompatible format %s != %s at %08x", + GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); } } diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 166f378b26c8..d0f7085969d6 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -123,11 +123,12 @@ struct TexCacheEntry { // Status, but int so we can zero initialize. int status; + u32 addr; u32 hash; VirtualFramebuffer *framebuffer; // if null, not sourced from an FBO. TODO: Collapse into texturePtr u32 sizeInRAM; // Could be computed - u8 format; + u8 format; // GeTextureFormat u8 maxLevel; u16 dim; u16 bufw; diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index b6c2dcf17c51..fcafb026856d 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -87,7 +87,6 @@ void TextureCacheDX9::SetFramebufferManager(FramebufferManagerDX9 *fbManager) { } void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { - DEBUG_LOG(G3D, "Deleting texture %p", entry->texturePtr); LPDIRECT3DTEXTURE9 &texture = DxTex(entry); if (texture) { texture->Release(); diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 48c4a3eda85e..9428cdf5d72e 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -73,7 +73,6 @@ void TextureCacheGLES::SetFramebufferManager(FramebufferManagerGLES *fbManager) } void TextureCacheGLES::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { - DEBUG_LOG(G3D, "Deleting texture %08x", entry->addr); if (delete_them) { if (entry->textureName) { render_->DeleteTexture(entry->textureName); diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 9ea555f538a0..d77221d6a4f8 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -575,6 +575,7 @@ + true true diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index 8dcbf8229d27..04ac5cae2d98 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -27,9 +27,6 @@ - - Common - Common @@ -288,6 +285,9 @@ DirectX9 + + Common + @@ -572,5 +572,8 @@ DirectX9 + + Common + \ No newline at end of file diff --git a/GPU/GeConstants.cpp b/GPU/GeConstants.cpp new file mode 100644 index 000000000000..a8a27685cb43 --- /dev/null +++ b/GPU/GeConstants.cpp @@ -0,0 +1,28 @@ +#include "GPU/ge_constants.h" + +const char *GeBufferFormatToString(GEBufferFormat fmt) { + switch (fmt) { + case GE_FORMAT_4444: return "4444"; + case GE_FORMAT_5551: return "5551"; + case GE_FORMAT_565: return "565"; + case GE_FORMAT_8888: return "8888"; + default: return "N/A"; + } +} + +const char *GeTextureFormatToString(GETextureFormat fmt) { + switch (fmt) { + case GE_TFMT_5650: return "565"; + case GE_TFMT_5551: return "5551"; + case GE_TFMT_4444: return "4444"; + case GE_TFMT_8888: return "8888"; + case GE_TFMT_CLUT4: return "CLUT4"; + case GE_TFMT_CLUT8: return "CLUT8"; + case GE_TFMT_CLUT16: return "CLUT16"; + case GE_TFMT_CLUT32: return "CLUT32"; + case GE_TFMT_DXT1: return "DXT1"; + case GE_TFMT_DXT3: return "DXT3"; + case GE_TFMT_DXT5: return "DXT5"; + default: return "N/A"; + } +} diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 5476af392a2e..8631e4cdea4b 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -416,7 +416,6 @@ void TextureCacheVulkan::CompileScalingShader() { } void TextureCacheVulkan::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { - DEBUG_LOG(G3D, "Deleting texture %p", entry->vkTex); delete entry->vkTex; entry->vkTex = nullptr; } diff --git a/GPU/ge_constants.h b/GPU/ge_constants.h index e9509767f0b6..fc7c2ca982a6 100644 --- a/GPU/ge_constants.h +++ b/GPU/ge_constants.h @@ -285,6 +285,8 @@ enum GEBufferFormat GE_FORMAT_INVALID = 0xFF, }; +const char *GeBufferFormatToString(GEBufferFormat fmt); + #define GE_VTYPE_TRANSFORM (0<<23) #define GE_VTYPE_THROUGH (1<<23) #define GE_VTYPE_THROUGH_MASK (1<<23) @@ -413,6 +415,14 @@ enum GETextureFormat GE_TFMT_DXT5 = 10, }; +const char *GeTextureFormatToString(GETextureFormat fmt); +inline bool IsClutFormat(GETextureFormat fmt) { + return fmt == GE_TFMT_CLUT4 || fmt == GE_TFMT_CLUT8 || fmt == GE_TFMT_CLUT16 || fmt == GE_TFMT_CLUT32; +} +inline bool IsDXTFormat(GETextureFormat fmt) { + return fmt == GE_TFMT_DXT1 || fmt == GE_TFMT_DXT3 || fmt == GE_TFMT_DXT5; +} + enum GETexLevelMode { GE_TEXLEVEL_MODE_AUTO = 0, GE_TEXLEVEL_MODE_CONST = 1, diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index 0a0e4ee1978c..248d1c6a2b0b 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -482,6 +482,7 @@ + diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters index 3c473397641e..261335da4672 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters @@ -45,6 +45,7 @@ + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 252572d1ba81..ac68cf181578 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -225,6 +225,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/GPU.cpp \ $(SRC)/GPU/GPUCommon.cpp \ $(SRC)/GPU/GPUState.cpp \ + $(SRC)/GPU/GeConstants.cpp \ $(SRC)/GPU/GeDisasm.cpp \ $(SRC)/GPU/Common/DepalettizeShaderCommon.cpp \ $(SRC)/GPU/Common/FramebufferManagerCommon.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 7cbf1ce5279b..ff7b5248753c 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -187,6 +187,7 @@ SOURCES_CXX += \ $(GPUDIR)/Software/TransformUnit.cpp \ $(GPUDIR)/Software/SoftGpu.cpp \ $(GPUDIR)/Software/Sampler.cpp \ + $(GPUDIR)/GeConstants.cpp \ $(GPUDIR)/GeDisasm.cpp \ $(GPUDIR)/GPUCommon.cpp \ $(GPUDIR)/GPU.cpp \ From 09e300e646b81337341b4a508a3ac00838a667fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 4 Aug 2020 14:48:28 +0200 Subject: [PATCH 3/3] Be a little more aggressive discarding non matching framebuffers when texturing. Enable create framebuffer from copy, fixing #12345 --- GPU/Common/TextureCacheCommon.cpp | 4 ++++ assets/compat.ini | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index e6e6666adb41..1b87c4afb5e8 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -847,6 +847,8 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi return true; } else if (IsClutFormat((GETextureFormat)(entry->format)) || IsDXTFormat((GETextureFormat)(entry->format))) { WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffers", GeTextureFormatToString((GETextureFormat)entry->format)); + DetachFramebuffer(entry, address, framebuffer); + return false; } // This is either normal or we failed to generate a shader to depalettize @@ -865,6 +867,8 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi } else { WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with incompatible format %s != %s at %08x", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); + DetachFramebuffer(entry, address, framebuffer); + return false; } } diff --git a/assets/compat.ini b/assets/compat.ini index 03ec98bbb053..068d3b9f05f9 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -523,6 +523,15 @@ NPEH00065 = true # Ys Seven NPJH50350 = true # Ys Seven ULJM08041 = true # Ys Seven +# Burnout Legends +ULES00125 = true +ULUS10025 = true +ULJM05228 = true +NPJH50305 = true +ULJM05049 = true +ULKS46027 = true +ULAS42019 = true + # Note! This whole flag is disabled temporarily by appending "Disabled" to its name). See 7914 [YugiohSaveFixDisabled] # The cause of Yu-gi-oh series 's bad save (cannot save) are load "save status" and use cwcheat,