Texture from framebuffer: Logging improvements

This commit is contained in:
Henrik Rydgård 2020-08-04 14:45:14 +02:00
parent 49efaaef59
commit 58ef0c8e80
16 changed files with 77 additions and 23 deletions

View file

@ -1402,6 +1402,8 @@ set(GPU_SOURCES
GPU/Debugger/RecordFormat.h GPU/Debugger/RecordFormat.h
GPU/Debugger/Stepping.cpp GPU/Debugger/Stepping.cpp
GPU/Debugger/Stepping.h GPU/Debugger/Stepping.h
GPU/ge_constants.h
GPU/GeConstants.cpp
GPU/GPUInterface.h GPU/GPUInterface.h
GPU/GeDisasm.cpp GPU/GeDisasm.cpp
GPU/GeDisasm.h GPU/GeDisasm.h

View file

@ -1304,7 +1304,7 @@ VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAd
float renderWidthFactor = renderWidth_ / 480.0f; float renderWidthFactor = renderWidth_ / 480.0f;
float renderHeightFactor = renderHeight_ / 272.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! // 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 // Make sure this one would be found by the algorithm above so we wouldn't

View file

@ -68,13 +68,15 @@ struct VirtualFramebuffer {
// There's also a top left of the drawing region, but meh... // 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 width;
u16 height; u16 height;
// renderWidth/renderHeight: The scaled size we render at. May be scaled to render at higher resolutions. // 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. // The physical buffer may be larger than renderWidth/renderHeight.
u16 renderWidth; u16 renderWidth;
u16 renderHeight; u16 renderHeight;
// bufferWidth/bufferHeight: The pre-scaling size of the buffer itself. May only be bigger than width/height. // 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. // 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. // The buffer may be used to render a width or height from 0 to these values without being recreated.

View file

@ -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 they match exactly, it's non-CLUT and from the top left.
if (exactMatch) { if (exactMatch) {
DEBUG_LOG(G3D, "Render to texture detected at %08x!", address);
if (framebuffer->fb_stride != entry->bufw) { 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) { if (entry->format != (GETextureFormat)framebuffer->format) {
WARN_LOG_REPORT_ONCE(diffFormat1, G3D, "Render to texture with different formats %d != %d", entry->format, framebuffer->format); 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. // 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. // However, some games use a different format to clear the buffer.
if (framebuffer->last_frame_attached + 1 < gpuStats.numFlips) { if (framebuffer->last_frame_attached + 1 < gpuStats.numFlips) {
DetachFramebuffer(entry, address, framebuffer); DetachFramebuffer(entry, address, framebuffer);
@ -792,10 +792,12 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi
if (!framebufferManager_->UseBufferedRendering()) if (!framebufferManager_->UseBufferedRendering())
return false; 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_CLUT32) ||
(framebuffer->format != GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT16); (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 bitOffset = (texaddr - addr) * 8;
const u32 pixelOffset = bitOffset / std::max(1U, (u32)textureBitsPerPixel[entry->format]); const u32 pixelOffset = bitOffset / std::max(1U, (u32)textureBitsPerPixel[entry->format]);
fbInfo.yOffset = entry->bufw == 0 ? 0 : pixelOffset / entry->bufw; 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 (framebuffer->fb_stride != entry->bufw) {
if (noOffset) { 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 { } else {
// Assume any render-to-tex with different bufw + offset is a render from ram. // Assume any render-to-tex with different bufw + offset is a render from ram.
DetachFramebuffer(entry, address, framebuffer); DetachFramebuffer(entry, address, framebuffer);
@ -823,32 +826,34 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi
DetachFramebuffer(entry, address, framebuffer); DetachFramebuffer(entry, address, framebuffer);
return false; return false;
} }
// Trying to play it safe. Below 0x04110000 is almost always framebuffers. // 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? // TODO: Maybe we can reduce this check and find a better way above 0x04110000?
if (fbInfo.yOffset > MAX_SUBAREA_Y_OFFSET_SAFE && addr > 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); DetachFramebuffer(entry, address, framebuffer);
return false; return false;
} }
// Check for CLUT. The framebuffer is always RGB, but it can be interpreted as a CLUT texture. // 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. // 3rd Birthday (and a bunch of other games) render to a 16 bit clut texture.
if (clutFormat) { if (matchingClutFormat) {
if (!noOffset) { 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); AttachFramebufferValid(entry, framebuffer, fbInfo);
entry->status |= TexCacheEntry::STATUS_DEPALETTIZE; entry->status |= TexCacheEntry::STATUS_DEPALETTIZE;
// We'll validate it compiles later. // We'll validate it compiles later.
return true; return true;
} else if (entry->format == GE_TFMT_CLUT8 || entry->format == GE_TFMT_CLUT4) { } else if (IsClutFormat((GETextureFormat)(entry->format)) || IsDXTFormat((GETextureFormat)(entry->format))) {
ERROR_LOG_REPORT_ONCE(fourEightBit, G3D, "4 and 8-bit CLUT format not supported for framebuffers"); 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 // 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) { 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); AttachFramebufferValid(entry, framebuffer, fbInfo);
return true; return true;
} else { } else {
@ -858,7 +863,8 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi
return true; return true;
} }
} else { } 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);
} }
} }

View file

@ -123,11 +123,12 @@ struct TexCacheEntry {
// Status, but int so we can zero initialize. // Status, but int so we can zero initialize.
int status; int status;
u32 addr; u32 addr;
u32 hash; u32 hash;
VirtualFramebuffer *framebuffer; // if null, not sourced from an FBO. TODO: Collapse into texturePtr VirtualFramebuffer *framebuffer; // if null, not sourced from an FBO. TODO: Collapse into texturePtr
u32 sizeInRAM; // Could be computed u32 sizeInRAM; // Could be computed
u8 format; u8 format; // GeTextureFormat
u8 maxLevel; u8 maxLevel;
u16 dim; u16 dim;
u16 bufw; u16 bufw;

View file

@ -87,7 +87,6 @@ void TextureCacheDX9::SetFramebufferManager(FramebufferManagerDX9 *fbManager) {
} }
void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) {
DEBUG_LOG(G3D, "Deleting texture %p", entry->texturePtr);
LPDIRECT3DTEXTURE9 &texture = DxTex(entry); LPDIRECT3DTEXTURE9 &texture = DxTex(entry);
if (texture) { if (texture) {
texture->Release(); texture->Release();

View file

@ -73,7 +73,6 @@ void TextureCacheGLES::SetFramebufferManager(FramebufferManagerGLES *fbManager)
} }
void TextureCacheGLES::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { void TextureCacheGLES::ReleaseTexture(TexCacheEntry *entry, bool delete_them) {
DEBUG_LOG(G3D, "Deleting texture %08x", entry->addr);
if (delete_them) { if (delete_them) {
if (entry->textureName) { if (entry->textureName) {
render_->DeleteTexture(entry->textureName); render_->DeleteTexture(entry->textureName);

View file

@ -575,6 +575,7 @@
<ClCompile Include="Directx9\DrawEngineDX9.cpp" /> <ClCompile Include="Directx9\DrawEngineDX9.cpp" />
<ClCompile Include="Directx9\VertexShaderGeneratorDX9.cpp" /> <ClCompile Include="Directx9\VertexShaderGeneratorDX9.cpp" />
<ClCompile Include="GeDisasm.cpp" /> <ClCompile Include="GeDisasm.cpp" />
<ClCompile Include="GeConstants.cpp" />
<ClCompile Include="GLES\DepalettizeShaderGLES.cpp"> <ClCompile Include="GLES\DepalettizeShaderGLES.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild>

View file

@ -27,9 +27,6 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ge_constants.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Math3D.h"> <ClInclude Include="Math3D.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
@ -288,6 +285,9 @@
<ClInclude Include="Directx9\FramebufferManagerDX9.h"> <ClInclude Include="Directx9\FramebufferManagerDX9.h">
<Filter>DirectX9</Filter> <Filter>DirectX9</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ge_constants.h">
<Filter>Common</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Math3D.cpp"> <ClCompile Include="Math3D.cpp">
@ -572,5 +572,8 @@
<ClCompile Include="Directx9\FramebufferManagerDX9.cpp"> <ClCompile Include="Directx9\FramebufferManagerDX9.cpp">
<Filter>DirectX9</Filter> <Filter>DirectX9</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="GeConstants.cpp">
<Filter>Common</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

28
GPU/GeConstants.cpp Normal file
View file

@ -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";
}
}

View file

@ -416,7 +416,6 @@ void TextureCacheVulkan::CompileScalingShader() {
} }
void TextureCacheVulkan::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { void TextureCacheVulkan::ReleaseTexture(TexCacheEntry *entry, bool delete_them) {
DEBUG_LOG(G3D, "Deleting texture %p", entry->vkTex);
delete entry->vkTex; delete entry->vkTex;
entry->vkTex = nullptr; entry->vkTex = nullptr;
} }

View file

@ -285,6 +285,8 @@ enum GEBufferFormat
GE_FORMAT_INVALID = 0xFF, GE_FORMAT_INVALID = 0xFF,
}; };
const char *GeBufferFormatToString(GEBufferFormat fmt);
#define GE_VTYPE_TRANSFORM (0<<23) #define GE_VTYPE_TRANSFORM (0<<23)
#define GE_VTYPE_THROUGH (1<<23) #define GE_VTYPE_THROUGH (1<<23)
#define GE_VTYPE_THROUGH_MASK (1<<23) #define GE_VTYPE_THROUGH_MASK (1<<23)
@ -413,6 +415,14 @@ enum GETextureFormat
GE_TFMT_DXT5 = 10, 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 { enum GETexLevelMode {
GE_TEXLEVEL_MODE_AUTO = 0, GE_TEXLEVEL_MODE_AUTO = 0,
GE_TEXLEVEL_MODE_CONST = 1, GE_TEXLEVEL_MODE_CONST = 1,

View file

@ -482,6 +482,7 @@
<ClCompile Include="..\..\GPU\Debugger\Stepping.cpp" /> <ClCompile Include="..\..\GPU\Debugger\Stepping.cpp" />
<ClCompile Include="..\..\GPU\Directx9\PixelShaderGeneratorDX9.cpp" /> <ClCompile Include="..\..\GPU\Directx9\PixelShaderGeneratorDX9.cpp" />
<ClCompile Include="..\..\GPU\Directx9\VertexShaderGeneratorDX9.cpp" /> <ClCompile Include="..\..\GPU\Directx9\VertexShaderGeneratorDX9.cpp" />
<ClCompile Include="..\..\GPU\GeConstants.cpp" />
<ClCompile Include="..\..\GPU\GeDisasm.cpp" /> <ClCompile Include="..\..\GPU\GeDisasm.cpp" />
<ClCompile Include="..\..\GPU\GPU.cpp" /> <ClCompile Include="..\..\GPU\GPU.cpp" />
<ClCompile Include="..\..\GPU\GPUCommon.cpp" /> <ClCompile Include="..\..\GPU\GPUCommon.cpp" />

View file

@ -45,6 +45,7 @@
<ClCompile Include="..\..\GPU\Debugger\Stepping.cpp" /> <ClCompile Include="..\..\GPU\Debugger\Stepping.cpp" />
<ClCompile Include="..\..\GPU\Directx9\PixelShaderGeneratorDX9.cpp" /> <ClCompile Include="..\..\GPU\Directx9\PixelShaderGeneratorDX9.cpp" />
<ClCompile Include="..\..\GPU\Directx9\VertexShaderGeneratorDX9.cpp" /> <ClCompile Include="..\..\GPU\Directx9\VertexShaderGeneratorDX9.cpp" />
<ClCompile Include="..\..\GPU\GeConstants.cpp" />
<ClCompile Include="..\..\GPU\GeDisasm.cpp" /> <ClCompile Include="..\..\GPU\GeDisasm.cpp" />
<ClCompile Include="..\..\GPU\GPU.cpp" /> <ClCompile Include="..\..\GPU\GPU.cpp" />
<ClCompile Include="..\..\GPU\GPUCommon.cpp" /> <ClCompile Include="..\..\GPU\GPUCommon.cpp" />

View file

@ -225,6 +225,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/GPU/GPU.cpp \ $(SRC)/GPU/GPU.cpp \
$(SRC)/GPU/GPUCommon.cpp \ $(SRC)/GPU/GPUCommon.cpp \
$(SRC)/GPU/GPUState.cpp \ $(SRC)/GPU/GPUState.cpp \
$(SRC)/GPU/GeConstants.cpp \
$(SRC)/GPU/GeDisasm.cpp \ $(SRC)/GPU/GeDisasm.cpp \
$(SRC)/GPU/Common/DepalettizeShaderCommon.cpp \ $(SRC)/GPU/Common/DepalettizeShaderCommon.cpp \
$(SRC)/GPU/Common/FramebufferManagerCommon.cpp \ $(SRC)/GPU/Common/FramebufferManagerCommon.cpp \

View file

@ -187,6 +187,7 @@ SOURCES_CXX += \
$(GPUDIR)/Software/TransformUnit.cpp \ $(GPUDIR)/Software/TransformUnit.cpp \
$(GPUDIR)/Software/SoftGpu.cpp \ $(GPUDIR)/Software/SoftGpu.cpp \
$(GPUDIR)/Software/Sampler.cpp \ $(GPUDIR)/Software/Sampler.cpp \
$(GPUDIR)/GeConstants.cpp \
$(GPUDIR)/GeDisasm.cpp \ $(GPUDIR)/GeDisasm.cpp \
$(GPUDIR)/GPUCommon.cpp \ $(GPUDIR)/GPUCommon.cpp \
$(GPUDIR)/GPU.cpp \ $(GPUDIR)/GPU.cpp \