1af69d88dSmrg/* 2af69d88dSmrg * Mesa 3-D graphics library 3af69d88dSmrg * 4af69d88dSmrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5af69d88dSmrg * Copyright (C) 1999-2013 VMware, Inc. All Rights Reserved. 6af69d88dSmrg * 7af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 8af69d88dSmrg * copy of this software and associated documentation files (the "Software"), 9af69d88dSmrg * to deal in the Software without restriction, including without limitation 10af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the 12af69d88dSmrg * Software is furnished to do so, subject to the following conditions: 13af69d88dSmrg * 14af69d88dSmrg * The above copyright notice and this permission notice shall be included 15af69d88dSmrg * in all copies or substantial portions of the Software. 16af69d88dSmrg * 17af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18af69d88dSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 24af69d88dSmrg */ 25af69d88dSmrg 26af69d88dSmrg/* 27af69d88dSmrg * glBlitFramebuffer functions. 28af69d88dSmrg */ 29af69d88dSmrg 30af69d88dSmrg#include <stdbool.h> 3101e04c3fSmrg#include <stdio.h> 32af69d88dSmrg 33af69d88dSmrg#include "context.h" 34af69d88dSmrg#include "enums.h" 35af69d88dSmrg#include "blit.h" 36af69d88dSmrg#include "fbobject.h" 3701e04c3fSmrg#include "framebuffer.h" 38af69d88dSmrg#include "glformats.h" 39af69d88dSmrg#include "mtypes.h" 4001e04c3fSmrg#include "macros.h" 41af69d88dSmrg#include "state.h" 42af69d88dSmrg 43af69d88dSmrg 44af69d88dSmrg/** Set this to 1 to debug/log glBlitFramebuffer() calls */ 45af69d88dSmrg#define DEBUG_BLIT 0 46af69d88dSmrg 47af69d88dSmrg 48af69d88dSmrg 49af69d88dSmrgstatic const struct gl_renderbuffer_attachment * 50af69d88dSmrgfind_attachment(const struct gl_framebuffer *fb, 51af69d88dSmrg const struct gl_renderbuffer *rb) 52af69d88dSmrg{ 53af69d88dSmrg GLuint i; 5401e04c3fSmrg for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) { 55af69d88dSmrg if (fb->Attachment[i].Renderbuffer == rb) 56af69d88dSmrg return &fb->Attachment[i]; 57af69d88dSmrg } 58af69d88dSmrg return NULL; 59af69d88dSmrg} 60af69d88dSmrg 61af69d88dSmrg 6201e04c3fSmrg/** 6301e04c3fSmrg * \return true if two regions overlap, false otherwise 6401e04c3fSmrg */ 6501e04c3fSmrgbool 6601e04c3fSmrg_mesa_regions_overlap(int srcX0, int srcY0, 6701e04c3fSmrg int srcX1, int srcY1, 6801e04c3fSmrg int dstX0, int dstY0, 6901e04c3fSmrg int dstX1, int dstY1) 7001e04c3fSmrg{ 7101e04c3fSmrg if (MAX2(srcX0, srcX1) <= MIN2(dstX0, dstX1)) 7201e04c3fSmrg return false; /* dst completely right of src */ 7301e04c3fSmrg 7401e04c3fSmrg if (MAX2(dstX0, dstX1) <= MIN2(srcX0, srcX1)) 7501e04c3fSmrg return false; /* dst completely left of src */ 7601e04c3fSmrg 7701e04c3fSmrg if (MAX2(srcY0, srcY1) <= MIN2(dstY0, dstY1)) 7801e04c3fSmrg return false; /* dst completely above src */ 7901e04c3fSmrg 8001e04c3fSmrg if (MAX2(dstY0, dstY1) <= MIN2(srcY0, srcY1)) 8101e04c3fSmrg return false; /* dst completely below src */ 8201e04c3fSmrg 8301e04c3fSmrg return true; /* some overlap */ 8401e04c3fSmrg} 8501e04c3fSmrg 8601e04c3fSmrg 87af69d88dSmrg/** 88af69d88dSmrg * Helper function for checking if the datatypes of color buffers are 89af69d88dSmrg * compatible for glBlitFramebuffer. From the 3.1 spec, page 198: 90af69d88dSmrg * 91af69d88dSmrg * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT 92af69d88dSmrg * and any of the following conditions hold: 93af69d88dSmrg * - The read buffer contains fixed-point or floating-point values and any 94af69d88dSmrg * draw buffer contains neither fixed-point nor floating-point values. 95af69d88dSmrg * - The read buffer contains unsigned integer values and any draw buffer 96af69d88dSmrg * does not contain unsigned integer values. 97af69d88dSmrg * - The read buffer contains signed integer values and any draw buffer 98af69d88dSmrg * does not contain signed integer values." 99af69d88dSmrg */ 100af69d88dSmrgstatic GLboolean 101af69d88dSmrgcompatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat) 102af69d88dSmrg{ 103af69d88dSmrg GLenum srcType = _mesa_get_format_datatype(srcFormat); 104af69d88dSmrg GLenum dstType = _mesa_get_format_datatype(dstFormat); 105af69d88dSmrg 106af69d88dSmrg if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) { 107af69d88dSmrg assert(srcType == GL_UNSIGNED_NORMALIZED || 108af69d88dSmrg srcType == GL_SIGNED_NORMALIZED || 109af69d88dSmrg srcType == GL_FLOAT); 110af69d88dSmrg /* Boil any of those types down to GL_FLOAT */ 111af69d88dSmrg srcType = GL_FLOAT; 112af69d88dSmrg } 113af69d88dSmrg 114af69d88dSmrg if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) { 115af69d88dSmrg assert(dstType == GL_UNSIGNED_NORMALIZED || 116af69d88dSmrg dstType == GL_SIGNED_NORMALIZED || 117af69d88dSmrg dstType == GL_FLOAT); 118af69d88dSmrg /* Boil any of those types down to GL_FLOAT */ 119af69d88dSmrg dstType = GL_FLOAT; 120af69d88dSmrg } 121af69d88dSmrg 122af69d88dSmrg return srcType == dstType; 123af69d88dSmrg} 124af69d88dSmrg 125af69d88dSmrg 126af69d88dSmrgstatic GLboolean 127af69d88dSmrgcompatible_resolve_formats(const struct gl_renderbuffer *readRb, 128af69d88dSmrg const struct gl_renderbuffer *drawRb) 129af69d88dSmrg{ 130af69d88dSmrg GLenum readFormat, drawFormat; 131af69d88dSmrg 13201e04c3fSmrg /* This checks whether the internal formats are compatible rather than the 13301e04c3fSmrg * Mesa format for two reasons: 13401e04c3fSmrg * 13501e04c3fSmrg * • Under some circumstances, the user may request e.g. two GL_RGBA8 13601e04c3fSmrg * textures and get two entirely different Mesa formats like RGBA8888 and 13701e04c3fSmrg * ARGB8888. Drivers behaving like that should be able to cope with 13801e04c3fSmrg * non-matching formats by themselves, because it's not the user's fault. 139af69d88dSmrg * 14001e04c3fSmrg * • Picking two different internal formats can end up with the same Mesa 14101e04c3fSmrg * format. For example the driver might be simulating GL_RGB textures 14201e04c3fSmrg * with GL_RGBA internally and in that case both internal formats would 14301e04c3fSmrg * end up with RGBA8888. 14401e04c3fSmrg * 14501e04c3fSmrg * This function is used to generate a GL error according to the spec so in 14601e04c3fSmrg * both cases we want to be looking at the application-level format, which 14701e04c3fSmrg * is InternalFormat. 148af69d88dSmrg * 149af69d88dSmrg * Blits between linear and sRGB formats are also allowed. 150af69d88dSmrg */ 151af69d88dSmrg readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat); 152af69d88dSmrg drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat); 153af69d88dSmrg readFormat = _mesa_get_linear_internalformat(readFormat); 154af69d88dSmrg drawFormat = _mesa_get_linear_internalformat(drawFormat); 155af69d88dSmrg 156af69d88dSmrg if (readFormat == drawFormat) { 157af69d88dSmrg return GL_TRUE; 158af69d88dSmrg } 159af69d88dSmrg 160af69d88dSmrg return GL_FALSE; 161af69d88dSmrg} 162af69d88dSmrg 163af69d88dSmrg 164af69d88dSmrgstatic GLboolean 165af69d88dSmrgis_valid_blit_filter(const struct gl_context *ctx, GLenum filter) 166af69d88dSmrg{ 167af69d88dSmrg switch (filter) { 168af69d88dSmrg case GL_NEAREST: 169af69d88dSmrg case GL_LINEAR: 170af69d88dSmrg return true; 171af69d88dSmrg case GL_SCALED_RESOLVE_FASTEST_EXT: 172af69d88dSmrg case GL_SCALED_RESOLVE_NICEST_EXT: 173af69d88dSmrg return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled; 174af69d88dSmrg default: 175af69d88dSmrg return false; 176af69d88dSmrg } 177af69d88dSmrg} 178af69d88dSmrg 179af69d88dSmrg 18001e04c3fSmrgstatic bool 18101e04c3fSmrgvalidate_color_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, 18201e04c3fSmrg struct gl_framebuffer *drawFb, GLenum filter, 18301e04c3fSmrg const char *func) 184af69d88dSmrg{ 18501e04c3fSmrg const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers; 18601e04c3fSmrg const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 18701e04c3fSmrg const struct gl_renderbuffer *colorDrawRb = NULL; 18801e04c3fSmrg GLuint i; 189af69d88dSmrg 19001e04c3fSmrg for (i = 0; i < numColorDrawBuffers; i++) { 19101e04c3fSmrg colorDrawRb = drawFb->_ColorDrawBuffers[i]; 19201e04c3fSmrg if (!colorDrawRb) 19301e04c3fSmrg continue; 194af69d88dSmrg 19501e04c3fSmrg /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL 19601e04c3fSmrg * ES 3.0.1 spec says: 19701e04c3fSmrg * 19801e04c3fSmrg * "If the source and destination buffers are identical, an 19901e04c3fSmrg * INVALID_OPERATION error is generated. Different mipmap levels of a 20001e04c3fSmrg * texture, different layers of a three- dimensional texture or 20101e04c3fSmrg * two-dimensional array texture, and different faces of a cube map 20201e04c3fSmrg * texture do not constitute identical buffers." 20301e04c3fSmrg */ 20401e04c3fSmrg if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) { 20501e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 20601e04c3fSmrg "%s(source and destination color buffer cannot be the " 20701e04c3fSmrg "same)", func); 20801e04c3fSmrg return false; 20901e04c3fSmrg } 210af69d88dSmrg 21101e04c3fSmrg if (!compatible_color_datatypes(colorReadRb->Format, 21201e04c3fSmrg colorDrawRb->Format)) { 21301e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 21401e04c3fSmrg "%s(color buffer datatypes mismatch)", func); 21501e04c3fSmrg return false; 21601e04c3fSmrg } 217af69d88dSmrg 21801e04c3fSmrg /* extra checks for multisample copies... */ 21901e04c3fSmrg if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) { 22001e04c3fSmrg /* color formats must match on GLES. This isn't checked on desktop GL 22101e04c3fSmrg * because the GL 4.4 spec was changed to allow it. In the section 22201e04c3fSmrg * entitled “Changes in the released 22301e04c3fSmrg * Specification of July 22, 2013” it says: 22401e04c3fSmrg * 22501e04c3fSmrg * “Relax BlitFramebuffer in section 18.3.1 so that format conversion 22601e04c3fSmrg * can take place during multisample blits, since drivers already 22701e04c3fSmrg * allow this and some apps depend on it.” 22801e04c3fSmrg */ 22901e04c3fSmrg if (_mesa_is_gles(ctx) && 23001e04c3fSmrg !compatible_resolve_formats(colorReadRb, colorDrawRb)) { 23101e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 23201e04c3fSmrg "%s(bad src/dst multisample pixel formats)", func); 23301e04c3fSmrg return false; 23401e04c3fSmrg } 23501e04c3fSmrg } 236af69d88dSmrg 23701e04c3fSmrg } 23801e04c3fSmrg 23901e04c3fSmrg if (filter != GL_NEAREST) { 24001e04c3fSmrg /* From EXT_framebuffer_multisample_blit_scaled specification: 24101e04c3fSmrg * "Calling BlitFramebuffer will result in an INVALID_OPERATION error if 24201e04c3fSmrg * filter is not NEAREST and read buffer contains integer data." 243af69d88dSmrg */ 24401e04c3fSmrg GLenum type = _mesa_get_format_datatype(colorReadRb->Format); 24501e04c3fSmrg if (type == GL_INT || type == GL_UNSIGNED_INT) { 24601e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 24701e04c3fSmrg "%s(integer color type)", func); 24801e04c3fSmrg return false; 24901e04c3fSmrg } 250af69d88dSmrg } 25101e04c3fSmrg return true; 25201e04c3fSmrg} 253af69d88dSmrg 25401e04c3fSmrg 25501e04c3fSmrgstatic bool 25601e04c3fSmrgvalidate_stencil_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, 25701e04c3fSmrg struct gl_framebuffer *drawFb, const char *func) 25801e04c3fSmrg{ 25901e04c3fSmrg struct gl_renderbuffer *readRb = 26001e04c3fSmrg readFb->Attachment[BUFFER_STENCIL].Renderbuffer; 26101e04c3fSmrg struct gl_renderbuffer *drawRb = 26201e04c3fSmrg drawFb->Attachment[BUFFER_STENCIL].Renderbuffer; 26301e04c3fSmrg int read_z_bits, draw_z_bits; 26401e04c3fSmrg 26501e04c3fSmrg if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { 26601e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 26701e04c3fSmrg "%s(source and destination stencil buffer cannot be the " 26801e04c3fSmrg "same)", func); 26901e04c3fSmrg return false; 270af69d88dSmrg } 271af69d88dSmrg 27201e04c3fSmrg if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) != 27301e04c3fSmrg _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) { 27401e04c3fSmrg /* There is no need to check the stencil datatype here, because 27501e04c3fSmrg * there is only one: GL_UNSIGNED_INT. 27601e04c3fSmrg */ 27701e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 27801e04c3fSmrg "%s(stencil attachment format mismatch)", func); 27901e04c3fSmrg return false; 280af69d88dSmrg } 281af69d88dSmrg 28201e04c3fSmrg read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS); 28301e04c3fSmrg draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS); 28401e04c3fSmrg 28501e04c3fSmrg /* If both buffers also have depth data, the depth formats must match 28601e04c3fSmrg * as well. If one doesn't have depth, it's not blitted, so we should 28701e04c3fSmrg * ignore the depth format check. 28801e04c3fSmrg */ 28901e04c3fSmrg if (read_z_bits > 0 && draw_z_bits > 0 && 29001e04c3fSmrg (read_z_bits != draw_z_bits || 29101e04c3fSmrg _mesa_get_format_datatype(readRb->Format) != 29201e04c3fSmrg _mesa_get_format_datatype(drawRb->Format))) { 29301e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 29401e04c3fSmrg "%s(stencil attachment depth format mismatch)", func); 29501e04c3fSmrg return false; 296af69d88dSmrg } 29701e04c3fSmrg return true; 29801e04c3fSmrg} 299af69d88dSmrg 30001e04c3fSmrg 30101e04c3fSmrgstatic bool 30201e04c3fSmrgvalidate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, 30301e04c3fSmrg struct gl_framebuffer *drawFb, const char *func) 30401e04c3fSmrg{ 30501e04c3fSmrg struct gl_renderbuffer *readRb = 30601e04c3fSmrg readFb->Attachment[BUFFER_DEPTH].Renderbuffer; 30701e04c3fSmrg struct gl_renderbuffer *drawRb = 30801e04c3fSmrg drawFb->Attachment[BUFFER_DEPTH].Renderbuffer; 30901e04c3fSmrg int read_s_bit, draw_s_bit; 31001e04c3fSmrg 31101e04c3fSmrg if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { 31201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 31301e04c3fSmrg "%s(source and destination depth buffer cannot be the same)", 31401e04c3fSmrg func); 31501e04c3fSmrg return false; 316af69d88dSmrg } 317af69d88dSmrg 31801e04c3fSmrg if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) != 31901e04c3fSmrg _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) || 32001e04c3fSmrg (_mesa_get_format_datatype(readRb->Format) != 32101e04c3fSmrg _mesa_get_format_datatype(drawRb->Format))) { 322af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 32301e04c3fSmrg "%s(depth attachment format mismatch)", func); 32401e04c3fSmrg return false; 32501e04c3fSmrg } 32601e04c3fSmrg 32701e04c3fSmrg read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS); 32801e04c3fSmrg draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS); 32901e04c3fSmrg 33001e04c3fSmrg /* If both buffers also have stencil data, the stencil formats must match as 33101e04c3fSmrg * well. If one doesn't have stencil, it's not blitted, so we should ignore 33201e04c3fSmrg * the stencil format check. 33301e04c3fSmrg */ 33401e04c3fSmrg if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) { 33501e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 33601e04c3fSmrg "%s(depth attachment stencil bits mismatch)", func); 33701e04c3fSmrg return false; 33801e04c3fSmrg } 33901e04c3fSmrg return true; 34001e04c3fSmrg} 34101e04c3fSmrg 34201e04c3fSmrg 34301e04c3fSmrgstatic ALWAYS_INLINE void 34401e04c3fSmrgblit_framebuffer(struct gl_context *ctx, 34501e04c3fSmrg struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb, 34601e04c3fSmrg GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 34701e04c3fSmrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 34801e04c3fSmrg GLbitfield mask, GLenum filter, bool no_error, const char *func) 34901e04c3fSmrg{ 3507ec681f3Smrg FLUSH_VERTICES(ctx, 0, 0); 35101e04c3fSmrg 35201e04c3fSmrg if (!readFb || !drawFb) { 35301e04c3fSmrg /* This will normally never happen but someday we may want to 35401e04c3fSmrg * support MakeCurrent() with no drawables. 35501e04c3fSmrg */ 356af69d88dSmrg return; 357af69d88dSmrg } 358af69d88dSmrg 35901e04c3fSmrg /* Update completeness status of readFb and drawFb. */ 36001e04c3fSmrg _mesa_update_framebuffer(ctx, readFb, drawFb); 36101e04c3fSmrg 36201e04c3fSmrg /* Make sure drawFb has an initialized bounding box. */ 36301e04c3fSmrg _mesa_update_draw_buffer_bounds(ctx, drawFb); 36401e04c3fSmrg 36501e04c3fSmrg if (!no_error) { 36601e04c3fSmrg const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT | 36701e04c3fSmrg GL_DEPTH_BUFFER_BIT | 36801e04c3fSmrg GL_STENCIL_BUFFER_BIT); 36901e04c3fSmrg 37001e04c3fSmrg /* check for complete framebuffers */ 37101e04c3fSmrg if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT || 37201e04c3fSmrg readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 37301e04c3fSmrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 37401e04c3fSmrg "%s(incomplete draw/read buffers)", func); 37501e04c3fSmrg return; 37601e04c3fSmrg } 37701e04c3fSmrg 37801e04c3fSmrg if (!is_valid_blit_filter(ctx, filter)) { 37901e04c3fSmrg _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func, 38001e04c3fSmrg _mesa_enum_to_string(filter)); 38101e04c3fSmrg return; 38201e04c3fSmrg } 38301e04c3fSmrg 38401e04c3fSmrg if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT || 38501e04c3fSmrg filter == GL_SCALED_RESOLVE_NICEST_EXT) && 38601e04c3fSmrg (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) { 38701e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func, 38801e04c3fSmrg _mesa_enum_to_string(filter)); 38901e04c3fSmrg return; 39001e04c3fSmrg } 39101e04c3fSmrg 39201e04c3fSmrg if (mask & ~legalMaskBits) { 39301e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func); 39401e04c3fSmrg return; 39501e04c3fSmrg } 39601e04c3fSmrg 39701e04c3fSmrg /* depth/stencil must be blitted with nearest filtering */ 39801e04c3fSmrg if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 39901e04c3fSmrg && filter != GL_NEAREST) { 40001e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 40101e04c3fSmrg "%s(depth/stencil requires GL_NEAREST filter)", func); 40201e04c3fSmrg return; 40301e04c3fSmrg } 40401e04c3fSmrg 40501e04c3fSmrg if (_mesa_is_gles3(ctx)) { 40601e04c3fSmrg /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES 40701e04c3fSmrg * 3.0.1 spec says: 40801e04c3fSmrg * 40901e04c3fSmrg * "If SAMPLE_BUFFERS for the draw framebuffer is greater than 41001e04c3fSmrg * zero, an INVALID_OPERATION error is generated." 41101e04c3fSmrg */ 41201e04c3fSmrg if (drawFb->Visual.samples > 0) { 41301e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 41401e04c3fSmrg "%s(destination samples must be 0)", func); 41501e04c3fSmrg return; 41601e04c3fSmrg } 41701e04c3fSmrg 41801e04c3fSmrg /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES 41901e04c3fSmrg * 3.0.1 spec says: 42001e04c3fSmrg * 42101e04c3fSmrg * "If SAMPLE_BUFFERS for the read framebuffer is greater than 42201e04c3fSmrg * zero, no copy is performed and an INVALID_OPERATION error is 42301e04c3fSmrg * generated if the formats of the read and draw framebuffers are 42401e04c3fSmrg * not identical or if the source and destination rectangles are 42501e04c3fSmrg * not defined with the same (X0, Y0) and (X1, Y1) bounds." 42601e04c3fSmrg * 42701e04c3fSmrg * The format check was made above because desktop OpenGL has the same 42801e04c3fSmrg * requirement. 42901e04c3fSmrg */ 43001e04c3fSmrg if (readFb->Visual.samples > 0 43101e04c3fSmrg && (srcX0 != dstX0 || srcY0 != dstY0 43201e04c3fSmrg || srcX1 != dstX1 || srcY1 != dstY1)) { 43301e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 43401e04c3fSmrg "%s(bad src/dst multisample region)", func); 43501e04c3fSmrg return; 43601e04c3fSmrg } 43701e04c3fSmrg } else { 43801e04c3fSmrg if (readFb->Visual.samples > 0 && 43901e04c3fSmrg drawFb->Visual.samples > 0 && 44001e04c3fSmrg readFb->Visual.samples != drawFb->Visual.samples) { 44101e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 44201e04c3fSmrg "%s(mismatched samples)", func); 44301e04c3fSmrg return; 44401e04c3fSmrg } 44501e04c3fSmrg 44601e04c3fSmrg /* extra checks for multisample copies... */ 44701e04c3fSmrg if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) && 44801e04c3fSmrg (filter == GL_NEAREST || filter == GL_LINEAR)) { 44901e04c3fSmrg /* src and dest region sizes must be the same */ 45001e04c3fSmrg if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) || 45101e04c3fSmrg abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) { 45201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 45301e04c3fSmrg "%s(bad src/dst multisample region sizes)", func); 45401e04c3fSmrg return; 45501e04c3fSmrg } 45601e04c3fSmrg } 45701e04c3fSmrg } 45801e04c3fSmrg } 45901e04c3fSmrg 460af69d88dSmrg /* get color read/draw renderbuffers */ 461af69d88dSmrg if (mask & GL_COLOR_BUFFER_BIT) { 46201e04c3fSmrg const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers; 463af69d88dSmrg const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 464af69d88dSmrg 465af69d88dSmrg /* From the EXT_framebuffer_object spec: 466af69d88dSmrg * 467af69d88dSmrg * "If a buffer is specified in <mask> and does not exist in both 468af69d88dSmrg * the read and draw framebuffers, the corresponding bit is silently 469af69d88dSmrg * ignored." 470af69d88dSmrg */ 471af69d88dSmrg if (!colorReadRb || numColorDrawBuffers == 0) { 472af69d88dSmrg mask &= ~GL_COLOR_BUFFER_BIT; 47301e04c3fSmrg } else if (!no_error) { 47401e04c3fSmrg if (!validate_color_buffer(ctx, readFb, drawFb, filter, func)) 47501e04c3fSmrg return; 476af69d88dSmrg } 477af69d88dSmrg } 478af69d88dSmrg 479af69d88dSmrg if (mask & GL_STENCIL_BUFFER_BIT) { 480af69d88dSmrg struct gl_renderbuffer *readRb = 481af69d88dSmrg readFb->Attachment[BUFFER_STENCIL].Renderbuffer; 482af69d88dSmrg struct gl_renderbuffer *drawRb = 483af69d88dSmrg drawFb->Attachment[BUFFER_STENCIL].Renderbuffer; 484af69d88dSmrg 485af69d88dSmrg /* From the EXT_framebuffer_object spec: 486af69d88dSmrg * 487af69d88dSmrg * "If a buffer is specified in <mask> and does not exist in both 488af69d88dSmrg * the read and draw framebuffers, the corresponding bit is silently 489af69d88dSmrg * ignored." 490af69d88dSmrg */ 491af69d88dSmrg if ((readRb == NULL) || (drawRb == NULL)) { 49201e04c3fSmrg mask &= ~GL_STENCIL_BUFFER_BIT; 49301e04c3fSmrg } else if (!no_error) { 49401e04c3fSmrg if (!validate_stencil_buffer(ctx, readFb, drawFb, func)) 495af69d88dSmrg return; 496af69d88dSmrg } 497af69d88dSmrg } 498af69d88dSmrg 499af69d88dSmrg if (mask & GL_DEPTH_BUFFER_BIT) { 500af69d88dSmrg struct gl_renderbuffer *readRb = 501af69d88dSmrg readFb->Attachment[BUFFER_DEPTH].Renderbuffer; 502af69d88dSmrg struct gl_renderbuffer *drawRb = 503af69d88dSmrg drawFb->Attachment[BUFFER_DEPTH].Renderbuffer; 504af69d88dSmrg 505af69d88dSmrg /* From the EXT_framebuffer_object spec: 506af69d88dSmrg * 507af69d88dSmrg * "If a buffer is specified in <mask> and does not exist in both 508af69d88dSmrg * the read and draw framebuffers, the corresponding bit is silently 509af69d88dSmrg * ignored." 510af69d88dSmrg */ 511af69d88dSmrg if ((readRb == NULL) || (drawRb == NULL)) { 51201e04c3fSmrg mask &= ~GL_DEPTH_BUFFER_BIT; 51301e04c3fSmrg } else if (!no_error) { 51401e04c3fSmrg if (!validate_depth_buffer(ctx, readFb, drawFb, func)) 515af69d88dSmrg return; 516af69d88dSmrg } 517af69d88dSmrg } 518af69d88dSmrg 519af69d88dSmrg /* Debug code */ 520af69d88dSmrg if (DEBUG_BLIT) { 521af69d88dSmrg const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 522af69d88dSmrg const struct gl_renderbuffer *colorDrawRb = NULL; 523af69d88dSmrg GLuint i = 0; 524af69d88dSmrg 52501e04c3fSmrg printf("%s(%d, %d, %d, %d, %d, %d, %d, %d," 52601e04c3fSmrg " 0x%x, 0x%x)\n", func, 52701e04c3fSmrg srcX0, srcY0, srcX1, srcY1, 52801e04c3fSmrg dstX0, dstY0, dstX1, dstY1, 52901e04c3fSmrg mask, filter); 53001e04c3fSmrg 531af69d88dSmrg if (colorReadRb) { 532af69d88dSmrg const struct gl_renderbuffer_attachment *att; 533af69d88dSmrg 534af69d88dSmrg att = find_attachment(readFb, colorReadRb); 535af69d88dSmrg printf(" Src FBO %u RB %u (%dx%d) ", 53601e04c3fSmrg readFb->Name, colorReadRb->Name, 53701e04c3fSmrg colorReadRb->Width, colorReadRb->Height); 538af69d88dSmrg if (att && att->Texture) { 539af69d88dSmrg printf("Tex %u tgt 0x%x level %u face %u", 54001e04c3fSmrg att->Texture->Name, 54101e04c3fSmrg att->Texture->Target, 54201e04c3fSmrg att->TextureLevel, 54301e04c3fSmrg att->CubeMapFace); 544af69d88dSmrg } 545af69d88dSmrg printf("\n"); 546af69d88dSmrg 547af69d88dSmrg /* Print all active color render buffers */ 54801e04c3fSmrg for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) { 54901e04c3fSmrg colorDrawRb = drawFb->_ColorDrawBuffers[i]; 550af69d88dSmrg if (!colorDrawRb) 551af69d88dSmrg continue; 552af69d88dSmrg 553af69d88dSmrg att = find_attachment(drawFb, colorDrawRb); 554af69d88dSmrg printf(" Dst FBO %u RB %u (%dx%d) ", 55501e04c3fSmrg drawFb->Name, colorDrawRb->Name, 55601e04c3fSmrg colorDrawRb->Width, colorDrawRb->Height); 557af69d88dSmrg if (att && att->Texture) { 558af69d88dSmrg printf("Tex %u tgt 0x%x level %u face %u", 55901e04c3fSmrg att->Texture->Name, 56001e04c3fSmrg att->Texture->Target, 56101e04c3fSmrg att->TextureLevel, 56201e04c3fSmrg att->CubeMapFace); 563af69d88dSmrg } 564af69d88dSmrg printf("\n"); 565af69d88dSmrg } 566af69d88dSmrg } 567af69d88dSmrg } 568af69d88dSmrg 569af69d88dSmrg if (!mask || 570af69d88dSmrg (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 || 571af69d88dSmrg (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) { 572af69d88dSmrg return; 573af69d88dSmrg } 574af69d88dSmrg 57501e04c3fSmrg assert(ctx->Driver.BlitFramebuffer); 57601e04c3fSmrg ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb, 577af69d88dSmrg srcX0, srcY0, srcX1, srcY1, 578af69d88dSmrg dstX0, dstY0, dstX1, dstY1, 579af69d88dSmrg mask, filter); 580af69d88dSmrg} 58101e04c3fSmrg 58201e04c3fSmrg 58301e04c3fSmrgstatic void 58401e04c3fSmrgblit_framebuffer_err(struct gl_context *ctx, 58501e04c3fSmrg struct gl_framebuffer *readFb, 58601e04c3fSmrg struct gl_framebuffer *drawFb, 58701e04c3fSmrg GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 58801e04c3fSmrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 58901e04c3fSmrg GLbitfield mask, GLenum filter, const char *func) 59001e04c3fSmrg{ 59101e04c3fSmrg /* We are wrapping the err variant of the always inlined 59201e04c3fSmrg * blit_framebuffer() to avoid inlining it in every caller. 59301e04c3fSmrg */ 59401e04c3fSmrg blit_framebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, 59501e04c3fSmrg dstX0, dstY0, dstX1, dstY1, mask, filter, false, func); 59601e04c3fSmrg} 59701e04c3fSmrg 59801e04c3fSmrg 59901e04c3fSmrg/** 60001e04c3fSmrg * Blit rectangular region, optionally from one framebuffer to another. 60101e04c3fSmrg * 60201e04c3fSmrg * Note, if the src buffer is multisampled and the dest is not, this is 60301e04c3fSmrg * when the samples must be resolved to a single color. 60401e04c3fSmrg */ 60501e04c3fSmrgvoid GLAPIENTRY 60601e04c3fSmrg_mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1, 60701e04c3fSmrg GLint srcY1, GLint dstX0, GLint dstY0, 60801e04c3fSmrg GLint dstX1, GLint dstY1, 60901e04c3fSmrg GLbitfield mask, GLenum filter) 61001e04c3fSmrg{ 61101e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 61201e04c3fSmrg 61301e04c3fSmrg blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 61401e04c3fSmrg srcX0, srcY0, srcX1, srcY1, 61501e04c3fSmrg dstX0, dstY0, dstX1, dstY1, 61601e04c3fSmrg mask, filter, true, "glBlitFramebuffer"); 61701e04c3fSmrg} 61801e04c3fSmrg 61901e04c3fSmrg 62001e04c3fSmrgvoid GLAPIENTRY 62101e04c3fSmrg_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 62201e04c3fSmrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 62301e04c3fSmrg GLbitfield mask, GLenum filter) 62401e04c3fSmrg{ 62501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 62601e04c3fSmrg 62701e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 62801e04c3fSmrg _mesa_debug(ctx, 62901e04c3fSmrg "glBlitFramebuffer(%d, %d, %d, %d, " 63001e04c3fSmrg " %d, %d, %d, %d, 0x%x, %s)\n", 63101e04c3fSmrg srcX0, srcY0, srcX1, srcY1, 63201e04c3fSmrg dstX0, dstY0, dstX1, dstY1, 63301e04c3fSmrg mask, _mesa_enum_to_string(filter)); 63401e04c3fSmrg 63501e04c3fSmrg blit_framebuffer_err(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 63601e04c3fSmrg srcX0, srcY0, srcX1, srcY1, 63701e04c3fSmrg dstX0, dstY0, dstX1, dstY1, 63801e04c3fSmrg mask, filter, "glBlitFramebuffer"); 63901e04c3fSmrg} 64001e04c3fSmrg 64101e04c3fSmrg 64201e04c3fSmrgstatic ALWAYS_INLINE void 64301e04c3fSmrgblit_named_framebuffer(struct gl_context *ctx, 64401e04c3fSmrg GLuint readFramebuffer, GLuint drawFramebuffer, 64501e04c3fSmrg GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 64601e04c3fSmrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 64701e04c3fSmrg GLbitfield mask, GLenum filter, bool no_error) 64801e04c3fSmrg{ 64901e04c3fSmrg struct gl_framebuffer *readFb, *drawFb; 65001e04c3fSmrg 65101e04c3fSmrg /* 65201e04c3fSmrg * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014, 65301e04c3fSmrg * Section 18.3 Copying Pixels): 65401e04c3fSmrg * "... if readFramebuffer or drawFramebuffer is zero (for 65501e04c3fSmrg * BlitNamedFramebuffer), then the default read or draw framebuffer is 65601e04c3fSmrg * used as the corresponding source or destination framebuffer, 65701e04c3fSmrg * respectively." 65801e04c3fSmrg */ 65901e04c3fSmrg if (readFramebuffer) { 66001e04c3fSmrg if (no_error) { 66101e04c3fSmrg readFb = _mesa_lookup_framebuffer(ctx, readFramebuffer); 66201e04c3fSmrg } else { 66301e04c3fSmrg readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer, 66401e04c3fSmrg "glBlitNamedFramebuffer"); 66501e04c3fSmrg if (!readFb) 66601e04c3fSmrg return; 66701e04c3fSmrg } 66801e04c3fSmrg } else { 66901e04c3fSmrg readFb = ctx->WinSysReadBuffer; 67001e04c3fSmrg } 67101e04c3fSmrg 67201e04c3fSmrg if (drawFramebuffer) { 67301e04c3fSmrg if (no_error) { 67401e04c3fSmrg drawFb = _mesa_lookup_framebuffer(ctx, drawFramebuffer); 67501e04c3fSmrg } else { 67601e04c3fSmrg drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer, 67701e04c3fSmrg "glBlitNamedFramebuffer"); 67801e04c3fSmrg if (!drawFb) 67901e04c3fSmrg return; 68001e04c3fSmrg } 68101e04c3fSmrg } else { 68201e04c3fSmrg drawFb = ctx->WinSysDrawBuffer; 68301e04c3fSmrg } 68401e04c3fSmrg 68501e04c3fSmrg blit_framebuffer(ctx, readFb, drawFb, 68601e04c3fSmrg srcX0, srcY0, srcX1, srcY1, 68701e04c3fSmrg dstX0, dstY0, dstX1, dstY1, 68801e04c3fSmrg mask, filter, no_error, "glBlitNamedFramebuffer"); 68901e04c3fSmrg} 69001e04c3fSmrg 69101e04c3fSmrg 69201e04c3fSmrgvoid GLAPIENTRY 69301e04c3fSmrg_mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer, 69401e04c3fSmrg GLuint drawFramebuffer, 69501e04c3fSmrg GLint srcX0, GLint srcY0, 69601e04c3fSmrg GLint srcX1, GLint srcY1, 69701e04c3fSmrg GLint dstX0, GLint dstY0, 69801e04c3fSmrg GLint dstX1, GLint dstY1, 69901e04c3fSmrg GLbitfield mask, GLenum filter) 70001e04c3fSmrg{ 70101e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 70201e04c3fSmrg 70301e04c3fSmrg blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer, 70401e04c3fSmrg srcX0, srcY0, srcX1, srcY1, 70501e04c3fSmrg dstX0, dstY0, dstX1, dstY1, 70601e04c3fSmrg mask, filter, true); 70701e04c3fSmrg} 70801e04c3fSmrg 70901e04c3fSmrg 71001e04c3fSmrgvoid GLAPIENTRY 71101e04c3fSmrg_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, 71201e04c3fSmrg GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 71301e04c3fSmrg GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 71401e04c3fSmrg GLbitfield mask, GLenum filter) 71501e04c3fSmrg{ 71601e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 71701e04c3fSmrg 71801e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 71901e04c3fSmrg _mesa_debug(ctx, 72001e04c3fSmrg "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, " 72101e04c3fSmrg " %d, %d, %d, %d, 0x%x, %s)\n", 72201e04c3fSmrg readFramebuffer, drawFramebuffer, 72301e04c3fSmrg srcX0, srcY0, srcX1, srcY1, 72401e04c3fSmrg dstX0, dstY0, dstX1, dstY1, 72501e04c3fSmrg mask, _mesa_enum_to_string(filter)); 72601e04c3fSmrg 72701e04c3fSmrg blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer, 72801e04c3fSmrg srcX0, srcY0, srcX1, srcY1, 72901e04c3fSmrg dstX0, dstY0, dstX1, dstY1, 73001e04c3fSmrg mask, filter, false); 73101e04c3fSmrg} 732