[Mesa-dev] [PATCH] mesa/blit: only error when the stencil and depth bits do not match (v3)
Max Qian
public at maxqia.com
Sun Feb 19 11:11:02 UTC 2017
This fixes some situations where glBlitFrameBuffer would error in Mesa,
but wouldn't error in other drivers (e.g Nvidia)
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97921
v2 : fix unintentional line removal
v3 : author correction, add commit message, and change the error message
---
src/mesa/main/blit.c | 84 +++++++++++++++++++++-------------------------------
1 file changed, 34 insertions(+), 50 deletions(-)
diff --git a/src/mesa/main/blit.c b/src/mesa/main/blit.c
index e739130f98..62cc8c2360 100644
--- a/src/mesa/main/blit.c
+++ b/src/mesa/main/blit.c
@@ -334,41 +334,13 @@ _mesa_blit_framebuffer(struct gl_context *ctx,
mask &= ~GL_STENCIL_BUFFER_BIT;
}
else {
- int read_z_bits, draw_z_bits;
-
if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(source and destination stencil "
"buffer cannot be the same)", func);
return;
}
-
- if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
- /* There is no need to check the stencil datatype here, because
- * there is only one: GL_UNSIGNED_INT.
- */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(stencil attachment format mismatch)", func);
- return;
- }
-
- read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
- draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
-
- /* If both buffers also have depth data, the depth formats must match
- * as well. If one doesn't have depth, it's not blitted, so we should
- * ignore the depth format check.
- */
- if (read_z_bits > 0 && draw_z_bits > 0 &&
- (read_z_bits != draw_z_bits ||
- _mesa_get_format_datatype(readRb->Format) !=
- _mesa_get_format_datatype(drawRb->Format))) {
-
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(stencil attachment depth format mismatch)", func);
- return;
- }
+ // check formats later
}
}
@@ -388,36 +360,48 @@ _mesa_blit_framebuffer(struct gl_context *ctx,
mask &= ~GL_DEPTH_BUFFER_BIT;
}
else {
- int read_s_bit, draw_s_bit;
-
if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(source and destination depth "
"buffer cannot be the same)", func);
return;
}
+ // check formats later
+ }
+ }
- if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
- (_mesa_get_format_datatype(readRb->Format) !=
- _mesa_get_format_datatype(drawRb->Format))) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(depth attachment format mismatch)", func);
- return;
- }
+ /* From the glBlitFramebuffer Spec :
+ *
+ * "GL_INVALID_OPERATION is generated if mask contains
+ * GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT and the source and
+ * destination depth and stencil formats do not match."
+ */
+ if (mask & GL_STENCIL_BUFFER_BIT || mask & GL_DEPTH_BUFFER_BIT) {
+ struct gl_renderbuffer *readStencilRb =
+ readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
+ struct gl_renderbuffer *drawStencilRb =
+ drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
+ struct gl_renderbuffer *readDepthRb =
+ readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ struct gl_renderbuffer *drawDepthRb =
+ drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
- read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
- draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
+ int read_z_bits, draw_z_bits, read_s_bit, draw_s_bit;
+ read_z_bits = _mesa_get_format_bits(readDepthRb->Format, GL_DEPTH_BITS);
+ draw_z_bits = _mesa_get_format_bits(drawDepthRb->Format, GL_DEPTH_BITS);
+ boolean depth = read_z_bits > 0 && draw_z_bits > 0 &&
+ (read_z_bits != draw_z_bits ||
+ _mesa_get_format_datatype(readDepthRb->Format) !=
+ _mesa_get_format_datatype(drawDepthRb->Format));
- /* If both buffers also have stencil data, the stencil formats must
- * match as well. If one doesn't have stencil, it's not blitted, so
- * we should ignore the stencil format check.
- */
- if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(depth attachment stencil bits mismatch)", func);
- return;
- }
+ read_s_bit = _mesa_get_format_bits(readStencilRb->Format, GL_STENCIL_BITS);
+ draw_s_bit = _mesa_get_format_bits(drawStencilRb->Format, GL_STENCIL_BITS);
+ boolean stencil = read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit;
+
+ if (stencil && depth) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(depth and stencil attachment bits and format mismatch)", func);
+ return;
}
}
--
2.11.1
More information about the mesa-dev
mailing list