mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-24 23:46:41 +00:00
Ensure that glBlitFramebuffer for internal copies has correct state
* In particular we need to disable scissor (which can affect the blit) and any color/write masks.
This commit is contained in:
@@ -1335,6 +1335,81 @@ GLuint GetBoundVertexBuffer(GLuint i)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void SafeBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
|
||||
GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
|
||||
{
|
||||
bool scissorEnabled = false;
|
||||
GLboolean ColorMask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
|
||||
GLboolean DepthMask = GL_TRUE;
|
||||
GLint StencilMask = 0xff, StencilBackMask = 0xff;
|
||||
|
||||
// fetch current state
|
||||
{
|
||||
if(HasExt[ARB_viewport_array])
|
||||
scissorEnabled = GL.glIsEnabledi(eGL_SCISSOR_TEST, 0) != 0;
|
||||
else
|
||||
scissorEnabled = GL.glIsEnabled(eGL_SCISSOR_TEST) != 0;
|
||||
|
||||
if(HasExt[EXT_draw_buffers2] || HasExt[ARB_draw_buffers_blend])
|
||||
GL.glGetBooleani_v(eGL_COLOR_WRITEMASK, 0, ColorMask);
|
||||
else
|
||||
GL.glGetBooleanv(eGL_COLOR_WRITEMASK, ColorMask);
|
||||
|
||||
GL.glGetBooleanv(eGL_DEPTH_WRITEMASK, &DepthMask);
|
||||
|
||||
GL.glGetIntegerv(eGL_STENCIL_WRITEMASK, &StencilMask);
|
||||
GL.glGetIntegerv(eGL_STENCIL_BACK_WRITEMASK, &StencilBackMask);
|
||||
}
|
||||
|
||||
// apply safe state
|
||||
{
|
||||
if(HasExt[ARB_viewport_array])
|
||||
GL.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
GL.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
if(HasExt[EXT_draw_buffers2] || HasExt[ARB_draw_buffers_blend])
|
||||
GL.glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
else
|
||||
GL.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
GL.glDepthMask(GL_TRUE);
|
||||
|
||||
GL.glStencilMaskSeparate(eGL_FRONT, 0xff);
|
||||
GL.glStencilMaskSeparate(eGL_BACK, 0xff);
|
||||
}
|
||||
|
||||
GL.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
||||
|
||||
// restore original state
|
||||
{
|
||||
if(HasExt[ARB_viewport_array])
|
||||
{
|
||||
if(scissorEnabled)
|
||||
GL.glEnablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
GL.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(scissorEnabled)
|
||||
GL.glEnable(eGL_SCISSOR_TEST);
|
||||
else
|
||||
GL.glDisable(eGL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
if(HasExt[EXT_draw_buffers2] || HasExt[ARB_draw_buffers_blend])
|
||||
GL.glColorMaski(0, ColorMask[0], ColorMask[1], ColorMask[2], ColorMask[3]);
|
||||
else
|
||||
GL.glColorMask(ColorMask[0], ColorMask[1], ColorMask[2], ColorMask[3]);
|
||||
|
||||
GL.glDepthMask(DepthMask);
|
||||
|
||||
GL.glStencilMaskSeparate(eGL_FRONT, StencilMask);
|
||||
GL.glStencilMaskSeparate(eGL_BACK, StencilBackMask);
|
||||
}
|
||||
}
|
||||
|
||||
BufferCategory MakeBufferCategory(GLenum bufferTarget)
|
||||
{
|
||||
switch(bufferTarget)
|
||||
|
||||
@@ -499,6 +499,11 @@ void GetBindpointMapping(GLuint curProg, int shadIdx, ShaderReflection *refl,
|
||||
|
||||
void ResortBindings(ShaderReflection *refl, ShaderBindpointMapping *mapping);
|
||||
|
||||
// calls glBlitFramebuffer but ensures no state can interfere like scissor or color mask
|
||||
// pops state for only a single drawbuffer!
|
||||
void SafeBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
|
||||
GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
|
||||
|
||||
enum UniformType
|
||||
{
|
||||
UNIFORM_UNKNOWN,
|
||||
|
||||
@@ -877,7 +877,7 @@ bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uin
|
||||
GL.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, texDetails.renderbufferFBOs[1]);
|
||||
GL.glBindFramebuffer(eGL_READ_FRAMEBUFFER, texDetails.renderbufferFBOs[0]);
|
||||
|
||||
GL.glBlitFramebuffer(
|
||||
SafeBlitFramebuffer(
|
||||
0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width, texDetails.height,
|
||||
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST);
|
||||
|
||||
@@ -1049,7 +1049,7 @@ bool GLReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip,
|
||||
GL.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, texDetails.renderbufferFBOs[1]);
|
||||
GL.glBindFramebuffer(eGL_READ_FRAMEBUFFER, texDetails.renderbufferFBOs[0]);
|
||||
|
||||
GL.glBlitFramebuffer(
|
||||
SafeBlitFramebuffer(
|
||||
0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width, texDetails.height,
|
||||
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST);
|
||||
|
||||
|
||||
@@ -699,9 +699,9 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve
|
||||
}
|
||||
|
||||
// get latest depth/stencil from read FBO (existing FBO) into draw FBO (overlay FBO)
|
||||
drv.glBlitFramebuffer(0, 0, DebugData.overlayTexWidth, DebugData.overlayTexHeight, 0, 0,
|
||||
DebugData.overlayTexWidth, DebugData.overlayTexHeight,
|
||||
GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST);
|
||||
SafeBlitFramebuffer(0, 0, DebugData.overlayTexWidth, DebugData.overlayTexHeight, 0, 0,
|
||||
DebugData.overlayTexWidth, DebugData.overlayTexHeight,
|
||||
GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST);
|
||||
|
||||
ReplayLog(eventId, eReplay_OnlyDraw);
|
||||
|
||||
@@ -1317,9 +1317,9 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve
|
||||
drv.glBindProgramPipeline(0);
|
||||
|
||||
drv.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curdrawfbo);
|
||||
drv.glBlitFramebuffer(0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width,
|
||||
texDetails.height, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
|
||||
eGL_NEAREST);
|
||||
SafeBlitFramebuffer(0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width,
|
||||
texDetails.height, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
|
||||
eGL_NEAREST);
|
||||
|
||||
m_pDriver->ReplayLog(0, events[i], eReplay_OnlyDraw);
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
|
||||
drv.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, texDetails.renderbufferFBOs[1]);
|
||||
drv.glBindFramebuffer(eGL_READ_FRAMEBUFFER, texDetails.renderbufferFBOs[0]);
|
||||
|
||||
drv.glBlitFramebuffer(
|
||||
SafeBlitFramebuffer(
|
||||
0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width, texDetails.height,
|
||||
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST);
|
||||
|
||||
|
||||
@@ -2317,7 +2317,7 @@ void GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip,
|
||||
float col[] = {0.3f, 0.4f, 0.5f, 1.0f};
|
||||
drv.glClearBufferfv(eGL_COLOR, 0, col);
|
||||
|
||||
drv.glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, eGL_NEAREST);
|
||||
SafeBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, eGL_NEAREST);
|
||||
|
||||
// rewrite the variables to temporary texture
|
||||
texType = eGL_TEXTURE_2D;
|
||||
@@ -2380,8 +2380,8 @@ void GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip,
|
||||
else if(b == eGL_DEPTH_STENCIL)
|
||||
mask = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
||||
|
||||
drv.glBlitFramebuffer(0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width,
|
||||
texDetails.height, mask, eGL_NEAREST);
|
||||
SafeBlitFramebuffer(0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width,
|
||||
texDetails.height, mask, eGL_NEAREST);
|
||||
|
||||
drv.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curDrawFBO);
|
||||
drv.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curReadFBO);
|
||||
|
||||
@@ -1198,8 +1198,8 @@ void APIENTRY _glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLev
|
||||
}
|
||||
else if(!layered)
|
||||
{
|
||||
GL.glBlitFramebuffer(srcX, srcY, srcX + srcWidth, srcY + srcHeight, dstX, dstY,
|
||||
dstX + srcWidth, dstY + srcHeight, mask, eGL_NEAREST);
|
||||
SafeBlitFramebuffer(srcX, srcY, srcX + srcWidth, srcY + srcHeight, dstX, dstY,
|
||||
dstX + srcWidth, dstY + srcHeight, mask, eGL_NEAREST);
|
||||
}
|
||||
else if(srcTarget == eGL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
@@ -1218,8 +1218,8 @@ void APIENTRY _glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLev
|
||||
GL.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, attach, textargets[dstZ + slice], dstName,
|
||||
dstLevel);
|
||||
|
||||
GL.glBlitFramebuffer(srcX, srcY, srcX + srcWidth, srcY + srcHeight, dstX, dstY,
|
||||
dstX + srcWidth, dstY + srcHeight, mask, eGL_NEAREST);
|
||||
SafeBlitFramebuffer(srcX, srcY, srcX + srcWidth, srcY + srcHeight, dstX, dstY,
|
||||
dstX + srcWidth, dstY + srcHeight, mask, eGL_NEAREST);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1229,8 +1229,8 @@ void APIENTRY _glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLev
|
||||
GL.glFramebufferTextureLayer(eGL_READ_FRAMEBUFFER, attach, srcName, srcLevel, srcZ + slice);
|
||||
GL.glFramebufferTextureLayer(eGL_DRAW_FRAMEBUFFER, attach, dstName, dstLevel, dstZ + slice);
|
||||
|
||||
GL.glBlitFramebuffer(srcX, srcY, srcX + srcWidth, srcY + srcHeight, dstX, dstY,
|
||||
dstX + srcWidth, dstY + srcHeight, mask, eGL_NEAREST);
|
||||
SafeBlitFramebuffer(srcX, srcY, srcX + srcWidth, srcY + srcHeight, dstX, dstY,
|
||||
dstX + srcWidth, dstY + srcHeight, mask, eGL_NEAREST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user