}
+static bool
+validate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
+ struct gl_framebuffer *drawFb, const char *func)
+{
+ struct gl_renderbuffer *readRb =
+ readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ struct gl_renderbuffer *drawRb =
+ drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ 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 false;
+ }
+
+ 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 false;
+ }
+
+ 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,
+ "%s(depth attachment stencil bits mismatch)", func);
+ return false;
+ }
+ return true;
+}
+
+
static ALWAYS_INLINE void
blit_framebuffer(struct gl_context *ctx,
struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb,
{
FLUSH_VERTICES(ctx, 0);
- /* Update completeness status of readFb and drawFb. */
- _mesa_update_framebuffer(ctx, readFb, drawFb);
-
- /* Make sure drawFb has an initialized bounding box. */
- _mesa_update_draw_buffer_bounds(ctx, drawFb);
-
if (!readFb || !drawFb) {
/* This will normally never happen but someday we may want to
* support MakeCurrent() with no drawables.
return;
}
+ /* Update completeness status of readFb and drawFb. */
+ _mesa_update_framebuffer(ctx, readFb, drawFb);
+
+ /* Make sure drawFb has an initialized bounding box. */
+ _mesa_update_draw_buffer_bounds(ctx, drawFb);
+
if (!no_error) {
const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT |
if ((readRb == NULL) || (drawRb == NULL)) {
mask &= ~GL_DEPTH_BUFFER_BIT;
} else if (!no_error) {
- 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;
- }
-
- 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;
- }
-
- 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,
- "%s(depth attachment stencil bits mismatch)", func);
+ if (!validate_depth_buffer(ctx, readFb, drawFb, func))
return;
- }
}
}
* Note, if the src buffer is multisampled and the dest is not, this is
* when the samples must be resolved to a single color.
*/
+void GLAPIENTRY
+_mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1,
+ GLint srcY1, GLint dstX0, GLint dstY0,
+ GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter, true, "glBlitFramebuffer");
+}
+
+
void GLAPIENTRY
_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
}
-void GLAPIENTRY
-_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
+static ALWAYS_INLINE void
+blit_named_framebuffer(struct gl_context *ctx,
+ GLuint readFramebuffer, GLuint drawFramebuffer,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter, bool no_error)
{
- GET_CURRENT_CONTEXT(ctx);
struct gl_framebuffer *readFb, *drawFb;
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx,
- "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
- " %d, %d, %d, %d, 0x%x, %s)\n",
- readFramebuffer, drawFramebuffer,
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, _mesa_enum_to_string(filter));
-
/*
* According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
* Section 18.3 Copying Pixels):
* respectively."
*/
if (readFramebuffer) {
- readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
- "glBlitNamedFramebuffer");
- if (!readFb)
- return;
- }
- else
+ if (no_error) {
+ readFb = _mesa_lookup_framebuffer(ctx, readFramebuffer);
+ } else {
+ readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
+ "glBlitNamedFramebuffer");
+ if (!readFb)
+ return;
+ }
+ } else {
readFb = ctx->WinSysReadBuffer;
+ }
if (drawFramebuffer) {
- drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
- "glBlitNamedFramebuffer");
- if (!drawFb)
- return;
- }
- else
+ if (no_error) {
+ drawFb = _mesa_lookup_framebuffer(ctx, drawFramebuffer);
+ } else {
+ drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
+ "glBlitNamedFramebuffer");
+ if (!drawFb)
+ return;
+ }
+ } else {
drawFb = ctx->WinSysDrawBuffer;
+ }
- blit_framebuffer_err(ctx, readFb, drawFb,
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, filter, "glBlitNamedFramebuffer");
+ blit_framebuffer(ctx, readFb, drawFb,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter, no_error, "glBlitNamedFramebuffer");
+}
+
+
+void GLAPIENTRY
+_mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer,
+ GLuint drawFramebuffer,
+ GLint srcX0, GLint srcY0,
+ GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0,
+ GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter, true);
+}
+
+
+void GLAPIENTRY
+_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx,
+ "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
+ " %d, %d, %d, %d, 0x%x, %s)\n",
+ readFramebuffer, drawFramebuffer,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, _mesa_enum_to_string(filter));
+
+ blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter, false);
}