gl-render-manager: Support scissored clears, as used by the GL backend. Fixes GT.

This commit is contained in:
Henrik Rydgård 2018-01-31 17:07:20 +01:00
parent 67b8c4527d
commit 5351c9ddb3
7 changed files with 33 additions and 13 deletions

View File

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

View File

@ -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);

View File

@ -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:
{

View File

@ -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;

View File

@ -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.

View File

@ -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);
}

View File

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