1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker * Copyright (C) 1999-2013 VMware, Inc. All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker *
7*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
9*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
10*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
12*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
15*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
16*61046927SAndroid Build Coastguard Worker *
17*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
24*61046927SAndroid Build Coastguard Worker */
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker /*
27*61046927SAndroid Build Coastguard Worker * glBlitFramebuffer functions.
28*61046927SAndroid Build Coastguard Worker */
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
31*61046927SAndroid Build Coastguard Worker #include <stdio.h>
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker #include "context.h"
34*61046927SAndroid Build Coastguard Worker #include "enums.h"
35*61046927SAndroid Build Coastguard Worker #include "blit.h"
36*61046927SAndroid Build Coastguard Worker #include "fbobject.h"
37*61046927SAndroid Build Coastguard Worker #include "framebuffer.h"
38*61046927SAndroid Build Coastguard Worker #include "glformats.h"
39*61046927SAndroid Build Coastguard Worker #include "image.h"
40*61046927SAndroid Build Coastguard Worker #include "mtypes.h"
41*61046927SAndroid Build Coastguard Worker #include "macros.h"
42*61046927SAndroid Build Coastguard Worker #include "readpix.h"
43*61046927SAndroid Build Coastguard Worker #include "renderbuffer.h"
44*61046927SAndroid Build Coastguard Worker #include "state.h"
45*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
46*61046927SAndroid Build Coastguard Worker
47*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_bitmap.h"
48*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_texture.h"
49*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_manager.h"
50*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_context.h"
51*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_scissor.h"
52*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_texture.h"
53*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_util.h"
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker /** Set this to 1 to debug/log glBlitFramebuffer() calls */
56*61046927SAndroid Build Coastguard Worker #define DEBUG_BLIT 0
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker static const struct gl_renderbuffer_attachment *
find_attachment(const struct gl_framebuffer * fb,const struct gl_renderbuffer * rb)61*61046927SAndroid Build Coastguard Worker find_attachment(const struct gl_framebuffer *fb,
62*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer *rb)
63*61046927SAndroid Build Coastguard Worker {
64*61046927SAndroid Build Coastguard Worker GLuint i;
65*61046927SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) {
66*61046927SAndroid Build Coastguard Worker if (fb->Attachment[i].Renderbuffer == rb)
67*61046927SAndroid Build Coastguard Worker return &fb->Attachment[i];
68*61046927SAndroid Build Coastguard Worker }
69*61046927SAndroid Build Coastguard Worker return NULL;
70*61046927SAndroid Build Coastguard Worker }
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker /**
74*61046927SAndroid Build Coastguard Worker * \return true if two regions overlap, false otherwise
75*61046927SAndroid Build Coastguard Worker */
76*61046927SAndroid Build Coastguard Worker bool
_mesa_regions_overlap(int srcX0,int srcY0,int srcX1,int srcY1,int dstX0,int dstY0,int dstX1,int dstY1)77*61046927SAndroid Build Coastguard Worker _mesa_regions_overlap(int srcX0, int srcY0,
78*61046927SAndroid Build Coastguard Worker int srcX1, int srcY1,
79*61046927SAndroid Build Coastguard Worker int dstX0, int dstY0,
80*61046927SAndroid Build Coastguard Worker int dstX1, int dstY1)
81*61046927SAndroid Build Coastguard Worker {
82*61046927SAndroid Build Coastguard Worker if (MAX2(srcX0, srcX1) <= MIN2(dstX0, dstX1))
83*61046927SAndroid Build Coastguard Worker return false; /* dst completely right of src */
84*61046927SAndroid Build Coastguard Worker
85*61046927SAndroid Build Coastguard Worker if (MAX2(dstX0, dstX1) <= MIN2(srcX0, srcX1))
86*61046927SAndroid Build Coastguard Worker return false; /* dst completely left of src */
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker if (MAX2(srcY0, srcY1) <= MIN2(dstY0, dstY1))
89*61046927SAndroid Build Coastguard Worker return false; /* dst completely above src */
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker if (MAX2(dstY0, dstY1) <= MIN2(srcY0, srcY1))
92*61046927SAndroid Build Coastguard Worker return false; /* dst completely below src */
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker return true; /* some overlap */
95*61046927SAndroid Build Coastguard Worker }
96*61046927SAndroid Build Coastguard Worker
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker /**
99*61046927SAndroid Build Coastguard Worker * Helper function for checking if the datatypes of color buffers are
100*61046927SAndroid Build Coastguard Worker * compatible for glBlitFramebuffer. From the 3.1 spec, page 198:
101*61046927SAndroid Build Coastguard Worker *
102*61046927SAndroid Build Coastguard Worker * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
103*61046927SAndroid Build Coastguard Worker * and any of the following conditions hold:
104*61046927SAndroid Build Coastguard Worker * - The read buffer contains fixed-point or floating-point values and any
105*61046927SAndroid Build Coastguard Worker * draw buffer contains neither fixed-point nor floating-point values.
106*61046927SAndroid Build Coastguard Worker * - The read buffer contains unsigned integer values and any draw buffer
107*61046927SAndroid Build Coastguard Worker * does not contain unsigned integer values.
108*61046927SAndroid Build Coastguard Worker * - The read buffer contains signed integer values and any draw buffer
109*61046927SAndroid Build Coastguard Worker * does not contain signed integer values."
110*61046927SAndroid Build Coastguard Worker */
111*61046927SAndroid Build Coastguard Worker static GLboolean
compatible_color_datatypes(mesa_format srcFormat,mesa_format dstFormat)112*61046927SAndroid Build Coastguard Worker compatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat)
113*61046927SAndroid Build Coastguard Worker {
114*61046927SAndroid Build Coastguard Worker GLenum srcType = _mesa_get_format_datatype(srcFormat);
115*61046927SAndroid Build Coastguard Worker GLenum dstType = _mesa_get_format_datatype(dstFormat);
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
118*61046927SAndroid Build Coastguard Worker assert(srcType == GL_UNSIGNED_NORMALIZED ||
119*61046927SAndroid Build Coastguard Worker srcType == GL_SIGNED_NORMALIZED ||
120*61046927SAndroid Build Coastguard Worker srcType == GL_FLOAT);
121*61046927SAndroid Build Coastguard Worker /* Boil any of those types down to GL_FLOAT */
122*61046927SAndroid Build Coastguard Worker srcType = GL_FLOAT;
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
126*61046927SAndroid Build Coastguard Worker assert(dstType == GL_UNSIGNED_NORMALIZED ||
127*61046927SAndroid Build Coastguard Worker dstType == GL_SIGNED_NORMALIZED ||
128*61046927SAndroid Build Coastguard Worker dstType == GL_FLOAT);
129*61046927SAndroid Build Coastguard Worker /* Boil any of those types down to GL_FLOAT */
130*61046927SAndroid Build Coastguard Worker dstType = GL_FLOAT;
131*61046927SAndroid Build Coastguard Worker }
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker return srcType == dstType;
134*61046927SAndroid Build Coastguard Worker }
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker static GLboolean
compatible_resolve_formats(const struct gl_renderbuffer * readRb,const struct gl_renderbuffer * drawRb)138*61046927SAndroid Build Coastguard Worker compatible_resolve_formats(const struct gl_renderbuffer *readRb,
139*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer *drawRb)
140*61046927SAndroid Build Coastguard Worker {
141*61046927SAndroid Build Coastguard Worker GLenum readFormat, drawFormat;
142*61046927SAndroid Build Coastguard Worker
143*61046927SAndroid Build Coastguard Worker /* This checks whether the internal formats are compatible rather than the
144*61046927SAndroid Build Coastguard Worker * Mesa format for two reasons:
145*61046927SAndroid Build Coastguard Worker *
146*61046927SAndroid Build Coastguard Worker * • Under some circumstances, the user may request e.g. two GL_RGBA8
147*61046927SAndroid Build Coastguard Worker * textures and get two entirely different Mesa formats like RGBA8888 and
148*61046927SAndroid Build Coastguard Worker * ARGB8888. Drivers behaving like that should be able to cope with
149*61046927SAndroid Build Coastguard Worker * non-matching formats by themselves, because it's not the user's fault.
150*61046927SAndroid Build Coastguard Worker *
151*61046927SAndroid Build Coastguard Worker * • Picking two different internal formats can end up with the same Mesa
152*61046927SAndroid Build Coastguard Worker * format. For example the driver might be simulating GL_RGB textures
153*61046927SAndroid Build Coastguard Worker * with GL_RGBA internally and in that case both internal formats would
154*61046927SAndroid Build Coastguard Worker * end up with RGBA8888.
155*61046927SAndroid Build Coastguard Worker *
156*61046927SAndroid Build Coastguard Worker * This function is used to generate a GL error according to the spec so in
157*61046927SAndroid Build Coastguard Worker * both cases we want to be looking at the application-level format, which
158*61046927SAndroid Build Coastguard Worker * is InternalFormat.
159*61046927SAndroid Build Coastguard Worker *
160*61046927SAndroid Build Coastguard Worker * Blits between linear and sRGB formats are also allowed.
161*61046927SAndroid Build Coastguard Worker */
162*61046927SAndroid Build Coastguard Worker readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat);
163*61046927SAndroid Build Coastguard Worker drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat);
164*61046927SAndroid Build Coastguard Worker readFormat = _mesa_get_linear_internalformat(readFormat);
165*61046927SAndroid Build Coastguard Worker drawFormat = _mesa_get_linear_internalformat(drawFormat);
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker if (readFormat == drawFormat) {
168*61046927SAndroid Build Coastguard Worker return GL_TRUE;
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker return GL_FALSE;
172*61046927SAndroid Build Coastguard Worker }
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker
175*61046927SAndroid Build Coastguard Worker static GLboolean
is_valid_blit_filter(const struct gl_context * ctx,GLenum filter)176*61046927SAndroid Build Coastguard Worker is_valid_blit_filter(const struct gl_context *ctx, GLenum filter)
177*61046927SAndroid Build Coastguard Worker {
178*61046927SAndroid Build Coastguard Worker switch (filter) {
179*61046927SAndroid Build Coastguard Worker case GL_NEAREST:
180*61046927SAndroid Build Coastguard Worker case GL_LINEAR:
181*61046927SAndroid Build Coastguard Worker return true;
182*61046927SAndroid Build Coastguard Worker case GL_SCALED_RESOLVE_FASTEST_EXT:
183*61046927SAndroid Build Coastguard Worker case GL_SCALED_RESOLVE_NICEST_EXT:
184*61046927SAndroid Build Coastguard Worker return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled;
185*61046927SAndroid Build Coastguard Worker default:
186*61046927SAndroid Build Coastguard Worker return false;
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker }
189*61046927SAndroid Build Coastguard Worker
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker static bool
validate_color_buffer(struct gl_context * ctx,struct gl_framebuffer * readFb,struct gl_framebuffer * drawFb,GLenum filter,const char * func)192*61046927SAndroid Build Coastguard Worker validate_color_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
193*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *drawFb, GLenum filter,
194*61046927SAndroid Build Coastguard Worker const char *func)
195*61046927SAndroid Build Coastguard Worker {
196*61046927SAndroid Build Coastguard Worker const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
197*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
198*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer *colorDrawRb = NULL;
199*61046927SAndroid Build Coastguard Worker GLuint i;
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker for (i = 0; i < numColorDrawBuffers; i++) {
202*61046927SAndroid Build Coastguard Worker colorDrawRb = drawFb->_ColorDrawBuffers[i];
203*61046927SAndroid Build Coastguard Worker if (!colorDrawRb)
204*61046927SAndroid Build Coastguard Worker continue;
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
207*61046927SAndroid Build Coastguard Worker * ES 3.0.1 spec says:
208*61046927SAndroid Build Coastguard Worker *
209*61046927SAndroid Build Coastguard Worker * "If the source and destination buffers are identical, an
210*61046927SAndroid Build Coastguard Worker * INVALID_OPERATION error is generated. Different mipmap levels of a
211*61046927SAndroid Build Coastguard Worker * texture, different layers of a three- dimensional texture or
212*61046927SAndroid Build Coastguard Worker * two-dimensional array texture, and different faces of a cube map
213*61046927SAndroid Build Coastguard Worker * texture do not constitute identical buffers."
214*61046927SAndroid Build Coastguard Worker */
215*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
216*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
217*61046927SAndroid Build Coastguard Worker "%s(source and destination color buffer cannot be the "
218*61046927SAndroid Build Coastguard Worker "same)", func);
219*61046927SAndroid Build Coastguard Worker return false;
220*61046927SAndroid Build Coastguard Worker }
221*61046927SAndroid Build Coastguard Worker
222*61046927SAndroid Build Coastguard Worker if (!compatible_color_datatypes(colorReadRb->Format,
223*61046927SAndroid Build Coastguard Worker colorDrawRb->Format)) {
224*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
225*61046927SAndroid Build Coastguard Worker "%s(color buffer datatypes mismatch)", func);
226*61046927SAndroid Build Coastguard Worker return false;
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker /* extra checks for multisample copies... */
230*61046927SAndroid Build Coastguard Worker if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
231*61046927SAndroid Build Coastguard Worker /* color formats must match on GLES. This isn't checked on desktop GL
232*61046927SAndroid Build Coastguard Worker * because the GL 4.4 spec was changed to allow it. In the section
233*61046927SAndroid Build Coastguard Worker * entitled “Changes in the released
234*61046927SAndroid Build Coastguard Worker * Specification of July 22, 2013” it says:
235*61046927SAndroid Build Coastguard Worker *
236*61046927SAndroid Build Coastguard Worker * “Relax BlitFramebuffer in section 18.3.1 so that format conversion
237*61046927SAndroid Build Coastguard Worker * can take place during multisample blits, since drivers already
238*61046927SAndroid Build Coastguard Worker * allow this and some apps depend on it.”
239*61046927SAndroid Build Coastguard Worker */
240*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles(ctx) &&
241*61046927SAndroid Build Coastguard Worker !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
242*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
243*61046927SAndroid Build Coastguard Worker "%s(bad src/dst multisample pixel formats)", func);
244*61046927SAndroid Build Coastguard Worker return false;
245*61046927SAndroid Build Coastguard Worker }
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker }
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker if (filter != GL_NEAREST) {
251*61046927SAndroid Build Coastguard Worker /* From EXT_framebuffer_multisample_blit_scaled specification:
252*61046927SAndroid Build Coastguard Worker * "Calling BlitFramebuffer will result in an INVALID_OPERATION error if
253*61046927SAndroid Build Coastguard Worker * filter is not NEAREST and read buffer contains integer data."
254*61046927SAndroid Build Coastguard Worker */
255*61046927SAndroid Build Coastguard Worker GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
256*61046927SAndroid Build Coastguard Worker if (type == GL_INT || type == GL_UNSIGNED_INT) {
257*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
258*61046927SAndroid Build Coastguard Worker "%s(integer color type)", func);
259*61046927SAndroid Build Coastguard Worker return false;
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker }
262*61046927SAndroid Build Coastguard Worker return true;
263*61046927SAndroid Build Coastguard Worker }
264*61046927SAndroid Build Coastguard Worker
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker static bool
validate_stencil_buffer(struct gl_context * ctx,struct gl_framebuffer * readFb,struct gl_framebuffer * drawFb,const char * func)267*61046927SAndroid Build Coastguard Worker validate_stencil_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
268*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *drawFb, const char *func)
269*61046927SAndroid Build Coastguard Worker {
270*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *readRb =
271*61046927SAndroid Build Coastguard Worker readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
272*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *drawRb =
273*61046927SAndroid Build Coastguard Worker drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
274*61046927SAndroid Build Coastguard Worker int read_z_bits, draw_z_bits;
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
277*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
278*61046927SAndroid Build Coastguard Worker "%s(source and destination stencil buffer cannot be the "
279*61046927SAndroid Build Coastguard Worker "same)", func);
280*61046927SAndroid Build Coastguard Worker return false;
281*61046927SAndroid Build Coastguard Worker }
282*61046927SAndroid Build Coastguard Worker
283*61046927SAndroid Build Coastguard Worker if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
284*61046927SAndroid Build Coastguard Worker _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
285*61046927SAndroid Build Coastguard Worker /* There is no need to check the stencil datatype here, because
286*61046927SAndroid Build Coastguard Worker * there is only one: GL_UNSIGNED_INT.
287*61046927SAndroid Build Coastguard Worker */
288*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
289*61046927SAndroid Build Coastguard Worker "%s(stencil attachment format mismatch)", func);
290*61046927SAndroid Build Coastguard Worker return false;
291*61046927SAndroid Build Coastguard Worker }
292*61046927SAndroid Build Coastguard Worker
293*61046927SAndroid Build Coastguard Worker read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
294*61046927SAndroid Build Coastguard Worker draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker /* If both buffers also have depth data, the depth formats must match
297*61046927SAndroid Build Coastguard Worker * as well. If one doesn't have depth, it's not blitted, so we should
298*61046927SAndroid Build Coastguard Worker * ignore the depth format check.
299*61046927SAndroid Build Coastguard Worker */
300*61046927SAndroid Build Coastguard Worker if (read_z_bits > 0 && draw_z_bits > 0 &&
301*61046927SAndroid Build Coastguard Worker (read_z_bits != draw_z_bits ||
302*61046927SAndroid Build Coastguard Worker _mesa_get_format_datatype(readRb->Format) !=
303*61046927SAndroid Build Coastguard Worker _mesa_get_format_datatype(drawRb->Format))) {
304*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
305*61046927SAndroid Build Coastguard Worker "%s(stencil attachment depth format mismatch)", func);
306*61046927SAndroid Build Coastguard Worker return false;
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker return true;
309*61046927SAndroid Build Coastguard Worker }
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker
312*61046927SAndroid Build Coastguard Worker static bool
validate_depth_buffer(struct gl_context * ctx,struct gl_framebuffer * readFb,struct gl_framebuffer * drawFb,const char * func)313*61046927SAndroid Build Coastguard Worker validate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
314*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *drawFb, const char *func)
315*61046927SAndroid Build Coastguard Worker {
316*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *readRb =
317*61046927SAndroid Build Coastguard Worker readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
318*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *drawRb =
319*61046927SAndroid Build Coastguard Worker drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
320*61046927SAndroid Build Coastguard Worker int read_s_bit, draw_s_bit;
321*61046927SAndroid Build Coastguard Worker
322*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
323*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
324*61046927SAndroid Build Coastguard Worker "%s(source and destination depth buffer cannot be the same)",
325*61046927SAndroid Build Coastguard Worker func);
326*61046927SAndroid Build Coastguard Worker return false;
327*61046927SAndroid Build Coastguard Worker }
328*61046927SAndroid Build Coastguard Worker
329*61046927SAndroid Build Coastguard Worker if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
330*61046927SAndroid Build Coastguard Worker _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
331*61046927SAndroid Build Coastguard Worker (_mesa_get_format_datatype(readRb->Format) !=
332*61046927SAndroid Build Coastguard Worker _mesa_get_format_datatype(drawRb->Format))) {
333*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
334*61046927SAndroid Build Coastguard Worker "%s(depth attachment format mismatch)", func);
335*61046927SAndroid Build Coastguard Worker return false;
336*61046927SAndroid Build Coastguard Worker }
337*61046927SAndroid Build Coastguard Worker
338*61046927SAndroid Build Coastguard Worker read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
339*61046927SAndroid Build Coastguard Worker draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
340*61046927SAndroid Build Coastguard Worker
341*61046927SAndroid Build Coastguard Worker /* If both buffers also have stencil data, the stencil formats must match as
342*61046927SAndroid Build Coastguard Worker * well. If one doesn't have stencil, it's not blitted, so we should ignore
343*61046927SAndroid Build Coastguard Worker * the stencil format check.
344*61046927SAndroid Build Coastguard Worker */
345*61046927SAndroid Build Coastguard Worker if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
346*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
347*61046927SAndroid Build Coastguard Worker "%s(depth attachment stencil bits mismatch)", func);
348*61046927SAndroid Build Coastguard Worker return false;
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker return true;
351*61046927SAndroid Build Coastguard Worker }
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker
354*61046927SAndroid Build Coastguard Worker static void
do_blit_framebuffer(struct gl_context * ctx,struct gl_framebuffer * readFB,struct gl_framebuffer * drawFB,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)355*61046927SAndroid Build Coastguard Worker do_blit_framebuffer(struct gl_context *ctx,
356*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *readFB,
357*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *drawFB,
358*61046927SAndroid Build Coastguard Worker GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
359*61046927SAndroid Build Coastguard Worker GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
360*61046927SAndroid Build Coastguard Worker GLbitfield mask, GLenum filter)
361*61046927SAndroid Build Coastguard Worker {
362*61046927SAndroid Build Coastguard Worker struct st_context *st = st_context(ctx);
363*61046927SAndroid Build Coastguard Worker const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT |
364*61046927SAndroid Build Coastguard Worker GL_STENCIL_BUFFER_BIT);
365*61046927SAndroid Build Coastguard Worker const uint pFilter = ((filter == GL_NEAREST)
366*61046927SAndroid Build Coastguard Worker ? PIPE_TEX_FILTER_NEAREST
367*61046927SAndroid Build Coastguard Worker : PIPE_TEX_FILTER_LINEAR);
368*61046927SAndroid Build Coastguard Worker struct {
369*61046927SAndroid Build Coastguard Worker GLint srcX0, srcY0, srcX1, srcY1;
370*61046927SAndroid Build Coastguard Worker GLint dstX0, dstY0, dstX1, dstY1;
371*61046927SAndroid Build Coastguard Worker } clip;
372*61046927SAndroid Build Coastguard Worker struct pipe_blit_info blit;
373*61046927SAndroid Build Coastguard Worker
374*61046927SAndroid Build Coastguard Worker st_manager_validate_framebuffers(st);
375*61046927SAndroid Build Coastguard Worker
376*61046927SAndroid Build Coastguard Worker /* Make sure bitmap rendering has landed in the framebuffers */
377*61046927SAndroid Build Coastguard Worker st_flush_bitmap_cache(st);
378*61046927SAndroid Build Coastguard Worker st_invalidate_readpix_cache(st);
379*61046927SAndroid Build Coastguard Worker
380*61046927SAndroid Build Coastguard Worker clip.srcX0 = srcX0;
381*61046927SAndroid Build Coastguard Worker clip.srcY0 = srcY0;
382*61046927SAndroid Build Coastguard Worker clip.srcX1 = srcX1;
383*61046927SAndroid Build Coastguard Worker clip.srcY1 = srcY1;
384*61046927SAndroid Build Coastguard Worker clip.dstX0 = dstX0;
385*61046927SAndroid Build Coastguard Worker clip.dstY0 = dstY0;
386*61046927SAndroid Build Coastguard Worker clip.dstX1 = dstX1;
387*61046927SAndroid Build Coastguard Worker clip.dstY1 = dstY1;
388*61046927SAndroid Build Coastguard Worker
389*61046927SAndroid Build Coastguard Worker /* NOTE: If the src and dst dimensions don't match, we cannot simply adjust
390*61046927SAndroid Build Coastguard Worker * the integer coordinates to account for clipping (or scissors) because that
391*61046927SAndroid Build Coastguard Worker * would make us cut off fractional parts, affecting the result of the blit.
392*61046927SAndroid Build Coastguard Worker *
393*61046927SAndroid Build Coastguard Worker * XXX: This should depend on mask !
394*61046927SAndroid Build Coastguard Worker */
395*61046927SAndroid Build Coastguard Worker if (!_mesa_clip_blit(ctx, readFB, drawFB,
396*61046927SAndroid Build Coastguard Worker &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1,
397*61046927SAndroid Build Coastguard Worker &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) {
398*61046927SAndroid Build Coastguard Worker return; /* nothing to draw/blit */
399*61046927SAndroid Build Coastguard Worker }
400*61046927SAndroid Build Coastguard Worker memset(&blit, 0, sizeof(struct pipe_blit_info));
401*61046927SAndroid Build Coastguard Worker blit.scissor_enable =
402*61046927SAndroid Build Coastguard Worker (dstX0 != clip.dstX0) ||
403*61046927SAndroid Build Coastguard Worker (dstY0 != clip.dstY0) ||
404*61046927SAndroid Build Coastguard Worker (dstX1 != clip.dstX1) ||
405*61046927SAndroid Build Coastguard Worker (dstY1 != clip.dstY1);
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker if (_mesa_fb_orientation(drawFB) == Y_0_TOP) {
408*61046927SAndroid Build Coastguard Worker /* invert Y for dest */
409*61046927SAndroid Build Coastguard Worker dstY0 = drawFB->Height - dstY0;
410*61046927SAndroid Build Coastguard Worker dstY1 = drawFB->Height - dstY1;
411*61046927SAndroid Build Coastguard Worker /* invert Y for clip */
412*61046927SAndroid Build Coastguard Worker clip.dstY0 = drawFB->Height - clip.dstY0;
413*61046927SAndroid Build Coastguard Worker clip.dstY1 = drawFB->Height - clip.dstY1;
414*61046927SAndroid Build Coastguard Worker }
415*61046927SAndroid Build Coastguard Worker if (blit.scissor_enable) {
416*61046927SAndroid Build Coastguard Worker blit.scissor.minx = MIN2(clip.dstX0, clip.dstX1);
417*61046927SAndroid Build Coastguard Worker blit.scissor.miny = MIN2(clip.dstY0, clip.dstY1);
418*61046927SAndroid Build Coastguard Worker blit.scissor.maxx = MAX2(clip.dstX0, clip.dstX1);
419*61046927SAndroid Build Coastguard Worker blit.scissor.maxy = MAX2(clip.dstY0, clip.dstY1);
420*61046927SAndroid Build Coastguard Worker #if 0
421*61046927SAndroid Build Coastguard Worker debug_printf("scissor = (%i,%i)-(%i,%i)\n",
422*61046927SAndroid Build Coastguard Worker blit.scissor.minx,blit.scissor.miny,
423*61046927SAndroid Build Coastguard Worker blit.scissor.maxx,blit.scissor.maxy);
424*61046927SAndroid Build Coastguard Worker #endif
425*61046927SAndroid Build Coastguard Worker }
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker if (_mesa_fb_orientation(readFB) == Y_0_TOP) {
428*61046927SAndroid Build Coastguard Worker /* invert Y for src */
429*61046927SAndroid Build Coastguard Worker srcY0 = readFB->Height - srcY0;
430*61046927SAndroid Build Coastguard Worker srcY1 = readFB->Height - srcY1;
431*61046927SAndroid Build Coastguard Worker }
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker if (srcY0 > srcY1 && dstY0 > dstY1) {
434*61046927SAndroid Build Coastguard Worker /* Both src and dst are upside down. Swap Y to make it
435*61046927SAndroid Build Coastguard Worker * right-side up to increase odds of using a fast path.
436*61046927SAndroid Build Coastguard Worker * Recall that all Gallium raster coords have Y=0=top.
437*61046927SAndroid Build Coastguard Worker */
438*61046927SAndroid Build Coastguard Worker GLint tmp;
439*61046927SAndroid Build Coastguard Worker tmp = srcY0;
440*61046927SAndroid Build Coastguard Worker srcY0 = srcY1;
441*61046927SAndroid Build Coastguard Worker srcY1 = tmp;
442*61046927SAndroid Build Coastguard Worker tmp = dstY0;
443*61046927SAndroid Build Coastguard Worker dstY0 = dstY1;
444*61046927SAndroid Build Coastguard Worker dstY1 = tmp;
445*61046927SAndroid Build Coastguard Worker }
446*61046927SAndroid Build Coastguard Worker
447*61046927SAndroid Build Coastguard Worker blit.src.box.depth = 1;
448*61046927SAndroid Build Coastguard Worker blit.dst.box.depth = 1;
449*61046927SAndroid Build Coastguard Worker
450*61046927SAndroid Build Coastguard Worker /* Destination dimensions have to be positive: */
451*61046927SAndroid Build Coastguard Worker if (dstX0 < dstX1) {
452*61046927SAndroid Build Coastguard Worker blit.dst.box.x = dstX0;
453*61046927SAndroid Build Coastguard Worker blit.src.box.x = srcX0;
454*61046927SAndroid Build Coastguard Worker blit.dst.box.width = dstX1 - dstX0;
455*61046927SAndroid Build Coastguard Worker blit.src.box.width = srcX1 - srcX0;
456*61046927SAndroid Build Coastguard Worker } else {
457*61046927SAndroid Build Coastguard Worker blit.dst.box.x = dstX1;
458*61046927SAndroid Build Coastguard Worker blit.src.box.x = srcX1;
459*61046927SAndroid Build Coastguard Worker blit.dst.box.width = dstX0 - dstX1;
460*61046927SAndroid Build Coastguard Worker blit.src.box.width = srcX0 - srcX1;
461*61046927SAndroid Build Coastguard Worker }
462*61046927SAndroid Build Coastguard Worker if (dstY0 < dstY1) {
463*61046927SAndroid Build Coastguard Worker blit.dst.box.y = dstY0;
464*61046927SAndroid Build Coastguard Worker blit.src.box.y = srcY0;
465*61046927SAndroid Build Coastguard Worker blit.dst.box.height = dstY1 - dstY0;
466*61046927SAndroid Build Coastguard Worker blit.src.box.height = srcY1 - srcY0;
467*61046927SAndroid Build Coastguard Worker } else {
468*61046927SAndroid Build Coastguard Worker blit.dst.box.y = dstY1;
469*61046927SAndroid Build Coastguard Worker blit.src.box.y = srcY1;
470*61046927SAndroid Build Coastguard Worker blit.dst.box.height = dstY0 - dstY1;
471*61046927SAndroid Build Coastguard Worker blit.src.box.height = srcY0 - srcY1;
472*61046927SAndroid Build Coastguard Worker }
473*61046927SAndroid Build Coastguard Worker
474*61046927SAndroid Build Coastguard Worker if (drawFB != ctx->WinSysDrawBuffer)
475*61046927SAndroid Build Coastguard Worker st_window_rectangles_to_blit(ctx, &blit);
476*61046927SAndroid Build Coastguard Worker
477*61046927SAndroid Build Coastguard Worker blit.filter = pFilter;
478*61046927SAndroid Build Coastguard Worker blit.render_condition_enable = st->has_conditional_render;
479*61046927SAndroid Build Coastguard Worker blit.alpha_blend = false;
480*61046927SAndroid Build Coastguard Worker
481*61046927SAndroid Build Coastguard Worker if (mask & GL_COLOR_BUFFER_BIT) {
482*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *srcAtt =
483*61046927SAndroid Build Coastguard Worker &readFB->Attachment[readFB->_ColorReadBufferIndex];
484*61046927SAndroid Build Coastguard Worker GLuint i;
485*61046927SAndroid Build Coastguard Worker
486*61046927SAndroid Build Coastguard Worker blit.mask = PIPE_MASK_RGBA;
487*61046927SAndroid Build Coastguard Worker
488*61046927SAndroid Build Coastguard Worker if (srcAtt->Type == GL_TEXTURE) {
489*61046927SAndroid Build Coastguard Worker /* Make sure that the st_texture_object->pt is the current storage for
490*61046927SAndroid Build Coastguard Worker * our miplevel. The finalize would happen at some point anyway, might
491*61046927SAndroid Build Coastguard Worker * as well be now.
492*61046927SAndroid Build Coastguard Worker */
493*61046927SAndroid Build Coastguard Worker st_finalize_texture(ctx, ctx->pipe, srcAtt->Texture, srcAtt->CubeMapFace);
494*61046927SAndroid Build Coastguard Worker
495*61046927SAndroid Build Coastguard Worker struct gl_texture_object *srcObj = srcAtt->Texture;
496*61046927SAndroid Build Coastguard Worker
497*61046927SAndroid Build Coastguard Worker if (!srcObj || !srcObj->pt) {
498*61046927SAndroid Build Coastguard Worker return;
499*61046927SAndroid Build Coastguard Worker }
500*61046927SAndroid Build Coastguard Worker
501*61046927SAndroid Build Coastguard Worker blit.src.resource = srcObj->pt;
502*61046927SAndroid Build Coastguard Worker blit.src.level = srcAtt->TextureLevel;
503*61046927SAndroid Build Coastguard Worker blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace;
504*61046927SAndroid Build Coastguard Worker blit.src.format = srcObj->surface_based ? srcObj->surface_format : srcObj->pt->format;
505*61046927SAndroid Build Coastguard Worker
506*61046927SAndroid Build Coastguard Worker if (!ctx->Color.sRGBEnabled)
507*61046927SAndroid Build Coastguard Worker blit.src.format = util_format_linear(blit.src.format);
508*61046927SAndroid Build Coastguard Worker }
509*61046927SAndroid Build Coastguard Worker else {
510*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *srcRb = readFB->_ColorReadBuffer;
511*61046927SAndroid Build Coastguard Worker struct pipe_surface *srcSurf;
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker if (!srcRb)
514*61046927SAndroid Build Coastguard Worker return;
515*61046927SAndroid Build Coastguard Worker
516*61046927SAndroid Build Coastguard Worker _mesa_update_renderbuffer_surface(ctx, srcRb);
517*61046927SAndroid Build Coastguard Worker
518*61046927SAndroid Build Coastguard Worker if (!srcRb->surface)
519*61046927SAndroid Build Coastguard Worker return;
520*61046927SAndroid Build Coastguard Worker
521*61046927SAndroid Build Coastguard Worker srcSurf = srcRb->surface;
522*61046927SAndroid Build Coastguard Worker
523*61046927SAndroid Build Coastguard Worker blit.src.resource = srcSurf->texture;
524*61046927SAndroid Build Coastguard Worker blit.src.level = srcSurf->u.tex.level;
525*61046927SAndroid Build Coastguard Worker blit.src.box.z = srcSurf->u.tex.first_layer;
526*61046927SAndroid Build Coastguard Worker blit.src.format = srcSurf->format;
527*61046927SAndroid Build Coastguard Worker }
528*61046927SAndroid Build Coastguard Worker
529*61046927SAndroid Build Coastguard Worker for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) {
530*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *dstRb = drawFB->_ColorDrawBuffers[i];
531*61046927SAndroid Build Coastguard Worker
532*61046927SAndroid Build Coastguard Worker if (dstRb) {
533*61046927SAndroid Build Coastguard Worker struct pipe_surface *dstSurf;
534*61046927SAndroid Build Coastguard Worker
535*61046927SAndroid Build Coastguard Worker _mesa_update_renderbuffer_surface(ctx, dstRb);
536*61046927SAndroid Build Coastguard Worker
537*61046927SAndroid Build Coastguard Worker dstSurf = dstRb->surface;
538*61046927SAndroid Build Coastguard Worker
539*61046927SAndroid Build Coastguard Worker if (dstSurf) {
540*61046927SAndroid Build Coastguard Worker blit.dst.resource = dstSurf->texture;
541*61046927SAndroid Build Coastguard Worker blit.dst.level = dstSurf->u.tex.level;
542*61046927SAndroid Build Coastguard Worker blit.dst.box.z = dstSurf->u.tex.first_layer;
543*61046927SAndroid Build Coastguard Worker blit.dst.format = dstSurf->format;
544*61046927SAndroid Build Coastguard Worker
545*61046927SAndroid Build Coastguard Worker ctx->pipe->blit(ctx->pipe, &blit);
546*61046927SAndroid Build Coastguard Worker dstRb->defined = true; /* front buffer tracking */
547*61046927SAndroid Build Coastguard Worker }
548*61046927SAndroid Build Coastguard Worker }
549*61046927SAndroid Build Coastguard Worker }
550*61046927SAndroid Build Coastguard Worker }
551*61046927SAndroid Build Coastguard Worker
552*61046927SAndroid Build Coastguard Worker if (mask & depthStencil) {
553*61046927SAndroid Build Coastguard Worker /* depth and/or stencil blit */
554*61046927SAndroid Build Coastguard Worker
555*61046927SAndroid Build Coastguard Worker /* get src/dst depth surfaces */
556*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *srcDepthRb =
557*61046927SAndroid Build Coastguard Worker readFB->Attachment[BUFFER_DEPTH].Renderbuffer;
558*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *dstDepthRb =
559*61046927SAndroid Build Coastguard Worker drawFB->Attachment[BUFFER_DEPTH].Renderbuffer;
560*61046927SAndroid Build Coastguard Worker struct pipe_surface *dstDepthSurf =
561*61046927SAndroid Build Coastguard Worker dstDepthRb ? dstDepthRb->surface : NULL;
562*61046927SAndroid Build Coastguard Worker
563*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *srcStencilRb =
564*61046927SAndroid Build Coastguard Worker readFB->Attachment[BUFFER_STENCIL].Renderbuffer;
565*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *dstStencilRb =
566*61046927SAndroid Build Coastguard Worker drawFB->Attachment[BUFFER_STENCIL].Renderbuffer;
567*61046927SAndroid Build Coastguard Worker struct pipe_surface *dstStencilSurf =
568*61046927SAndroid Build Coastguard Worker dstStencilRb ? dstStencilRb->surface : NULL;
569*61046927SAndroid Build Coastguard Worker
570*61046927SAndroid Build Coastguard Worker if (_mesa_has_depthstencil_combined(readFB) &&
571*61046927SAndroid Build Coastguard Worker _mesa_has_depthstencil_combined(drawFB)) {
572*61046927SAndroid Build Coastguard Worker blit.mask = 0;
573*61046927SAndroid Build Coastguard Worker if (mask & GL_DEPTH_BUFFER_BIT)
574*61046927SAndroid Build Coastguard Worker blit.mask |= PIPE_MASK_Z;
575*61046927SAndroid Build Coastguard Worker if (mask & GL_STENCIL_BUFFER_BIT)
576*61046927SAndroid Build Coastguard Worker blit.mask |= PIPE_MASK_S;
577*61046927SAndroid Build Coastguard Worker
578*61046927SAndroid Build Coastguard Worker blit.dst.resource = dstDepthSurf->texture;
579*61046927SAndroid Build Coastguard Worker blit.dst.level = dstDepthSurf->u.tex.level;
580*61046927SAndroid Build Coastguard Worker blit.dst.box.z = dstDepthSurf->u.tex.first_layer;
581*61046927SAndroid Build Coastguard Worker blit.dst.format = dstDepthSurf->format;
582*61046927SAndroid Build Coastguard Worker
583*61046927SAndroid Build Coastguard Worker blit.src.resource = srcDepthRb->texture;
584*61046927SAndroid Build Coastguard Worker blit.src.level = srcDepthRb->surface->u.tex.level;
585*61046927SAndroid Build Coastguard Worker blit.src.box.z = srcDepthRb->surface->u.tex.first_layer;
586*61046927SAndroid Build Coastguard Worker blit.src.format = srcDepthRb->surface->format;
587*61046927SAndroid Build Coastguard Worker
588*61046927SAndroid Build Coastguard Worker ctx->pipe->blit(ctx->pipe, &blit);
589*61046927SAndroid Build Coastguard Worker }
590*61046927SAndroid Build Coastguard Worker else {
591*61046927SAndroid Build Coastguard Worker /* blitting depth and stencil separately */
592*61046927SAndroid Build Coastguard Worker
593*61046927SAndroid Build Coastguard Worker if (mask & GL_DEPTH_BUFFER_BIT) {
594*61046927SAndroid Build Coastguard Worker blit.mask = PIPE_MASK_Z;
595*61046927SAndroid Build Coastguard Worker
596*61046927SAndroid Build Coastguard Worker blit.dst.resource = dstDepthSurf->texture;
597*61046927SAndroid Build Coastguard Worker blit.dst.level = dstDepthSurf->u.tex.level;
598*61046927SAndroid Build Coastguard Worker blit.dst.box.z = dstDepthSurf->u.tex.first_layer;
599*61046927SAndroid Build Coastguard Worker blit.dst.format = dstDepthSurf->format;
600*61046927SAndroid Build Coastguard Worker
601*61046927SAndroid Build Coastguard Worker blit.src.resource = srcDepthRb->texture;
602*61046927SAndroid Build Coastguard Worker blit.src.level = srcDepthRb->surface->u.tex.level;
603*61046927SAndroid Build Coastguard Worker blit.src.box.z = srcDepthRb->surface->u.tex.first_layer;
604*61046927SAndroid Build Coastguard Worker blit.src.format = srcDepthRb->surface->format;
605*61046927SAndroid Build Coastguard Worker
606*61046927SAndroid Build Coastguard Worker ctx->pipe->blit(ctx->pipe, &blit);
607*61046927SAndroid Build Coastguard Worker }
608*61046927SAndroid Build Coastguard Worker
609*61046927SAndroid Build Coastguard Worker if (mask & GL_STENCIL_BUFFER_BIT) {
610*61046927SAndroid Build Coastguard Worker blit.mask = PIPE_MASK_S;
611*61046927SAndroid Build Coastguard Worker
612*61046927SAndroid Build Coastguard Worker blit.dst.resource = dstStencilSurf->texture;
613*61046927SAndroid Build Coastguard Worker blit.dst.level = dstStencilSurf->u.tex.level;
614*61046927SAndroid Build Coastguard Worker blit.dst.box.z = dstStencilSurf->u.tex.first_layer;
615*61046927SAndroid Build Coastguard Worker blit.dst.format = dstStencilSurf->format;
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker blit.src.resource = srcStencilRb->texture;
618*61046927SAndroid Build Coastguard Worker blit.src.level = srcStencilRb->surface->u.tex.level;
619*61046927SAndroid Build Coastguard Worker blit.src.box.z = srcStencilRb->surface->u.tex.first_layer;
620*61046927SAndroid Build Coastguard Worker blit.src.format = srcStencilRb->surface->format;
621*61046927SAndroid Build Coastguard Worker
622*61046927SAndroid Build Coastguard Worker ctx->pipe->blit(ctx->pipe, &blit);
623*61046927SAndroid Build Coastguard Worker }
624*61046927SAndroid Build Coastguard Worker }
625*61046927SAndroid Build Coastguard Worker }
626*61046927SAndroid Build Coastguard Worker }
627*61046927SAndroid Build Coastguard Worker
628*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
blit_framebuffer(struct gl_context * ctx,struct gl_framebuffer * readFb,struct gl_framebuffer * drawFb,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter,bool no_error,const char * func)629*61046927SAndroid Build Coastguard Worker blit_framebuffer(struct gl_context *ctx,
630*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb,
631*61046927SAndroid Build Coastguard Worker GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
632*61046927SAndroid Build Coastguard Worker GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
633*61046927SAndroid Build Coastguard Worker GLbitfield mask, GLenum filter, bool no_error, const char *func)
634*61046927SAndroid Build Coastguard Worker {
635*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
636*61046927SAndroid Build Coastguard Worker
637*61046927SAndroid Build Coastguard Worker if (!readFb || !drawFb) {
638*61046927SAndroid Build Coastguard Worker /* This will normally never happen but someday we may want to
639*61046927SAndroid Build Coastguard Worker * support MakeCurrent() with no drawables.
640*61046927SAndroid Build Coastguard Worker */
641*61046927SAndroid Build Coastguard Worker return;
642*61046927SAndroid Build Coastguard Worker }
643*61046927SAndroid Build Coastguard Worker
644*61046927SAndroid Build Coastguard Worker /* Update completeness status of readFb and drawFb. */
645*61046927SAndroid Build Coastguard Worker _mesa_update_framebuffer(ctx, readFb, drawFb);
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker /* Make sure drawFb has an initialized bounding box. */
648*61046927SAndroid Build Coastguard Worker _mesa_update_draw_buffer_bounds(ctx, drawFb);
649*61046927SAndroid Build Coastguard Worker
650*61046927SAndroid Build Coastguard Worker if (!no_error) {
651*61046927SAndroid Build Coastguard Worker const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
652*61046927SAndroid Build Coastguard Worker GL_DEPTH_BUFFER_BIT |
653*61046927SAndroid Build Coastguard Worker GL_STENCIL_BUFFER_BIT);
654*61046927SAndroid Build Coastguard Worker
655*61046927SAndroid Build Coastguard Worker /* check for complete framebuffers */
656*61046927SAndroid Build Coastguard Worker if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
657*61046927SAndroid Build Coastguard Worker readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
658*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
659*61046927SAndroid Build Coastguard Worker "%s(incomplete draw/read buffers)", func);
660*61046927SAndroid Build Coastguard Worker return;
661*61046927SAndroid Build Coastguard Worker }
662*61046927SAndroid Build Coastguard Worker
663*61046927SAndroid Build Coastguard Worker if (!is_valid_blit_filter(ctx, filter)) {
664*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
665*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(filter));
666*61046927SAndroid Build Coastguard Worker return;
667*61046927SAndroid Build Coastguard Worker }
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
670*61046927SAndroid Build Coastguard Worker filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
671*61046927SAndroid Build Coastguard Worker (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
672*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
673*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(filter));
674*61046927SAndroid Build Coastguard Worker return;
675*61046927SAndroid Build Coastguard Worker }
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker if (mask & ~legalMaskBits) {
678*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
679*61046927SAndroid Build Coastguard Worker return;
680*61046927SAndroid Build Coastguard Worker }
681*61046927SAndroid Build Coastguard Worker
682*61046927SAndroid Build Coastguard Worker /* depth/stencil must be blitted with nearest filtering */
683*61046927SAndroid Build Coastguard Worker if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
684*61046927SAndroid Build Coastguard Worker && filter != GL_NEAREST) {
685*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
686*61046927SAndroid Build Coastguard Worker "%s(depth/stencil requires GL_NEAREST filter)", func);
687*61046927SAndroid Build Coastguard Worker return;
688*61046927SAndroid Build Coastguard Worker }
689*61046927SAndroid Build Coastguard Worker
690*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles3(ctx)) {
691*61046927SAndroid Build Coastguard Worker /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
692*61046927SAndroid Build Coastguard Worker * 3.0.1 spec says:
693*61046927SAndroid Build Coastguard Worker *
694*61046927SAndroid Build Coastguard Worker * "If SAMPLE_BUFFERS for the draw framebuffer is greater than
695*61046927SAndroid Build Coastguard Worker * zero, an INVALID_OPERATION error is generated."
696*61046927SAndroid Build Coastguard Worker */
697*61046927SAndroid Build Coastguard Worker if (drawFb->Visual.samples > 0) {
698*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
699*61046927SAndroid Build Coastguard Worker "%s(destination samples must be 0)", func);
700*61046927SAndroid Build Coastguard Worker return;
701*61046927SAndroid Build Coastguard Worker }
702*61046927SAndroid Build Coastguard Worker
703*61046927SAndroid Build Coastguard Worker /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
704*61046927SAndroid Build Coastguard Worker * 3.0.1 spec says:
705*61046927SAndroid Build Coastguard Worker *
706*61046927SAndroid Build Coastguard Worker * "If SAMPLE_BUFFERS for the read framebuffer is greater than
707*61046927SAndroid Build Coastguard Worker * zero, no copy is performed and an INVALID_OPERATION error is
708*61046927SAndroid Build Coastguard Worker * generated if the formats of the read and draw framebuffers are
709*61046927SAndroid Build Coastguard Worker * not identical or if the source and destination rectangles are
710*61046927SAndroid Build Coastguard Worker * not defined with the same (X0, Y0) and (X1, Y1) bounds."
711*61046927SAndroid Build Coastguard Worker *
712*61046927SAndroid Build Coastguard Worker * The format check was made above because desktop OpenGL has the same
713*61046927SAndroid Build Coastguard Worker * requirement.
714*61046927SAndroid Build Coastguard Worker */
715*61046927SAndroid Build Coastguard Worker if (readFb->Visual.samples > 0
716*61046927SAndroid Build Coastguard Worker && (srcX0 != dstX0 || srcY0 != dstY0
717*61046927SAndroid Build Coastguard Worker || srcX1 != dstX1 || srcY1 != dstY1)) {
718*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
719*61046927SAndroid Build Coastguard Worker "%s(bad src/dst multisample region)", func);
720*61046927SAndroid Build Coastguard Worker return;
721*61046927SAndroid Build Coastguard Worker }
722*61046927SAndroid Build Coastguard Worker } else {
723*61046927SAndroid Build Coastguard Worker if (readFb->Visual.samples > 0 &&
724*61046927SAndroid Build Coastguard Worker drawFb->Visual.samples > 0 &&
725*61046927SAndroid Build Coastguard Worker readFb->Visual.samples != drawFb->Visual.samples) {
726*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
727*61046927SAndroid Build Coastguard Worker "%s(mismatched samples)", func);
728*61046927SAndroid Build Coastguard Worker return;
729*61046927SAndroid Build Coastguard Worker }
730*61046927SAndroid Build Coastguard Worker
731*61046927SAndroid Build Coastguard Worker /* extra checks for multisample copies... */
732*61046927SAndroid Build Coastguard Worker if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
733*61046927SAndroid Build Coastguard Worker (filter == GL_NEAREST || filter == GL_LINEAR)) {
734*61046927SAndroid Build Coastguard Worker /* src and dest region sizes must be the same */
735*61046927SAndroid Build Coastguard Worker if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
736*61046927SAndroid Build Coastguard Worker abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
737*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
738*61046927SAndroid Build Coastguard Worker "%s(bad src/dst multisample region sizes)", func);
739*61046927SAndroid Build Coastguard Worker return;
740*61046927SAndroid Build Coastguard Worker }
741*61046927SAndroid Build Coastguard Worker }
742*61046927SAndroid Build Coastguard Worker }
743*61046927SAndroid Build Coastguard Worker }
744*61046927SAndroid Build Coastguard Worker
745*61046927SAndroid Build Coastguard Worker /* get color read/draw renderbuffers */
746*61046927SAndroid Build Coastguard Worker if (mask & GL_COLOR_BUFFER_BIT) {
747*61046927SAndroid Build Coastguard Worker const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
748*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
749*61046927SAndroid Build Coastguard Worker
750*61046927SAndroid Build Coastguard Worker /* From the EXT_framebuffer_object spec:
751*61046927SAndroid Build Coastguard Worker *
752*61046927SAndroid Build Coastguard Worker * "If a buffer is specified in <mask> and does not exist in both
753*61046927SAndroid Build Coastguard Worker * the read and draw framebuffers, the corresponding bit is silently
754*61046927SAndroid Build Coastguard Worker * ignored."
755*61046927SAndroid Build Coastguard Worker */
756*61046927SAndroid Build Coastguard Worker if (!colorReadRb || numColorDrawBuffers == 0) {
757*61046927SAndroid Build Coastguard Worker mask &= ~GL_COLOR_BUFFER_BIT;
758*61046927SAndroid Build Coastguard Worker } else if (!no_error) {
759*61046927SAndroid Build Coastguard Worker if (!validate_color_buffer(ctx, readFb, drawFb, filter, func))
760*61046927SAndroid Build Coastguard Worker return;
761*61046927SAndroid Build Coastguard Worker }
762*61046927SAndroid Build Coastguard Worker }
763*61046927SAndroid Build Coastguard Worker
764*61046927SAndroid Build Coastguard Worker if (mask & GL_STENCIL_BUFFER_BIT) {
765*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *readRb =
766*61046927SAndroid Build Coastguard Worker readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
767*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *drawRb =
768*61046927SAndroid Build Coastguard Worker drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
769*61046927SAndroid Build Coastguard Worker
770*61046927SAndroid Build Coastguard Worker /* From the EXT_framebuffer_object spec:
771*61046927SAndroid Build Coastguard Worker *
772*61046927SAndroid Build Coastguard Worker * "If a buffer is specified in <mask> and does not exist in both
773*61046927SAndroid Build Coastguard Worker * the read and draw framebuffers, the corresponding bit is silently
774*61046927SAndroid Build Coastguard Worker * ignored."
775*61046927SAndroid Build Coastguard Worker */
776*61046927SAndroid Build Coastguard Worker if ((readRb == NULL) || (drawRb == NULL)) {
777*61046927SAndroid Build Coastguard Worker mask &= ~GL_STENCIL_BUFFER_BIT;
778*61046927SAndroid Build Coastguard Worker } else if (!no_error) {
779*61046927SAndroid Build Coastguard Worker if (!validate_stencil_buffer(ctx, readFb, drawFb, func))
780*61046927SAndroid Build Coastguard Worker return;
781*61046927SAndroid Build Coastguard Worker }
782*61046927SAndroid Build Coastguard Worker }
783*61046927SAndroid Build Coastguard Worker
784*61046927SAndroid Build Coastguard Worker if (mask & GL_DEPTH_BUFFER_BIT) {
785*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *readRb =
786*61046927SAndroid Build Coastguard Worker readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
787*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *drawRb =
788*61046927SAndroid Build Coastguard Worker drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
789*61046927SAndroid Build Coastguard Worker
790*61046927SAndroid Build Coastguard Worker /* From the EXT_framebuffer_object spec:
791*61046927SAndroid Build Coastguard Worker *
792*61046927SAndroid Build Coastguard Worker * "If a buffer is specified in <mask> and does not exist in both
793*61046927SAndroid Build Coastguard Worker * the read and draw framebuffers, the corresponding bit is silently
794*61046927SAndroid Build Coastguard Worker * ignored."
795*61046927SAndroid Build Coastguard Worker */
796*61046927SAndroid Build Coastguard Worker if ((readRb == NULL) || (drawRb == NULL)) {
797*61046927SAndroid Build Coastguard Worker mask &= ~GL_DEPTH_BUFFER_BIT;
798*61046927SAndroid Build Coastguard Worker } else if (!no_error) {
799*61046927SAndroid Build Coastguard Worker if (!validate_depth_buffer(ctx, readFb, drawFb, func))
800*61046927SAndroid Build Coastguard Worker return;
801*61046927SAndroid Build Coastguard Worker }
802*61046927SAndroid Build Coastguard Worker }
803*61046927SAndroid Build Coastguard Worker
804*61046927SAndroid Build Coastguard Worker /* Debug code */
805*61046927SAndroid Build Coastguard Worker if (DEBUG_BLIT) {
806*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
807*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer *colorDrawRb = NULL;
808*61046927SAndroid Build Coastguard Worker GLuint i = 0;
809*61046927SAndroid Build Coastguard Worker
810*61046927SAndroid Build Coastguard Worker printf("%s(%d, %d, %d, %d, %d, %d, %d, %d,"
811*61046927SAndroid Build Coastguard Worker " 0x%x, 0x%x)\n", func,
812*61046927SAndroid Build Coastguard Worker srcX0, srcY0, srcX1, srcY1,
813*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1,
814*61046927SAndroid Build Coastguard Worker mask, filter);
815*61046927SAndroid Build Coastguard Worker
816*61046927SAndroid Build Coastguard Worker if (colorReadRb) {
817*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *att;
818*61046927SAndroid Build Coastguard Worker
819*61046927SAndroid Build Coastguard Worker att = find_attachment(readFb, colorReadRb);
820*61046927SAndroid Build Coastguard Worker printf(" Src FBO %u RB %u (%dx%d) ",
821*61046927SAndroid Build Coastguard Worker readFb->Name, colorReadRb->Name,
822*61046927SAndroid Build Coastguard Worker colorReadRb->Width, colorReadRb->Height);
823*61046927SAndroid Build Coastguard Worker if (att && att->Texture) {
824*61046927SAndroid Build Coastguard Worker printf("Tex %u tgt 0x%x level %u face %u",
825*61046927SAndroid Build Coastguard Worker att->Texture->Name,
826*61046927SAndroid Build Coastguard Worker att->Texture->Target,
827*61046927SAndroid Build Coastguard Worker att->TextureLevel,
828*61046927SAndroid Build Coastguard Worker att->CubeMapFace);
829*61046927SAndroid Build Coastguard Worker }
830*61046927SAndroid Build Coastguard Worker printf("\n");
831*61046927SAndroid Build Coastguard Worker
832*61046927SAndroid Build Coastguard Worker /* Print all active color render buffers */
833*61046927SAndroid Build Coastguard Worker for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
834*61046927SAndroid Build Coastguard Worker colorDrawRb = drawFb->_ColorDrawBuffers[i];
835*61046927SAndroid Build Coastguard Worker if (!colorDrawRb)
836*61046927SAndroid Build Coastguard Worker continue;
837*61046927SAndroid Build Coastguard Worker
838*61046927SAndroid Build Coastguard Worker att = find_attachment(drawFb, colorDrawRb);
839*61046927SAndroid Build Coastguard Worker printf(" Dst FBO %u RB %u (%dx%d) ",
840*61046927SAndroid Build Coastguard Worker drawFb->Name, colorDrawRb->Name,
841*61046927SAndroid Build Coastguard Worker colorDrawRb->Width, colorDrawRb->Height);
842*61046927SAndroid Build Coastguard Worker if (att && att->Texture) {
843*61046927SAndroid Build Coastguard Worker printf("Tex %u tgt 0x%x level %u face %u",
844*61046927SAndroid Build Coastguard Worker att->Texture->Name,
845*61046927SAndroid Build Coastguard Worker att->Texture->Target,
846*61046927SAndroid Build Coastguard Worker att->TextureLevel,
847*61046927SAndroid Build Coastguard Worker att->CubeMapFace);
848*61046927SAndroid Build Coastguard Worker }
849*61046927SAndroid Build Coastguard Worker printf("\n");
850*61046927SAndroid Build Coastguard Worker }
851*61046927SAndroid Build Coastguard Worker }
852*61046927SAndroid Build Coastguard Worker }
853*61046927SAndroid Build Coastguard Worker
854*61046927SAndroid Build Coastguard Worker if (!mask ||
855*61046927SAndroid Build Coastguard Worker (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
856*61046927SAndroid Build Coastguard Worker (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
857*61046927SAndroid Build Coastguard Worker return;
858*61046927SAndroid Build Coastguard Worker }
859*61046927SAndroid Build Coastguard Worker
860*61046927SAndroid Build Coastguard Worker do_blit_framebuffer(ctx, readFb, drawFb,
861*61046927SAndroid Build Coastguard Worker srcX0, srcY0, srcX1, srcY1,
862*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1,
863*61046927SAndroid Build Coastguard Worker mask, filter);
864*61046927SAndroid Build Coastguard Worker }
865*61046927SAndroid Build Coastguard Worker
866*61046927SAndroid Build Coastguard Worker
867*61046927SAndroid Build Coastguard Worker static void
blit_framebuffer_err(struct gl_context * ctx,struct gl_framebuffer * readFb,struct gl_framebuffer * drawFb,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter,const char * func)868*61046927SAndroid Build Coastguard Worker blit_framebuffer_err(struct gl_context *ctx,
869*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *readFb,
870*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *drawFb,
871*61046927SAndroid Build Coastguard Worker GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
872*61046927SAndroid Build Coastguard Worker GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
873*61046927SAndroid Build Coastguard Worker GLbitfield mask, GLenum filter, const char *func)
874*61046927SAndroid Build Coastguard Worker {
875*61046927SAndroid Build Coastguard Worker /* We are wrapping the err variant of the always inlined
876*61046927SAndroid Build Coastguard Worker * blit_framebuffer() to avoid inlining it in every caller.
877*61046927SAndroid Build Coastguard Worker */
878*61046927SAndroid Build Coastguard Worker blit_framebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1,
879*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1, mask, filter, false, func);
880*61046927SAndroid Build Coastguard Worker }
881*61046927SAndroid Build Coastguard Worker
882*61046927SAndroid Build Coastguard Worker
883*61046927SAndroid Build Coastguard Worker /**
884*61046927SAndroid Build Coastguard Worker * Blit rectangular region, optionally from one framebuffer to another.
885*61046927SAndroid Build Coastguard Worker *
886*61046927SAndroid Build Coastguard Worker * Note, if the src buffer is multisampled and the dest is not, this is
887*61046927SAndroid Build Coastguard Worker * when the samples must be resolved to a single color.
888*61046927SAndroid Build Coastguard Worker */
889*61046927SAndroid Build Coastguard Worker 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)890*61046927SAndroid Build Coastguard Worker _mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1,
891*61046927SAndroid Build Coastguard Worker GLint srcY1, GLint dstX0, GLint dstY0,
892*61046927SAndroid Build Coastguard Worker GLint dstX1, GLint dstY1,
893*61046927SAndroid Build Coastguard Worker GLbitfield mask, GLenum filter)
894*61046927SAndroid Build Coastguard Worker {
895*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
896*61046927SAndroid Build Coastguard Worker
897*61046927SAndroid Build Coastguard Worker blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
898*61046927SAndroid Build Coastguard Worker srcX0, srcY0, srcX1, srcY1,
899*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1,
900*61046927SAndroid Build Coastguard Worker mask, filter, true, "glBlitFramebuffer");
901*61046927SAndroid Build Coastguard Worker }
902*61046927SAndroid Build Coastguard Worker
903*61046927SAndroid Build Coastguard Worker
904*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BlitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)905*61046927SAndroid Build Coastguard Worker _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
906*61046927SAndroid Build Coastguard Worker GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
907*61046927SAndroid Build Coastguard Worker GLbitfield mask, GLenum filter)
908*61046927SAndroid Build Coastguard Worker {
909*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
910*61046927SAndroid Build Coastguard Worker
911*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
912*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx,
913*61046927SAndroid Build Coastguard Worker "glBlitFramebuffer(%d, %d, %d, %d, "
914*61046927SAndroid Build Coastguard Worker " %d, %d, %d, %d, 0x%x, %s)\n",
915*61046927SAndroid Build Coastguard Worker srcX0, srcY0, srcX1, srcY1,
916*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1,
917*61046927SAndroid Build Coastguard Worker mask, _mesa_enum_to_string(filter));
918*61046927SAndroid Build Coastguard Worker
919*61046927SAndroid Build Coastguard Worker blit_framebuffer_err(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
920*61046927SAndroid Build Coastguard Worker srcX0, srcY0, srcX1, srcY1,
921*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1,
922*61046927SAndroid Build Coastguard Worker mask, filter, "glBlitFramebuffer");
923*61046927SAndroid Build Coastguard Worker }
924*61046927SAndroid Build Coastguard Worker
925*61046927SAndroid Build Coastguard Worker
926*61046927SAndroid Build Coastguard Worker 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)927*61046927SAndroid Build Coastguard Worker blit_named_framebuffer(struct gl_context *ctx,
928*61046927SAndroid Build Coastguard Worker GLuint readFramebuffer, GLuint drawFramebuffer,
929*61046927SAndroid Build Coastguard Worker GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
930*61046927SAndroid Build Coastguard Worker GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
931*61046927SAndroid Build Coastguard Worker GLbitfield mask, GLenum filter, bool no_error)
932*61046927SAndroid Build Coastguard Worker {
933*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *readFb, *drawFb;
934*61046927SAndroid Build Coastguard Worker
935*61046927SAndroid Build Coastguard Worker /*
936*61046927SAndroid Build Coastguard Worker * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
937*61046927SAndroid Build Coastguard Worker * Section 18.3 Copying Pixels):
938*61046927SAndroid Build Coastguard Worker * "... if readFramebuffer or drawFramebuffer is zero (for
939*61046927SAndroid Build Coastguard Worker * BlitNamedFramebuffer), then the default read or draw framebuffer is
940*61046927SAndroid Build Coastguard Worker * used as the corresponding source or destination framebuffer,
941*61046927SAndroid Build Coastguard Worker * respectively."
942*61046927SAndroid Build Coastguard Worker */
943*61046927SAndroid Build Coastguard Worker if (readFramebuffer) {
944*61046927SAndroid Build Coastguard Worker if (no_error) {
945*61046927SAndroid Build Coastguard Worker readFb = _mesa_lookup_framebuffer(ctx, readFramebuffer);
946*61046927SAndroid Build Coastguard Worker } else {
947*61046927SAndroid Build Coastguard Worker readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
948*61046927SAndroid Build Coastguard Worker "glBlitNamedFramebuffer");
949*61046927SAndroid Build Coastguard Worker if (!readFb)
950*61046927SAndroid Build Coastguard Worker return;
951*61046927SAndroid Build Coastguard Worker }
952*61046927SAndroid Build Coastguard Worker } else {
953*61046927SAndroid Build Coastguard Worker readFb = ctx->WinSysReadBuffer;
954*61046927SAndroid Build Coastguard Worker }
955*61046927SAndroid Build Coastguard Worker
956*61046927SAndroid Build Coastguard Worker if (drawFramebuffer) {
957*61046927SAndroid Build Coastguard Worker if (no_error) {
958*61046927SAndroid Build Coastguard Worker drawFb = _mesa_lookup_framebuffer(ctx, drawFramebuffer);
959*61046927SAndroid Build Coastguard Worker } else {
960*61046927SAndroid Build Coastguard Worker drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
961*61046927SAndroid Build Coastguard Worker "glBlitNamedFramebuffer");
962*61046927SAndroid Build Coastguard Worker if (!drawFb)
963*61046927SAndroid Build Coastguard Worker return;
964*61046927SAndroid Build Coastguard Worker }
965*61046927SAndroid Build Coastguard Worker } else {
966*61046927SAndroid Build Coastguard Worker drawFb = ctx->WinSysDrawBuffer;
967*61046927SAndroid Build Coastguard Worker }
968*61046927SAndroid Build Coastguard Worker
969*61046927SAndroid Build Coastguard Worker blit_framebuffer(ctx, readFb, drawFb,
970*61046927SAndroid Build Coastguard Worker srcX0, srcY0, srcX1, srcY1,
971*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1,
972*61046927SAndroid Build Coastguard Worker mask, filter, no_error, "glBlitNamedFramebuffer");
973*61046927SAndroid Build Coastguard Worker }
974*61046927SAndroid Build Coastguard Worker
975*61046927SAndroid Build Coastguard Worker
976*61046927SAndroid Build Coastguard Worker 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)977*61046927SAndroid Build Coastguard Worker _mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer,
978*61046927SAndroid Build Coastguard Worker GLuint drawFramebuffer,
979*61046927SAndroid Build Coastguard Worker GLint srcX0, GLint srcY0,
980*61046927SAndroid Build Coastguard Worker GLint srcX1, GLint srcY1,
981*61046927SAndroid Build Coastguard Worker GLint dstX0, GLint dstY0,
982*61046927SAndroid Build Coastguard Worker GLint dstX1, GLint dstY1,
983*61046927SAndroid Build Coastguard Worker GLbitfield mask, GLenum filter)
984*61046927SAndroid Build Coastguard Worker {
985*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
986*61046927SAndroid Build Coastguard Worker
987*61046927SAndroid Build Coastguard Worker blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
988*61046927SAndroid Build Coastguard Worker srcX0, srcY0, srcX1, srcY1,
989*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1,
990*61046927SAndroid Build Coastguard Worker mask, filter, true);
991*61046927SAndroid Build Coastguard Worker }
992*61046927SAndroid Build Coastguard Worker
993*61046927SAndroid Build Coastguard Worker
994*61046927SAndroid Build Coastguard Worker 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)995*61046927SAndroid Build Coastguard Worker _mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
996*61046927SAndroid Build Coastguard Worker GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
997*61046927SAndroid Build Coastguard Worker GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
998*61046927SAndroid Build Coastguard Worker GLbitfield mask, GLenum filter)
999*61046927SAndroid Build Coastguard Worker {
1000*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1001*61046927SAndroid Build Coastguard Worker
1002*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
1003*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx,
1004*61046927SAndroid Build Coastguard Worker "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
1005*61046927SAndroid Build Coastguard Worker " %d, %d, %d, %d, 0x%x, %s)\n",
1006*61046927SAndroid Build Coastguard Worker readFramebuffer, drawFramebuffer,
1007*61046927SAndroid Build Coastguard Worker srcX0, srcY0, srcX1, srcY1,
1008*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1,
1009*61046927SAndroid Build Coastguard Worker mask, _mesa_enum_to_string(filter));
1010*61046927SAndroid Build Coastguard Worker
1011*61046927SAndroid Build Coastguard Worker blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
1012*61046927SAndroid Build Coastguard Worker srcX0, srcY0, srcX1, srcY1,
1013*61046927SAndroid Build Coastguard Worker dstX0, dstY0, dstX1, dstY1,
1014*61046927SAndroid Build Coastguard Worker mask, filter, false);
1015*61046927SAndroid Build Coastguard Worker }
1016