[Mesa-dev] [PATCH 3/3 v3] mesa: Fix GL error generation in glBlitFramebuffer()
Anuj Phogat
anuj.phogat at gmail.com
Tue Jan 8 02:03:47 PST 2013
On Tue, Jan 8, 2013 at 5:25 AM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> From: Anuj Phogat <anuj.phogat at gmail.com>
>
> V2:
> If mask has GL_STENCIL_BUFFER_BIT set, the depth formats for readRenderBuffer
> and drawRenderBuffer must match unless one of the two buffers doesn't have
> depth, in which case it's not blitted, so the format check should be ignored.
> Same comment goes for stencil formats in depth renderbuffers if mask has
> GL_DEPTH_BUFFER_BIT set.
>
> v3 (Kayden): Refactor code to be a bit more readable.
>
> Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
> src/mesa/main/fbobject.c | 59 ++++++++++++++++++++++++++++++++++++------------
> 1 file changed, 44 insertions(+), 15 deletions(-)
>
> Anuj,
>
> This looks correct, but the run-on conditionals are pretty hard to read...
> just too much going on in a single if-statement.
>
> How about splitting them up a bit? Here's my proposed version. It also
> gives slightly more descriptive messages.
>
I'm happy with the refactored code except a small mistake I explained below.
> Untested.
>
> diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
> index 281cdd0..bf613ff 100644
> --- a/src/mesa/main/fbobject.c
> +++ b/src/mesa/main/fbobject.c
> @@ -2833,14 +2833,28 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
> if ((readRb == NULL) || (drawRb == NULL)) {
> mask &= ~GL_STENCIL_BUFFER_BIT;
> }
> - else 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,
> - "glBlitFramebufferEXT(stencil buffer size mismatch)");
> - return;
> + else {
> + if ((_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
> + _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) ||
> + (_mesa_get_format_datatype(readRb->Format) !=
> + _mesa_get_format_datatype(drawRb->Format))) {
Matching the data type is not required here as data type for stencil buffer is
always GL_UNSIGNED_INT. But, data type of GL_DEPTH24_STENCIL8 is
GL_UNSIGNED_NORMALIZED. So, matching the data types here will disallow
blitting between GL_STENCIL_INDEX8 and GL_DEPTH24_STENCIL8 which is a
valid blitting case. This caused 7 gles3 conformance blitframebuffer test cases
fail.
> + _mesa_error(ctx, GL_INVALID_OPERATION,
> + "glBlitFramebuffer(stencil attachment format mismatch)");
> + return;
> + }
> +
> + int read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
> + int 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) {
Above mentioned data type checking should be moved here. Observed no regressions
in gles3 conformance after making this change.
> + _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer"
> + "(stencil attachment depth format mismatch)");
> + return;
> + }
> }
> }
>
> @@ -2859,13 +2873,28 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
> if ((readRb == NULL) || (drawRb == NULL)) {
> mask &= ~GL_DEPTH_BUFFER_BIT;
> }
> - else 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,
> - "glBlitFramebufferEXT(depth buffer format mismatch)");
> - return;
> + else {
> + 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,
> + "glBlitFramebuffer(depth attachment format mismatch)");
> + return;
> + }
> +
> + int read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
> + int draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
> +
> + /* 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, "glBlitFramebuffer"
> + "(depth attachment stencil bits mismatch)");
> + return;
> + }
> }
> }
>
> --
> 1.8.1
>
More information about the mesa-dev
mailing list