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> 31b8e80941Smrg#include <stdio.h> 32848b8605Smrg 33848b8605Smrg#include "context.h" 34848b8605Smrg#include "enums.h" 35848b8605Smrg#include "blit.h" 36848b8605Smrg#include "fbobject.h" 37b8e80941Smrg#include "framebuffer.h" 38848b8605Smrg#include "glformats.h" 39848b8605Smrg#include "mtypes.h" 40b8e80941Smrg#include "macros.h" 41848b8605Smrg#include "state.h" 42848b8605Smrg 43848b8605Smrg 44848b8605Smrg/** Set this to 1 to debug/log glBlitFramebuffer() calls */ 45848b8605Smrg#define DEBUG_BLIT 0 46848b8605Smrg 47848b8605Smrg 48848b8605Smrg 49848b8605Smrgstatic const struct gl_renderbuffer_attachment * 50848b8605Smrgfind_attachment(const struct gl_framebuffer *fb, 51848b8605Smrg const struct gl_renderbuffer *rb) 52848b8605Smrg{ 53848b8605Smrg GLuint i; 54b8e80941Smrg for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) { 55848b8605Smrg if (fb->Attachment[i].Renderbuffer == rb) 56848b8605Smrg return &fb->Attachment[i]; 57848b8605Smrg } 58848b8605Smrg return NULL; 59848b8605Smrg} 60848b8605Smrg 61848b8605Smrg 62b8e80941Smrg/** 63b8e80941Smrg * \return true if two regions overlap, false otherwise 64b8e80941Smrg */ 65b8e80941Smrgbool 66b8e80941Smrg_mesa_regions_overlap(int srcX0, int srcY0, 67b8e80941Smrg int srcX1, int srcY1, 68b8e80941Smrg int dstX0, int dstY0, 69b8e80941Smrg int dstX1, int dstY1) 70b8e80941Smrg{ 71b8e80941Smrg if (MAX2(srcX0, srcX1) <= MIN2(dstX0, dstX1)) 72b8e80941Smrg return false; /* dst completely right of src */ 73b8e80941Smrg 74b8e80941Smrg if (MAX2(dstX0, dstX1) <= MIN2(srcX0, srcX1)) 75b8e80941Smrg return false; /* dst completely left of src */ 76b8e80941Smrg 77b8e80941Smrg if (MAX2(srcY0, srcY1) <= MIN2(dstY0, dstY1)) 78b8e80941Smrg return false; /* dst completely above src */ 79b8e80941Smrg 80b8e80941Smrg if (MAX2(dstY0, dstY1) <= MIN2(srcY0, srcY1)) 81b8e80941Smrg return false; /* dst completely below src */ 82b8e80941Smrg 83b8e80941Smrg return true; /* some overlap */ 84b8e80941Smrg} 85b8e80941Smrg 86b8e80941Smrg 87848b8605Smrg/** 88848b8605Smrg * Helper function for checking if the datatypes of color buffers are 89848b8605Smrg * compatible for glBlitFramebuffer. From the 3.1 spec, page 198: 90848b8605Smrg * 91848b8605Smrg * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT 92848b8605Smrg * and any of the following conditions hold: 93848b8605Smrg * - The read buffer contains fixed-point or floating-point values and any 94848b8605Smrg * draw buffer contains neither fixed-point nor floating-point values. 95848b8605Smrg * - The read buffer contains unsigned integer values and any draw buffer 96848b8605Smrg * does not contain unsigned integer values. 97848b8605Smrg * - The read buffer contains signed integer values and any draw buffer 98848b8605Smrg * does not contain signed integer values." 99848b8605Smrg */ 100848b8605Smrgstatic GLboolean 101848b8605Smrgcompatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat) 102848b8605Smrg{ 103848b8605Smrg GLenum srcType = _mesa_get_format_datatype(srcFormat); 104848b8605Smrg GLenum dstType = _mesa_get_format_datatype(dstFormat); 105848b8605Smrg 106848b8605Smrg if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) { 107848b8605Smrg assert(srcType == GL_UNSIGNED_NORMALIZED || 108848b8605Smrg srcType == GL_SIGNED_NORMALIZED || 109848b8605Smrg srcType == GL_FLOAT); 110848b8605Smrg /* Boil any of those types down to GL_FLOAT */ 111848b8605Smrg srcType = GL_FLOAT; 112848b8605Smrg } 113848b8605Smrg 114848b8605Smrg if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) { 115848b8605Smrg assert(dstType == GL_UNSIGNED_NORMALIZED || 116848b8605Smrg dstType == GL_SIGNED_NORMALIZED || 117848b8605Smrg dstType == GL_FLOAT); 118848b8605Smrg /* Boil any of those types down to GL_FLOAT */ 119848b8605Smrg dstType = GL_FLOAT; 120848b8605Smrg } 121848b8605Smrg 122848b8605Smrg return srcType == dstType; 123848b8605Smrg} 124848b8605Smrg 125848b8605Smrg 126848b8605Smrgstatic GLboolean 127848b8605Smrgcompatible_resolve_formats(const struct gl_renderbuffer *readRb, 128848b8605Smrg const struct gl_renderbuffer *drawRb) 129848b8605Smrg{ 130848b8605Smrg GLenum readFormat, drawFormat; 131848b8605Smrg 132b8e80941Smrg /* This checks whether the internal formats are compatible rather than the 133b8e80941Smrg * Mesa format for two reasons: 134b8e80941Smrg * 135b8e80941Smrg * • Under some circumstances, the user may request e.g. two GL_RGBA8 136b8e80941Smrg * textures and get two entirely different Mesa formats like RGBA8888 and 137b8e80941Smrg * ARGB8888. Drivers behaving like that should be able to cope with 138b8e80941Smrg * non-matching formats by themselves, because it's not the user's fault. 139848b8605Smrg * 140b8e80941Smrg * • Picking two different internal formats can end up with the same Mesa 141b8e80941Smrg * format. For example the driver might be simulating GL_RGB textures 142b8e80941Smrg * with GL_RGBA internally and in that case both internal formats would 143b8e80941Smrg * end up with RGBA8888. 144b8e80941Smrg * 145b8e80941Smrg * This function is used to generate a GL error according to the spec so in 146b8e80941Smrg * both cases we want to be looking at the application-level format, which 147b8e80941Smrg * is InternalFormat. 148848b8605Smrg * 149848b8605Smrg * Blits between linear and sRGB formats are also allowed. 150848b8605Smrg */ 151848b8605Smrg readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat); 152848b8605Smrg drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat); 153848b8605Smrg readFormat = _mesa_get_linear_internalformat(readFormat); 154848b8605Smrg drawFormat = _mesa_get_linear_internalformat(drawFormat); 155848b8605Smrg 156848b8605Smrg if (readFormat == drawFormat) { 157848b8605Smrg return GL_TRUE; 158848b8605Smrg } 159848b8605Smrg 160848b8605Smrg return GL_FALSE; 161848b8605Smrg} 162848b8605Smrg 163848b8605Smrg 164848b8605Smrgstatic GLboolean 165848b8605Smrgis_valid_blit_filter(const struct gl_context *ctx, GLenum filter) 166848b8605Smrg{ 167848b8605Smrg switch (filter) { 168848b8605Smrg case GL_NEAREST: 169848b8605Smrg case GL_LINEAR: 170848b8605Smrg return true; 171848b8605Smrg case GL_SCALED_RESOLVE_FASTEST_EXT: 172848b8605Smrg case GL_SCALED_RESOLVE_NICEST_EXT: 173848b8605Smrg return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled; 174848b8605Smrg default: 175848b8605Smrg return false; 176848b8605Smrg } 177848b8605Smrg} 178848b8605Smrg 179848b8605Smrg 180b8e80941Smrgstatic bool 181b8e80941Smrgvalidate_color_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, 182b8e80941Smrg struct gl_framebuffer *drawFb, GLenum filter, 183b8e80941Smrg const char *func) 184848b8605Smrg{ 185b8e80941Smrg const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers; 186b8e80941Smrg const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 187b8e80941Smrg const struct gl_renderbuffer *colorDrawRb = NULL; 188b8e80941Smrg GLuint i; 189848b8605Smrg 190b8e80941Smrg for (i = 0; i < numColorDrawBuffers; i++) { 191b8e80941Smrg colorDrawRb = drawFb->_ColorDrawBuffers[i]; 192b8e80941Smrg if (!colorDrawRb) 193b8e80941Smrg continue; 194848b8605Smrg 195b8e80941Smrg /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL 196b8e80941Smrg * ES 3.0.1 spec says: 197b8e80941Smrg * 198b8e80941Smrg * "If the source and destination buffers are identical, an 199b8e80941Smrg * INVALID_OPERATION error is generated. Different mipmap levels of a 200b8e80941Smrg * texture, different layers of a three- dimensional texture or 201b8e80941Smrg * two-dimensional array texture, and different faces of a cube map 202b8e80941Smrg * texture do not constitute identical buffers." 203b8e80941Smrg */ 204b8e80941Smrg if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) { 205b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 206b8e80941Smrg "%s(source and destination color buffer cannot be the " 207b8e80941Smrg "same)", func); 208b8e80941Smrg return false; 209b8e80941Smrg } 210848b8605Smrg 211b8e80941Smrg if (!compatible_color_datatypes(colorReadRb->Format, 212b8e80941Smrg colorDrawRb->Format)) { 213b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 214b8e80941Smrg "%s(color buffer datatypes mismatch)", func); 215b8e80941Smrg return false; 216b8e80941Smrg } 217848b8605Smrg 218b8e80941Smrg /* extra checks for multisample copies... */ 219b8e80941Smrg if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) { 220b8e80941Smrg /* color formats must match on GLES. This isn't checked on desktop GL 221b8e80941Smrg * because the GL 4.4 spec was changed to allow it. In the section 222b8e80941Smrg * entitled “Changes in the released 223b8e80941Smrg * Specification of July 22, 2013” it says: 224b8e80941Smrg * 225b8e80941Smrg * “Relax BlitFramebuffer in section 18.3.1 so that format conversion 226b8e80941Smrg * can take place during multisample blits, since drivers already 227b8e80941Smrg * allow this and some apps depend on it.” 228b8e80941Smrg */ 229b8e80941Smrg if (_mesa_is_gles(ctx) && 230b8e80941Smrg !compatible_resolve_formats(colorReadRb, colorDrawRb)) { 231b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 232b8e80941Smrg "%s(bad src/dst multisample pixel formats)", func); 233b8e80941Smrg return false; 234b8e80941Smrg } 235b8e80941Smrg } 236848b8605Smrg 237b8e80941Smrg } 238b8e80941Smrg 239b8e80941Smrg if (filter != GL_NEAREST) { 240b8e80941Smrg /* From EXT_framebuffer_multisample_blit_scaled specification: 241b8e80941Smrg * "Calling BlitFramebuffer will result in an INVALID_OPERATION error if 242b8e80941Smrg * filter is not NEAREST and read buffer contains integer data." 243848b8605Smrg */ 244b8e80941Smrg GLenum type = _mesa_get_format_datatype(colorReadRb->Format); 245b8e80941Smrg if (type == GL_INT || type == GL_UNSIGNED_INT) { 246b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 247b8e80941Smrg "%s(integer color type)", func); 248b8e80941Smrg return false; 249b8e80941Smrg } 250848b8605Smrg } 251b8e80941Smrg return true; 252b8e80941Smrg} 253848b8605Smrg 254b8e80941Smrg 255b8e80941Smrgstatic bool 256b8e80941Smrgvalidate_stencil_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, 257b8e80941Smrg struct gl_framebuffer *drawFb, const char *func) 258b8e80941Smrg{ 259b8e80941Smrg struct gl_renderbuffer *readRb = 260b8e80941Smrg readFb->Attachment[BUFFER_STENCIL].Renderbuffer; 261b8e80941Smrg struct gl_renderbuffer *drawRb = 262b8e80941Smrg drawFb->Attachment[BUFFER_STENCIL].Renderbuffer; 263b8e80941Smrg int read_z_bits, draw_z_bits; 264b8e80941Smrg 265b8e80941Smrg if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { 266b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 267b8e80941Smrg "%s(source and destination stencil buffer cannot be the " 268b8e80941Smrg "same)", func); 269b8e80941Smrg return false; 270848b8605Smrg } 271848b8605Smrg 272b8e80941Smrg if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) != 273b8e80941Smrg _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) { 274b8e80941Smrg /* There is no need to check the stencil datatype here, because 275b8e80941Smrg * there is only one: GL_UNSIGNED_INT. 276b8e80941Smrg */ 277b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 278b8e80941Smrg "%s(stencil attachment format mismatch)", func); 279b8e80941Smrg return false; 280848b8605Smrg } 281848b8605Smrg 282b8e80941Smrg read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS); 283b8e80941Smrg draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS); 284b8e80941Smrg 285b8e80941Smrg /* If both buffers also have depth data, the depth formats must match 286b8e80941Smrg * as well. If one doesn't have depth, it's not blitted, so we should 287b8e80941Smrg * ignore the depth format check. 288b8e80941Smrg */ 289b8e80941Smrg if (read_z_bits > 0 && draw_z_bits > 0 && 290b8e80941Smrg (read_z_bits != draw_z_bits || 291b8e80941Smrg _mesa_get_format_datatype(readRb->Format) != 292b8e80941Smrg _mesa_get_format_datatype(drawRb->Format))) { 293b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 294b8e80941Smrg "%s(stencil attachment depth format mismatch)", func); 295b8e80941Smrg return false; 296848b8605Smrg } 297b8e80941Smrg return true; 298b8e80941Smrg} 299848b8605Smrg 300b8e80941Smrg 301b8e80941Smrgstatic bool 302b8e80941Smrgvalidate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, 303b8e80941Smrg struct gl_framebuffer *drawFb, const char *func) 304b8e80941Smrg{ 305b8e80941Smrg struct gl_renderbuffer *readRb = 306b8e80941Smrg readFb->Attachment[BUFFER_DEPTH].Renderbuffer; 307b8e80941Smrg struct gl_renderbuffer *drawRb = 308b8e80941Smrg drawFb->Attachment[BUFFER_DEPTH].Renderbuffer; 309b8e80941Smrg int read_s_bit, draw_s_bit; 310b8e80941Smrg 311b8e80941Smrg if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { 312b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 313b8e80941Smrg "%s(source and destination depth buffer cannot be the same)", 314b8e80941Smrg func); 315b8e80941Smrg return false; 316848b8605Smrg } 317848b8605Smrg 318b8e80941Smrg if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) != 319b8e80941Smrg _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) || 320b8e80941Smrg (_mesa_get_format_datatype(readRb->Format) != 321b8e80941Smrg _mesa_get_format_datatype(drawRb->Format))) { 322848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 323b8e80941Smrg "%s(depth attachment format mismatch)", func); 324b8e80941Smrg return false; 325b8e80941Smrg } 326b8e80941Smrg 327b8e80941Smrg read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS); 328b8e80941Smrg draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS); 329b8e80941Smrg 330b8e80941Smrg /* If both buffers also have stencil data, the stencil formats must match as 331b8e80941Smrg * well. If one doesn't have stencil, it's not blitted, so we should ignore 332b8e80941Smrg * the stencil format check. 333b8e80941Smrg */ 334b8e80941Smrg if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) { 335b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 336b8e80941Smrg "%s(depth attachment stencil bits mismatch)", func); 337b8e80941Smrg return false; 338b8e80941Smrg } 339b8e80941Smrg return true; 340b8e80941Smrg} 341b8e80941Smrg 342b8e80941Smrg 343b8e80941Smrgstatic ALWAYS_INLINE void 344b8e80941Smrgblit_framebuffer(struct gl_context *ctx, 345b8e80941Smrg struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb, 346b8e80941Smrg GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 347b8e80941Smrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 348b8e80941Smrg GLbitfield mask, GLenum filter, bool no_error, const char *func) 349b8e80941Smrg{ 350b8e80941Smrg FLUSH_VERTICES(ctx, 0); 351b8e80941Smrg 352b8e80941Smrg if (!readFb || !drawFb) { 353b8e80941Smrg /* This will normally never happen but someday we may want to 354b8e80941Smrg * support MakeCurrent() with no drawables. 355b8e80941Smrg */ 356848b8605Smrg return; 357848b8605Smrg } 358848b8605Smrg 359b8e80941Smrg /* Update completeness status of readFb and drawFb. */ 360b8e80941Smrg _mesa_update_framebuffer(ctx, readFb, drawFb); 361b8e80941Smrg 362b8e80941Smrg /* Make sure drawFb has an initialized bounding box. */ 363b8e80941Smrg _mesa_update_draw_buffer_bounds(ctx, drawFb); 364b8e80941Smrg 365b8e80941Smrg if (!no_error) { 366b8e80941Smrg const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT | 367b8e80941Smrg GL_DEPTH_BUFFER_BIT | 368b8e80941Smrg GL_STENCIL_BUFFER_BIT); 369b8e80941Smrg 370b8e80941Smrg /* check for complete framebuffers */ 371b8e80941Smrg if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT || 372b8e80941Smrg readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 373b8e80941Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 374b8e80941Smrg "%s(incomplete draw/read buffers)", func); 375b8e80941Smrg return; 376b8e80941Smrg } 377b8e80941Smrg 378b8e80941Smrg if (!is_valid_blit_filter(ctx, filter)) { 379b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func, 380b8e80941Smrg _mesa_enum_to_string(filter)); 381b8e80941Smrg return; 382b8e80941Smrg } 383b8e80941Smrg 384b8e80941Smrg if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT || 385b8e80941Smrg filter == GL_SCALED_RESOLVE_NICEST_EXT) && 386b8e80941Smrg (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) { 387b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func, 388b8e80941Smrg _mesa_enum_to_string(filter)); 389b8e80941Smrg return; 390b8e80941Smrg } 391b8e80941Smrg 392b8e80941Smrg if (mask & ~legalMaskBits) { 393b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func); 394b8e80941Smrg return; 395b8e80941Smrg } 396b8e80941Smrg 397b8e80941Smrg /* depth/stencil must be blitted with nearest filtering */ 398b8e80941Smrg if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 399b8e80941Smrg && filter != GL_NEAREST) { 400b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 401b8e80941Smrg "%s(depth/stencil requires GL_NEAREST filter)", func); 402b8e80941Smrg return; 403b8e80941Smrg } 404b8e80941Smrg 405b8e80941Smrg if (_mesa_is_gles3(ctx)) { 406b8e80941Smrg /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES 407b8e80941Smrg * 3.0.1 spec says: 408b8e80941Smrg * 409b8e80941Smrg * "If SAMPLE_BUFFERS for the draw framebuffer is greater than 410b8e80941Smrg * zero, an INVALID_OPERATION error is generated." 411b8e80941Smrg */ 412b8e80941Smrg if (drawFb->Visual.samples > 0) { 413b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 414b8e80941Smrg "%s(destination samples must be 0)", func); 415b8e80941Smrg return; 416b8e80941Smrg } 417b8e80941Smrg 418b8e80941Smrg /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES 419b8e80941Smrg * 3.0.1 spec says: 420b8e80941Smrg * 421b8e80941Smrg * "If SAMPLE_BUFFERS for the read framebuffer is greater than 422b8e80941Smrg * zero, no copy is performed and an INVALID_OPERATION error is 423b8e80941Smrg * generated if the formats of the read and draw framebuffers are 424b8e80941Smrg * not identical or if the source and destination rectangles are 425b8e80941Smrg * not defined with the same (X0, Y0) and (X1, Y1) bounds." 426b8e80941Smrg * 427b8e80941Smrg * The format check was made above because desktop OpenGL has the same 428b8e80941Smrg * requirement. 429b8e80941Smrg */ 430b8e80941Smrg if (readFb->Visual.samples > 0 431b8e80941Smrg && (srcX0 != dstX0 || srcY0 != dstY0 432b8e80941Smrg || srcX1 != dstX1 || srcY1 != dstY1)) { 433b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 434b8e80941Smrg "%s(bad src/dst multisample region)", func); 435b8e80941Smrg return; 436b8e80941Smrg } 437b8e80941Smrg } else { 438b8e80941Smrg if (readFb->Visual.samples > 0 && 439b8e80941Smrg drawFb->Visual.samples > 0 && 440b8e80941Smrg readFb->Visual.samples != drawFb->Visual.samples) { 441b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 442b8e80941Smrg "%s(mismatched samples)", func); 443b8e80941Smrg return; 444b8e80941Smrg } 445b8e80941Smrg 446b8e80941Smrg /* extra checks for multisample copies... */ 447b8e80941Smrg if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) && 448b8e80941Smrg (filter == GL_NEAREST || filter == GL_LINEAR)) { 449b8e80941Smrg /* src and dest region sizes must be the same */ 450b8e80941Smrg if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) || 451b8e80941Smrg abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) { 452b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 453b8e80941Smrg "%s(bad src/dst multisample region sizes)", func); 454b8e80941Smrg return; 455b8e80941Smrg } 456b8e80941Smrg } 457b8e80941Smrg } 458b8e80941Smrg } 459b8e80941Smrg 460848b8605Smrg /* get color read/draw renderbuffers */ 461848b8605Smrg if (mask & GL_COLOR_BUFFER_BIT) { 462b8e80941Smrg const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers; 463848b8605Smrg const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 464848b8605Smrg 465848b8605Smrg /* From the EXT_framebuffer_object spec: 466848b8605Smrg * 467848b8605Smrg * "If a buffer is specified in <mask> and does not exist in both 468848b8605Smrg * the read and draw framebuffers, the corresponding bit is silently 469848b8605Smrg * ignored." 470848b8605Smrg */ 471848b8605Smrg if (!colorReadRb || numColorDrawBuffers == 0) { 472848b8605Smrg mask &= ~GL_COLOR_BUFFER_BIT; 473b8e80941Smrg } else if (!no_error) { 474b8e80941Smrg if (!validate_color_buffer(ctx, readFb, drawFb, filter, func)) 475b8e80941Smrg return; 476848b8605Smrg } 477848b8605Smrg } 478848b8605Smrg 479848b8605Smrg if (mask & GL_STENCIL_BUFFER_BIT) { 480848b8605Smrg struct gl_renderbuffer *readRb = 481848b8605Smrg readFb->Attachment[BUFFER_STENCIL].Renderbuffer; 482848b8605Smrg struct gl_renderbuffer *drawRb = 483848b8605Smrg drawFb->Attachment[BUFFER_STENCIL].Renderbuffer; 484848b8605Smrg 485848b8605Smrg /* From the EXT_framebuffer_object spec: 486848b8605Smrg * 487848b8605Smrg * "If a buffer is specified in <mask> and does not exist in both 488848b8605Smrg * the read and draw framebuffers, the corresponding bit is silently 489848b8605Smrg * ignored." 490848b8605Smrg */ 491848b8605Smrg if ((readRb == NULL) || (drawRb == NULL)) { 492b8e80941Smrg mask &= ~GL_STENCIL_BUFFER_BIT; 493b8e80941Smrg } else if (!no_error) { 494b8e80941Smrg if (!validate_stencil_buffer(ctx, readFb, drawFb, func)) 495848b8605Smrg return; 496848b8605Smrg } 497848b8605Smrg } 498848b8605Smrg 499848b8605Smrg if (mask & GL_DEPTH_BUFFER_BIT) { 500848b8605Smrg struct gl_renderbuffer *readRb = 501848b8605Smrg readFb->Attachment[BUFFER_DEPTH].Renderbuffer; 502848b8605Smrg struct gl_renderbuffer *drawRb = 503848b8605Smrg drawFb->Attachment[BUFFER_DEPTH].Renderbuffer; 504848b8605Smrg 505848b8605Smrg /* From the EXT_framebuffer_object spec: 506848b8605Smrg * 507848b8605Smrg * "If a buffer is specified in <mask> and does not exist in both 508848b8605Smrg * the read and draw framebuffers, the corresponding bit is silently 509848b8605Smrg * ignored." 510848b8605Smrg */ 511848b8605Smrg if ((readRb == NULL) || (drawRb == NULL)) { 512b8e80941Smrg mask &= ~GL_DEPTH_BUFFER_BIT; 513b8e80941Smrg } else if (!no_error) { 514b8e80941Smrg if (!validate_depth_buffer(ctx, readFb, drawFb, func)) 515848b8605Smrg return; 516848b8605Smrg } 517848b8605Smrg } 518848b8605Smrg 519848b8605Smrg /* Debug code */ 520848b8605Smrg if (DEBUG_BLIT) { 521848b8605Smrg const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 522848b8605Smrg const struct gl_renderbuffer *colorDrawRb = NULL; 523848b8605Smrg GLuint i = 0; 524848b8605Smrg 525b8e80941Smrg printf("%s(%d, %d, %d, %d, %d, %d, %d, %d," 526b8e80941Smrg " 0x%x, 0x%x)\n", func, 527b8e80941Smrg srcX0, srcY0, srcX1, srcY1, 528b8e80941Smrg dstX0, dstY0, dstX1, dstY1, 529b8e80941Smrg mask, filter); 530b8e80941Smrg 531848b8605Smrg if (colorReadRb) { 532848b8605Smrg const struct gl_renderbuffer_attachment *att; 533848b8605Smrg 534848b8605Smrg att = find_attachment(readFb, colorReadRb); 535848b8605Smrg printf(" Src FBO %u RB %u (%dx%d) ", 536b8e80941Smrg readFb->Name, colorReadRb->Name, 537b8e80941Smrg colorReadRb->Width, colorReadRb->Height); 538848b8605Smrg if (att && att->Texture) { 539848b8605Smrg printf("Tex %u tgt 0x%x level %u face %u", 540b8e80941Smrg att->Texture->Name, 541b8e80941Smrg att->Texture->Target, 542b8e80941Smrg att->TextureLevel, 543b8e80941Smrg att->CubeMapFace); 544848b8605Smrg } 545848b8605Smrg printf("\n"); 546848b8605Smrg 547848b8605Smrg /* Print all active color render buffers */ 548b8e80941Smrg for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) { 549b8e80941Smrg colorDrawRb = drawFb->_ColorDrawBuffers[i]; 550848b8605Smrg if (!colorDrawRb) 551848b8605Smrg continue; 552848b8605Smrg 553848b8605Smrg att = find_attachment(drawFb, colorDrawRb); 554848b8605Smrg printf(" Dst FBO %u RB %u (%dx%d) ", 555b8e80941Smrg drawFb->Name, colorDrawRb->Name, 556b8e80941Smrg colorDrawRb->Width, colorDrawRb->Height); 557848b8605Smrg if (att && att->Texture) { 558848b8605Smrg printf("Tex %u tgt 0x%x level %u face %u", 559b8e80941Smrg att->Texture->Name, 560b8e80941Smrg att->Texture->Target, 561b8e80941Smrg att->TextureLevel, 562b8e80941Smrg att->CubeMapFace); 563848b8605Smrg } 564848b8605Smrg printf("\n"); 565848b8605Smrg } 566848b8605Smrg } 567848b8605Smrg } 568848b8605Smrg 569848b8605Smrg if (!mask || 570848b8605Smrg (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 || 571848b8605Smrg (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) { 572848b8605Smrg return; 573848b8605Smrg } 574848b8605Smrg 575b8e80941Smrg assert(ctx->Driver.BlitFramebuffer); 576b8e80941Smrg ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb, 577848b8605Smrg srcX0, srcY0, srcX1, srcY1, 578848b8605Smrg dstX0, dstY0, dstX1, dstY1, 579848b8605Smrg mask, filter); 580848b8605Smrg} 581b8e80941Smrg 582b8e80941Smrg 583b8e80941Smrgstatic void 584b8e80941Smrgblit_framebuffer_err(struct gl_context *ctx, 585b8e80941Smrg struct gl_framebuffer *readFb, 586b8e80941Smrg struct gl_framebuffer *drawFb, 587b8e80941Smrg GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 588b8e80941Smrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 589b8e80941Smrg GLbitfield mask, GLenum filter, const char *func) 590b8e80941Smrg{ 591b8e80941Smrg /* We are wrapping the err variant of the always inlined 592b8e80941Smrg * blit_framebuffer() to avoid inlining it in every caller. 593b8e80941Smrg */ 594b8e80941Smrg blit_framebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, 595b8e80941Smrg dstX0, dstY0, dstX1, dstY1, mask, filter, false, func); 596b8e80941Smrg} 597b8e80941Smrg 598b8e80941Smrg 599b8e80941Smrg/** 600b8e80941Smrg * Blit rectangular region, optionally from one framebuffer to another. 601b8e80941Smrg * 602b8e80941Smrg * Note, if the src buffer is multisampled and the dest is not, this is 603b8e80941Smrg * when the samples must be resolved to a single color. 604b8e80941Smrg */ 605b8e80941Smrgvoid GLAPIENTRY 606b8e80941Smrg_mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1, 607b8e80941Smrg GLint srcY1, GLint dstX0, GLint dstY0, 608b8e80941Smrg GLint dstX1, GLint dstY1, 609b8e80941Smrg GLbitfield mask, GLenum filter) 610b8e80941Smrg{ 611b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 612b8e80941Smrg 613b8e80941Smrg blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 614b8e80941Smrg srcX0, srcY0, srcX1, srcY1, 615b8e80941Smrg dstX0, dstY0, dstX1, dstY1, 616b8e80941Smrg mask, filter, true, "glBlitFramebuffer"); 617b8e80941Smrg} 618b8e80941Smrg 619b8e80941Smrg 620b8e80941Smrgvoid GLAPIENTRY 621b8e80941Smrg_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 622b8e80941Smrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 623b8e80941Smrg GLbitfield mask, GLenum filter) 624b8e80941Smrg{ 625b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 626b8e80941Smrg 627b8e80941Smrg if (MESA_VERBOSE & VERBOSE_API) 628b8e80941Smrg _mesa_debug(ctx, 629b8e80941Smrg "glBlitFramebuffer(%d, %d, %d, %d, " 630b8e80941Smrg " %d, %d, %d, %d, 0x%x, %s)\n", 631b8e80941Smrg srcX0, srcY0, srcX1, srcY1, 632b8e80941Smrg dstX0, dstY0, dstX1, dstY1, 633b8e80941Smrg mask, _mesa_enum_to_string(filter)); 634b8e80941Smrg 635b8e80941Smrg blit_framebuffer_err(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 636b8e80941Smrg srcX0, srcY0, srcX1, srcY1, 637b8e80941Smrg dstX0, dstY0, dstX1, dstY1, 638b8e80941Smrg mask, filter, "glBlitFramebuffer"); 639b8e80941Smrg} 640b8e80941Smrg 641b8e80941Smrg 642b8e80941Smrgstatic ALWAYS_INLINE void 643b8e80941Smrgblit_named_framebuffer(struct gl_context *ctx, 644b8e80941Smrg GLuint readFramebuffer, GLuint drawFramebuffer, 645b8e80941Smrg GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 646b8e80941Smrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 647b8e80941Smrg GLbitfield mask, GLenum filter, bool no_error) 648b8e80941Smrg{ 649b8e80941Smrg struct gl_framebuffer *readFb, *drawFb; 650b8e80941Smrg 651b8e80941Smrg /* 652b8e80941Smrg * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014, 653b8e80941Smrg * Section 18.3 Copying Pixels): 654b8e80941Smrg * "... if readFramebuffer or drawFramebuffer is zero (for 655b8e80941Smrg * BlitNamedFramebuffer), then the default read or draw framebuffer is 656b8e80941Smrg * used as the corresponding source or destination framebuffer, 657b8e80941Smrg * respectively." 658b8e80941Smrg */ 659b8e80941Smrg if (readFramebuffer) { 660b8e80941Smrg if (no_error) { 661b8e80941Smrg readFb = _mesa_lookup_framebuffer(ctx, readFramebuffer); 662b8e80941Smrg } else { 663b8e80941Smrg readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer, 664b8e80941Smrg "glBlitNamedFramebuffer"); 665b8e80941Smrg if (!readFb) 666b8e80941Smrg return; 667b8e80941Smrg } 668b8e80941Smrg } else { 669b8e80941Smrg readFb = ctx->WinSysReadBuffer; 670b8e80941Smrg } 671b8e80941Smrg 672b8e80941Smrg if (drawFramebuffer) { 673b8e80941Smrg if (no_error) { 674b8e80941Smrg drawFb = _mesa_lookup_framebuffer(ctx, drawFramebuffer); 675b8e80941Smrg } else { 676b8e80941Smrg drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer, 677b8e80941Smrg "glBlitNamedFramebuffer"); 678b8e80941Smrg if (!drawFb) 679b8e80941Smrg return; 680b8e80941Smrg } 681b8e80941Smrg } else { 682b8e80941Smrg drawFb = ctx->WinSysDrawBuffer; 683b8e80941Smrg } 684b8e80941Smrg 685b8e80941Smrg blit_framebuffer(ctx, readFb, drawFb, 686b8e80941Smrg srcX0, srcY0, srcX1, srcY1, 687b8e80941Smrg dstX0, dstY0, dstX1, dstY1, 688b8e80941Smrg mask, filter, no_error, "glBlitNamedFramebuffer"); 689b8e80941Smrg} 690b8e80941Smrg 691b8e80941Smrg 692b8e80941Smrgvoid GLAPIENTRY 693b8e80941Smrg_mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer, 694b8e80941Smrg GLuint drawFramebuffer, 695b8e80941Smrg GLint srcX0, GLint srcY0, 696b8e80941Smrg GLint srcX1, GLint srcY1, 697b8e80941Smrg GLint dstX0, GLint dstY0, 698b8e80941Smrg GLint dstX1, GLint dstY1, 699b8e80941Smrg GLbitfield mask, GLenum filter) 700b8e80941Smrg{ 701b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 702b8e80941Smrg 703b8e80941Smrg blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer, 704b8e80941Smrg srcX0, srcY0, srcX1, srcY1, 705b8e80941Smrg dstX0, dstY0, dstX1, dstY1, 706b8e80941Smrg mask, filter, true); 707b8e80941Smrg} 708b8e80941Smrg 709b8e80941Smrg 710b8e80941Smrgvoid GLAPIENTRY 711b8e80941Smrg_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, 712b8e80941Smrg GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 713b8e80941Smrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 714b8e80941Smrg GLbitfield mask, GLenum filter) 715b8e80941Smrg{ 716b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 717b8e80941Smrg 718b8e80941Smrg if (MESA_VERBOSE & VERBOSE_API) 719b8e80941Smrg _mesa_debug(ctx, 720b8e80941Smrg "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, " 721b8e80941Smrg " %d, %d, %d, %d, 0x%x, %s)\n", 722b8e80941Smrg readFramebuffer, drawFramebuffer, 723b8e80941Smrg srcX0, srcY0, srcX1, srcY1, 724b8e80941Smrg dstX0, dstY0, dstX1, dstY1, 725b8e80941Smrg mask, _mesa_enum_to_string(filter)); 726b8e80941Smrg 727b8e80941Smrg blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer, 728b8e80941Smrg srcX0, srcY0, srcX1, srcY1, 729b8e80941Smrg dstX0, dstY0, dstX1, dstY1, 730b8e80941Smrg mask, filter, false); 731b8e80941Smrg} 732