diff options
Diffstat (limited to 'mesalib/src/mesa/main/fbobject.c')
-rw-r--r-- | mesalib/src/mesa/main/fbobject.c | 244 |
1 files changed, 170 insertions, 74 deletions
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 50ad84c56..9db5035d1 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -245,6 +245,25 @@ _mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, { assert(_mesa_is_winsys_fbo(fb)); + if (_mesa_is_gles3(ctx)) { + assert(attachment == GL_BACK || + attachment == GL_DEPTH || + attachment == GL_STENCIL); + switch (attachment) { + case GL_BACK: + /* Since there is no stereo rendering in ES 3.0, only return the + * LEFT bits. + */ + if (ctx->DrawBuffer->Visual.doubleBufferMode) + return &fb->Attachment[BUFFER_BACK_LEFT]; + return &fb->Attachment[BUFFER_FRONT_LEFT]; + case GL_DEPTH: + return &fb->Attachment[BUFFER_DEPTH]; + case GL_STENCIL: + return &fb->Attachment[BUFFER_STENCIL]; + } + } + switch (attachment) { case GL_FRONT_LEFT: return &fb->Attachment[BUFFER_FRONT_LEFT]; @@ -492,7 +511,8 @@ _mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat) case GL_LUMINANCE_ALPHA: case GL_INTENSITY: case GL_ALPHA: - return ctx->Extensions.ARB_framebuffer_object; + return ctx->API == API_OPENGL_COMPAT && + ctx->Extensions.ARB_framebuffer_object; case GL_RED: case GL_RG: return ctx->Extensions.ARB_texture_rg; @@ -1110,7 +1130,7 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) case GL_RGB16: return _mesa_is_desktop_gl(ctx) ? GL_RGB : 0; case GL_SRGB8_EXT: - return _mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx) ? GL_RGB : 0; + return _mesa_is_desktop_gl(ctx) ? GL_RGB : 0; case GL_RGBA4: case GL_RGB5_A1: case GL_RGBA8: @@ -1197,25 +1217,21 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0; case GL_R16F: case GL_R32F: - return ctx->Version >= 30 - || (ctx->API == API_OPENGL_COMPAT && + return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_rg && ctx->Extensions.ARB_texture_float) ? GL_RED : 0; case GL_RG16F: case GL_RG32F: - return ctx->Version >= 30 - || (ctx->API == API_OPENGL_COMPAT && + return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_rg && ctx->Extensions.ARB_texture_float) ? GL_RG : 0; case GL_RGB16F: case GL_RGB32F: return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_float) - || _mesa_is_gles3(ctx) ? GL_RGB : 0; case GL_RGBA16F: case GL_RGBA32F: return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_float) - || _mesa_is_gles3(ctx) ? GL_RGBA : 0; case GL_ALPHA16F_ARB: case GL_ALPHA32F_ARB: @@ -1240,10 +1256,10 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) case GL_RGB9_E5: return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_shared_exponent) - || _mesa_is_gles3(ctx) ? GL_RGB : 0; + ? GL_RGB : 0; case GL_R11F_G11F_B10F: return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_packed_float) - || _mesa_is_gles3(ctx) ? GL_RGB : 0; + ? GL_RGB : 0; case GL_RGBA8UI_EXT: case GL_RGBA16UI_EXT: @@ -1378,13 +1394,28 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei samples) { const char *func = samples == NO_SAMPLES ? - "glRenderbufferStorage" : "RenderbufferStorageMultisample"; + "glRenderbufferStorage" : "glRenderbufferStorageMultisample"; struct gl_renderbuffer *rb; GLenum baseFormat; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (MESA_VERBOSE & VERBOSE_API) { + if (samples == NO_SAMPLES) + _mesa_debug(ctx, "%s(%s, %s, %d, %d)\n", + func, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(internalFormat), + width, height); + else + _mesa_debug(ctx, "%s(%s, %s, %d, %d, %d)\n", + func, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(internalFormat), + width, height, samples); + } + if (target != GL_RENDERBUFFER_EXT) { _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); return; @@ -1904,6 +1935,10 @@ _mesa_CheckFramebufferStatus(GLenum target) ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glCheckFramebufferStatus(%s)\n", + _mesa_lookup_enum_by_nr(target)); + buffer = get_framebuffer_target(ctx, target); if (!buffer) { _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)"); @@ -2347,11 +2382,19 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, * OES_framebuffer_object spec refers to the EXT_framebuffer_object * spec. */ - if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_framebuffer_object) { + if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_framebuffer_object) + && !_mesa_is_gles3(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetFramebufferAttachmentParameteriv(bound FBO = 0)"); return; } + + if (_mesa_is_gles3(ctx) && attachment != GL_BACK && + attachment != GL_DEPTH && attachment != GL_STENCIL) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetFramebufferAttachmentParameteriv(attachment)"); + return; + } /* the default / window-system FBO */ att = _mesa_get_fb0_attachment(ctx, buffer, attachment); } @@ -2739,7 +2782,6 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); const struct gl_framebuffer *readFb, *drawFb; - const struct gl_renderbuffer *colorReadRb, *colorDrawRb; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -2794,8 +2836,10 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, /* get color read/draw renderbuffers */ if (mask & GL_COLOR_BUFFER_BIT) { - colorReadRb = readFb->_ColorReadBuffer; - colorDrawRb = drawFb->_ColorDrawBuffers[0]; + const GLuint numColorDrawBuffers = ctx->DrawBuffer->_NumColorDrawBuffers; + const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; + const struct gl_renderbuffer *colorDrawRb = NULL; + GLuint i; /* From the EXT_framebuffer_object spec: * @@ -2803,20 +2847,45 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, * the read and draw framebuffers, the corresponding bit is silently * ignored." */ - if ((colorReadRb == NULL) || (colorDrawRb == NULL)) { - colorReadRb = colorDrawRb = NULL; - mask &= ~GL_COLOR_BUFFER_BIT; + if (!colorReadRb || numColorDrawBuffers == 0) { + mask &= ~GL_COLOR_BUFFER_BIT; } - else if (!compatible_color_datatypes(colorReadRb->Format, - colorDrawRb->Format)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBlitFramebufferEXT(color buffer datatypes mismatch)"); - return; + else { + for (i = 0; i < numColorDrawBuffers; i++) { + colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i]; + if (!colorDrawRb) + continue; + + if (!compatible_color_datatypes(colorReadRb->Format, + colorDrawRb->Format)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBlitFramebufferEXT(color buffer datatypes mismatch)"); + return; + } + /* extra checks for multisample copies... */ + if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) { + /* color formats must match */ + if (!compatible_resolve_formats(colorReadRb, colorDrawRb)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBlitFramebufferEXT(bad src/dst multisample pixel formats)"); + return; + } + } + } + if (filter == GL_LINEAR) { + /* 3.1 spec, page 199: + * "Calling BlitFramebuffer will result in an INVALID_OPERATION error + * if filter is LINEAR and read buffer contains integer data." + */ + GLenum type = _mesa_get_format_datatype(colorReadRb->Format); + if (type == GL_INT || type == GL_UNSIGNED_INT) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBlitFramebufferEXT(integer color type)"); + return; + } + } } } - else { - colorReadRb = colorDrawRb = NULL; - } if (mask & GL_STENCIL_BUFFER_BIT) { struct gl_renderbuffer *readRb = @@ -2833,14 +2902,35 @@ _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 { + int read_z_bits, draw_z_bits; + + 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, + "glBlitFramebuffer(stencil attachment format mismatch)"); + 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, "glBlitFramebuffer" + "(stencil attachment depth format mismatch)"); + return; + } } } @@ -2859,13 +2949,30 @@ _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 { + int read_s_bit, draw_s_bit; + + 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; + } + + read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS); + 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; + } } } @@ -2886,28 +2993,6 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, "glBlitFramebufferEXT(bad src/dst multisample region sizes)"); return; } - - /* color formats must match */ - if (colorReadRb && - colorDrawRb && - !compatible_resolve_formats(colorReadRb, colorDrawRb)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBlitFramebufferEXT(bad src/dst multisample pixel formats)"); - return; - } - } - - if (filter == GL_LINEAR && (mask & GL_COLOR_BUFFER_BIT)) { - /* 3.1 spec, page 199: - * "Calling BlitFramebuffer will result in an INVALID_OPERATION error - * if filter is LINEAR and read buffer contains integer data." - */ - GLenum type = _mesa_get_format_datatype(colorReadRb->Format); - if (type == GL_INT || type == GL_UNSIGNED_INT) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBlitFramebufferEXT(integer color type)"); - return; - } } if (!ctx->Extensions.EXT_framebuffer_blit) { @@ -2917,6 +3002,10 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, /* Debug code */ if (DEBUG_BLIT) { + const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; + const struct gl_renderbuffer *colorDrawRb = NULL; + GLuint i = 0; + printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d," " 0x%x, 0x%x)\n", srcX0, srcY0, srcX1, srcY1, @@ -2938,18 +3027,25 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, } printf("\n"); - att = find_attachment(drawFb, colorDrawRb); - printf(" Dst FBO %u RB %u (%dx%d) ", - drawFb->Name, colorDrawRb->Name, - colorDrawRb->Width, colorDrawRb->Height); - if (att && att->Texture) { - printf("Tex %u tgt 0x%x level %u face %u", - att->Texture->Name, - att->Texture->Target, - att->TextureLevel, - att->CubeMapFace); + /* Print all active color render buffers */ + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i]; + if (!colorDrawRb) + continue; + + att = find_attachment(drawFb, colorDrawRb); + printf(" Dst FBO %u RB %u (%dx%d) ", + drawFb->Name, colorDrawRb->Name, + colorDrawRb->Width, colorDrawRb->Height); + if (att && att->Texture) { + printf("Tex %u tgt 0x%x level %u face %u", + att->Texture->Name, + att->Texture->Target, + att->TextureLevel, + att->CubeMapFace); + } + printf("\n"); } - printf("\n"); } } |