diff --git a/CMakeLists.txt b/CMakeLists.txt index a6d488f2df..a1edc34f9e 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 1ca924df16..5be05dfded 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 e1fbd2958c..66954c511c 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 462e72fc63..e6e6666adb 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 166f378b26..d0f7085969 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 b6c2dcf17c..fcafb02685 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 48c4a3eda8..9428cdf5d7 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 9ea555f538..d77221d6a4 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 8dcbf8229d..04ac5cae2d 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 0000000000..a8a27685cb --- /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 5476af392a..8631e4cdea 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 e9509767f0..fc7c2ca982 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 0a0e4ee197..248d1c6a2b 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 3c47339764..261335da46 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 252572d1ba..ac68cf1815 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 7cbf1ce527..ff7b524875 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 \