blit.c revision 848b8605
1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 1999-2013 VMware, Inc. All Rights Reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 24848b8605Smrg */ 25848b8605Smrg 26848b8605Smrg/* 27848b8605Smrg * glBlitFramebuffer functions. 28848b8605Smrg */ 29848b8605Smrg 30848b8605Smrg#include <stdbool.h> 31848b8605Smrg 32848b8605Smrg#include "context.h" 33848b8605Smrg#include "enums.h" 34848b8605Smrg#include "blit.h" 35848b8605Smrg#include "fbobject.h" 36848b8605Smrg#include "glformats.h" 37848b8605Smrg#include "mtypes.h" 38848b8605Smrg#include "state.h" 39848b8605Smrg 40848b8605Smrg 41848b8605Smrg/** Set this to 1 to debug/log glBlitFramebuffer() calls */ 42848b8605Smrg#define DEBUG_BLIT 0 43848b8605Smrg 44848b8605Smrg 45848b8605Smrg 46848b8605Smrgstatic const struct gl_renderbuffer_attachment * 47848b8605Smrgfind_attachment(const struct gl_framebuffer *fb, 48848b8605Smrg const struct gl_renderbuffer *rb) 49848b8605Smrg{ 50848b8605Smrg GLuint i; 51848b8605Smrg for (i = 0; i < Elements(fb->Attachment); i++) { 52848b8605Smrg if (fb->Attachment[i].Renderbuffer == rb) 53848b8605Smrg return &fb->Attachment[i]; 54848b8605Smrg } 55848b8605Smrg return NULL; 56848b8605Smrg} 57848b8605Smrg 58848b8605Smrg 59848b8605Smrg/** 60848b8605Smrg * Helper function for checking if the datatypes of color buffers are 61848b8605Smrg * compatible for glBlitFramebuffer. From the 3.1 spec, page 198: 62848b8605Smrg * 63848b8605Smrg * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT 64848b8605Smrg * and any of the following conditions hold: 65848b8605Smrg * - The read buffer contains fixed-point or floating-point values and any 66848b8605Smrg * draw buffer contains neither fixed-point nor floating-point values. 67848b8605Smrg * - The read buffer contains unsigned integer values and any draw buffer 68848b8605Smrg * does not contain unsigned integer values. 69848b8605Smrg * - The read buffer contains signed integer values and any draw buffer 70848b8605Smrg * does not contain signed integer values." 71848b8605Smrg */ 72848b8605Smrgstatic GLboolean 73848b8605Smrgcompatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat) 74848b8605Smrg{ 75848b8605Smrg GLenum srcType = _mesa_get_format_datatype(srcFormat); 76848b8605Smrg GLenum dstType = _mesa_get_format_datatype(dstFormat); 77848b8605Smrg 78848b8605Smrg if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) { 79848b8605Smrg assert(srcType == GL_UNSIGNED_NORMALIZED || 80848b8605Smrg srcType == GL_SIGNED_NORMALIZED || 81848b8605Smrg srcType == GL_FLOAT); 82848b8605Smrg /* Boil any of those types down to GL_FLOAT */ 83848b8605Smrg srcType = GL_FLOAT; 84848b8605Smrg } 85848b8605Smrg 86848b8605Smrg if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) { 87848b8605Smrg assert(dstType == GL_UNSIGNED_NORMALIZED || 88848b8605Smrg dstType == GL_SIGNED_NORMALIZED || 89848b8605Smrg dstType == GL_FLOAT); 90848b8605Smrg /* Boil any of those types down to GL_FLOAT */ 91848b8605Smrg dstType = GL_FLOAT; 92848b8605Smrg } 93848b8605Smrg 94848b8605Smrg return srcType == dstType; 95848b8605Smrg} 96848b8605Smrg 97848b8605Smrg 98848b8605Smrgstatic GLboolean 99848b8605Smrgcompatible_resolve_formats(const struct gl_renderbuffer *readRb, 100848b8605Smrg const struct gl_renderbuffer *drawRb) 101848b8605Smrg{ 102848b8605Smrg GLenum readFormat, drawFormat; 103848b8605Smrg 104848b8605Smrg /* The simple case where we know the backing Mesa formats are the same. 105848b8605Smrg */ 106848b8605Smrg if (_mesa_get_srgb_format_linear(readRb->Format) == 107848b8605Smrg _mesa_get_srgb_format_linear(drawRb->Format)) { 108848b8605Smrg return GL_TRUE; 109848b8605Smrg } 110848b8605Smrg 111848b8605Smrg /* The Mesa formats are different, so we must check whether the internal 112848b8605Smrg * formats are compatible. 113848b8605Smrg * 114848b8605Smrg * Under some circumstances, the user may request e.g. two GL_RGBA8 115848b8605Smrg * textures and get two entirely different Mesa formats like RGBA8888 and 116848b8605Smrg * ARGB8888. Drivers behaving like that should be able to cope with 117848b8605Smrg * non-matching formats by themselves, because it's not the user's fault. 118848b8605Smrg * 119848b8605Smrg * Blits between linear and sRGB formats are also allowed. 120848b8605Smrg */ 121848b8605Smrg readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat); 122848b8605Smrg drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat); 123848b8605Smrg readFormat = _mesa_get_linear_internalformat(readFormat); 124848b8605Smrg drawFormat = _mesa_get_linear_internalformat(drawFormat); 125848b8605Smrg 126848b8605Smrg if (readFormat == drawFormat) { 127848b8605Smrg return GL_TRUE; 128848b8605Smrg } 129848b8605Smrg 130848b8605Smrg return GL_FALSE; 131848b8605Smrg} 132848b8605Smrg 133848b8605Smrg 134848b8605Smrgstatic GLboolean 135848b8605Smrgis_valid_blit_filter(const struct gl_context *ctx, GLenum filter) 136848b8605Smrg{ 137848b8605Smrg switch (filter) { 138848b8605Smrg case GL_NEAREST: 139848b8605Smrg case GL_LINEAR: 140848b8605Smrg return true; 141848b8605Smrg case GL_SCALED_RESOLVE_FASTEST_EXT: 142848b8605Smrg case GL_SCALED_RESOLVE_NICEST_EXT: 143848b8605Smrg return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled; 144848b8605Smrg default: 145848b8605Smrg return false; 146848b8605Smrg } 147848b8605Smrg} 148848b8605Smrg 149848b8605Smrg 150848b8605Smrg/** 151848b8605Smrg * Blit rectangular region, optionally from one framebuffer to another. 152848b8605Smrg * 153848b8605Smrg * Note, if the src buffer is multisampled and the dest is not, this is 154848b8605Smrg * when the samples must be resolved to a single color. 155848b8605Smrg */ 156848b8605Smrgvoid GLAPIENTRY 157848b8605Smrg_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 158848b8605Smrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 159848b8605Smrg GLbitfield mask, GLenum filter) 160848b8605Smrg{ 161848b8605Smrg const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT | 162848b8605Smrg GL_DEPTH_BUFFER_BIT | 163848b8605Smrg GL_STENCIL_BUFFER_BIT); 164848b8605Smrg const struct gl_framebuffer *readFb, *drawFb; 165848b8605Smrg GET_CURRENT_CONTEXT(ctx); 166848b8605Smrg 167848b8605Smrg FLUSH_VERTICES(ctx, 0); 168848b8605Smrg 169848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) 170848b8605Smrg _mesa_debug(ctx, 171848b8605Smrg "glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, 0x%x, %s)\n", 172848b8605Smrg srcX0, srcY0, srcX1, srcY1, 173848b8605Smrg dstX0, dstY0, dstX1, dstY1, 174848b8605Smrg mask, _mesa_lookup_enum_by_nr(filter)); 175848b8605Smrg 176848b8605Smrg if (ctx->NewState) { 177848b8605Smrg _mesa_update_state(ctx); 178848b8605Smrg } 179848b8605Smrg 180848b8605Smrg readFb = ctx->ReadBuffer; 181848b8605Smrg drawFb = ctx->DrawBuffer; 182848b8605Smrg 183848b8605Smrg if (!readFb || !drawFb) { 184848b8605Smrg /* This will normally never happen but someday we may want to 185848b8605Smrg * support MakeCurrent() with no drawables. 186848b8605Smrg */ 187848b8605Smrg return; 188848b8605Smrg } 189848b8605Smrg 190848b8605Smrg /* check for complete framebuffers */ 191848b8605Smrg if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT || 192848b8605Smrg readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 193848b8605Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 194848b8605Smrg "glBlitFramebufferEXT(incomplete draw/read buffers)"); 195848b8605Smrg return; 196848b8605Smrg } 197848b8605Smrg 198848b8605Smrg if (!is_valid_blit_filter(ctx, filter)) { 199848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(%s)", 200848b8605Smrg _mesa_lookup_enum_by_nr(filter)); 201848b8605Smrg return; 202848b8605Smrg } 203848b8605Smrg 204848b8605Smrg if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT || 205848b8605Smrg filter == GL_SCALED_RESOLVE_NICEST_EXT) && 206848b8605Smrg (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) { 207848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(%s)", 208848b8605Smrg _mesa_lookup_enum_by_nr(filter)); 209848b8605Smrg return; 210848b8605Smrg } 211848b8605Smrg 212848b8605Smrg if (mask & ~legalMaskBits) { 213848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)"); 214848b8605Smrg return; 215848b8605Smrg } 216848b8605Smrg 217848b8605Smrg /* depth/stencil must be blitted with nearest filtering */ 218848b8605Smrg if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 219848b8605Smrg && filter != GL_NEAREST) { 220848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 221848b8605Smrg "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter)"); 222848b8605Smrg return; 223848b8605Smrg } 224848b8605Smrg 225848b8605Smrg /* get color read/draw renderbuffers */ 226848b8605Smrg if (mask & GL_COLOR_BUFFER_BIT) { 227848b8605Smrg const GLuint numColorDrawBuffers = ctx->DrawBuffer->_NumColorDrawBuffers; 228848b8605Smrg const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 229848b8605Smrg const struct gl_renderbuffer *colorDrawRb = NULL; 230848b8605Smrg GLuint i; 231848b8605Smrg 232848b8605Smrg /* From the EXT_framebuffer_object spec: 233848b8605Smrg * 234848b8605Smrg * "If a buffer is specified in <mask> and does not exist in both 235848b8605Smrg * the read and draw framebuffers, the corresponding bit is silently 236848b8605Smrg * ignored." 237848b8605Smrg */ 238848b8605Smrg if (!colorReadRb || numColorDrawBuffers == 0) { 239848b8605Smrg mask &= ~GL_COLOR_BUFFER_BIT; 240848b8605Smrg } 241848b8605Smrg else { 242848b8605Smrg for (i = 0; i < numColorDrawBuffers; i++) { 243848b8605Smrg colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i]; 244848b8605Smrg if (!colorDrawRb) 245848b8605Smrg continue; 246848b8605Smrg 247848b8605Smrg /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL 248848b8605Smrg * ES 3.0.1 spec says: 249848b8605Smrg * 250848b8605Smrg * "If the source and destination buffers are identical, an 251848b8605Smrg * INVALID_OPERATION error is generated. Different mipmap 252848b8605Smrg * levels of a texture, different layers of a three- 253848b8605Smrg * dimensional texture or two-dimensional array texture, and 254848b8605Smrg * different faces of a cube map texture do not constitute 255848b8605Smrg * identical buffers." 256848b8605Smrg */ 257848b8605Smrg if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) { 258848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 259848b8605Smrg "glBlitFramebuffer(source and destination color " 260848b8605Smrg "buffer cannot be the same)"); 261848b8605Smrg return; 262848b8605Smrg } 263848b8605Smrg 264848b8605Smrg if (!compatible_color_datatypes(colorReadRb->Format, 265848b8605Smrg colorDrawRb->Format)) { 266848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 267848b8605Smrg "glBlitFramebufferEXT(color buffer datatypes mismatch)"); 268848b8605Smrg return; 269848b8605Smrg } 270848b8605Smrg /* extra checks for multisample copies... */ 271848b8605Smrg if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) { 272848b8605Smrg /* color formats must match */ 273848b8605Smrg if (!compatible_resolve_formats(colorReadRb, colorDrawRb)) { 274848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 275848b8605Smrg "glBlitFramebufferEXT(bad src/dst multisample pixel formats)"); 276848b8605Smrg return; 277848b8605Smrg } 278848b8605Smrg } 279848b8605Smrg } 280848b8605Smrg if (filter != GL_NEAREST) { 281848b8605Smrg /* From EXT_framebuffer_multisample_blit_scaled specification: 282848b8605Smrg * "Calling BlitFramebuffer will result in an INVALID_OPERATION error 283848b8605Smrg * if filter is not NEAREST and read buffer contains integer data." 284848b8605Smrg */ 285848b8605Smrg GLenum type = _mesa_get_format_datatype(colorReadRb->Format); 286848b8605Smrg if (type == GL_INT || type == GL_UNSIGNED_INT) { 287848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 288848b8605Smrg "glBlitFramebufferEXT(integer color type)"); 289848b8605Smrg return; 290848b8605Smrg } 291848b8605Smrg } 292848b8605Smrg } 293848b8605Smrg } 294848b8605Smrg 295848b8605Smrg if (mask & GL_STENCIL_BUFFER_BIT) { 296848b8605Smrg struct gl_renderbuffer *readRb = 297848b8605Smrg readFb->Attachment[BUFFER_STENCIL].Renderbuffer; 298848b8605Smrg struct gl_renderbuffer *drawRb = 299848b8605Smrg drawFb->Attachment[BUFFER_STENCIL].Renderbuffer; 300848b8605Smrg 301848b8605Smrg /* From the EXT_framebuffer_object spec: 302848b8605Smrg * 303848b8605Smrg * "If a buffer is specified in <mask> and does not exist in both 304848b8605Smrg * the read and draw framebuffers, the corresponding bit is silently 305848b8605Smrg * ignored." 306848b8605Smrg */ 307848b8605Smrg if ((readRb == NULL) || (drawRb == NULL)) { 308848b8605Smrg mask &= ~GL_STENCIL_BUFFER_BIT; 309848b8605Smrg } 310848b8605Smrg else { 311848b8605Smrg int read_z_bits, draw_z_bits; 312848b8605Smrg 313848b8605Smrg if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { 314848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 315848b8605Smrg "glBlitFramebuffer(source and destination stencil " 316848b8605Smrg "buffer cannot be the same)"); 317848b8605Smrg return; 318848b8605Smrg } 319848b8605Smrg 320848b8605Smrg if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) != 321848b8605Smrg _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) { 322848b8605Smrg /* There is no need to check the stencil datatype here, because 323848b8605Smrg * there is only one: GL_UNSIGNED_INT. 324848b8605Smrg */ 325848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 326848b8605Smrg "glBlitFramebuffer(stencil attachment format mismatch)"); 327848b8605Smrg return; 328848b8605Smrg } 329848b8605Smrg 330848b8605Smrg read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS); 331848b8605Smrg draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS); 332848b8605Smrg 333848b8605Smrg /* If both buffers also have depth data, the depth formats must match 334848b8605Smrg * as well. If one doesn't have depth, it's not blitted, so we should 335848b8605Smrg * ignore the depth format check. 336848b8605Smrg */ 337848b8605Smrg if (read_z_bits > 0 && draw_z_bits > 0 && 338848b8605Smrg (read_z_bits != draw_z_bits || 339848b8605Smrg _mesa_get_format_datatype(readRb->Format) != 340848b8605Smrg _mesa_get_format_datatype(drawRb->Format))) { 341848b8605Smrg 342848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer" 343848b8605Smrg "(stencil attachment depth format mismatch)"); 344848b8605Smrg return; 345848b8605Smrg } 346848b8605Smrg } 347848b8605Smrg } 348848b8605Smrg 349848b8605Smrg if (mask & GL_DEPTH_BUFFER_BIT) { 350848b8605Smrg struct gl_renderbuffer *readRb = 351848b8605Smrg readFb->Attachment[BUFFER_DEPTH].Renderbuffer; 352848b8605Smrg struct gl_renderbuffer *drawRb = 353848b8605Smrg drawFb->Attachment[BUFFER_DEPTH].Renderbuffer; 354848b8605Smrg 355848b8605Smrg /* From the EXT_framebuffer_object spec: 356848b8605Smrg * 357848b8605Smrg * "If a buffer is specified in <mask> and does not exist in both 358848b8605Smrg * the read and draw framebuffers, the corresponding bit is silently 359848b8605Smrg * ignored." 360848b8605Smrg */ 361848b8605Smrg if ((readRb == NULL) || (drawRb == NULL)) { 362848b8605Smrg mask &= ~GL_DEPTH_BUFFER_BIT; 363848b8605Smrg } 364848b8605Smrg else { 365848b8605Smrg int read_s_bit, draw_s_bit; 366848b8605Smrg 367848b8605Smrg if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { 368848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 369848b8605Smrg "glBlitFramebuffer(source and destination depth " 370848b8605Smrg "buffer cannot be the same)"); 371848b8605Smrg return; 372848b8605Smrg } 373848b8605Smrg 374848b8605Smrg if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) != 375848b8605Smrg _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) || 376848b8605Smrg (_mesa_get_format_datatype(readRb->Format) != 377848b8605Smrg _mesa_get_format_datatype(drawRb->Format))) { 378848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 379848b8605Smrg "glBlitFramebuffer(depth attachment format mismatch)"); 380848b8605Smrg return; 381848b8605Smrg } 382848b8605Smrg 383848b8605Smrg read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS); 384848b8605Smrg draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS); 385848b8605Smrg 386848b8605Smrg /* If both buffers also have stencil data, the stencil formats must 387848b8605Smrg * match as well. If one doesn't have stencil, it's not blitted, so 388848b8605Smrg * we should ignore the stencil format check. 389848b8605Smrg */ 390848b8605Smrg if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) { 391848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer" 392848b8605Smrg "(depth attachment stencil bits mismatch)"); 393848b8605Smrg return; 394848b8605Smrg } 395848b8605Smrg } 396848b8605Smrg } 397848b8605Smrg 398848b8605Smrg 399848b8605Smrg if (_mesa_is_gles3(ctx)) { 400848b8605Smrg /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES 401848b8605Smrg * 3.0.1 spec says: 402848b8605Smrg * 403848b8605Smrg * "If SAMPLE_BUFFERS for the draw framebuffer is greater than zero, 404848b8605Smrg * an INVALID_OPERATION error is generated." 405848b8605Smrg */ 406848b8605Smrg if (drawFb->Visual.samples > 0) { 407848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 408848b8605Smrg "glBlitFramebuffer(destination samples must be 0)"); 409848b8605Smrg return; 410848b8605Smrg } 411848b8605Smrg 412848b8605Smrg /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES 413848b8605Smrg * 3.0.1 spec says: 414848b8605Smrg * 415848b8605Smrg * "If SAMPLE_BUFFERS for the read framebuffer is greater than zero, 416848b8605Smrg * no copy is performed and an INVALID_OPERATION error is generated 417848b8605Smrg * if the formats of the read and draw framebuffers are not 418848b8605Smrg * identical or if the source and destination rectangles are not 419848b8605Smrg * defined with the same (X0, Y0) and (X1, Y1) bounds." 420848b8605Smrg * 421848b8605Smrg * The format check was made above because desktop OpenGL has the same 422848b8605Smrg * requirement. 423848b8605Smrg */ 424848b8605Smrg if (readFb->Visual.samples > 0 425848b8605Smrg && (srcX0 != dstX0 || srcY0 != dstY0 426848b8605Smrg || srcX1 != dstX1 || srcY1 != dstY1)) { 427848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 428848b8605Smrg "glBlitFramebuffer(bad src/dst multisample region)"); 429848b8605Smrg return; 430848b8605Smrg } 431848b8605Smrg } else { 432848b8605Smrg if (readFb->Visual.samples > 0 && 433848b8605Smrg drawFb->Visual.samples > 0 && 434848b8605Smrg readFb->Visual.samples != drawFb->Visual.samples) { 435848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 436848b8605Smrg "glBlitFramebufferEXT(mismatched samples)"); 437848b8605Smrg return; 438848b8605Smrg } 439848b8605Smrg 440848b8605Smrg /* extra checks for multisample copies... */ 441848b8605Smrg if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) && 442848b8605Smrg (filter == GL_NEAREST || filter == GL_LINEAR)) { 443848b8605Smrg /* src and dest region sizes must be the same */ 444848b8605Smrg if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) || 445848b8605Smrg abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) { 446848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 447848b8605Smrg "glBlitFramebufferEXT(bad src/dst multisample region sizes)"); 448848b8605Smrg return; 449848b8605Smrg } 450848b8605Smrg } 451848b8605Smrg } 452848b8605Smrg 453848b8605Smrg /* Debug code */ 454848b8605Smrg if (DEBUG_BLIT) { 455848b8605Smrg const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 456848b8605Smrg const struct gl_renderbuffer *colorDrawRb = NULL; 457848b8605Smrg GLuint i = 0; 458848b8605Smrg 459848b8605Smrg printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d," 460848b8605Smrg " 0x%x, 0x%x)\n", 461848b8605Smrg srcX0, srcY0, srcX1, srcY1, 462848b8605Smrg dstX0, dstY0, dstX1, dstY1, 463848b8605Smrg mask, filter); 464848b8605Smrg if (colorReadRb) { 465848b8605Smrg const struct gl_renderbuffer_attachment *att; 466848b8605Smrg 467848b8605Smrg att = find_attachment(readFb, colorReadRb); 468848b8605Smrg printf(" Src FBO %u RB %u (%dx%d) ", 469848b8605Smrg readFb->Name, colorReadRb->Name, 470848b8605Smrg colorReadRb->Width, colorReadRb->Height); 471848b8605Smrg if (att && att->Texture) { 472848b8605Smrg printf("Tex %u tgt 0x%x level %u face %u", 473848b8605Smrg att->Texture->Name, 474848b8605Smrg att->Texture->Target, 475848b8605Smrg att->TextureLevel, 476848b8605Smrg att->CubeMapFace); 477848b8605Smrg } 478848b8605Smrg printf("\n"); 479848b8605Smrg 480848b8605Smrg /* Print all active color render buffers */ 481848b8605Smrg for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { 482848b8605Smrg colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i]; 483848b8605Smrg if (!colorDrawRb) 484848b8605Smrg continue; 485848b8605Smrg 486848b8605Smrg att = find_attachment(drawFb, colorDrawRb); 487848b8605Smrg printf(" Dst FBO %u RB %u (%dx%d) ", 488848b8605Smrg drawFb->Name, colorDrawRb->Name, 489848b8605Smrg colorDrawRb->Width, colorDrawRb->Height); 490848b8605Smrg if (att && att->Texture) { 491848b8605Smrg printf("Tex %u tgt 0x%x level %u face %u", 492848b8605Smrg att->Texture->Name, 493848b8605Smrg att->Texture->Target, 494848b8605Smrg att->TextureLevel, 495848b8605Smrg att->CubeMapFace); 496848b8605Smrg } 497848b8605Smrg printf("\n"); 498848b8605Smrg } 499848b8605Smrg } 500848b8605Smrg } 501848b8605Smrg 502848b8605Smrg if (!mask || 503848b8605Smrg (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 || 504848b8605Smrg (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) { 505848b8605Smrg return; 506848b8605Smrg } 507848b8605Smrg 508848b8605Smrg ASSERT(ctx->Driver.BlitFramebuffer); 509848b8605Smrg ctx->Driver.BlitFramebuffer(ctx, 510848b8605Smrg srcX0, srcY0, srcX1, srcY1, 511848b8605Smrg dstX0, dstY0, dstX1, dstY1, 512848b8605Smrg mask, filter); 513848b8605Smrg} 514