Merge pull request #1694 from unknownbrackets/font-fix

Match PSP error behavior in some sceFont functions
This commit is contained in:
Henrik Rydgård 2013-05-06 00:14:52 -07:00
commit 87a78f2e65
11 changed files with 170 additions and 108 deletions

View File

@ -25,6 +25,9 @@
#include "Core/Font/PGF.h"
#include "Core/HLE/HLE.h"
#include "GPU/GPUInterface.h"
#include "GPU/GPUState.h"
// These fonts, created by ttf2pgf, don't have complete glyph info and need to be identified.
static bool isJPCSPFont(const char *fontName) {
return !strcmp(fontName, "Liberation") || !strcmp(fontName, "Sazanami") || !strcmp(fontName, "UnDotum");
@ -241,11 +244,12 @@ int PGF::GetCharIndex(int charCode, const std::vector<int> &charmapCompressed) {
bool PGF::GetCharInfo(int charCode, PGFCharInfo *charInfo) {
Glyph glyph;
memset(charInfo, 0, sizeof(*charInfo));
if (!GetCharGlyph(charCode, FONT_PGF_CHARGLYPH, glyph)) {
// Character not in font, return zeroed charInfo as on real PSP.
return false;
}
memset(charInfo, 0, sizeof(*charInfo));
charInfo->bitmapWidth = glyph.w;
charInfo->bitmapHeight = glyph.h;
@ -408,7 +412,7 @@ bool PGF::GetCharGlyph(int charCode, int glyphType, Glyph &glyph) {
return true;
}
void PGF::DrawCharacter(u32 base, int bpl, int bufWidth, int bufHeight, int x, int y, int clipX, int clipY, int clipWidth, int clipHeight, int pixelformat, int charCode, int altCharCode, int glyphType) {
void PGF::DrawCharacter(const GlyphImage *image, int clipX, int clipY, int clipWidth, int clipHeight, int charCode, int altCharCode, int glyphType) {
Glyph glyph;
if (!GetCharGlyph(charCode, glyphType, glyph)) {
// No Glyph available for this charCode, try to use the alternate char.
@ -431,6 +435,9 @@ void PGF::DrawCharacter(u32 base, int bpl, int bufWidth, int bufHeight, int x, i
int numberPixels = glyph.w * glyph.h;
int pixelIndex = 0;
int x = image->xPos64 >> 6;
int y = image->yPos64 >> 6;
while (pixelIndex < numberPixels && bitPtr + 8 < fontDataSize * 8) {
// This is some kind of nibble based RLE compression.
int nibble = getBits(4, fontData, bitPtr);
@ -466,7 +473,7 @@ void PGF::DrawCharacter(u32 base, int bpl, int bufWidth, int bufHeight, int x, i
if (pixelX >= clipX && pixelX < clipX + clipWidth && pixelY >= clipY && pixelY < clipY + clipHeight) {
// 4-bit color value
int pixelColor = value;
switch (pixelformat) {
switch (image->pixelFormat) {
case PSP_FONT_PIXELFORMAT_8:
// 8-bit color value
pixelColor |= pixelColor << 4;
@ -485,12 +492,14 @@ void PGF::DrawCharacter(u32 base, int bpl, int bufWidth, int bufHeight, int x, i
break;
}
SetFontPixel(base, bpl, bufWidth, bufHeight, pixelX, pixelY, pixelColor, pixelformat);
SetFontPixel(image->bufferPtr, image->bytesPerLine, image->bufWidth, image->bufHeight, pixelX, pixelY, pixelColor, image->pixelFormat);
}
pixelIndex++;
}
}
gpu->InvalidateCache(image->bufferPtr, image->bytesPerLine * image->bufHeight, GPU_INVALIDATE_SAFE);
}
void PGF::SetFontPixel(u32 base, int bpl, int bufWidth, int bufHeight, int x, int y, int pixelColor, int pixelformat) {

View File

@ -108,6 +108,17 @@ struct Glyph {
u32 ptr;
};
struct GlyphImage {
FontPixelFormat pixelFormat;
s32 xPos64;
s32 yPos64;
u16 bufWidth;
u16 bufHeight;
u16 bytesPerLine;
u16 pad;
u32 bufferPtr;
};
#pragma pack(push,1)
struct PGFHeader
{
@ -243,7 +254,7 @@ public:
bool GetCharInfo(int charCode, PGFCharInfo *ci);
void GetFontInfo(PGFFontInfo *fi);
void DrawCharacter(u32 base, int bpl, int bufWidth, int bufHeight, int x, int y, int clipX, int clipY, int clipWidth, int clipHeight, int pixelformat, int charCode, int altCharCode, int glyphType);
void DrawCharacter(const GlyphImage *image, int clipX, int clipY, int clipWidth, int clipHeight, int charCode, int altCharCode, int glyphType);
void DoState(PointerWrap &p);

View File

@ -57,17 +57,6 @@ struct FontNewLibParams {
u32 ioFinishFuncAddr;
};
struct GlyphImage {
FontPixelFormat pixelFormat;
s32 xPos64;
s32 yPos64;
u16 bufWidth;
u16 bufHeight;
u16 bytesPerLine;
u16 pad;
u32 bufferPtr;
};
struct FontRegistryEntry {
int hSize;
int vSize;
@ -231,6 +220,7 @@ public:
: fontLibID_(fontLibID), font_(font), handle_(handle) {}
Font *GetFont() { return font_; }
PGF *GetPGF() { return font_->GetPGF(); }
FontLib *GetFontLib() { if (!IsOpen()) return NULL; return fontLibList[fontLibID_]; }
u32 Handle() const { return handle_; }
@ -615,13 +605,18 @@ int sceFontDoneLib(u32 fontLibHandle) {
// Open internal font into a FontLib
u32 sceFontOpen(u32 libHandle, u32 index, u32 mode, u32 errorCodePtr) {
INFO_LOG(HLE, "sceFontOpen(%x, %x, %x, %x)", libHandle, index, mode, errorCodePtr);
if (!Memory::IsValidAddress(errorCodePtr)) {
Memory::Write_U32(ERROR_FONT_INVALID_PARAMETER, errorCodePtr);
// Would crash on the PSP.
ERROR_LOG(HLE, "sceFontOpen(%x, %x, %x, %x): invalid pointer", libHandle, index, mode, errorCodePtr);
return 0;
}
INFO_LOG(HLE, "sceFontOpen(%x, %x, %x, %x)", libHandle, index, mode, errorCodePtr);
FontLib *fontLib = GetFontLib(libHandle);
if (fontLib == NULL) {
Memory::Write_U32(ERROR_FONT_INVALID_LIBID, errorCodePtr);
return 0;
}
if (index >= internalFonts.size()) {
Memory::Write_U32(ERROR_FONT_INVALID_PARAMETER, errorCodePtr);
return 0;
@ -763,21 +758,21 @@ int sceFontFindFont(u32 libHandlePtr, u32 fontStylePtr, u32 errorCodePtr) {
}
int sceFontGetFontInfo(u32 fontHandle, u32 fontInfoPtr) {
ERROR_LOG(HLE, "sceFontGetFontInfo(%x, %x)", fontHandle, fontInfoPtr);
PGFFontInfo fi;
memset (&fi, 0, sizeof(fi));
if (!Memory::IsValidAddress(fontInfoPtr))
return 0;
if (!Memory::IsValidAddress(fontInfoPtr)) {
ERROR_LOG(HLE, "sceFontGetFontInfo(%x, %x): bad fontInfo pointer", fontHandle, fontInfoPtr);
return ERROR_FONT_INVALID_PARAMETER;
}
LoadedFont *font = GetLoadedFont(fontHandle, true);
if (!font)
return 0;
PGF *pgf = font->GetFont()->GetPGF();
pgf->GetFontInfo(&fi);
fi.fontStyle = font->GetFont()->GetFontStyle();
if (!font) {
ERROR_LOG(HLE, "sceFontGetFontInfo(%x, %x): bad font", fontHandle, fontInfoPtr);
return ERROR_FONT_INVALID_PARAMETER;
}
INFO_LOG(HLE, "sceFontGetFontInfo(%x, %x)", fontHandle, fontInfoPtr);
auto fi = Memory::GetStruct<PGFFontInfo>(fontInfoPtr);
font->GetPGF()->GetFontInfo(fi);
fi->fontStyle = font->GetFont()->GetFontStyle();
Memory::WriteStruct(fontInfoPtr, &fi);
return 0;
}
@ -789,19 +784,21 @@ int sceFontGetFontInfoByIndexNumber(u32 libHandle, u32 fontInfoPtr, u32 unknown,
}
int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) {
INFO_LOG(HLE, "sceFontGetCharInfo(%08x, %i, %08x)", fontHandle, charCode, charInfoPtr);
if (!Memory::IsValidAddress(charInfoPtr))
return -1;
PGFCharInfo charInfo;
memset(&charInfo, 0, sizeof(charInfo));
LoadedFont *font = GetLoadedFont(fontHandle, false);
if (font) {
font->GetFont()->GetPGF()->GetCharInfo(charCode, &charInfo);
} else {
ERROR_LOG(HLE, "sceFontGetCharInfo - invalid font");
if (!Memory::IsValidAddress(charInfoPtr)) {
ERROR_LOG(HLE, "sceFontGetCharInfo(%08x, %i, %08x): bad charInfo pointer", fontHandle, charCode, charInfoPtr);
return ERROR_FONT_INVALID_PARAMETER;
}
Memory::WriteStruct(charInfoPtr, &charInfo);
LoadedFont *font = GetLoadedFont(fontHandle, false);
if (!font) {
// The PSP crashes, but we assume it'd work like sceFontGetFontInfo(), and not touch charInfo.
ERROR_LOG(HLE, "sceFontGetCharInfo(%08x, %i, %08x): bad font", fontHandle, charCode, charInfoPtr);
return ERROR_FONT_INVALID_PARAMETER;
}
DEBUG_LOG(HLE, "sceFontGetCharInfo(%08x, %i, %08x)", fontHandle, charCode, charInfoPtr);
auto charInfo = Memory::GetStruct<PGFCharInfo>(charInfoPtr);
font->GetPGF()->GetCharInfo(charCode, charInfo);
return 0;
}
@ -820,7 +817,7 @@ int sceFontGetCharImageRect(u32 fontHandle, u32 charCode, u32 charRectPtr) {
PGFCharInfo charInfo;
LoadedFont *font = GetLoadedFont(fontHandle, false);
if (font) {
font->GetFont()->GetPGF()->GetCharInfo(charCode, &charInfo);
font->GetPGF()->GetCharInfo(charCode, &charInfo);
Memory::Write_U16(charInfo.bitmapWidth, charRectPtr); // character bitmap width in pixels
Memory::Write_U16(charInfo.bitmapHeight, charRectPtr + 2); // character bitmap height in pixels
} else {
@ -835,44 +832,38 @@ int sceFontGetShadowImageRect(u32 fontHandle, u32 charCode, u32 charRectPtr) {
}
int sceFontGetCharGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) {
INFO_LOG(HLE, "sceFontGetCharGlyphImage(%x, %x, %x)", fontHandle, charCode, glyphImagePtr);
int pixelFormat = Memory::Read_U32(glyphImagePtr);
int xPos64 = Memory::Read_U32(glyphImagePtr+4);
int yPos64 = Memory::Read_U32(glyphImagePtr+8);
int bufWidth = Memory::Read_U16(glyphImagePtr+12);
int bufHeight = Memory::Read_U16(glyphImagePtr+14);
int bytesPerLine = Memory::Read_U16(glyphImagePtr+16);
int buffer = Memory::Read_U32(glyphImagePtr+20);
if (!Memory::IsValidAddress(glyphImagePtr)) {
ERROR_LOG(HLE, "sceFontGetCharGlyphImage(%x, %x, %x): bad glyphImage pointer", fontHandle, charCode, glyphImagePtr);
return ERROR_FONT_INVALID_PARAMETER;
}
LoadedFont *font = GetLoadedFont(fontHandle, false);
if (!font) {
ERROR_LOG(HLE, "%08x is not a valid font handle!", fontHandle);
return 0;
ERROR_LOG(HLE, "sceFontGetCharGlyphImage(%x, %x, %x): bad font", fontHandle, charCode, glyphImagePtr);
return ERROR_FONT_INVALID_PARAMETER;
}
INFO_LOG(HLE, "sceFontGetCharGlyphImage(%x, %x, %x)", fontHandle, charCode, glyphImagePtr);
auto glyph = Memory::GetStruct<const GlyphImage>(glyphImagePtr);
int altCharCode = font->GetFontLib()->GetAltCharCode();
font->GetFont()->GetPGF()->DrawCharacter(buffer, bytesPerLine, bufWidth, bufHeight, xPos64 >> 6, yPos64 >> 6, 0, 0, 8192, 8192, pixelFormat, charCode, altCharCode, FONT_PGF_CHARGLYPH);
font->GetPGF()->DrawCharacter(glyph, 0, 0, 8192, 8192, charCode, altCharCode, FONT_PGF_CHARGLYPH);
return 0;
}
int sceFontGetCharGlyphImage_Clip(u32 fontHandle, u32 charCode, u32 glyphImagePtr, int clipXPos, int clipYPos, int clipWidth, int clipHeight) {
INFO_LOG(HLE, "sceFontGetCharGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i)", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight);
int pixelFormat = Memory::Read_U32(glyphImagePtr);
int xPos64 = Memory::Read_U32(glyphImagePtr+4);
int yPos64 = Memory::Read_U32(glyphImagePtr+8);
int bufWidth = Memory::Read_U16(glyphImagePtr+12);
int bufHeight = Memory::Read_U16(glyphImagePtr+14);
int bytesPerLine = Memory::Read_U16(glyphImagePtr+16);
int buffer = Memory::Read_U32(glyphImagePtr+20);
if (!Memory::IsValidAddress(glyphImagePtr)) {
ERROR_LOG(HLE, "sceFontGetCharGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i): bad glyphImage pointer", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight);
return ERROR_FONT_INVALID_PARAMETER;
}
LoadedFont *font = GetLoadedFont(fontHandle, false);
if (!font) {
ERROR_LOG(HLE, "%08x is not a valid font handle!", fontHandle);
return 0;
ERROR_LOG(HLE, "sceFontGetCharGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i): bad font", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight);
return ERROR_FONT_INVALID_PARAMETER;
}
INFO_LOG(HLE, "sceFontGetCharGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i)", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight);
auto glyph = Memory::GetStruct<const GlyphImage>(glyphImagePtr);
int altCharCode = font->GetFontLib()->GetAltCharCode();
font->GetFont()->GetPGF()->DrawCharacter(buffer, bytesPerLine, bufWidth, bufHeight, xPos64 >> 6, yPos64 >> 6, clipXPos, clipYPos, clipXPos + clipWidth, clipYPos + clipHeight, pixelFormat, charCode, altCharCode, FONT_PGF_CHARGLYPH);
font->GetPGF()->DrawCharacter(glyph, clipXPos, clipYPos, clipXPos + clipWidth, clipYPos + clipHeight, charCode, altCharCode, FONT_PGF_CHARGLYPH);
return 0;
}

View File

@ -307,7 +307,7 @@ int sceKernelDcacheInvalidateRange(u32 addr, int size)
return SCE_KERNEL_ERROR_CACHE_ALIGNMENT;
if (addr != 0)
gpu->InvalidateCache(addr, size);
gpu->InvalidateCache(addr, size, GPU_INVALIDATE_HINT);
}
return 0;
}
@ -325,7 +325,7 @@ int sceKernelDcacheWritebackAll()
#endif
// Some games seem to use this a lot, it doesn't make sense
// to zap the whole texture cache.
gpu->InvalidateCacheHint(0, -1);
gpu->InvalidateCache(0, -1, GPU_INVALIDATE_ALL);
return 0;
}
@ -338,7 +338,7 @@ int sceKernelDcacheWritebackRange(u32 addr, int size)
return SCE_KERNEL_ERROR_INVALID_SIZE;
if (size > 0 && addr != 0) {
gpu->InvalidateCache(addr, size);
gpu->InvalidateCache(addr, size, GPU_INVALIDATE_HINT);
}
return 0;
}
@ -351,7 +351,7 @@ int sceKernelDcacheWritebackInvalidateRange(u32 addr, int size)
return SCE_KERNEL_ERROR_INVALID_SIZE;
if (size > 0 && addr != 0) {
gpu->InvalidateCache(addr, size);
gpu->InvalidateCache(addr, size, GPU_INVALIDATE_HINT);
}
return 0;
}
@ -360,7 +360,7 @@ int sceKernelDcacheWritebackInvalidateAll()
#ifdef LOG_CACHE
NOTICE_LOG(HLE,"sceKernelDcacheInvalidateAll()");
#endif
gpu->InvalidateCacheHint(0, -1);
gpu->InvalidateCache(0, -1, GPU_INVALIDATE_ALL);
return 0;
}

View File

@ -980,21 +980,14 @@ void GLES_GPU::DoBlockTransfer() {
// TODO: Notify all overlapping FBOs that they need to reload.
textureCache_.Invalidate(dstBasePtr + dstY * dstStride + dstX, height * dstStride + width * bpp, true);
textureCache_.Invalidate(dstBasePtr + dstY * dstStride + dstX, height * dstStride + width * bpp, GPU_INVALIDATE_HINT);
}
void GLES_GPU::InvalidateCache(u32 addr, int size) {
void GLES_GPU::InvalidateCache(u32 addr, int size, GPUInvalidationType type) {
if (size > 0)
textureCache_.Invalidate(addr, size, true);
textureCache_.Invalidate(addr, size, type);
else
textureCache_.InvalidateAll(true);
}
void GLES_GPU::InvalidateCacheHint(u32 addr, int size) {
if (size > 0)
textureCache_.Invalidate(addr, size, false);
else
textureCache_.InvalidateAll(false);
textureCache_.InvalidateAll(type);
}
void GLES_GPU::ClearCacheNextFrame() {

View File

@ -44,8 +44,7 @@ public:
virtual void CopyDisplayToOutput();
virtual void BeginFrame();
virtual void UpdateStats();
virtual void InvalidateCache(u32 addr, int size);
virtual void InvalidateCacheHint(u32 addr, int size);
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type);
virtual void ClearCacheNextFrame();
virtual void DeviceLost(); // Only happens on Android. Drop all textures and shaders.

View File

@ -108,7 +108,7 @@ void TextureCache::Decimate() {
}
}
void TextureCache::Invalidate(u32 addr, int size, bool force) {
void TextureCache::Invalidate(u32 addr, int size, GPUInvalidationType type) {
addr &= 0xFFFFFFF;
u32 addr_end = addr + size;
@ -125,10 +125,10 @@ void TextureCache::Invalidate(u32 addr, int size, bool force) {
if (iter->second.status == TexCacheEntry::STATUS_RELIABLE) {
iter->second.status = TexCacheEntry::STATUS_HASHING;
}
if (force) {
if (type != GPU_INVALIDATE_ALL) {
gpuStats.numTextureInvalidations++;
// Start it over from 0.
iter->second.numFrames = 0;
// Start it over from 0 (unless it's safe.)
iter->second.numFrames = type == GPU_INVALIDATE_SAFE ? 256 : 0;
iter->second.framesUntilNextFullHash = 0;
} else {
iter->second.invalidHint++;
@ -137,8 +137,8 @@ void TextureCache::Invalidate(u32 addr, int size, bool force) {
}
}
void TextureCache::InvalidateAll(bool force) {
Invalidate(0, 0xFFFFFFFF, force);
void TextureCache::InvalidateAll(GPUInvalidationType type) {
Invalidate(0, 0xFFFFFFFF, type);
}
void TextureCache::ClearNextFrame() {
@ -318,12 +318,39 @@ inline void DeIndexTexture4(ClutT *dest, const u8 *indexed, int length, const Cl
}
}
template <typename ClutT>
inline void DeIndexTexture4Optimal(ClutT *dest, const u8 *indexed, int length, ClutT color) {
for (int i = 0; i < length; i += 2) {
u8 index = *indexed++;
dest[i + 0] = color | ((index >> 0) & 0xf);
dest[i + 1] = color | ((index >> 4) & 0xf);
}
}
template <>
inline void DeIndexTexture4Optimal<u16>(u16 *dest, const u8 *indexed, int length, u16 color) {
const u16 *indexed16 = (const u16 *)indexed;
const u32 color32 = (color << 16) | color;
u32 *dest32 = (u32 *)dest;
for (int i = 0; i < length / 2; i += 2) {
u16 index = *indexed16++;
dest32[i + 0] = color32 | ((index & 0x00f0) << 12) | ((index & 0x000f) >> 0);
dest32[i + 1] = color32 | ((index & 0xf000) << 4) | ((index & 0x0f00) >> 8);
}
}
template <typename ClutT>
inline void DeIndexTexture4(ClutT *dest, const u32 texaddr, int length, const ClutT *clut) {
const u8 *indexed = (const u8 *) Memory::GetPointer(texaddr);
DeIndexTexture4(dest, indexed, length, clut);
}
template <typename ClutT>
inline void DeIndexTexture4Optimal(ClutT *dest, const u32 texaddr, int length, ClutT color) {
const u8 *indexed = (const u8 *) Memory::GetPointer(texaddr);
DeIndexTexture4Optimal(dest, indexed, length, color);
}
void *TextureCache::readIndexedTex(int level, u32 texaddr, int bytesPerIndex, GLuint dstFmt) {
// Special rules for kernel textures (PPGe):
int mask = 0x3FF;
@ -1036,12 +1063,41 @@ void *TextureCache::DecodeTextureLevel(u8 format, u8 clutformat, int level, u32
const u16 *clut = clutBuf16;
u32 clutSharingOffset = 0; //(gstate.mipmapShareClut & 1) ? 0 : level * 16;
texByteAlign = 2;
// Special optimization: fonts typically draw clut4 with just alpha values in a single color.
bool linearClut = false;
u16 linearColor = 0;
if (gstate.clutformat == (0xC500FF00 | GE_CMODE_16BIT_ABGR4444)) {
// TODO: Do this check once per CLUT load?
linearClut = true;
linearColor = clut[clutSharingOffset + 15] & 0xFFF0;
for (int i = 0; i < 16; ++i) {
if ((clut[clutSharingOffset + i] & 0xf) != i) {
linearClut = false;
break;
}
// Alpha 0 doesn't matter.
if (i != 0 && (clut[clutSharingOffset + i] & 0xFFF0) != linearColor) {
linearClut = false;
break;
}
}
}
if (!(gstate.texmode & 1)) {
DeIndexTexture4(tmpTexBuf16.data(), texaddr, bufw * h, clut + clutSharingOffset);
if (linearClut) {
DeIndexTexture4Optimal(tmpTexBuf16.data(), texaddr, bufw * h, linearColor);
} else {
DeIndexTexture4(tmpTexBuf16.data(), texaddr, bufw * h, clut + clutSharingOffset);
}
} else {
tmpTexBuf32.resize(std::max(bufw, w) * h);
UnswizzleFromMem(texaddr, bufw, 0, level);
DeIndexTexture4(tmpTexBuf16.data(), (u8 *)tmpTexBuf32.data(), bufw * h, clut + clutSharingOffset);
if (linearClut) {
DeIndexTexture4Optimal(tmpTexBuf16.data(), (u8 *)tmpTexBuf32.data(), bufw * h, linearColor);
} else {
DeIndexTexture4(tmpTexBuf16.data(), (u8 *)tmpTexBuf32.data(), bufw * h, clut + clutSharingOffset);
}
}
finalBuf = tmpTexBuf16.data();
}

View File

@ -19,6 +19,7 @@
#include "../Globals.h"
#include "gfx_es2/fbo.h"
#include "GPU/GPUInterface.h"
#include "GPU/GPUState.h"
#include "TextureScaler.h"
@ -34,8 +35,8 @@ public:
void Clear(bool delete_them);
void StartFrame();
void Invalidate(u32 addr, int size, bool force);
void InvalidateAll(bool force);
void Invalidate(u32 addr, int size, GPUInvalidationType type);
void InvalidateAll(GPUInvalidationType type);
void ClearNextFrame();
// FramebufferManager keeps TextureCache updated about what regions of memory

View File

@ -132,6 +132,15 @@ struct DisplayList
u64 waitTicks;
};
enum GPUInvalidationType {
// Affects all memory. Not considered highly.
GPU_INVALIDATE_ALL,
// Indicates some memory may have changed.
GPU_INVALIDATE_HINT,
// Reliable invalidation (where any hashing, etc. is unneeded, it'll always invalidate.)
GPU_INVALIDATE_SAFE,
};
class GPUInterface
{
public:
@ -171,8 +180,7 @@ public:
// Invalidate any cached content sourced from the specified range.
// If size = -1, invalidate everything.
virtual void InvalidateCache(u32 addr, int size) = 0;
virtual void InvalidateCacheHint(u32 addr, int size) = 0;
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type) = 0;
// Will cause the texture cache to be cleared at the start of the next frame.
virtual void ClearCacheNextFrame() = 0;

View File

@ -674,12 +674,7 @@ void NullGPU::UpdateStats()
gpuStats.numTextures = 0;
}
void NullGPU::InvalidateCache(u32 addr, int size)
{
// Nothing to invalidate.
}
void NullGPU::InvalidateCacheHint(u32 addr, int size)
void NullGPU::InvalidateCache(u32 addr, int size, GPUInvalidationType type)
{
// Nothing to invalidate.
}

View File

@ -34,8 +34,7 @@ public:
virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) {}
virtual void CopyDisplayToOutput() {}
virtual void UpdateStats();
virtual void InvalidateCache(u32 addr, int size);
virtual void InvalidateCacheHint(u32 addr, int size);
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type);
virtual void ClearCacheNextFrame() {};
virtual void Flush() {}