mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-10 13:06:24 +02:00
GPU: Skip alpha stencil upload when safe.
Otherwise, let's not do things that give different behavior at 1x or are inconsistent.
This commit is contained in:
1 parent
e6ea07bc9d
commit
20c2ec1392
9 files changed
+28
-24
No files matched your search
@@ -370,7 +370,7 @@ void CheckGLExtensions() {
|
||||
gl_extensions.ARB_depth_clamp = g_set_gl_extensions.count("GL_ARB_depth_clamp") != 0;
|
||||
gl_extensions.ARB_uniform_buffer_object = g_set_gl_extensions.count("GL_ARB_uniform_buffer_object") != 0;
|
||||
gl_extensions.ARB_explicit_attrib_location = g_set_gl_extensions.count("GL_ARB_explicit_attrib_location") != 0;
|
||||
gl_extensions.ARB_texture_non_power_of_two = g_set_gl_extensions.count("GL_ARB_texture_non_power_of_two");
|
||||
gl_extensions.ARB_texture_non_power_of_two = g_set_gl_extensions.count("GL_ARB_texture_non_power_of_two") != 0;
|
||||
if (gl_extensions.IsGLES) {
|
||||
gl_extensions.EXT_blend_func_extended = g_set_gl_extensions.count("GL_EXT_blend_func_extended") != 0;
|
||||
gl_extensions.OES_texture_npot = g_set_gl_extensions.count("GL_OES_texture_npot") != 0;
|
||||
|
||||
@@ -708,7 +708,7 @@ static int Hook_hexyzforce_monoclome_thread() {
|
||||
static int Hook_starocean_write_stencil() {
|
||||
const u32 fb_address = currentMIPS->r[MIPS_REG_T7];
|
||||
if (Memory::IsVRAMAddress(fb_address)) {
|
||||
gpu->PerformStencilUpload(fb_address, 0x00088000);
|
||||
gpu->PerformStencilUpload(fb_address, 0x00088000, StencilUpload::IGNORE_ALPHA);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -171,11 +171,6 @@ inline DrawTextureFlags operator | (const DrawTextureFlags &lhs, const DrawTextu
|
||||
return DrawTextureFlags((u32)lhs | (u32)rhs);
|
||||
}
|
||||
|
||||
enum class StencilUpload {
|
||||
NEEDS_CLEAR,
|
||||
STENCIL_IS_ZERO,
|
||||
};
|
||||
|
||||
enum class TempFBO {
|
||||
DEPAL,
|
||||
BLIT,
|
||||
@@ -261,7 +256,7 @@ public:
|
||||
void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt);
|
||||
void UpdateFromMemory(u32 addr, int size, bool safe);
|
||||
void ApplyClearToMemory(int x1, int y1, int x2, int y2, u32 clearColor);
|
||||
bool PerformStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR);
|
||||
bool PerformStencilUpload(u32 addr, int size, StencilUpload flags);
|
||||
// Returns true if it's sure this is a direct FBO->FBO transfer and it has already handle it.
|
||||
// In that case we hardly need to actually copy the bytes in VRAM, they will be wrong anyway (unless
|
||||
// read framebuffers is on, in which case this should always return false).
|
||||
|
||||
@@ -182,17 +182,17 @@ bool FramebufferManagerCommon::PerformStencilUpload(u32 addr, int size, StencilU
|
||||
return false;
|
||||
}
|
||||
|
||||
shaderManager_->DirtyLastShader();
|
||||
// Otherwise, we can skip alpha in many cases, in which case we don't even use a shader.
|
||||
if (flags == StencilUpload::IGNORE_ALPHA) {
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
// Let's not bother with the shader if it's just zero.
|
||||
if (dstBuffer->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "PerformStencilUpload_Clear");
|
||||
if (dstBuffer->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "PerformStencilUpload_Clear");
|
||||
}
|
||||
|
||||
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Here we might want to clear destination alpha by using a draw, but we haven't found a need for this yet.
|
||||
// Will implement when needed...
|
||||
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE);
|
||||
return true;
|
||||
}
|
||||
|
||||
shaderManager_->DirtyLastShader();
|
||||
@@ -263,10 +263,13 @@ bool FramebufferManagerCommon::PerformStencilUpload(u32 addr, int size, StencilU
|
||||
// Our fragment shader (and discard) is slow. Since the source is 1x, we can stencil to 1x.
|
||||
// Then after we're done, we'll just blit it across and stretch it there. Not worth doing
|
||||
// if already at 1x size though, of course.
|
||||
// TODO: This path means that we don't write color alpha... Ugh.
|
||||
if (dstBuffer->width == dstBuffer->renderWidth || !dstBuffer->fbo) {
|
||||
useBlit = false;
|
||||
}
|
||||
// The blit path doesn't set alpha, so we can't use it if that's needed.
|
||||
if (flags != StencilUpload::IGNORE_ALPHA) {
|
||||
useBlit = false;
|
||||
}
|
||||
|
||||
u16 w = useBlit ? dstBuffer->width : dstBuffer->renderWidth;
|
||||
u16 h = useBlit ? dstBuffer->height : dstBuffer->renderHeight;
|
||||
|
||||
+2
-2
@@ -2931,9 +2931,9 @@ void GPUCommon::NotifyVideoUpload(u32 addr, int size, int width, int format) {
|
||||
InvalidateCache(addr, size, GPU_INVALIDATE_SAFE);
|
||||
}
|
||||
|
||||
bool GPUCommon::PerformStencilUpload(u32 dest, int size) {
|
||||
bool GPUCommon::PerformStencilUpload(u32 dest, int size, StencilUpload flags) {
|
||||
if (framebufferManager_->MayIntersectFramebuffer(dest)) {
|
||||
framebufferManager_->PerformStencilUpload(dest, size);
|
||||
framebufferManager_->PerformStencilUpload(dest, size, flags);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ public:
|
||||
|
||||
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override;
|
||||
void NotifyVideoUpload(u32 addr, int size, int width, int format) override;
|
||||
bool PerformStencilUpload(u32 dest, int size) override;
|
||||
bool PerformStencilUpload(u32 dest, int size, StencilUpload flags) override;
|
||||
|
||||
void Execute_OffsetAddr(u32 op, u32 diff);
|
||||
void Execute_Vaddr(u32 op, u32 diff);
|
||||
|
||||
+7
-1
@@ -106,6 +106,12 @@ enum GPUSyncType {
|
||||
GPU_SYNC_LIST,
|
||||
};
|
||||
|
||||
enum class StencilUpload {
|
||||
NEEDS_CLEAR,
|
||||
STENCIL_IS_ZERO,
|
||||
IGNORE_ALPHA,
|
||||
};
|
||||
|
||||
// Used for debug
|
||||
struct FramebufferInfo {
|
||||
u32 fb_address;
|
||||
@@ -216,7 +222,7 @@ public:
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size) = 0;
|
||||
virtual bool PerformMemoryDownload(u32 dest, int size) = 0;
|
||||
virtual bool PerformMemoryUpload(u32 dest, int size) = 0;
|
||||
virtual bool PerformStencilUpload(u32 dest, int size) = 0;
|
||||
virtual bool PerformStencilUpload(u32 dest, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) = 0;
|
||||
|
||||
// Will cause the texture cache to be cleared at the start of the next frame.
|
||||
virtual void ClearCacheNextFrame() = 0;
|
||||
|
||||
@@ -1161,7 +1161,7 @@ bool SoftGPU::PerformMemoryUpload(u32 dest, int size)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SoftGPU::PerformStencilUpload(u32 dest, int size)
|
||||
bool SoftGPU::PerformStencilUpload(u32 dest, int size, StencilUpload flags)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
||||
bool PerformMemoryDownload(u32 dest, int size) override;
|
||||
bool PerformMemoryUpload(u32 dest, int size) override;
|
||||
bool PerformStencilUpload(u32 dest, int size) override;
|
||||
bool PerformStencilUpload(u32 dest, int size, StencilUpload flags) override;
|
||||
void ClearCacheNextFrame() override {}
|
||||
|
||||
void DeviceLost() override;
|
||||
|
||||
Reference in new issue
Block a user