mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 15:30:35 +00:00
gl-render-manager: Support scissored clears, as used by the GL backend. Fixes GT.
This commit is contained in:
parent
67b8c4527d
commit
5351c9ddb3
@ -724,13 +724,13 @@ rotateVBO:
|
||||
if (alphaMask) target |= GL_STENCIL_BUFFER_BIT;
|
||||
if (depthMask) target |= GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
render_->Clear(clearColor, clearDepth, clearColor >> 24, target, rgbaMask);
|
||||
framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason);
|
||||
|
||||
int scissorX1 = gstate.getScissorX1();
|
||||
int scissorY1 = gstate.getScissorY1();
|
||||
int scissorX2 = gstate.getScissorX2() + 1;
|
||||
int scissorY2 = gstate.getScissorY2() + 1;
|
||||
|
||||
render_->Clear(clearColor, clearDepth, clearColor >> 24, target, rgbaMask, scissorX1, scissorY1, scissorX2 - scissorX1, scissorY2 - scissorY1);
|
||||
framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason);
|
||||
framebufferManager_->SetSafeSize(scissorX2, scissorY2);
|
||||
|
||||
if (g_Config.bBlockTransferGPU && (gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && colorMask && (alphaMask || gstate.FrameBufFormat() == GE_FORMAT_565)) {
|
||||
|
@ -113,7 +113,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
|
||||
if (dstBuffer->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR });
|
||||
}
|
||||
render_->Clear(0, 0, 0, GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT, 0x8);
|
||||
render_->Clear(0, 0, 0, GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT, 0x8, 0, 0, 0, 0);
|
||||
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE);
|
||||
return true;
|
||||
}
|
||||
@ -169,7 +169,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
|
||||
textureCacheGL_->ForgetLastTexture();
|
||||
|
||||
// We must bind the program after starting the render pass, and set the color mask after clearing.
|
||||
render_->Clear(0, 0, 0, GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, 0x8);
|
||||
render_->Clear(0, 0, 0, GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, 0x8, 0, 0, 0, 0);
|
||||
render_->SetStencilFunc(GL_TRUE, GL_ALWAYS, 0xFF, 0xFF);
|
||||
render_->BindProgram(stencilUploadProgram_);
|
||||
render_->SetNoBlendAndMask(0x8);
|
||||
|
@ -629,7 +629,12 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) {
|
||||
#endif
|
||||
break;
|
||||
case GLRRenderCommand::CLEAR:
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
if (c.clear.scissorW > 0) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(c.clear.scissorX, c.clear.scissorY, c.clear.scissorW, c.clear.scissorH);
|
||||
} else {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
if (c.clear.colorMask != colorMask) {
|
||||
glColorMask(c.clear.colorMask & 1, (c.clear.colorMask >> 1) & 1, (c.clear.colorMask >> 2) & 1, (c.clear.colorMask >> 3) & 1);
|
||||
colorMask = c.clear.colorMask;
|
||||
@ -650,7 +655,9 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) {
|
||||
glClearStencil(c.clear.clearStencil);
|
||||
}
|
||||
glClear(c.clear.clearMask);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
if (c.clear.scissorW > 0) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
break;
|
||||
case GLRRenderCommand::INVALIDATE:
|
||||
{
|
||||
|
@ -122,9 +122,13 @@ struct GLRRenderData {
|
||||
struct {
|
||||
uint32_t clearColor;
|
||||
float clearZ;
|
||||
int clearStencil;
|
||||
int clearMask; // VK_IMAGE_ASPECT_COLOR_BIT etc
|
||||
int colorMask; // Like blend, but for the clear.
|
||||
uint8_t clearStencil;
|
||||
uint8_t colorMask; // Like blend, but for the clear.
|
||||
GLuint clearMask; // GL_COLOR_BUFFER_BIT etc
|
||||
int16_t scissorX;
|
||||
int16_t scissorY;
|
||||
int16_t scissorW;
|
||||
int16_t scissorH;
|
||||
} clear;
|
||||
struct {
|
||||
int slot;
|
||||
|
@ -203,11 +203,14 @@ void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRende
|
||||
data.clear.clearStencil = clearStencil;
|
||||
}
|
||||
if (clearMask) {
|
||||
data.clear.scissorX = 0;
|
||||
data.clear.scissorY = 0;
|
||||
data.clear.scissorW = 0;
|
||||
data.clear.scissorH = 0;
|
||||
data.clear.clearMask = clearMask;
|
||||
data.clear.colorMask = 0xF;
|
||||
step->commands.push_back(data);
|
||||
}
|
||||
|
||||
curRenderStep_ = step;
|
||||
|
||||
// Every step clears this state.
|
||||
|
@ -578,14 +578,20 @@ public:
|
||||
curRenderStep_->commands.push_back(data);
|
||||
}
|
||||
|
||||
void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask, int colorMask = 0xF) {
|
||||
// If scissorW == 0, no scissor is applied.
|
||||
void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask, int colorMask, int scissorX, int scissorY, int scissorW, int scissorH) {
|
||||
_dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
|
||||
GLRRenderData data{ GLRRenderCommand::CLEAR };
|
||||
_assert_(clearMask != 0); // What would be the point?
|
||||
data.clear.clearMask = clearMask;
|
||||
data.clear.clearColor = clearColor;
|
||||
data.clear.clearZ = clearZ;
|
||||
data.clear.clearStencil = clearStencil;
|
||||
data.clear.colorMask = colorMask;
|
||||
data.clear.scissorX = scissorX;
|
||||
data.clear.scissorY = scissorY;
|
||||
data.clear.scissorW = scissorW;
|
||||
data.clear.scissorH = scissorH;
|
||||
curRenderStep_->commands.push_back(data);
|
||||
}
|
||||
|
||||
|
@ -1023,7 +1023,7 @@ void OpenGLContext::Clear(int mask, uint32_t colorval, float depthVal, int stenc
|
||||
if (mask & FBChannel::FB_STENCIL_BIT) {
|
||||
glMask |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
renderManager_.Clear(colorval, depthVal, stencilVal, glMask);
|
||||
renderManager_.Clear(colorval, depthVal, stencilVal, glMask, 0xF, 0, 0, targetWidth_, targetHeight_);
|
||||
}
|
||||
|
||||
DrawContext *T3DCreateGLContext() {
|
||||
|
Loading…
Reference in New Issue
Block a user