Use sceKernelDcache*() to invalidate the texcache.

Also in the block transfer code.
This commit is contained in:
Unknown W. Brackets 2012-12-21 14:10:57 -08:00
parent b486ca1620
commit 6a9a183dd3
8 changed files with 48 additions and 1 deletions

View File

@ -25,6 +25,8 @@
#include "../PSPLoaders.h"
#include "../../Core/CoreTiming.h"
#include "../../Core/System.h"
#include "../../GPU/GPUInterface.h"
#include "../../GPU/GPUState.h"
#include "__sceAudio.h"
@ -187,6 +189,7 @@ void sceKernelGetGPI()
// textures, and in the future display lists, in some cases though.
void sceKernelDcacheInvalidateRange(u32 addr, int size)
{
gpu->InvalidateCache(addr, size);
}
void sceKernelDcacheWritebackAll()
{
@ -196,9 +199,11 @@ void sceKernelDcacheWritebackRange(u32 addr, int size)
}
void sceKernelDcacheWritebackInvalidateRange(u32 addr, int size)
{
gpu->InvalidateCache(addr, size);
}
void sceKernelDcacheWritebackInvalidateAll()
{
gpu->InvalidateCache(0, -1);
}
KernelObjectPool kernelObjects;

View File

@ -1259,7 +1259,7 @@ void GLES_GPU::DoBlockTransfer()
{
// TODO: This is used a lot to copy data around between render targets and textures,
// and also to quickly load textures from RAM to VRAM. So we should do checks like the following:
// * Does dstBasePtr point to an existing texture? If so invalidate it and reload it immediately.
// * Does dstBasePtr point to an existing texture? If so maybe reload it immediately.
//
// * Does srcBasePtr point to a render target, and dstBasePtr to a texture? If so
// either copy between rt and texture or reassign the texture to point to the render target
@ -1293,4 +1293,14 @@ void GLES_GPU::DoBlockTransfer()
}
// TODO: Notify all overlapping textures that it's time to die/reload.
TextureCache_Invalidate(srcBasePtr + srcY * srcStride + srcX, height * srcStride + width * bpp);
}
void GLES_GPU::InvalidateCache(u32 addr, int size)
{
if (size > 0)
TextureCache_Invalidate(addr, size);
else
TextureCache_Clear(true);
}

View File

@ -49,6 +49,7 @@ public:
virtual void CopyDisplayToOutput();
virtual void BeginFrame();
virtual void UpdateStats();
virtual void InvalidateCache(u32 addr, int size);
private:
// TransformPipeline.cpp

View File

@ -106,6 +106,26 @@ void TextureCache_Decimate()
}
}
void TextureCache_Invalidate(u32 addr, int size)
{
u32 addr_end = addr + size;
for (TexCache::iterator iter = cache.begin(); iter != cache.end(); )
{
// Clear if either the addr or clutaddr is in the range.
bool invalidate = iter->second.addr >= addr && iter->second.addr < addr_end;
invalidate |= iter->second.clutaddr >= addr && iter->second.clutaddr < addr_end;
if (invalidate)
{
glDeleteTextures(1, &iter->second.texture);
cache.erase(iter++);
}
else
++iter;
}
}
int TextureCache_NumLoadedTextures()
{
return cache.size();

View File

@ -25,4 +25,5 @@ void TextureCache_Init();
void TextureCache_Shutdown();
void TextureCache_Clear(bool delete_them);
void TextureCache_Decimate(); // Run this once per frame to get rid of old textures.
void TextureCache_Invalidate(u32 addr, int size);
int TextureCache_NumLoadedTextures();

View File

@ -45,6 +45,10 @@ public:
// Tells the GPU to update the gpuStats structure.
virtual void UpdateStats() = 0;
// Invalidate any cached content sourced from the specified range.
// If size = -1, invalidate everything.
virtual void InvalidateCache(u32 addr, int size) = 0;
// Internal hack to avoid interrupts from "PPGe" drawing (utility UI, etc)
virtual void EnableInterrupts(bool enable) = 0;
};

View File

@ -838,3 +838,8 @@ void NullGPU::UpdateStats()
gpuStats.numShaders = 0;
gpuStats.numTextures = 0;
}
void NullGPU::InvalidateCache(u32 addr, int size)
{
// Nothing to invalidate.
}

View File

@ -40,6 +40,7 @@ public:
virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) {}
virtual void CopyDisplayToOutput() {}
virtual void UpdateStats();
virtual void InvalidateCache(u32 addr, int size);
private:
bool ProcessDLQueue();