Improve GPU invalidation interface, check fonts.

When a font is rendered, tell the GPU about it, but don't rehash.

This not only improves perf (less hashing) but makes font changes more
immediate (no deferred hashing.)  But only if they use sceFont.
This commit is contained in:
Unknown W. Brackets 2013-05-05 22:52:01 -07:00
parent 995ab510e9
commit 3c0ed69fd2
9 changed files with 36 additions and 36 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");
@ -495,6 +498,8 @@ void PGF::DrawCharacter(const GlyphImage *image, int clipX, int clipY, int clipW
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

@ -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() {

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() {}