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 \