mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Use a separate func for gpu memset().
This commit is contained in:
parent
b73c575418
commit
8dcc09c9e1
@ -106,7 +106,7 @@ static int Replace_memcpy() {
|
||||
u32 bytes = PARAM(2);
|
||||
bool skip = false;
|
||||
if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) {
|
||||
skip = gpu->UpdateMemory(destPtr, srcPtr, bytes);
|
||||
skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes);
|
||||
}
|
||||
if (!skip && bytes != 0) {
|
||||
u8 *dst = Memory::GetPointerUnchecked(destPtr);
|
||||
@ -127,7 +127,7 @@ static int Replace_memcpy16() {
|
||||
u32 bytes = PARAM(2) * 16;
|
||||
bool skip = false;
|
||||
if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) {
|
||||
skip = gpu->UpdateMemory(destPtr, srcPtr, bytes);
|
||||
skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes);
|
||||
}
|
||||
if (!skip && bytes != 0) {
|
||||
u8 *dst = Memory::GetPointerUnchecked(destPtr);
|
||||
@ -150,7 +150,7 @@ static int Replace_memcpy_swizzled() {
|
||||
if (Memory::IsVRAMAddress(srcPtr)) {
|
||||
// Cheat a bit to force a download of the framebuffer.
|
||||
// VRAM + 0x00400000 is simply a VRAM mirror.
|
||||
gpu->UpdateMemory(srcPtr ^ 0x00400000, srcPtr, pitch * h);
|
||||
gpu->PerformMemoryCopy(srcPtr ^ 0x00400000, srcPtr, pitch * h);
|
||||
}
|
||||
u8 *dstp = Memory::GetPointerUnchecked(destPtr);
|
||||
const u8 *srcp = Memory::GetPointerUnchecked(srcPtr);
|
||||
@ -184,7 +184,7 @@ static int Replace_memmove() {
|
||||
u32 bytes = PARAM(2);
|
||||
bool skip = false;
|
||||
if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) {
|
||||
skip = gpu->UpdateMemory(destPtr, srcPtr, bytes);
|
||||
skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes);
|
||||
}
|
||||
if (!skip && bytes != 0) {
|
||||
u8 *dst = Memory::GetPointerUnchecked(destPtr);
|
||||
@ -204,9 +204,12 @@ static int Replace_memset() {
|
||||
u8 *dst = Memory::GetPointerUnchecked(destPtr);
|
||||
u8 value = PARAM(1);
|
||||
u32 bytes = PARAM(2);
|
||||
memset(dst, value, bytes);
|
||||
bool skip = false;
|
||||
if (Memory::IsVRAMAddress(destPtr)) {
|
||||
gpu->UpdateMemory(destPtr, destPtr, bytes);
|
||||
skip = gpu->PerformMemorySet(destPtr, value, bytes);
|
||||
}
|
||||
if (!skip) {
|
||||
memset(dst, value, bytes);
|
||||
}
|
||||
RETURN(destPtr);
|
||||
#ifndef MOBILE_DEVICE
|
||||
|
@ -50,7 +50,7 @@ int __DmacMemcpy(u32 dst, u32 src, u32 size) {
|
||||
|
||||
bool skip = false;
|
||||
if (Memory::IsVRAMAddress(src) || Memory::IsVRAMAddress(dst)) {
|
||||
skip = gpu->UpdateMemory(dst, src, size);
|
||||
skip = gpu->PerformMemoryCopy(dst, src, size);
|
||||
}
|
||||
if (!skip) {
|
||||
Memory::Memcpy(dst, Memory::GetPointer(src), size);
|
||||
|
@ -552,9 +552,12 @@ u32 sceKernelMemset(u32 addr, u32 fillc, u32 n)
|
||||
{
|
||||
u8 c = fillc & 0xff;
|
||||
DEBUG_LOG(SCEINTC, "sceKernelMemset(ptr = %08x, c = %02x, n = %08x)", addr, c, n);
|
||||
Memory::Memset(addr, c, n);
|
||||
bool skip = false;
|
||||
if (Memory::IsVRAMAddress(addr)) {
|
||||
gpu->UpdateMemory(addr, addr, n);
|
||||
skip = gpu->PerformMemorySet(addr, fillc, n);
|
||||
}
|
||||
if (!skip) {
|
||||
Memory::Memset(addr, c, n);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@ -565,7 +568,7 @@ u32 sceKernelMemcpy(u32 dst, u32 src, u32 size)
|
||||
|
||||
bool skip = false;
|
||||
if (Memory::IsVRAMAddress(src) || Memory::IsVRAMAddress(dst)) {
|
||||
skip = gpu->UpdateMemory(dst, src, size);
|
||||
skip = gpu->PerformMemoryCopy(dst, src, size);
|
||||
}
|
||||
|
||||
// Technically should crash if these are invalid and size > 0...
|
||||
|
@ -1315,7 +1315,12 @@ void DIRECTX9_GPU::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationTy
|
||||
framebufferManager_.UpdateFromMemory(addr, size);
|
||||
}
|
||||
|
||||
bool DIRECTX9_GPU::UpdateMemory(u32 dest, u32 src, int size) {
|
||||
bool DIRECTX9_GPU::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DIRECTX9_GPU::PerformMemorySet(u32 dest, u8 v, int size) {
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
return false;
|
||||
}
|
||||
|
@ -46,7 +46,8 @@ public:
|
||||
virtual void BeginFrame();
|
||||
virtual void UpdateStats();
|
||||
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type);
|
||||
virtual bool UpdateMemory(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size);
|
||||
virtual void ClearCacheNextFrame();
|
||||
virtual void DeviceLost(); // Only happens on Android. Drop all textures and shaders.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@ -1851,7 +1851,7 @@ void FramebufferManager::UpdateFromMemory(u32 addr, int size, bool safe) {
|
||||
}
|
||||
}
|
||||
|
||||
bool FramebufferManager::NotifyFramebufferCopy(u32 src, u32 dst, int size) {
|
||||
bool FramebufferManager::NotifyFramebufferCopy(u32 src, u32 dst, int size, bool isMemset) {
|
||||
if (!useBufferedRendering_ || updateVRAM_) {
|
||||
return false;
|
||||
}
|
||||
@ -1880,11 +1880,9 @@ bool FramebufferManager::NotifyFramebufferCopy(u32 src, u32 dst, int size) {
|
||||
}
|
||||
}
|
||||
|
||||
bool actuallyMemset = src == dst;
|
||||
|
||||
// TODO: Do ReadFramebufferToMemory etc where applicable.
|
||||
// This will slow down MotoGP but make the hack above unnecessary.
|
||||
if (dstBuffer && srcBuffer && !actuallyMemset) {
|
||||
if (dstBuffer && srcBuffer && !isMemset) {
|
||||
if (srcBuffer == dstBuffer) {
|
||||
WARN_LOG_REPORT_ONCE(dstsrccpy, G3D, "Intra-buffer memcpy (not supported) %08x -> %08x", src, dst);
|
||||
} else {
|
||||
|
@ -211,7 +211,7 @@ public:
|
||||
}
|
||||
inline bool ShouldDownloadFramebuffer(const VirtualFramebuffer *vfb) const;
|
||||
|
||||
bool NotifyFramebufferCopy(u32 src, u32 dest, int size);
|
||||
bool NotifyFramebufferCopy(u32 src, u32 dest, int size, bool isMemset = false);
|
||||
|
||||
void DestroyFramebuf(VirtualFramebuffer *vfb);
|
||||
|
||||
|
@ -662,7 +662,11 @@ void GLES_GPU::ProcessEvent(GPUEvent ev) {
|
||||
break;
|
||||
|
||||
case GPU_EVENT_FB_MEMCPY:
|
||||
UpdateMemoryInternal(ev.fb_memcpy.dst, ev.fb_memcpy.src, ev.fb_memcpy.size);
|
||||
PerformMemoryCopyInternal(ev.fb_memcpy.dst, ev.fb_memcpy.src, ev.fb_memcpy.size);
|
||||
break;
|
||||
|
||||
case GPU_EVENT_FB_MEMSET:
|
||||
PerformMemorySetInternal(ev.fb_memset.dst, ev.fb_memset.v, ev.fb_memset.size);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1968,16 +1972,20 @@ void GLES_GPU::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType t
|
||||
}
|
||||
}
|
||||
|
||||
void GLES_GPU::UpdateMemoryInternal(u32 dest, u32 src, int size) {
|
||||
void GLES_GPU::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size)) {
|
||||
Memory::Memcpy(dest, Memory::GetPointer(src), size);
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
} else {
|
||||
}
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
}
|
||||
|
||||
void GLES_GPU::PerformMemorySetInternal(u32 dest, u8 v, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(dest, dest, size, true)) {
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
}
|
||||
}
|
||||
|
||||
bool GLES_GPU::UpdateMemory(u32 dest, u32 src, int size) {
|
||||
bool GLES_GPU::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||
// Track stray copies of a framebuffer in RAM. MotoGP does this.
|
||||
if (framebufferManager_.MayIntersectFramebuffer(src) || framebufferManager_.MayIntersectFramebuffer(dest)) {
|
||||
if (IsOnSeparateCPUThread()) {
|
||||
@ -1990,7 +1998,7 @@ bool GLES_GPU::UpdateMemory(u32 dest, u32 src, int size) {
|
||||
// This is a memcpy, so we need to wait for it to complete.
|
||||
SyncThread();
|
||||
} else {
|
||||
UpdateMemoryInternal(dest, src, size);
|
||||
PerformMemoryCopyInternal(dest, src, size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1999,6 +2007,30 @@ bool GLES_GPU::UpdateMemory(u32 dest, u32 src, int size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GLES_GPU::PerformMemorySet(u32 dest, u8 v, int size) {
|
||||
// This may indicate a memset, usually to 0, of a framebuffer.
|
||||
if (framebufferManager_.MayIntersectFramebuffer(dest)) {
|
||||
Memory::Memset(dest, v, size);
|
||||
|
||||
if (IsOnSeparateCPUThread()) {
|
||||
GPUEvent ev(GPU_EVENT_FB_MEMSET);
|
||||
ev.fb_memset.dst = dest;
|
||||
ev.fb_memset.v = v;
|
||||
ev.fb_memset.size = size;
|
||||
ScheduleEvent(ev);
|
||||
|
||||
// We don't need to wait for the framebuffer to be updated.
|
||||
} else {
|
||||
PerformMemorySetInternal(dest, v, size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Or perhaps a texture, let's invalidate.
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
return false;
|
||||
}
|
||||
|
||||
void GLES_GPU::ClearCacheNextFrame() {
|
||||
textureCache_.ClearNextFrame();
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ public:
|
||||
virtual void BeginFrame();
|
||||
virtual void UpdateStats();
|
||||
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type);
|
||||
virtual bool UpdateMemory(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size);
|
||||
virtual void ClearCacheNextFrame();
|
||||
virtual void DeviceLost(); // Only happens on Android. Drop all textures and shaders.
|
||||
|
||||
@ -151,7 +152,8 @@ private:
|
||||
void InitClearInternal();
|
||||
void BeginFrameInternal();
|
||||
void CopyDisplayToOutputInternal();
|
||||
void UpdateMemoryInternal(u32 dest, u32 src, int size);
|
||||
void PerformMemoryCopyInternal(u32 dest, u32 src, int size);
|
||||
void PerformMemorySetInternal(u32 dest, u8 v, int size);
|
||||
void InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type);
|
||||
|
||||
static CommandInfo cmdInfo_[256];
|
||||
|
@ -164,6 +164,7 @@ enum GPUEventType {
|
||||
GPU_EVENT_FINISH_EVENT_LOOP,
|
||||
GPU_EVENT_SYNC_THREAD,
|
||||
GPU_EVENT_FB_MEMCPY,
|
||||
GPU_EVENT_FB_MEMSET,
|
||||
};
|
||||
|
||||
struct GPUEvent {
|
||||
@ -182,6 +183,12 @@ struct GPUEvent {
|
||||
u32 src;
|
||||
int size;
|
||||
} fb_memcpy;
|
||||
// GPU_EVENT_FB_MEMSET
|
||||
struct {
|
||||
u32 dst;
|
||||
u8 v;
|
||||
int size;
|
||||
} fb_memset;
|
||||
};
|
||||
|
||||
operator GPUEventType() const {
|
||||
@ -234,7 +241,8 @@ public:
|
||||
// If size = -1, invalidate everything.
|
||||
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type) = 0;
|
||||
// Update either RAM from VRAM, or VRAM from RAM... or even VRAM from VRAM.
|
||||
virtual bool UpdateMemory(u32 dest, u32 src, int size) = 0;
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size) = 0;
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size) = 0;
|
||||
|
||||
// Will cause the texture cache to be cleared at the start of the next frame.
|
||||
virtual void ClearCacheNextFrame() = 0;
|
||||
|
@ -657,7 +657,13 @@ void NullGPU::InvalidateCache(u32 addr, int size, GPUInvalidationType type) {
|
||||
// Nothing to invalidate.
|
||||
}
|
||||
|
||||
bool NullGPU::UpdateMemory(u32 dest, u32 src, int size) {
|
||||
bool NullGPU::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||
// Nothing to update.
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NullGPU::PerformMemorySet(u32 dest, u8 v, int size) {
|
||||
// Nothing to update.
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
return false;
|
||||
|
@ -34,7 +34,8 @@ public:
|
||||
virtual void CopyDisplayToOutput() {}
|
||||
virtual void UpdateStats();
|
||||
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type);
|
||||
virtual bool UpdateMemory(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size);
|
||||
virtual void ClearCacheNextFrame() {};
|
||||
|
||||
virtual void DeviceLost() {}
|
||||
|
@ -851,7 +851,16 @@ void SoftGPU::InvalidateCache(u32 addr, int size, GPUInvalidationType type)
|
||||
// Nothing to invalidate.
|
||||
}
|
||||
|
||||
bool SoftGPU::UpdateMemory(u32 dest, u32 src, int size)
|
||||
bool SoftGPU::PerformMemoryCopy(u32 dest, u32 src, int size)
|
||||
{
|
||||
// Nothing to update.
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
// Let's just be safe.
|
||||
framebufferDirty_ = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SoftGPU::PerformMemorySet(u32 dest, u8 v, int size)
|
||||
{
|
||||
// Nothing to update.
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
|
@ -59,7 +59,8 @@ public:
|
||||
virtual void CopyDisplayToOutput();
|
||||
virtual void UpdateStats();
|
||||
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type);
|
||||
virtual bool UpdateMemory(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size);
|
||||
virtual void ClearCacheNextFrame() {};
|
||||
|
||||
virtual void DeviceLost() {}
|
||||
|
Loading…
Reference in New Issue
Block a user