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-2009 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 /*
28*61046927SAndroid Build Coastguard Worker * GL_EXT/ARB_framebuffer_object extensions
29*61046927SAndroid Build Coastguard Worker *
30*61046927SAndroid Build Coastguard Worker * Authors:
31*61046927SAndroid Build Coastguard Worker * Brian Paul
32*61046927SAndroid Build Coastguard Worker */
33*61046927SAndroid Build Coastguard Worker
34*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
35*61046927SAndroid Build Coastguard Worker
36*61046927SAndroid Build Coastguard Worker #include "buffers.h"
37*61046927SAndroid Build Coastguard Worker #include "context.h"
38*61046927SAndroid Build Coastguard Worker #include "debug_output.h"
39*61046927SAndroid Build Coastguard Worker #include "draw_validate.h"
40*61046927SAndroid Build Coastguard Worker #include "enums.h"
41*61046927SAndroid Build Coastguard Worker #include "fbobject.h"
42*61046927SAndroid Build Coastguard Worker #include "formats.h"
43*61046927SAndroid Build Coastguard Worker #include "framebuffer.h"
44*61046927SAndroid Build Coastguard Worker #include "glformats.h"
45*61046927SAndroid Build Coastguard Worker #include "hash.h"
46*61046927SAndroid Build Coastguard Worker #include "macros.h"
47*61046927SAndroid Build Coastguard Worker #include "multisample.h"
48*61046927SAndroid Build Coastguard Worker #include "mtypes.h"
49*61046927SAndroid Build Coastguard Worker #include "renderbuffer.h"
50*61046927SAndroid Build Coastguard Worker #include "state.h"
51*61046927SAndroid Build Coastguard Worker #include "teximage.h"
52*61046927SAndroid Build Coastguard Worker #include "texobj.h"
53*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker #include "util/u_memory.h"
56*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_eglimage.h"
57*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_context.h"
58*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_format.h"
59*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_util.h"
60*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker /**
63*61046927SAndroid Build Coastguard Worker * Notes:
64*61046927SAndroid Build Coastguard Worker *
65*61046927SAndroid Build Coastguard Worker * None of the GL_EXT_framebuffer_object functions are compiled into
66*61046927SAndroid Build Coastguard Worker * display lists.
67*61046927SAndroid Build Coastguard Worker */
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Worker static void
delete_dummy_renderbuffer(struct gl_context * ctx,struct gl_renderbuffer * rb)72*61046927SAndroid Build Coastguard Worker delete_dummy_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
73*61046927SAndroid Build Coastguard Worker {
74*61046927SAndroid Build Coastguard Worker /* no op */
75*61046927SAndroid Build Coastguard Worker }
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker static void
delete_dummy_framebuffer(struct gl_framebuffer * fb)78*61046927SAndroid Build Coastguard Worker delete_dummy_framebuffer(struct gl_framebuffer *fb)
79*61046927SAndroid Build Coastguard Worker {
80*61046927SAndroid Build Coastguard Worker /* no op */
81*61046927SAndroid Build Coastguard Worker }
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker /*
85*61046927SAndroid Build Coastguard Worker * When glGenRender/FramebuffersEXT() is called we insert pointers to
86*61046927SAndroid Build Coastguard Worker * these placeholder objects into the hash table.
87*61046927SAndroid Build Coastguard Worker * Later, when the object ID is first bound, we replace the placeholder
88*61046927SAndroid Build Coastguard Worker * with the real frame/renderbuffer.
89*61046927SAndroid Build Coastguard Worker */
90*61046927SAndroid Build Coastguard Worker static struct gl_framebuffer DummyFramebuffer = {
91*61046927SAndroid Build Coastguard Worker .Mutex = SIMPLE_MTX_INITIALIZER,
92*61046927SAndroid Build Coastguard Worker .Delete = delete_dummy_framebuffer,
93*61046927SAndroid Build Coastguard Worker };
94*61046927SAndroid Build Coastguard Worker static struct gl_renderbuffer DummyRenderbuffer = {
95*61046927SAndroid Build Coastguard Worker .Delete = delete_dummy_renderbuffer,
96*61046927SAndroid Build Coastguard Worker };
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker /* We bind this framebuffer when applications pass a NULL
99*61046927SAndroid Build Coastguard Worker * drawable/surface in make current. */
100*61046927SAndroid Build Coastguard Worker static struct gl_framebuffer IncompleteFramebuffer = {
101*61046927SAndroid Build Coastguard Worker .Mutex = SIMPLE_MTX_INITIALIZER,
102*61046927SAndroid Build Coastguard Worker .Delete = delete_dummy_framebuffer,
103*61046927SAndroid Build Coastguard Worker };
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *
_mesa_get_incomplete_framebuffer(void)107*61046927SAndroid Build Coastguard Worker _mesa_get_incomplete_framebuffer(void)
108*61046927SAndroid Build Coastguard Worker {
109*61046927SAndroid Build Coastguard Worker return &IncompleteFramebuffer;
110*61046927SAndroid Build Coastguard Worker }
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker /**
113*61046927SAndroid Build Coastguard Worker * Helper routine for getting a gl_renderbuffer.
114*61046927SAndroid Build Coastguard Worker */
115*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *
_mesa_lookup_renderbuffer(struct gl_context * ctx,GLuint id)116*61046927SAndroid Build Coastguard Worker _mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id)
117*61046927SAndroid Build Coastguard Worker {
118*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb;
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker if (id == 0)
121*61046927SAndroid Build Coastguard Worker return NULL;
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker rb = (struct gl_renderbuffer *)
124*61046927SAndroid Build Coastguard Worker _mesa_HashLookup(&ctx->Shared->RenderBuffers, id);
125*61046927SAndroid Build Coastguard Worker return rb;
126*61046927SAndroid Build Coastguard Worker }
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker /**
130*61046927SAndroid Build Coastguard Worker * A convenience function for direct state access that throws
131*61046927SAndroid Build Coastguard Worker * GL_INVALID_OPERATION if the renderbuffer doesn't exist.
132*61046927SAndroid Build Coastguard Worker */
133*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *
_mesa_lookup_renderbuffer_err(struct gl_context * ctx,GLuint id,const char * func)134*61046927SAndroid Build Coastguard Worker _mesa_lookup_renderbuffer_err(struct gl_context *ctx, GLuint id,
135*61046927SAndroid Build Coastguard Worker const char *func)
136*61046927SAndroid Build Coastguard Worker {
137*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb;
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker rb = _mesa_lookup_renderbuffer(ctx, id);
140*61046927SAndroid Build Coastguard Worker if (!rb || rb == &DummyRenderbuffer) {
141*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
142*61046927SAndroid Build Coastguard Worker "%s(non-existent renderbuffer %u)", func, id);
143*61046927SAndroid Build Coastguard Worker return NULL;
144*61046927SAndroid Build Coastguard Worker }
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker return rb;
147*61046927SAndroid Build Coastguard Worker }
148*61046927SAndroid Build Coastguard Worker
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker /**
151*61046927SAndroid Build Coastguard Worker * Helper routine for getting a gl_framebuffer.
152*61046927SAndroid Build Coastguard Worker */
153*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *
_mesa_lookup_framebuffer(struct gl_context * ctx,GLuint id)154*61046927SAndroid Build Coastguard Worker _mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id)
155*61046927SAndroid Build Coastguard Worker {
156*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker if (id == 0)
159*61046927SAndroid Build Coastguard Worker return NULL;
160*61046927SAndroid Build Coastguard Worker
161*61046927SAndroid Build Coastguard Worker fb = (struct gl_framebuffer *)
162*61046927SAndroid Build Coastguard Worker _mesa_HashLookup(&ctx->Shared->FrameBuffers, id);
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker return fb;
165*61046927SAndroid Build Coastguard Worker }
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker
168*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *
_mesa_lookup_framebuffer_dsa(struct gl_context * ctx,GLuint id,const char * func)169*61046927SAndroid Build Coastguard Worker _mesa_lookup_framebuffer_dsa(struct gl_context *ctx, GLuint id,
170*61046927SAndroid Build Coastguard Worker const char* func)
171*61046927SAndroid Build Coastguard Worker {
172*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker if (id == 0)
175*61046927SAndroid Build Coastguard Worker return NULL;
176*61046927SAndroid Build Coastguard Worker
177*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer(ctx, id);
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker /* Name exists but buffer is not initialized */
180*61046927SAndroid Build Coastguard Worker if (fb == &DummyFramebuffer) {
181*61046927SAndroid Build Coastguard Worker fb = _mesa_new_framebuffer(ctx, id);
182*61046927SAndroid Build Coastguard Worker _mesa_HashInsert(&ctx->Shared->FrameBuffers, id, fb);
183*61046927SAndroid Build Coastguard Worker }
184*61046927SAndroid Build Coastguard Worker /* Name doesn't exist */
185*61046927SAndroid Build Coastguard Worker else if (!fb) {
186*61046927SAndroid Build Coastguard Worker fb = _mesa_new_framebuffer(ctx, id);
187*61046927SAndroid Build Coastguard Worker if (!fb) {
188*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
189*61046927SAndroid Build Coastguard Worker return NULL;
190*61046927SAndroid Build Coastguard Worker }
191*61046927SAndroid Build Coastguard Worker _mesa_HashInsert(&ctx->Shared->FrameBuffers, id, fb);
192*61046927SAndroid Build Coastguard Worker }
193*61046927SAndroid Build Coastguard Worker return fb;
194*61046927SAndroid Build Coastguard Worker }
195*61046927SAndroid Build Coastguard Worker
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker /**
198*61046927SAndroid Build Coastguard Worker * A convenience function for direct state access that throws
199*61046927SAndroid Build Coastguard Worker * GL_INVALID_OPERATION if the framebuffer doesn't exist.
200*61046927SAndroid Build Coastguard Worker */
201*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *
_mesa_lookup_framebuffer_err(struct gl_context * ctx,GLuint id,const char * func)202*61046927SAndroid Build Coastguard Worker _mesa_lookup_framebuffer_err(struct gl_context *ctx, GLuint id,
203*61046927SAndroid Build Coastguard Worker const char *func)
204*61046927SAndroid Build Coastguard Worker {
205*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
206*61046927SAndroid Build Coastguard Worker
207*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer(ctx, id);
208*61046927SAndroid Build Coastguard Worker if (!fb || fb == &DummyFramebuffer) {
209*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
210*61046927SAndroid Build Coastguard Worker "%s(non-existent framebuffer %u)", func, id);
211*61046927SAndroid Build Coastguard Worker return NULL;
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker return fb;
215*61046927SAndroid Build Coastguard Worker }
216*61046927SAndroid Build Coastguard Worker
217*61046927SAndroid Build Coastguard Worker
218*61046927SAndroid Build Coastguard Worker /**
219*61046927SAndroid Build Coastguard Worker * Mark the given framebuffer as invalid. This will force the
220*61046927SAndroid Build Coastguard Worker * test for framebuffer completeness to be done before the framebuffer
221*61046927SAndroid Build Coastguard Worker * is used.
222*61046927SAndroid Build Coastguard Worker */
223*61046927SAndroid Build Coastguard Worker static void
invalidate_framebuffer(struct gl_framebuffer * fb)224*61046927SAndroid Build Coastguard Worker invalidate_framebuffer(struct gl_framebuffer *fb)
225*61046927SAndroid Build Coastguard Worker {
226*61046927SAndroid Build Coastguard Worker fb->_Status = 0; /* "indeterminate" */
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker
230*61046927SAndroid Build Coastguard Worker /**
231*61046927SAndroid Build Coastguard Worker * Return the gl_framebuffer object which corresponds to the given
232*61046927SAndroid Build Coastguard Worker * framebuffer target, such as GL_DRAW_FRAMEBUFFER.
233*61046927SAndroid Build Coastguard Worker * Check support for GL_EXT_framebuffer_blit to determine if certain
234*61046927SAndroid Build Coastguard Worker * targets are legal.
235*61046927SAndroid Build Coastguard Worker * \return gl_framebuffer pointer or NULL if target is illegal
236*61046927SAndroid Build Coastguard Worker */
237*61046927SAndroid Build Coastguard Worker static struct gl_framebuffer *
get_framebuffer_target(struct gl_context * ctx,GLenum target)238*61046927SAndroid Build Coastguard Worker get_framebuffer_target(struct gl_context *ctx, GLenum target)
239*61046927SAndroid Build Coastguard Worker {
240*61046927SAndroid Build Coastguard Worker bool have_fb_blit = _mesa_is_gles3(ctx) || _mesa_is_desktop_gl(ctx);
241*61046927SAndroid Build Coastguard Worker switch (target) {
242*61046927SAndroid Build Coastguard Worker case GL_DRAW_FRAMEBUFFER:
243*61046927SAndroid Build Coastguard Worker return have_fb_blit ? ctx->DrawBuffer : NULL;
244*61046927SAndroid Build Coastguard Worker case GL_READ_FRAMEBUFFER:
245*61046927SAndroid Build Coastguard Worker return have_fb_blit ? ctx->ReadBuffer : NULL;
246*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_EXT:
247*61046927SAndroid Build Coastguard Worker return ctx->DrawBuffer;
248*61046927SAndroid Build Coastguard Worker default:
249*61046927SAndroid Build Coastguard Worker return NULL;
250*61046927SAndroid Build Coastguard Worker }
251*61046927SAndroid Build Coastguard Worker }
252*61046927SAndroid Build Coastguard Worker
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker /**
255*61046927SAndroid Build Coastguard Worker * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
256*61046927SAndroid Build Coastguard Worker * gl_renderbuffer_attachment object.
257*61046927SAndroid Build Coastguard Worker * This function is only used for user-created FB objects, not the
258*61046927SAndroid Build Coastguard Worker * default / window-system FB object.
259*61046927SAndroid Build Coastguard Worker * If \p attachment is GL_DEPTH_STENCIL_ATTACHMENT, return a pointer to
260*61046927SAndroid Build Coastguard Worker * the depth buffer attachment point.
261*61046927SAndroid Build Coastguard Worker * Returns if the attachment is a GL_COLOR_ATTACHMENTm_EXT on
262*61046927SAndroid Build Coastguard Worker * is_color_attachment, because several callers would return different errors
263*61046927SAndroid Build Coastguard Worker * if they don't find the attachment.
264*61046927SAndroid Build Coastguard Worker */
265*61046927SAndroid Build Coastguard Worker static struct gl_renderbuffer_attachment *
get_attachment(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum attachment,bool * is_color_attachment)266*61046927SAndroid Build Coastguard Worker get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
267*61046927SAndroid Build Coastguard Worker GLenum attachment, bool *is_color_attachment)
268*61046927SAndroid Build Coastguard Worker {
269*61046927SAndroid Build Coastguard Worker GLuint i;
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker assert(_mesa_is_user_fbo(fb));
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker if (is_color_attachment)
274*61046927SAndroid Build Coastguard Worker *is_color_attachment = false;
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker switch (attachment) {
277*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT0_EXT:
278*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT1_EXT:
279*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT2_EXT:
280*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT3_EXT:
281*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT4_EXT:
282*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT5_EXT:
283*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT6_EXT:
284*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT7_EXT:
285*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT8_EXT:
286*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT9_EXT:
287*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT10_EXT:
288*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT11_EXT:
289*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT12_EXT:
290*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT13_EXT:
291*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT14_EXT:
292*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT15_EXT:
293*61046927SAndroid Build Coastguard Worker if (is_color_attachment)
294*61046927SAndroid Build Coastguard Worker *is_color_attachment = true;
295*61046927SAndroid Build Coastguard Worker /* Only OpenGL ES 1.x forbids color attachments other than
296*61046927SAndroid Build Coastguard Worker * GL_COLOR_ATTACHMENT0. For all other APIs the limit set by the
297*61046927SAndroid Build Coastguard Worker * hardware is used.
298*61046927SAndroid Build Coastguard Worker */
299*61046927SAndroid Build Coastguard Worker i = attachment - GL_COLOR_ATTACHMENT0_EXT;
300*61046927SAndroid Build Coastguard Worker if (i >= ctx->Const.MaxColorAttachments
301*61046927SAndroid Build Coastguard Worker || (i > 0 && _mesa_is_gles1(ctx))) {
302*61046927SAndroid Build Coastguard Worker return NULL;
303*61046927SAndroid Build Coastguard Worker }
304*61046927SAndroid Build Coastguard Worker assert(BUFFER_COLOR0 + i < ARRAY_SIZE(fb->Attachment));
305*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_COLOR0 + i];
306*61046927SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_ATTACHMENT:
307*61046927SAndroid Build Coastguard Worker if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
308*61046927SAndroid Build Coastguard Worker return NULL;
309*61046927SAndroid Build Coastguard Worker FALLTHROUGH;
310*61046927SAndroid Build Coastguard Worker case GL_DEPTH_ATTACHMENT_EXT:
311*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_DEPTH];
312*61046927SAndroid Build Coastguard Worker case GL_STENCIL_ATTACHMENT_EXT:
313*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_STENCIL];
314*61046927SAndroid Build Coastguard Worker default:
315*61046927SAndroid Build Coastguard Worker return NULL;
316*61046927SAndroid Build Coastguard Worker }
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker
320*61046927SAndroid Build Coastguard Worker /**
321*61046927SAndroid Build Coastguard Worker * As above, but only used for getting attachments of the default /
322*61046927SAndroid Build Coastguard Worker * window-system framebuffer (not user-created framebuffer objects).
323*61046927SAndroid Build Coastguard Worker */
324*61046927SAndroid Build Coastguard Worker static struct gl_renderbuffer_attachment *
get_fb0_attachment(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum attachment)325*61046927SAndroid Build Coastguard Worker get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
326*61046927SAndroid Build Coastguard Worker GLenum attachment)
327*61046927SAndroid Build Coastguard Worker {
328*61046927SAndroid Build Coastguard Worker assert(_mesa_is_winsys_fbo(fb));
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker attachment = _mesa_back_to_front_if_single_buffered(fb, attachment);
331*61046927SAndroid Build Coastguard Worker
332*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles3(ctx)) {
333*61046927SAndroid Build Coastguard Worker switch (attachment) {
334*61046927SAndroid Build Coastguard Worker case GL_BACK:
335*61046927SAndroid Build Coastguard Worker /* Since there is no stereo rendering in ES 3.0, only return the
336*61046927SAndroid Build Coastguard Worker * LEFT bits.
337*61046927SAndroid Build Coastguard Worker */
338*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_BACK_LEFT];
339*61046927SAndroid Build Coastguard Worker case GL_FRONT:
340*61046927SAndroid Build Coastguard Worker /* We might get this if back_to_front triggers above */
341*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_FRONT_LEFT];
342*61046927SAndroid Build Coastguard Worker case GL_DEPTH:
343*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_DEPTH];
344*61046927SAndroid Build Coastguard Worker case GL_STENCIL:
345*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_STENCIL];
346*61046927SAndroid Build Coastguard Worker default:
347*61046927SAndroid Build Coastguard Worker unreachable("invalid attachment");
348*61046927SAndroid Build Coastguard Worker }
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker
351*61046927SAndroid Build Coastguard Worker switch (attachment) {
352*61046927SAndroid Build Coastguard Worker case GL_FRONT:
353*61046927SAndroid Build Coastguard Worker case GL_FRONT_LEFT:
354*61046927SAndroid Build Coastguard Worker /* Front buffers can be allocated on the first use, but
355*61046927SAndroid Build Coastguard Worker * glGetFramebufferAttachmentParameteriv must work even if that
356*61046927SAndroid Build Coastguard Worker * allocation hasn't happened yet. In such case, use the back buffer,
357*61046927SAndroid Build Coastguard Worker * which should be the same.
358*61046927SAndroid Build Coastguard Worker */
359*61046927SAndroid Build Coastguard Worker if (fb->Attachment[BUFFER_FRONT_LEFT].Type == GL_NONE)
360*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_BACK_LEFT];
361*61046927SAndroid Build Coastguard Worker else
362*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_FRONT_LEFT];
363*61046927SAndroid Build Coastguard Worker case GL_FRONT_RIGHT:
364*61046927SAndroid Build Coastguard Worker /* Same as above. */
365*61046927SAndroid Build Coastguard Worker if (fb->Attachment[BUFFER_FRONT_RIGHT].Type == GL_NONE)
366*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_BACK_RIGHT];
367*61046927SAndroid Build Coastguard Worker else
368*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_FRONT_RIGHT];
369*61046927SAndroid Build Coastguard Worker case GL_BACK_LEFT:
370*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_BACK_LEFT];
371*61046927SAndroid Build Coastguard Worker case GL_BACK_RIGHT:
372*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_BACK_RIGHT];
373*61046927SAndroid Build Coastguard Worker case GL_BACK:
374*61046927SAndroid Build Coastguard Worker /* The ARB_ES3_1_compatibility spec says:
375*61046927SAndroid Build Coastguard Worker *
376*61046927SAndroid Build Coastguard Worker * "Since this command can only query a single framebuffer
377*61046927SAndroid Build Coastguard Worker * attachment, BACK is equivalent to BACK_LEFT."
378*61046927SAndroid Build Coastguard Worker */
379*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.ARB_ES3_1_compatibility)
380*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_BACK_LEFT];
381*61046927SAndroid Build Coastguard Worker return NULL;
382*61046927SAndroid Build Coastguard Worker case GL_AUX0:
383*61046927SAndroid Build Coastguard Worker return NULL;
384*61046927SAndroid Build Coastguard Worker
385*61046927SAndroid Build Coastguard Worker /* Page 336 (page 352 of the PDF) of the OpenGL 3.0 spec says:
386*61046927SAndroid Build Coastguard Worker *
387*61046927SAndroid Build Coastguard Worker * "If the default framebuffer is bound to target, then attachment must
388*61046927SAndroid Build Coastguard Worker * be one of FRONT LEFT, FRONT RIGHT, BACK LEFT, BACK RIGHT, or AUXi,
389*61046927SAndroid Build Coastguard Worker * identifying a color buffer; DEPTH, identifying the depth buffer; or
390*61046927SAndroid Build Coastguard Worker * STENCIL, identifying the stencil buffer."
391*61046927SAndroid Build Coastguard Worker *
392*61046927SAndroid Build Coastguard Worker * Revision #34 of the ARB_framebuffer_object spec has essentially the same
393*61046927SAndroid Build Coastguard Worker * language. However, revision #33 of the ARB_framebuffer_object spec
394*61046927SAndroid Build Coastguard Worker * says:
395*61046927SAndroid Build Coastguard Worker *
396*61046927SAndroid Build Coastguard Worker * "If the default framebuffer is bound to <target>, then <attachment>
397*61046927SAndroid Build Coastguard Worker * must be one of FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, AUXi,
398*61046927SAndroid Build Coastguard Worker * DEPTH_BUFFER, or STENCIL_BUFFER, identifying a color buffer, the
399*61046927SAndroid Build Coastguard Worker * depth buffer, or the stencil buffer, and <pname> may be
400*61046927SAndroid Build Coastguard Worker * FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE or
401*61046927SAndroid Build Coastguard Worker * FRAMEBUFFER_ATTACHMENT_OBJECT_NAME."
402*61046927SAndroid Build Coastguard Worker *
403*61046927SAndroid Build Coastguard Worker * The enum values for DEPTH_BUFFER and STENCIL_BUFFER have been removed
404*61046927SAndroid Build Coastguard Worker * from glext.h, so shipping apps should not use those values.
405*61046927SAndroid Build Coastguard Worker *
406*61046927SAndroid Build Coastguard Worker * Note that neither EXT_framebuffer_object nor OES_framebuffer_object
407*61046927SAndroid Build Coastguard Worker * support queries of the window system FBO.
408*61046927SAndroid Build Coastguard Worker */
409*61046927SAndroid Build Coastguard Worker case GL_DEPTH:
410*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_DEPTH];
411*61046927SAndroid Build Coastguard Worker case GL_STENCIL:
412*61046927SAndroid Build Coastguard Worker return &fb->Attachment[BUFFER_STENCIL];
413*61046927SAndroid Build Coastguard Worker default:
414*61046927SAndroid Build Coastguard Worker return NULL;
415*61046927SAndroid Build Coastguard Worker }
416*61046927SAndroid Build Coastguard Worker }
417*61046927SAndroid Build Coastguard Worker
418*61046927SAndroid Build Coastguard Worker /**
419*61046927SAndroid Build Coastguard Worker * Return the pipe_resource which stores a particular texture image.
420*61046927SAndroid Build Coastguard Worker */
421*61046927SAndroid Build Coastguard Worker static struct pipe_resource *
get_teximage_resource(struct gl_texture_object * texObj,unsigned face,unsigned level)422*61046927SAndroid Build Coastguard Worker get_teximage_resource(struct gl_texture_object *texObj,
423*61046927SAndroid Build Coastguard Worker unsigned face, unsigned level)
424*61046927SAndroid Build Coastguard Worker {
425*61046927SAndroid Build Coastguard Worker struct gl_texture_image *stImg =
426*61046927SAndroid Build Coastguard Worker texObj->Image[face][level];
427*61046927SAndroid Build Coastguard Worker
428*61046927SAndroid Build Coastguard Worker return stImg->pt;
429*61046927SAndroid Build Coastguard Worker }
430*61046927SAndroid Build Coastguard Worker
431*61046927SAndroid Build Coastguard Worker static void
render_texture(struct gl_context * ctx,struct gl_framebuffer * fb,struct gl_renderbuffer_attachment * att)432*61046927SAndroid Build Coastguard Worker render_texture(struct gl_context *ctx,
433*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
434*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att)
435*61046927SAndroid Build Coastguard Worker {
436*61046927SAndroid Build Coastguard Worker struct st_context *st = st_context(ctx);
437*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = att->Renderbuffer;
438*61046927SAndroid Build Coastguard Worker struct pipe_resource *pt;
439*61046927SAndroid Build Coastguard Worker
440*61046927SAndroid Build Coastguard Worker pt = get_teximage_resource(att->Texture,
441*61046927SAndroid Build Coastguard Worker att->CubeMapFace,
442*61046927SAndroid Build Coastguard Worker att->TextureLevel);
443*61046927SAndroid Build Coastguard Worker assert(pt);
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker /* point renderbuffer at texobject */
446*61046927SAndroid Build Coastguard Worker rb->is_rtt = true;
447*61046927SAndroid Build Coastguard Worker rb->rtt_face = att->CubeMapFace;
448*61046927SAndroid Build Coastguard Worker rb->rtt_slice = att->Zoffset;
449*61046927SAndroid Build Coastguard Worker rb->rtt_layered = att->Layered;
450*61046927SAndroid Build Coastguard Worker rb->rtt_nr_samples = att->NumSamples;
451*61046927SAndroid Build Coastguard Worker rb->rtt_numviews = att->NumViews;
452*61046927SAndroid Build Coastguard Worker pipe_resource_reference(&rb->texture, pt);
453*61046927SAndroid Build Coastguard Worker
454*61046927SAndroid Build Coastguard Worker _mesa_update_renderbuffer_surface(ctx, rb);
455*61046927SAndroid Build Coastguard Worker
456*61046927SAndroid Build Coastguard Worker /* Invalidate buffer state so that the pipe's framebuffer state
457*61046927SAndroid Build Coastguard Worker * gets updated.
458*61046927SAndroid Build Coastguard Worker * That's where the new renderbuffer (which we just created) gets
459*61046927SAndroid Build Coastguard Worker * passed to the pipe as a (color/depth) render target.
460*61046927SAndroid Build Coastguard Worker */
461*61046927SAndroid Build Coastguard Worker st_invalidate_buffers(st);
462*61046927SAndroid Build Coastguard Worker
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker /* Need to trigger a call to update_framebuffer() since we just
465*61046927SAndroid Build Coastguard Worker * attached a new renderbuffer.
466*61046927SAndroid Build Coastguard Worker */
467*61046927SAndroid Build Coastguard Worker ctx->NewState |= _NEW_BUFFERS;
468*61046927SAndroid Build Coastguard Worker }
469*61046927SAndroid Build Coastguard Worker
470*61046927SAndroid Build Coastguard Worker static void
finish_render_texture(struct gl_context * ctx,struct gl_renderbuffer * rb)471*61046927SAndroid Build Coastguard Worker finish_render_texture(struct gl_context *ctx, struct gl_renderbuffer *rb)
472*61046927SAndroid Build Coastguard Worker {
473*61046927SAndroid Build Coastguard Worker rb->is_rtt = false;
474*61046927SAndroid Build Coastguard Worker
475*61046927SAndroid Build Coastguard Worker /* restore previous framebuffer state */
476*61046927SAndroid Build Coastguard Worker st_invalidate_buffers(st_context(ctx));
477*61046927SAndroid Build Coastguard Worker }
478*61046927SAndroid Build Coastguard Worker
479*61046927SAndroid Build Coastguard Worker /**
480*61046927SAndroid Build Coastguard Worker * Remove any texture or renderbuffer attached to the given attachment
481*61046927SAndroid Build Coastguard Worker * point. Update reference counts, etc.
482*61046927SAndroid Build Coastguard Worker */
483*61046927SAndroid Build Coastguard Worker static void
remove_attachment(struct gl_context * ctx,struct gl_renderbuffer_attachment * att)484*61046927SAndroid Build Coastguard Worker remove_attachment(struct gl_context *ctx,
485*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att)
486*61046927SAndroid Build Coastguard Worker {
487*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = att->Renderbuffer;
488*61046927SAndroid Build Coastguard Worker
489*61046927SAndroid Build Coastguard Worker /* tell driver that we're done rendering to this texture. */
490*61046927SAndroid Build Coastguard Worker if (rb)
491*61046927SAndroid Build Coastguard Worker finish_render_texture(ctx, rb);
492*61046927SAndroid Build Coastguard Worker
493*61046927SAndroid Build Coastguard Worker if (att->Type == GL_TEXTURE) {
494*61046927SAndroid Build Coastguard Worker assert(att->Texture);
495*61046927SAndroid Build Coastguard Worker _mesa_reference_texobj(&att->Texture, NULL); /* unbind */
496*61046927SAndroid Build Coastguard Worker assert(!att->Texture);
497*61046927SAndroid Build Coastguard Worker }
498*61046927SAndroid Build Coastguard Worker if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
499*61046927SAndroid Build Coastguard Worker assert(!att->Texture);
500*61046927SAndroid Build Coastguard Worker _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */
501*61046927SAndroid Build Coastguard Worker assert(!att->Renderbuffer);
502*61046927SAndroid Build Coastguard Worker }
503*61046927SAndroid Build Coastguard Worker att->Type = GL_NONE;
504*61046927SAndroid Build Coastguard Worker att->Complete = GL_TRUE;
505*61046927SAndroid Build Coastguard Worker }
506*61046927SAndroid Build Coastguard Worker
507*61046927SAndroid Build Coastguard Worker /**
508*61046927SAndroid Build Coastguard Worker * Verify a couple error conditions that will lead to an incomplete FBO and
509*61046927SAndroid Build Coastguard Worker * may cause problems for the driver's RenderTexture path.
510*61046927SAndroid Build Coastguard Worker */
511*61046927SAndroid Build Coastguard Worker static bool
driver_RenderTexture_is_safe(const struct gl_renderbuffer_attachment * att)512*61046927SAndroid Build Coastguard Worker driver_RenderTexture_is_safe(const struct gl_renderbuffer_attachment *att)
513*61046927SAndroid Build Coastguard Worker {
514*61046927SAndroid Build Coastguard Worker const struct gl_texture_image *const texImage =
515*61046927SAndroid Build Coastguard Worker att->Texture->Image[att->CubeMapFace][att->TextureLevel];
516*61046927SAndroid Build Coastguard Worker
517*61046927SAndroid Build Coastguard Worker if (!texImage ||
518*61046927SAndroid Build Coastguard Worker !texImage->pt ||
519*61046927SAndroid Build Coastguard Worker _mesa_is_zero_size_texture(texImage))
520*61046927SAndroid Build Coastguard Worker return false;
521*61046927SAndroid Build Coastguard Worker
522*61046927SAndroid Build Coastguard Worker if ((texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY
523*61046927SAndroid Build Coastguard Worker && att->Zoffset >= texImage->Height)
524*61046927SAndroid Build Coastguard Worker || (texImage->TexObject->Target != GL_TEXTURE_1D_ARRAY
525*61046927SAndroid Build Coastguard Worker && att->Zoffset >= texImage->Depth))
526*61046927SAndroid Build Coastguard Worker return false;
527*61046927SAndroid Build Coastguard Worker
528*61046927SAndroid Build Coastguard Worker return true;
529*61046927SAndroid Build Coastguard Worker }
530*61046927SAndroid Build Coastguard Worker
531*61046927SAndroid Build Coastguard Worker static struct gl_renderbuffer *
new_renderbuffer(struct gl_context * ctx,GLuint name)532*61046927SAndroid Build Coastguard Worker new_renderbuffer(struct gl_context *ctx, GLuint name)
533*61046927SAndroid Build Coastguard Worker {
534*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
535*61046927SAndroid Build Coastguard Worker if (rb) {
536*61046927SAndroid Build Coastguard Worker assert(name != 0);
537*61046927SAndroid Build Coastguard Worker _mesa_init_renderbuffer(rb, name);
538*61046927SAndroid Build Coastguard Worker return rb;
539*61046927SAndroid Build Coastguard Worker }
540*61046927SAndroid Build Coastguard Worker return NULL;
541*61046927SAndroid Build Coastguard Worker }
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker /**
544*61046927SAndroid Build Coastguard Worker * Create a renderbuffer which will be set up by the driver to wrap the
545*61046927SAndroid Build Coastguard Worker * texture image slice.
546*61046927SAndroid Build Coastguard Worker *
547*61046927SAndroid Build Coastguard Worker * By using a gl_renderbuffer (like user-allocated renderbuffers), drivers get
548*61046927SAndroid Build Coastguard Worker * to share most of their framebuffer rendering code between winsys,
549*61046927SAndroid Build Coastguard Worker * renderbuffer, and texture attachments.
550*61046927SAndroid Build Coastguard Worker *
551*61046927SAndroid Build Coastguard Worker * The allocated renderbuffer uses a non-zero Name so that drivers can check
552*61046927SAndroid Build Coastguard Worker * it for determining vertical orientation, but we use ~0 to make it fairly
553*61046927SAndroid Build Coastguard Worker * unambiguous with actual user (non-texture) renderbuffers.
554*61046927SAndroid Build Coastguard Worker */
555*61046927SAndroid Build Coastguard Worker void
_mesa_update_texture_renderbuffer(struct gl_context * ctx,struct gl_framebuffer * fb,struct gl_renderbuffer_attachment * att)556*61046927SAndroid Build Coastguard Worker _mesa_update_texture_renderbuffer(struct gl_context *ctx,
557*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
558*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att)
559*61046927SAndroid Build Coastguard Worker {
560*61046927SAndroid Build Coastguard Worker struct gl_texture_image *texImage;
561*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb;
562*61046927SAndroid Build Coastguard Worker
563*61046927SAndroid Build Coastguard Worker texImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
564*61046927SAndroid Build Coastguard Worker
565*61046927SAndroid Build Coastguard Worker rb = att->Renderbuffer;
566*61046927SAndroid Build Coastguard Worker if (!rb) {
567*61046927SAndroid Build Coastguard Worker rb = new_renderbuffer(ctx, ~0);
568*61046927SAndroid Build Coastguard Worker if (!rb) {
569*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()");
570*61046927SAndroid Build Coastguard Worker return;
571*61046927SAndroid Build Coastguard Worker }
572*61046927SAndroid Build Coastguard Worker att->Renderbuffer = rb;
573*61046927SAndroid Build Coastguard Worker
574*61046927SAndroid Build Coastguard Worker /* This can't get called on a texture renderbuffer, so set it to NULL
575*61046927SAndroid Build Coastguard Worker * for clarity compared to user renderbuffers.
576*61046927SAndroid Build Coastguard Worker */
577*61046927SAndroid Build Coastguard Worker rb->AllocStorage = NULL;
578*61046927SAndroid Build Coastguard Worker }
579*61046927SAndroid Build Coastguard Worker
580*61046927SAndroid Build Coastguard Worker if (!texImage)
581*61046927SAndroid Build Coastguard Worker return;
582*61046927SAndroid Build Coastguard Worker
583*61046927SAndroid Build Coastguard Worker rb->_BaseFormat = texImage->_BaseFormat;
584*61046927SAndroid Build Coastguard Worker rb->Format = texImage->TexFormat;
585*61046927SAndroid Build Coastguard Worker rb->InternalFormat = texImage->InternalFormat;
586*61046927SAndroid Build Coastguard Worker rb->Width = texImage->Width2;
587*61046927SAndroid Build Coastguard Worker rb->Height = texImage->Height2;
588*61046927SAndroid Build Coastguard Worker rb->Depth = texImage->Depth2;
589*61046927SAndroid Build Coastguard Worker rb->NumSamples = texImage->NumSamples;
590*61046927SAndroid Build Coastguard Worker rb->NumStorageSamples = texImage->NumSamples;
591*61046927SAndroid Build Coastguard Worker rb->TexImage = texImage;
592*61046927SAndroid Build Coastguard Worker
593*61046927SAndroid Build Coastguard Worker if (driver_RenderTexture_is_safe(att))
594*61046927SAndroid Build Coastguard Worker render_texture(ctx, fb, att);
595*61046927SAndroid Build Coastguard Worker }
596*61046927SAndroid Build Coastguard Worker
597*61046927SAndroid Build Coastguard Worker /**
598*61046927SAndroid Build Coastguard Worker * Bind a texture object to an attachment point.
599*61046927SAndroid Build Coastguard Worker * The previous binding, if any, will be removed first.
600*61046927SAndroid Build Coastguard Worker */
601*61046927SAndroid Build Coastguard Worker static void
set_texture_attachment(struct gl_context * ctx,struct gl_framebuffer * fb,struct gl_renderbuffer_attachment * att,struct gl_texture_object * texObj,GLenum texTarget,GLuint level,GLsizei samples,GLuint layer,GLboolean layered,GLint numviews)602*61046927SAndroid Build Coastguard Worker set_texture_attachment(struct gl_context *ctx,
603*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
604*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att,
605*61046927SAndroid Build Coastguard Worker struct gl_texture_object *texObj,
606*61046927SAndroid Build Coastguard Worker GLenum texTarget, GLuint level, GLsizei samples,
607*61046927SAndroid Build Coastguard Worker GLuint layer, GLboolean layered, GLint numviews)
608*61046927SAndroid Build Coastguard Worker {
609*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = att->Renderbuffer;
610*61046927SAndroid Build Coastguard Worker
611*61046927SAndroid Build Coastguard Worker if (rb)
612*61046927SAndroid Build Coastguard Worker finish_render_texture(ctx, rb);
613*61046927SAndroid Build Coastguard Worker
614*61046927SAndroid Build Coastguard Worker if (att->Texture == texObj) {
615*61046927SAndroid Build Coastguard Worker /* re-attaching same texture */
616*61046927SAndroid Build Coastguard Worker assert(att->Type == GL_TEXTURE);
617*61046927SAndroid Build Coastguard Worker }
618*61046927SAndroid Build Coastguard Worker else {
619*61046927SAndroid Build Coastguard Worker /* new attachment */
620*61046927SAndroid Build Coastguard Worker remove_attachment(ctx, att);
621*61046927SAndroid Build Coastguard Worker att->Type = GL_TEXTURE;
622*61046927SAndroid Build Coastguard Worker assert(!att->Texture);
623*61046927SAndroid Build Coastguard Worker _mesa_reference_texobj(&att->Texture, texObj);
624*61046927SAndroid Build Coastguard Worker }
625*61046927SAndroid Build Coastguard Worker invalidate_framebuffer(fb);
626*61046927SAndroid Build Coastguard Worker
627*61046927SAndroid Build Coastguard Worker /* always update these fields */
628*61046927SAndroid Build Coastguard Worker att->TextureLevel = level;
629*61046927SAndroid Build Coastguard Worker att->NumSamples = samples;
630*61046927SAndroid Build Coastguard Worker att->CubeMapFace = _mesa_tex_target_to_face(texTarget);
631*61046927SAndroid Build Coastguard Worker att->Zoffset = layer;
632*61046927SAndroid Build Coastguard Worker att->Layered = layered;
633*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
634*61046927SAndroid Build Coastguard Worker att->NumViews = numviews;
635*61046927SAndroid Build Coastguard Worker
636*61046927SAndroid Build Coastguard Worker _mesa_update_texture_renderbuffer(ctx, fb, att);
637*61046927SAndroid Build Coastguard Worker }
638*61046927SAndroid Build Coastguard Worker
639*61046927SAndroid Build Coastguard Worker
640*61046927SAndroid Build Coastguard Worker /**
641*61046927SAndroid Build Coastguard Worker * Bind a renderbuffer to an attachment point.
642*61046927SAndroid Build Coastguard Worker * The previous binding, if any, will be removed first.
643*61046927SAndroid Build Coastguard Worker */
644*61046927SAndroid Build Coastguard Worker static void
set_renderbuffer_attachment(struct gl_context * ctx,struct gl_renderbuffer_attachment * att,struct gl_renderbuffer * rb)645*61046927SAndroid Build Coastguard Worker set_renderbuffer_attachment(struct gl_context *ctx,
646*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att,
647*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb)
648*61046927SAndroid Build Coastguard Worker {
649*61046927SAndroid Build Coastguard Worker /* XXX check if re-doing same attachment, exit early */
650*61046927SAndroid Build Coastguard Worker remove_attachment(ctx, att);
651*61046927SAndroid Build Coastguard Worker att->Type = GL_RENDERBUFFER_EXT;
652*61046927SAndroid Build Coastguard Worker att->Texture = NULL; /* just to be safe */
653*61046927SAndroid Build Coastguard Worker att->Layered = GL_FALSE;
654*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
655*61046927SAndroid Build Coastguard Worker _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
656*61046927SAndroid Build Coastguard Worker }
657*61046927SAndroid Build Coastguard Worker
658*61046927SAndroid Build Coastguard Worker
659*61046927SAndroid Build Coastguard Worker /**
660*61046927SAndroid Build Coastguard Worker * Fallback for ctx->Driver.FramebufferRenderbuffer()
661*61046927SAndroid Build Coastguard Worker * Attach a renderbuffer object to a framebuffer object.
662*61046927SAndroid Build Coastguard Worker */
663*61046927SAndroid Build Coastguard Worker static void
_mesa_FramebufferRenderbuffer_sw(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum attachment,struct gl_renderbuffer * rb)664*61046927SAndroid Build Coastguard Worker _mesa_FramebufferRenderbuffer_sw(struct gl_context *ctx,
665*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
666*61046927SAndroid Build Coastguard Worker GLenum attachment,
667*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb)
668*61046927SAndroid Build Coastguard Worker {
669*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att;
670*61046927SAndroid Build Coastguard Worker
671*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&fb->Mutex);
672*61046927SAndroid Build Coastguard Worker
673*61046927SAndroid Build Coastguard Worker att = get_attachment(ctx, fb, attachment, NULL);
674*61046927SAndroid Build Coastguard Worker assert(att);
675*61046927SAndroid Build Coastguard Worker if (rb) {
676*61046927SAndroid Build Coastguard Worker set_renderbuffer_attachment(ctx, att, rb);
677*61046927SAndroid Build Coastguard Worker if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
678*61046927SAndroid Build Coastguard Worker /* do stencil attachment here (depth already done above) */
679*61046927SAndroid Build Coastguard Worker att = get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT, NULL);
680*61046927SAndroid Build Coastguard Worker assert(att);
681*61046927SAndroid Build Coastguard Worker set_renderbuffer_attachment(ctx, att, rb);
682*61046927SAndroid Build Coastguard Worker }
683*61046927SAndroid Build Coastguard Worker rb->AttachedAnytime = GL_TRUE;
684*61046927SAndroid Build Coastguard Worker }
685*61046927SAndroid Build Coastguard Worker else {
686*61046927SAndroid Build Coastguard Worker remove_attachment(ctx, att);
687*61046927SAndroid Build Coastguard Worker if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
688*61046927SAndroid Build Coastguard Worker /* detach stencil (depth was detached above) */
689*61046927SAndroid Build Coastguard Worker att = get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT, NULL);
690*61046927SAndroid Build Coastguard Worker assert(att);
691*61046927SAndroid Build Coastguard Worker remove_attachment(ctx, att);
692*61046927SAndroid Build Coastguard Worker }
693*61046927SAndroid Build Coastguard Worker }
694*61046927SAndroid Build Coastguard Worker
695*61046927SAndroid Build Coastguard Worker invalidate_framebuffer(fb);
696*61046927SAndroid Build Coastguard Worker
697*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&fb->Mutex);
698*61046927SAndroid Build Coastguard Worker }
699*61046927SAndroid Build Coastguard Worker
700*61046927SAndroid Build Coastguard Worker /**
701*61046927SAndroid Build Coastguard Worker * Return true if the framebuffer has a combined depth/stencil
702*61046927SAndroid Build Coastguard Worker * renderbuffer attached.
703*61046927SAndroid Build Coastguard Worker */
704*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_has_depthstencil_combined(const struct gl_framebuffer * fb)705*61046927SAndroid Build Coastguard Worker _mesa_has_depthstencil_combined(const struct gl_framebuffer *fb)
706*61046927SAndroid Build Coastguard Worker {
707*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *depth =
708*61046927SAndroid Build Coastguard Worker &fb->Attachment[BUFFER_DEPTH];
709*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *stencil =
710*61046927SAndroid Build Coastguard Worker &fb->Attachment[BUFFER_STENCIL];
711*61046927SAndroid Build Coastguard Worker
712*61046927SAndroid Build Coastguard Worker if (depth->Type == stencil->Type) {
713*61046927SAndroid Build Coastguard Worker if (depth->Type == GL_RENDERBUFFER_EXT &&
714*61046927SAndroid Build Coastguard Worker depth->Renderbuffer == stencil->Renderbuffer)
715*61046927SAndroid Build Coastguard Worker return GL_TRUE;
716*61046927SAndroid Build Coastguard Worker
717*61046927SAndroid Build Coastguard Worker if (depth->Type == GL_TEXTURE &&
718*61046927SAndroid Build Coastguard Worker depth->Texture == stencil->Texture)
719*61046927SAndroid Build Coastguard Worker return GL_TRUE;
720*61046927SAndroid Build Coastguard Worker }
721*61046927SAndroid Build Coastguard Worker
722*61046927SAndroid Build Coastguard Worker return GL_FALSE;
723*61046927SAndroid Build Coastguard Worker }
724*61046927SAndroid Build Coastguard Worker
725*61046927SAndroid Build Coastguard Worker
726*61046927SAndroid Build Coastguard Worker /**
727*61046927SAndroid Build Coastguard Worker * For debug only.
728*61046927SAndroid Build Coastguard Worker */
729*61046927SAndroid Build Coastguard Worker static void
att_incomplete(const char * msg)730*61046927SAndroid Build Coastguard Worker att_incomplete(const char *msg)
731*61046927SAndroid Build Coastguard Worker {
732*61046927SAndroid Build Coastguard Worker if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) {
733*61046927SAndroid Build Coastguard Worker _mesa_debug(NULL, "attachment incomplete: %s\n", msg);
734*61046927SAndroid Build Coastguard Worker }
735*61046927SAndroid Build Coastguard Worker }
736*61046927SAndroid Build Coastguard Worker
737*61046927SAndroid Build Coastguard Worker
738*61046927SAndroid Build Coastguard Worker /**
739*61046927SAndroid Build Coastguard Worker * For debug only.
740*61046927SAndroid Build Coastguard Worker */
741*61046927SAndroid Build Coastguard Worker static void
fbo_incomplete(struct gl_context * ctx,const char * msg,int index)742*61046927SAndroid Build Coastguard Worker fbo_incomplete(struct gl_context *ctx, const char *msg, int index)
743*61046927SAndroid Build Coastguard Worker {
744*61046927SAndroid Build Coastguard Worker static GLuint msg_id;
745*61046927SAndroid Build Coastguard Worker
746*61046927SAndroid Build Coastguard Worker _mesa_gl_debugf(ctx, &msg_id,
747*61046927SAndroid Build Coastguard Worker MESA_DEBUG_SOURCE_API,
748*61046927SAndroid Build Coastguard Worker MESA_DEBUG_TYPE_OTHER,
749*61046927SAndroid Build Coastguard Worker MESA_DEBUG_SEVERITY_MEDIUM,
750*61046927SAndroid Build Coastguard Worker "FBO incomplete: %s [%d]\n", msg, index);
751*61046927SAndroid Build Coastguard Worker
752*61046927SAndroid Build Coastguard Worker if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) {
753*61046927SAndroid Build Coastguard Worker _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
754*61046927SAndroid Build Coastguard Worker }
755*61046927SAndroid Build Coastguard Worker
756*61046927SAndroid Build Coastguard Worker _mesa_update_valid_to_render_state(ctx);
757*61046927SAndroid Build Coastguard Worker }
758*61046927SAndroid Build Coastguard Worker
759*61046927SAndroid Build Coastguard Worker
760*61046927SAndroid Build Coastguard Worker /**
761*61046927SAndroid Build Coastguard Worker * Is the given base format a legal format for a color renderbuffer?
762*61046927SAndroid Build Coastguard Worker */
763*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_is_legal_color_format(const struct gl_context * ctx,GLenum baseFormat)764*61046927SAndroid Build Coastguard Worker _mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat)
765*61046927SAndroid Build Coastguard Worker {
766*61046927SAndroid Build Coastguard Worker switch (baseFormat) {
767*61046927SAndroid Build Coastguard Worker case GL_RGB:
768*61046927SAndroid Build Coastguard Worker case GL_RGBA:
769*61046927SAndroid Build Coastguard Worker return GL_TRUE;
770*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE:
771*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA:
772*61046927SAndroid Build Coastguard Worker case GL_INTENSITY:
773*61046927SAndroid Build Coastguard Worker case GL_ALPHA:
774*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
775*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object;
776*61046927SAndroid Build Coastguard Worker case GL_RED:
777*61046927SAndroid Build Coastguard Worker case GL_RG:
778*61046927SAndroid Build Coastguard Worker return ctx->Extensions.ARB_texture_rg;
779*61046927SAndroid Build Coastguard Worker default:
780*61046927SAndroid Build Coastguard Worker return GL_FALSE;
781*61046927SAndroid Build Coastguard Worker }
782*61046927SAndroid Build Coastguard Worker }
783*61046927SAndroid Build Coastguard Worker
784*61046927SAndroid Build Coastguard Worker static GLboolean
is_float_format(GLenum internalFormat)785*61046927SAndroid Build Coastguard Worker is_float_format(GLenum internalFormat)
786*61046927SAndroid Build Coastguard Worker {
787*61046927SAndroid Build Coastguard Worker switch (internalFormat) {
788*61046927SAndroid Build Coastguard Worker case GL_R16F:
789*61046927SAndroid Build Coastguard Worker case GL_RG16F:
790*61046927SAndroid Build Coastguard Worker case GL_RGB16F:
791*61046927SAndroid Build Coastguard Worker case GL_RGBA16F:
792*61046927SAndroid Build Coastguard Worker case GL_R32F:
793*61046927SAndroid Build Coastguard Worker case GL_RG32F:
794*61046927SAndroid Build Coastguard Worker case GL_RGB32F:
795*61046927SAndroid Build Coastguard Worker case GL_RGBA32F:
796*61046927SAndroid Build Coastguard Worker return true;
797*61046927SAndroid Build Coastguard Worker default:
798*61046927SAndroid Build Coastguard Worker return false;
799*61046927SAndroid Build Coastguard Worker }
800*61046927SAndroid Build Coastguard Worker }
801*61046927SAndroid Build Coastguard Worker
802*61046927SAndroid Build Coastguard Worker /**
803*61046927SAndroid Build Coastguard Worker * Is the given base format a legal format for a color renderbuffer?
804*61046927SAndroid Build Coastguard Worker */
805*61046927SAndroid Build Coastguard Worker static GLboolean
is_format_color_renderable(const struct gl_context * ctx,mesa_format format,GLenum internalFormat)806*61046927SAndroid Build Coastguard Worker is_format_color_renderable(const struct gl_context *ctx, mesa_format format,
807*61046927SAndroid Build Coastguard Worker GLenum internalFormat)
808*61046927SAndroid Build Coastguard Worker {
809*61046927SAndroid Build Coastguard Worker const GLenum baseFormat =
810*61046927SAndroid Build Coastguard Worker _mesa_get_format_base_format(format);
811*61046927SAndroid Build Coastguard Worker GLboolean valid;
812*61046927SAndroid Build Coastguard Worker
813*61046927SAndroid Build Coastguard Worker valid = _mesa_is_legal_color_format(ctx, baseFormat);
814*61046927SAndroid Build Coastguard Worker if (!valid || _mesa_is_desktop_gl(ctx)) {
815*61046927SAndroid Build Coastguard Worker return valid;
816*61046927SAndroid Build Coastguard Worker }
817*61046927SAndroid Build Coastguard Worker
818*61046927SAndroid Build Coastguard Worker /* Reject additional cases for GLES */
819*61046927SAndroid Build Coastguard Worker switch (internalFormat) {
820*61046927SAndroid Build Coastguard Worker case GL_R8_SNORM:
821*61046927SAndroid Build Coastguard Worker case GL_RG8_SNORM:
822*61046927SAndroid Build Coastguard Worker case GL_RGBA8_SNORM:
823*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_render_snorm(ctx);
824*61046927SAndroid Build Coastguard Worker case GL_R16_SNORM:
825*61046927SAndroid Build Coastguard Worker case GL_RG16_SNORM:
826*61046927SAndroid Build Coastguard Worker case GL_RGBA16_SNORM:
827*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_norm16(ctx) &&
828*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_render_snorm(ctx);
829*61046927SAndroid Build Coastguard Worker case GL_R:
830*61046927SAndroid Build Coastguard Worker case GL_RG:
831*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_rg(ctx);
832*61046927SAndroid Build Coastguard Worker case GL_R16F:
833*61046927SAndroid Build Coastguard Worker case GL_RG16F:
834*61046927SAndroid Build Coastguard Worker return _mesa_is_gles3(ctx) ||
835*61046927SAndroid Build Coastguard Worker (_mesa_has_EXT_color_buffer_half_float(ctx) &&
836*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_texture_rg(ctx));
837*61046927SAndroid Build Coastguard Worker case GL_RGBA16F:
838*61046927SAndroid Build Coastguard Worker return _mesa_is_gles3(ctx) ||
839*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_color_buffer_half_float(ctx);
840*61046927SAndroid Build Coastguard Worker case GL_RGBA32F:
841*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_color_buffer_float(ctx);
842*61046927SAndroid Build Coastguard Worker case GL_RGB16F:
843*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_color_buffer_half_float(ctx);
844*61046927SAndroid Build Coastguard Worker case GL_RGB10_A2:
845*61046927SAndroid Build Coastguard Worker return _mesa_is_gles3(ctx);
846*61046927SAndroid Build Coastguard Worker case GL_RGB32F:
847*61046927SAndroid Build Coastguard Worker case GL_RGB32I:
848*61046927SAndroid Build Coastguard Worker case GL_RGB32UI:
849*61046927SAndroid Build Coastguard Worker case GL_RGB16I:
850*61046927SAndroid Build Coastguard Worker case GL_RGB16UI:
851*61046927SAndroid Build Coastguard Worker case GL_RGB8_SNORM:
852*61046927SAndroid Build Coastguard Worker case GL_RGB8I:
853*61046927SAndroid Build Coastguard Worker case GL_RGB8UI:
854*61046927SAndroid Build Coastguard Worker case GL_SRGB8:
855*61046927SAndroid Build Coastguard Worker case GL_RGB10:
856*61046927SAndroid Build Coastguard Worker case GL_RGB9_E5:
857*61046927SAndroid Build Coastguard Worker case GL_SR8_EXT:
858*61046927SAndroid Build Coastguard Worker case GL_SRG8_EXT:
859*61046927SAndroid Build Coastguard Worker return GL_FALSE;
860*61046927SAndroid Build Coastguard Worker default:
861*61046927SAndroid Build Coastguard Worker break;
862*61046927SAndroid Build Coastguard Worker }
863*61046927SAndroid Build Coastguard Worker
864*61046927SAndroid Build Coastguard Worker if (internalFormat != GL_RGB10_A2 &&
865*61046927SAndroid Build Coastguard Worker (format == MESA_FORMAT_B10G10R10A2_UNORM ||
866*61046927SAndroid Build Coastguard Worker format == MESA_FORMAT_B10G10R10X2_UNORM ||
867*61046927SAndroid Build Coastguard Worker format == MESA_FORMAT_R10G10B10A2_UNORM ||
868*61046927SAndroid Build Coastguard Worker format == MESA_FORMAT_R10G10B10X2_UNORM)) {
869*61046927SAndroid Build Coastguard Worker return GL_FALSE;
870*61046927SAndroid Build Coastguard Worker }
871*61046927SAndroid Build Coastguard Worker
872*61046927SAndroid Build Coastguard Worker return GL_TRUE;
873*61046927SAndroid Build Coastguard Worker }
874*61046927SAndroid Build Coastguard Worker
875*61046927SAndroid Build Coastguard Worker /**
876*61046927SAndroid Build Coastguard Worker * Check that implements various limitations of floating point
877*61046927SAndroid Build Coastguard Worker * rendering extensions on OpenGL ES.
878*61046927SAndroid Build Coastguard Worker *
879*61046927SAndroid Build Coastguard Worker * Check passes if texture format is not floating point or
880*61046927SAndroid Build Coastguard Worker * is floating point and is color renderable.
881*61046927SAndroid Build Coastguard Worker *
882*61046927SAndroid Build Coastguard Worker * Check fails if texture format is floating point and cannot
883*61046927SAndroid Build Coastguard Worker * be rendered to with current context and set of supported
884*61046927SAndroid Build Coastguard Worker * extensions.
885*61046927SAndroid Build Coastguard Worker */
886*61046927SAndroid Build Coastguard Worker static GLboolean
gles_check_float_renderable(const struct gl_context * ctx,struct gl_renderbuffer_attachment * att)887*61046927SAndroid Build Coastguard Worker gles_check_float_renderable(const struct gl_context *ctx,
888*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att)
889*61046927SAndroid Build Coastguard Worker {
890*61046927SAndroid Build Coastguard Worker /* Only check floating point texture cases. */
891*61046927SAndroid Build Coastguard Worker if (!att->Texture || !is_float_format(att->Renderbuffer->InternalFormat))
892*61046927SAndroid Build Coastguard Worker return true;
893*61046927SAndroid Build Coastguard Worker
894*61046927SAndroid Build Coastguard Worker /* GL_RGBA with unsized GL_FLOAT type, no extension can make this
895*61046927SAndroid Build Coastguard Worker * color renderable.
896*61046927SAndroid Build Coastguard Worker */
897*61046927SAndroid Build Coastguard Worker if (att->Texture->_IsFloat && att->Renderbuffer->_BaseFormat == GL_RGBA)
898*61046927SAndroid Build Coastguard Worker return false;
899*61046927SAndroid Build Coastguard Worker
900*61046927SAndroid Build Coastguard Worker /* Unsized GL_HALF_FLOAT supported only with EXT_color_buffer_half_float. */
901*61046927SAndroid Build Coastguard Worker if (att->Texture->_IsHalfFloat && !_mesa_has_EXT_color_buffer_half_float(ctx))
902*61046927SAndroid Build Coastguard Worker return false;
903*61046927SAndroid Build Coastguard Worker
904*61046927SAndroid Build Coastguard Worker const struct gl_texture_object *texObj = att->Texture;
905*61046927SAndroid Build Coastguard Worker const struct gl_texture_image *texImage =
906*61046927SAndroid Build Coastguard Worker texObj->Image[att->CubeMapFace][att->TextureLevel];
907*61046927SAndroid Build Coastguard Worker
908*61046927SAndroid Build Coastguard Worker return is_format_color_renderable(ctx, texImage->TexFormat,
909*61046927SAndroid Build Coastguard Worker att->Renderbuffer->InternalFormat);
910*61046927SAndroid Build Coastguard Worker }
911*61046927SAndroid Build Coastguard Worker
912*61046927SAndroid Build Coastguard Worker /**
913*61046927SAndroid Build Coastguard Worker * Is the given base format a legal format for a depth/stencil renderbuffer?
914*61046927SAndroid Build Coastguard Worker */
915*61046927SAndroid Build Coastguard Worker static GLboolean
is_legal_depth_format(const struct gl_context * ctx,GLenum baseFormat)916*61046927SAndroid Build Coastguard Worker is_legal_depth_format(const struct gl_context *ctx, GLenum baseFormat)
917*61046927SAndroid Build Coastguard Worker {
918*61046927SAndroid Build Coastguard Worker switch (baseFormat) {
919*61046927SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT:
920*61046927SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_EXT:
921*61046927SAndroid Build Coastguard Worker return GL_TRUE;
922*61046927SAndroid Build Coastguard Worker default:
923*61046927SAndroid Build Coastguard Worker return GL_FALSE;
924*61046927SAndroid Build Coastguard Worker }
925*61046927SAndroid Build Coastguard Worker }
926*61046927SAndroid Build Coastguard Worker
927*61046927SAndroid Build Coastguard Worker
928*61046927SAndroid Build Coastguard Worker /**
929*61046927SAndroid Build Coastguard Worker * Test if an attachment point is complete and update its Complete field.
930*61046927SAndroid Build Coastguard Worker * \param format if GL_COLOR, this is a color attachment point,
931*61046927SAndroid Build Coastguard Worker * if GL_DEPTH, this is a depth component attachment point,
932*61046927SAndroid Build Coastguard Worker * if GL_STENCIL, this is a stencil component attachment point.
933*61046927SAndroid Build Coastguard Worker */
934*61046927SAndroid Build Coastguard Worker static void
test_attachment_completeness(const struct gl_context * ctx,GLenum format,struct gl_renderbuffer_attachment * att)935*61046927SAndroid Build Coastguard Worker test_attachment_completeness(const struct gl_context *ctx, GLenum format,
936*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att)
937*61046927SAndroid Build Coastguard Worker {
938*61046927SAndroid Build Coastguard Worker assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL);
939*61046927SAndroid Build Coastguard Worker
940*61046927SAndroid Build Coastguard Worker /* assume complete */
941*61046927SAndroid Build Coastguard Worker att->Complete = GL_TRUE;
942*61046927SAndroid Build Coastguard Worker
943*61046927SAndroid Build Coastguard Worker /* Look for reasons why the attachment might be incomplete */
944*61046927SAndroid Build Coastguard Worker if (att->Type == GL_TEXTURE) {
945*61046927SAndroid Build Coastguard Worker const struct gl_texture_object *texObj = att->Texture;
946*61046927SAndroid Build Coastguard Worker const struct gl_texture_image *texImage;
947*61046927SAndroid Build Coastguard Worker GLenum baseFormat;
948*61046927SAndroid Build Coastguard Worker
949*61046927SAndroid Build Coastguard Worker if (!texObj) {
950*61046927SAndroid Build Coastguard Worker att_incomplete("no texobj");
951*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
952*61046927SAndroid Build Coastguard Worker return;
953*61046927SAndroid Build Coastguard Worker }
954*61046927SAndroid Build Coastguard Worker
955*61046927SAndroid Build Coastguard Worker texImage = texObj->Image[att->CubeMapFace][att->TextureLevel];
956*61046927SAndroid Build Coastguard Worker if (!texImage) {
957*61046927SAndroid Build Coastguard Worker att_incomplete("no teximage");
958*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
959*61046927SAndroid Build Coastguard Worker return;
960*61046927SAndroid Build Coastguard Worker }
961*61046927SAndroid Build Coastguard Worker
962*61046927SAndroid Build Coastguard Worker /* Mutable non base level texture as framebuffer attachment
963*61046927SAndroid Build Coastguard Worker * must be mipmap complete.
964*61046927SAndroid Build Coastguard Worker */
965*61046927SAndroid Build Coastguard Worker if (texImage->Level > texObj->Attrib.BaseLevel &&
966*61046927SAndroid Build Coastguard Worker !texObj->_MipmapComplete) {
967*61046927SAndroid Build Coastguard Worker /* Test if texture has become mipmap complete meanwhile. */
968*61046927SAndroid Build Coastguard Worker _mesa_test_texobj_completeness(ctx, att->Texture);
969*61046927SAndroid Build Coastguard Worker if (!texObj->_MipmapComplete) {
970*61046927SAndroid Build Coastguard Worker att_incomplete("texture attachment not mipmap complete");
971*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
972*61046927SAndroid Build Coastguard Worker return;
973*61046927SAndroid Build Coastguard Worker }
974*61046927SAndroid Build Coastguard Worker }
975*61046927SAndroid Build Coastguard Worker
976*61046927SAndroid Build Coastguard Worker if (texImage->Width < 1 || texImage->Height < 1) {
977*61046927SAndroid Build Coastguard Worker att_incomplete("teximage width/height=0");
978*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
979*61046927SAndroid Build Coastguard Worker return;
980*61046927SAndroid Build Coastguard Worker }
981*61046927SAndroid Build Coastguard Worker
982*61046927SAndroid Build Coastguard Worker switch (texObj->Target) {
983*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
984*61046927SAndroid Build Coastguard Worker if (att->Zoffset >= texImage->Depth) {
985*61046927SAndroid Build Coastguard Worker att_incomplete("bad z offset");
986*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
987*61046927SAndroid Build Coastguard Worker return;
988*61046927SAndroid Build Coastguard Worker }
989*61046927SAndroid Build Coastguard Worker break;
990*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D_ARRAY:
991*61046927SAndroid Build Coastguard Worker if (att->Zoffset >= texImage->Height) {
992*61046927SAndroid Build Coastguard Worker att_incomplete("bad 1D-array layer");
993*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
994*61046927SAndroid Build Coastguard Worker return;
995*61046927SAndroid Build Coastguard Worker }
996*61046927SAndroid Build Coastguard Worker break;
997*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY:
998*61046927SAndroid Build Coastguard Worker if (att->Zoffset >= texImage->Depth) {
999*61046927SAndroid Build Coastguard Worker att_incomplete("bad 2D-array layer");
1000*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1001*61046927SAndroid Build Coastguard Worker return;
1002*61046927SAndroid Build Coastguard Worker }
1003*61046927SAndroid Build Coastguard Worker break;
1004*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_ARRAY:
1005*61046927SAndroid Build Coastguard Worker if (att->Zoffset >= texImage->Depth) {
1006*61046927SAndroid Build Coastguard Worker att_incomplete("bad cube-array layer");
1007*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1008*61046927SAndroid Build Coastguard Worker return;
1009*61046927SAndroid Build Coastguard Worker }
1010*61046927SAndroid Build Coastguard Worker break;
1011*61046927SAndroid Build Coastguard Worker }
1012*61046927SAndroid Build Coastguard Worker
1013*61046927SAndroid Build Coastguard Worker baseFormat = texImage->_BaseFormat;
1014*61046927SAndroid Build Coastguard Worker
1015*61046927SAndroid Build Coastguard Worker if (format == GL_COLOR) {
1016*61046927SAndroid Build Coastguard Worker if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
1017*61046927SAndroid Build Coastguard Worker att_incomplete("bad format");
1018*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1019*61046927SAndroid Build Coastguard Worker return;
1020*61046927SAndroid Build Coastguard Worker }
1021*61046927SAndroid Build Coastguard Worker if (_mesa_is_format_compressed(texImage->TexFormat)) {
1022*61046927SAndroid Build Coastguard Worker att_incomplete("compressed internalformat");
1023*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1024*61046927SAndroid Build Coastguard Worker return;
1025*61046927SAndroid Build Coastguard Worker }
1026*61046927SAndroid Build Coastguard Worker
1027*61046927SAndroid Build Coastguard Worker /* OES_texture_float allows creation and use of floating point
1028*61046927SAndroid Build Coastguard Worker * textures with GL_FLOAT, GL_HALF_FLOAT but it does not allow
1029*61046927SAndroid Build Coastguard Worker * these textures to be used as a render target, this is done via
1030*61046927SAndroid Build Coastguard Worker * GL_EXT_color_buffer(_half)_float with set of new sized types.
1031*61046927SAndroid Build Coastguard Worker */
1032*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles(ctx) && !gles_check_float_renderable(ctx, att)) {
1033*61046927SAndroid Build Coastguard Worker att_incomplete("bad internal format");
1034*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1035*61046927SAndroid Build Coastguard Worker return;
1036*61046927SAndroid Build Coastguard Worker }
1037*61046927SAndroid Build Coastguard Worker }
1038*61046927SAndroid Build Coastguard Worker else if (format == GL_DEPTH) {
1039*61046927SAndroid Build Coastguard Worker if (baseFormat != GL_DEPTH_COMPONENT &&
1040*61046927SAndroid Build Coastguard Worker baseFormat != GL_DEPTH_STENCIL) {
1041*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1042*61046927SAndroid Build Coastguard Worker att_incomplete("bad depth format");
1043*61046927SAndroid Build Coastguard Worker return;
1044*61046927SAndroid Build Coastguard Worker }
1045*61046927SAndroid Build Coastguard Worker }
1046*61046927SAndroid Build Coastguard Worker else {
1047*61046927SAndroid Build Coastguard Worker assert(format == GL_STENCIL);
1048*61046927SAndroid Build Coastguard Worker if (baseFormat == GL_DEPTH_STENCIL) {
1049*61046927SAndroid Build Coastguard Worker /* OK */
1050*61046927SAndroid Build Coastguard Worker } else if (ctx->Extensions.ARB_texture_stencil8 &&
1051*61046927SAndroid Build Coastguard Worker baseFormat == GL_STENCIL_INDEX) {
1052*61046927SAndroid Build Coastguard Worker /* OK */
1053*61046927SAndroid Build Coastguard Worker } else {
1054*61046927SAndroid Build Coastguard Worker /* no such thing as stencil-only textures */
1055*61046927SAndroid Build Coastguard Worker att_incomplete("illegal stencil texture");
1056*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1057*61046927SAndroid Build Coastguard Worker return;
1058*61046927SAndroid Build Coastguard Worker }
1059*61046927SAndroid Build Coastguard Worker }
1060*61046927SAndroid Build Coastguard Worker }
1061*61046927SAndroid Build Coastguard Worker else if (att->Type == GL_RENDERBUFFER_EXT) {
1062*61046927SAndroid Build Coastguard Worker const GLenum baseFormat = att->Renderbuffer->_BaseFormat;
1063*61046927SAndroid Build Coastguard Worker
1064*61046927SAndroid Build Coastguard Worker assert(att->Renderbuffer);
1065*61046927SAndroid Build Coastguard Worker if (!att->Renderbuffer->InternalFormat ||
1066*61046927SAndroid Build Coastguard Worker att->Renderbuffer->Width < 1 ||
1067*61046927SAndroid Build Coastguard Worker att->Renderbuffer->Height < 1) {
1068*61046927SAndroid Build Coastguard Worker att_incomplete("0x0 renderbuffer");
1069*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1070*61046927SAndroid Build Coastguard Worker return;
1071*61046927SAndroid Build Coastguard Worker }
1072*61046927SAndroid Build Coastguard Worker if (format == GL_COLOR) {
1073*61046927SAndroid Build Coastguard Worker if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
1074*61046927SAndroid Build Coastguard Worker att_incomplete("bad renderbuffer color format");
1075*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1076*61046927SAndroid Build Coastguard Worker return;
1077*61046927SAndroid Build Coastguard Worker }
1078*61046927SAndroid Build Coastguard Worker }
1079*61046927SAndroid Build Coastguard Worker else if (format == GL_DEPTH) {
1080*61046927SAndroid Build Coastguard Worker if (baseFormat == GL_DEPTH_COMPONENT) {
1081*61046927SAndroid Build Coastguard Worker /* OK */
1082*61046927SAndroid Build Coastguard Worker }
1083*61046927SAndroid Build Coastguard Worker else if (baseFormat == GL_DEPTH_STENCIL) {
1084*61046927SAndroid Build Coastguard Worker /* OK */
1085*61046927SAndroid Build Coastguard Worker }
1086*61046927SAndroid Build Coastguard Worker else {
1087*61046927SAndroid Build Coastguard Worker att_incomplete("bad renderbuffer depth format");
1088*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1089*61046927SAndroid Build Coastguard Worker return;
1090*61046927SAndroid Build Coastguard Worker }
1091*61046927SAndroid Build Coastguard Worker }
1092*61046927SAndroid Build Coastguard Worker else {
1093*61046927SAndroid Build Coastguard Worker assert(format == GL_STENCIL);
1094*61046927SAndroid Build Coastguard Worker if (baseFormat == GL_STENCIL_INDEX ||
1095*61046927SAndroid Build Coastguard Worker baseFormat == GL_DEPTH_STENCIL) {
1096*61046927SAndroid Build Coastguard Worker /* OK */
1097*61046927SAndroid Build Coastguard Worker }
1098*61046927SAndroid Build Coastguard Worker else {
1099*61046927SAndroid Build Coastguard Worker att->Complete = GL_FALSE;
1100*61046927SAndroid Build Coastguard Worker att_incomplete("bad renderbuffer stencil format");
1101*61046927SAndroid Build Coastguard Worker return;
1102*61046927SAndroid Build Coastguard Worker }
1103*61046927SAndroid Build Coastguard Worker }
1104*61046927SAndroid Build Coastguard Worker }
1105*61046927SAndroid Build Coastguard Worker else {
1106*61046927SAndroid Build Coastguard Worker assert(att->Type == GL_NONE);
1107*61046927SAndroid Build Coastguard Worker /* complete */
1108*61046927SAndroid Build Coastguard Worker return;
1109*61046927SAndroid Build Coastguard Worker }
1110*61046927SAndroid Build Coastguard Worker }
1111*61046927SAndroid Build Coastguard Worker
1112*61046927SAndroid Build Coastguard Worker /** Debug helper */
1113*61046927SAndroid Build Coastguard Worker static void
fbo_invalid(const char * reason)1114*61046927SAndroid Build Coastguard Worker fbo_invalid(const char *reason)
1115*61046927SAndroid Build Coastguard Worker {
1116*61046927SAndroid Build Coastguard Worker if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) {
1117*61046927SAndroid Build Coastguard Worker _mesa_debug(NULL, "Invalid FBO: %s\n", reason);
1118*61046927SAndroid Build Coastguard Worker }
1119*61046927SAndroid Build Coastguard Worker }
1120*61046927SAndroid Build Coastguard Worker
1121*61046927SAndroid Build Coastguard Worker
1122*61046927SAndroid Build Coastguard Worker /**
1123*61046927SAndroid Build Coastguard Worker * Validate a renderbuffer attachment for a particular set of bindings.
1124*61046927SAndroid Build Coastguard Worker */
1125*61046927SAndroid Build Coastguard Worker static GLboolean
do_validate_attachment(struct gl_context * ctx,struct pipe_screen * screen,const struct gl_renderbuffer_attachment * att,unsigned bindings)1126*61046927SAndroid Build Coastguard Worker do_validate_attachment(struct gl_context *ctx,
1127*61046927SAndroid Build Coastguard Worker struct pipe_screen *screen,
1128*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *att,
1129*61046927SAndroid Build Coastguard Worker unsigned bindings)
1130*61046927SAndroid Build Coastguard Worker {
1131*61046927SAndroid Build Coastguard Worker const struct gl_texture_object *stObj = att->Texture;
1132*61046927SAndroid Build Coastguard Worker enum pipe_format format;
1133*61046927SAndroid Build Coastguard Worker mesa_format texFormat;
1134*61046927SAndroid Build Coastguard Worker GLboolean valid;
1135*61046927SAndroid Build Coastguard Worker
1136*61046927SAndroid Build Coastguard Worker /* Sanity check: we must be binding the surface as a (color) render target
1137*61046927SAndroid Build Coastguard Worker * or depth/stencil target.
1138*61046927SAndroid Build Coastguard Worker */
1139*61046927SAndroid Build Coastguard Worker assert(bindings == PIPE_BIND_RENDER_TARGET ||
1140*61046927SAndroid Build Coastguard Worker bindings == PIPE_BIND_DEPTH_STENCIL);
1141*61046927SAndroid Build Coastguard Worker
1142*61046927SAndroid Build Coastguard Worker /* Only validate texture attachments for now, since
1143*61046927SAndroid Build Coastguard Worker * st_renderbuffer_alloc_storage makes sure that
1144*61046927SAndroid Build Coastguard Worker * the format is supported.
1145*61046927SAndroid Build Coastguard Worker */
1146*61046927SAndroid Build Coastguard Worker if (att->Type != GL_TEXTURE)
1147*61046927SAndroid Build Coastguard Worker return GL_TRUE;
1148*61046927SAndroid Build Coastguard Worker
1149*61046927SAndroid Build Coastguard Worker if (!stObj || !stObj->pt)
1150*61046927SAndroid Build Coastguard Worker return GL_FALSE;
1151*61046927SAndroid Build Coastguard Worker
1152*61046927SAndroid Build Coastguard Worker format = stObj->pt->format;
1153*61046927SAndroid Build Coastguard Worker texFormat = att->Renderbuffer->TexImage->TexFormat;
1154*61046927SAndroid Build Coastguard Worker
1155*61046927SAndroid Build Coastguard Worker /* If the encoding is sRGB and sRGB rendering cannot be enabled,
1156*61046927SAndroid Build Coastguard Worker * check for linear format support instead.
1157*61046927SAndroid Build Coastguard Worker * Later when we create a surface, we change the format to a linear one. */
1158*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.EXT_sRGB && _mesa_is_format_srgb(texFormat)) {
1159*61046927SAndroid Build Coastguard Worker const mesa_format linearFormat = _mesa_get_srgb_format_linear(texFormat);
1160*61046927SAndroid Build Coastguard Worker format = st_mesa_format_to_pipe_format(st_context(ctx), linearFormat);
1161*61046927SAndroid Build Coastguard Worker }
1162*61046927SAndroid Build Coastguard Worker
1163*61046927SAndroid Build Coastguard Worker valid = screen->is_format_supported(screen, format,
1164*61046927SAndroid Build Coastguard Worker PIPE_TEXTURE_2D,
1165*61046927SAndroid Build Coastguard Worker stObj->pt->nr_samples,
1166*61046927SAndroid Build Coastguard Worker stObj->pt->nr_storage_samples,
1167*61046927SAndroid Build Coastguard Worker bindings);
1168*61046927SAndroid Build Coastguard Worker if (!valid) {
1169*61046927SAndroid Build Coastguard Worker fbo_invalid("Invalid format");
1170*61046927SAndroid Build Coastguard Worker }
1171*61046927SAndroid Build Coastguard Worker
1172*61046927SAndroid Build Coastguard Worker return valid;
1173*61046927SAndroid Build Coastguard Worker }
1174*61046927SAndroid Build Coastguard Worker
1175*61046927SAndroid Build Coastguard Worker
1176*61046927SAndroid Build Coastguard Worker /**
1177*61046927SAndroid Build Coastguard Worker * Check that the framebuffer configuration is valid in terms of what
1178*61046927SAndroid Build Coastguard Worker * the driver can support.
1179*61046927SAndroid Build Coastguard Worker *
1180*61046927SAndroid Build Coastguard Worker * For Gallium we only supports combined Z+stencil, not separate buffers.
1181*61046927SAndroid Build Coastguard Worker */
1182*61046927SAndroid Build Coastguard Worker static void
do_validate_framebuffer(struct gl_context * ctx,struct gl_framebuffer * fb)1183*61046927SAndroid Build Coastguard Worker do_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
1184*61046927SAndroid Build Coastguard Worker {
1185*61046927SAndroid Build Coastguard Worker struct pipe_screen *screen = ctx->screen;
1186*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *depth =
1187*61046927SAndroid Build Coastguard Worker &fb->Attachment[BUFFER_DEPTH];
1188*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *stencil =
1189*61046927SAndroid Build Coastguard Worker &fb->Attachment[BUFFER_STENCIL];
1190*61046927SAndroid Build Coastguard Worker GLuint i;
1191*61046927SAndroid Build Coastguard Worker enum pipe_format first_format = PIPE_FORMAT_NONE;
1192*61046927SAndroid Build Coastguard Worker bool mixed_formats =
1193*61046927SAndroid Build Coastguard Worker screen->get_param(screen, PIPE_CAP_MIXED_COLORBUFFER_FORMATS) != 0;
1194*61046927SAndroid Build Coastguard Worker
1195*61046927SAndroid Build Coastguard Worker if (depth->Type && stencil->Type && depth->Type != stencil->Type) {
1196*61046927SAndroid Build Coastguard Worker fbo_invalid("Different Depth/Stencil buffer formats");
1197*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1198*61046927SAndroid Build Coastguard Worker return;
1199*61046927SAndroid Build Coastguard Worker }
1200*61046927SAndroid Build Coastguard Worker if (depth->Type == GL_RENDERBUFFER_EXT &&
1201*61046927SAndroid Build Coastguard Worker stencil->Type == GL_RENDERBUFFER_EXT &&
1202*61046927SAndroid Build Coastguard Worker depth->Renderbuffer != stencil->Renderbuffer) {
1203*61046927SAndroid Build Coastguard Worker fbo_invalid("Separate Depth/Stencil buffers");
1204*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1205*61046927SAndroid Build Coastguard Worker return;
1206*61046927SAndroid Build Coastguard Worker }
1207*61046927SAndroid Build Coastguard Worker if (depth->Type == GL_TEXTURE &&
1208*61046927SAndroid Build Coastguard Worker stencil->Type == GL_TEXTURE &&
1209*61046927SAndroid Build Coastguard Worker depth->Texture != stencil->Texture) {
1210*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1211*61046927SAndroid Build Coastguard Worker fbo_invalid("Different Depth/Stencil textures");
1212*61046927SAndroid Build Coastguard Worker return;
1213*61046927SAndroid Build Coastguard Worker }
1214*61046927SAndroid Build Coastguard Worker
1215*61046927SAndroid Build Coastguard Worker if (!do_validate_attachment(ctx, screen, depth, PIPE_BIND_DEPTH_STENCIL)) {
1216*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1217*61046927SAndroid Build Coastguard Worker fbo_invalid("Invalid depth attachment");
1218*61046927SAndroid Build Coastguard Worker return;
1219*61046927SAndroid Build Coastguard Worker }
1220*61046927SAndroid Build Coastguard Worker if (!do_validate_attachment(ctx, screen, stencil, PIPE_BIND_DEPTH_STENCIL)) {
1221*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1222*61046927SAndroid Build Coastguard Worker fbo_invalid("Invalid stencil attachment");
1223*61046927SAndroid Build Coastguard Worker return;
1224*61046927SAndroid Build Coastguard Worker }
1225*61046927SAndroid Build Coastguard Worker for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {
1226*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att =
1227*61046927SAndroid Build Coastguard Worker &fb->Attachment[BUFFER_COLOR0 + i];
1228*61046927SAndroid Build Coastguard Worker enum pipe_format format;
1229*61046927SAndroid Build Coastguard Worker
1230*61046927SAndroid Build Coastguard Worker if (!do_validate_attachment(ctx, screen, att, PIPE_BIND_RENDER_TARGET)) {
1231*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1232*61046927SAndroid Build Coastguard Worker fbo_invalid("Invalid color attachment");
1233*61046927SAndroid Build Coastguard Worker return;
1234*61046927SAndroid Build Coastguard Worker }
1235*61046927SAndroid Build Coastguard Worker
1236*61046927SAndroid Build Coastguard Worker if (!mixed_formats) {
1237*61046927SAndroid Build Coastguard Worker /* Disallow mixed formats. */
1238*61046927SAndroid Build Coastguard Worker if (att->Type != GL_NONE) {
1239*61046927SAndroid Build Coastguard Worker format = att->Renderbuffer->surface->format;
1240*61046927SAndroid Build Coastguard Worker } else {
1241*61046927SAndroid Build Coastguard Worker continue;
1242*61046927SAndroid Build Coastguard Worker }
1243*61046927SAndroid Build Coastguard Worker
1244*61046927SAndroid Build Coastguard Worker if (first_format == PIPE_FORMAT_NONE) {
1245*61046927SAndroid Build Coastguard Worker first_format = format;
1246*61046927SAndroid Build Coastguard Worker } else if (format != first_format) {
1247*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1248*61046927SAndroid Build Coastguard Worker fbo_invalid("Mixed color formats");
1249*61046927SAndroid Build Coastguard Worker return;
1250*61046927SAndroid Build Coastguard Worker }
1251*61046927SAndroid Build Coastguard Worker }
1252*61046927SAndroid Build Coastguard Worker }
1253*61046927SAndroid Build Coastguard Worker }
1254*61046927SAndroid Build Coastguard Worker
1255*61046927SAndroid Build Coastguard Worker
1256*61046927SAndroid Build Coastguard Worker /**
1257*61046927SAndroid Build Coastguard Worker * Test if the given framebuffer object is complete and update its
1258*61046927SAndroid Build Coastguard Worker * Status field with the results.
1259*61046927SAndroid Build Coastguard Worker * Calls the ctx->Driver.ValidateFramebuffer() function to allow the
1260*61046927SAndroid Build Coastguard Worker * driver to make hardware-specific validation/completeness checks.
1261*61046927SAndroid Build Coastguard Worker * Also update the framebuffer's Width and Height fields if the
1262*61046927SAndroid Build Coastguard Worker * framebuffer is complete.
1263*61046927SAndroid Build Coastguard Worker */
1264*61046927SAndroid Build Coastguard Worker void
_mesa_test_framebuffer_completeness(struct gl_context * ctx,struct gl_framebuffer * fb)1265*61046927SAndroid Build Coastguard Worker _mesa_test_framebuffer_completeness(struct gl_context *ctx,
1266*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb)
1267*61046927SAndroid Build Coastguard Worker {
1268*61046927SAndroid Build Coastguard Worker GLuint numImages;
1269*61046927SAndroid Build Coastguard Worker GLenum intFormat = GL_NONE; /* color buffers' internal format */
1270*61046927SAndroid Build Coastguard Worker GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
1271*61046927SAndroid Build Coastguard Worker GLint numColorSamples = -1;
1272*61046927SAndroid Build Coastguard Worker GLint numColorStorageSamples = -1;
1273*61046927SAndroid Build Coastguard Worker GLint numDepthSamples = -1;
1274*61046927SAndroid Build Coastguard Worker GLint fixedSampleLocations = -1;
1275*61046927SAndroid Build Coastguard Worker GLint i;
1276*61046927SAndroid Build Coastguard Worker GLuint j;
1277*61046927SAndroid Build Coastguard Worker /* Covers max_layer_count, is_layered, and layer_tex_target */
1278*61046927SAndroid Build Coastguard Worker bool layer_info_valid = false;
1279*61046927SAndroid Build Coastguard Worker GLuint max_layer_count = 0, att_layer_count;
1280*61046927SAndroid Build Coastguard Worker bool is_layered = false;
1281*61046927SAndroid Build Coastguard Worker GLenum layer_tex_target = 0;
1282*61046927SAndroid Build Coastguard Worker bool has_depth_attachment = false;
1283*61046927SAndroid Build Coastguard Worker bool has_stencil_attachment = false;
1284*61046927SAndroid Build Coastguard Worker
1285*61046927SAndroid Build Coastguard Worker assert(_mesa_is_user_fbo(fb));
1286*61046927SAndroid Build Coastguard Worker
1287*61046927SAndroid Build Coastguard Worker /* we're changing framebuffer fields here */
1288*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
1289*61046927SAndroid Build Coastguard Worker
1290*61046927SAndroid Build Coastguard Worker numImages = 0;
1291*61046927SAndroid Build Coastguard Worker fb->Width = 0;
1292*61046927SAndroid Build Coastguard Worker fb->Height = 0;
1293*61046927SAndroid Build Coastguard Worker fb->_AllColorBuffersFixedPoint = GL_TRUE;
1294*61046927SAndroid Build Coastguard Worker fb->_HasSNormOrFloatColorBuffer = GL_FALSE;
1295*61046927SAndroid Build Coastguard Worker fb->_HasAttachments = true;
1296*61046927SAndroid Build Coastguard Worker fb->_IntegerBuffers = 0;
1297*61046927SAndroid Build Coastguard Worker fb->_BlendForceAlphaToOne = 0;
1298*61046927SAndroid Build Coastguard Worker fb->_IsRGB = 0;
1299*61046927SAndroid Build Coastguard Worker fb->_FP32Buffers = 0;
1300*61046927SAndroid Build Coastguard Worker
1301*61046927SAndroid Build Coastguard Worker /* Start at -2 to more easily loop over all attachment points.
1302*61046927SAndroid Build Coastguard Worker * -2: depth buffer
1303*61046927SAndroid Build Coastguard Worker * -1: stencil buffer
1304*61046927SAndroid Build Coastguard Worker * >=0: color buffer
1305*61046927SAndroid Build Coastguard Worker */
1306*61046927SAndroid Build Coastguard Worker for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
1307*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att;
1308*61046927SAndroid Build Coastguard Worker GLenum f;
1309*61046927SAndroid Build Coastguard Worker GLenum baseFormat;
1310*61046927SAndroid Build Coastguard Worker mesa_format attFormat;
1311*61046927SAndroid Build Coastguard Worker GLenum att_tex_target = GL_NONE;
1312*61046927SAndroid Build Coastguard Worker
1313*61046927SAndroid Build Coastguard Worker /*
1314*61046927SAndroid Build Coastguard Worker * XXX for ARB_fbo, only check color buffers that are named by
1315*61046927SAndroid Build Coastguard Worker * GL_READ_BUFFER and GL_DRAW_BUFFERi.
1316*61046927SAndroid Build Coastguard Worker */
1317*61046927SAndroid Build Coastguard Worker
1318*61046927SAndroid Build Coastguard Worker /* check for attachment completeness
1319*61046927SAndroid Build Coastguard Worker */
1320*61046927SAndroid Build Coastguard Worker if (i == -2) {
1321*61046927SAndroid Build Coastguard Worker att = &fb->Attachment[BUFFER_DEPTH];
1322*61046927SAndroid Build Coastguard Worker test_attachment_completeness(ctx, GL_DEPTH, att);
1323*61046927SAndroid Build Coastguard Worker if (!att->Complete) {
1324*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
1325*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "depth attachment incomplete", -1);
1326*61046927SAndroid Build Coastguard Worker return;
1327*61046927SAndroid Build Coastguard Worker } else if (att->Type != GL_NONE) {
1328*61046927SAndroid Build Coastguard Worker has_depth_attachment = true;
1329*61046927SAndroid Build Coastguard Worker }
1330*61046927SAndroid Build Coastguard Worker }
1331*61046927SAndroid Build Coastguard Worker else if (i == -1) {
1332*61046927SAndroid Build Coastguard Worker att = &fb->Attachment[BUFFER_STENCIL];
1333*61046927SAndroid Build Coastguard Worker test_attachment_completeness(ctx, GL_STENCIL, att);
1334*61046927SAndroid Build Coastguard Worker if (!att->Complete) {
1335*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
1336*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "stencil attachment incomplete", -1);
1337*61046927SAndroid Build Coastguard Worker return;
1338*61046927SAndroid Build Coastguard Worker } else if (att->Type != GL_NONE) {
1339*61046927SAndroid Build Coastguard Worker has_stencil_attachment = true;
1340*61046927SAndroid Build Coastguard Worker }
1341*61046927SAndroid Build Coastguard Worker }
1342*61046927SAndroid Build Coastguard Worker else {
1343*61046927SAndroid Build Coastguard Worker att = &fb->Attachment[BUFFER_COLOR0 + i];
1344*61046927SAndroid Build Coastguard Worker test_attachment_completeness(ctx, GL_COLOR, att);
1345*61046927SAndroid Build Coastguard Worker if (!att->Complete) {
1346*61046927SAndroid Build Coastguard Worker /* With EXT_color_buffer_half_float, check if attachment was incomplete
1347*61046927SAndroid Build Coastguard Worker * due to invalid format. This is special case for the extension where
1348*61046927SAndroid Build Coastguard Worker * CTS tests expect unsupported framebuffer status instead of incomplete.
1349*61046927SAndroid Build Coastguard Worker */
1350*61046927SAndroid Build Coastguard Worker if (_mesa_has_EXT_color_buffer_half_float(ctx) &&
1351*61046927SAndroid Build Coastguard Worker !gles_check_float_renderable(ctx, att)) {
1352*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
1353*61046927SAndroid Build Coastguard Worker return;
1354*61046927SAndroid Build Coastguard Worker }
1355*61046927SAndroid Build Coastguard Worker
1356*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
1357*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "color attachment incomplete", i);
1358*61046927SAndroid Build Coastguard Worker return;
1359*61046927SAndroid Build Coastguard Worker }
1360*61046927SAndroid Build Coastguard Worker }
1361*61046927SAndroid Build Coastguard Worker
1362*61046927SAndroid Build Coastguard Worker /* get width, height, format of the renderbuffer/texture
1363*61046927SAndroid Build Coastguard Worker */
1364*61046927SAndroid Build Coastguard Worker unsigned attNumSamples, attNumStorageSamples;
1365*61046927SAndroid Build Coastguard Worker
1366*61046927SAndroid Build Coastguard Worker if (att->Type == GL_TEXTURE) {
1367*61046927SAndroid Build Coastguard Worker const struct gl_texture_image *texImg = att->Renderbuffer->TexImage;
1368*61046927SAndroid Build Coastguard Worker att_tex_target = att->Texture->Target;
1369*61046927SAndroid Build Coastguard Worker minWidth = MIN2(minWidth, texImg->Width);
1370*61046927SAndroid Build Coastguard Worker maxWidth = MAX2(maxWidth, texImg->Width);
1371*61046927SAndroid Build Coastguard Worker minHeight = MIN2(minHeight, texImg->Height);
1372*61046927SAndroid Build Coastguard Worker maxHeight = MAX2(maxHeight, texImg->Height);
1373*61046927SAndroid Build Coastguard Worker f = texImg->_BaseFormat;
1374*61046927SAndroid Build Coastguard Worker baseFormat = f;
1375*61046927SAndroid Build Coastguard Worker attFormat = texImg->TexFormat;
1376*61046927SAndroid Build Coastguard Worker numImages++;
1377*61046927SAndroid Build Coastguard Worker
1378*61046927SAndroid Build Coastguard Worker if (!is_format_color_renderable(ctx, attFormat,
1379*61046927SAndroid Build Coastguard Worker texImg->InternalFormat) &&
1380*61046927SAndroid Build Coastguard Worker !is_legal_depth_format(ctx, f) &&
1381*61046927SAndroid Build Coastguard Worker f != GL_STENCIL_INDEX) {
1382*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
1383*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "texture attachment incomplete", -1);
1384*61046927SAndroid Build Coastguard Worker return;
1385*61046927SAndroid Build Coastguard Worker }
1386*61046927SAndroid Build Coastguard Worker
1387*61046927SAndroid Build Coastguard Worker if (fixedSampleLocations < 0)
1388*61046927SAndroid Build Coastguard Worker fixedSampleLocations = texImg->FixedSampleLocations;
1389*61046927SAndroid Build Coastguard Worker else if (fixedSampleLocations != texImg->FixedSampleLocations) {
1390*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
1391*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "inconsistent fixed sample locations", -1);
1392*61046927SAndroid Build Coastguard Worker return;
1393*61046927SAndroid Build Coastguard Worker }
1394*61046927SAndroid Build Coastguard Worker
1395*61046927SAndroid Build Coastguard Worker if (att->NumSamples > 0)
1396*61046927SAndroid Build Coastguard Worker attNumSamples = att->NumSamples;
1397*61046927SAndroid Build Coastguard Worker else
1398*61046927SAndroid Build Coastguard Worker attNumSamples = texImg->NumSamples;
1399*61046927SAndroid Build Coastguard Worker attNumStorageSamples = attNumSamples;
1400*61046927SAndroid Build Coastguard Worker }
1401*61046927SAndroid Build Coastguard Worker else if (att->Type == GL_RENDERBUFFER_EXT) {
1402*61046927SAndroid Build Coastguard Worker minWidth = MIN2(minWidth, att->Renderbuffer->Width);
1403*61046927SAndroid Build Coastguard Worker maxWidth = MAX2(maxWidth, att->Renderbuffer->Width);
1404*61046927SAndroid Build Coastguard Worker minHeight = MIN2(minHeight, att->Renderbuffer->Height);
1405*61046927SAndroid Build Coastguard Worker maxHeight = MAX2(maxHeight, att->Renderbuffer->Height);
1406*61046927SAndroid Build Coastguard Worker f = att->Renderbuffer->InternalFormat;
1407*61046927SAndroid Build Coastguard Worker baseFormat = att->Renderbuffer->_BaseFormat;
1408*61046927SAndroid Build Coastguard Worker attFormat = att->Renderbuffer->Format;
1409*61046927SAndroid Build Coastguard Worker numImages++;
1410*61046927SAndroid Build Coastguard Worker
1411*61046927SAndroid Build Coastguard Worker /* RENDERBUFFER has fixedSampleLocations implicitly true */
1412*61046927SAndroid Build Coastguard Worker if (fixedSampleLocations < 0)
1413*61046927SAndroid Build Coastguard Worker fixedSampleLocations = GL_TRUE;
1414*61046927SAndroid Build Coastguard Worker else if (fixedSampleLocations != GL_TRUE) {
1415*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
1416*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "inconsistent fixed sample locations", -1);
1417*61046927SAndroid Build Coastguard Worker return;
1418*61046927SAndroid Build Coastguard Worker }
1419*61046927SAndroid Build Coastguard Worker
1420*61046927SAndroid Build Coastguard Worker attNumSamples = att->Renderbuffer->NumSamples;
1421*61046927SAndroid Build Coastguard Worker attNumStorageSamples = att->Renderbuffer->NumStorageSamples;
1422*61046927SAndroid Build Coastguard Worker }
1423*61046927SAndroid Build Coastguard Worker else {
1424*61046927SAndroid Build Coastguard Worker assert(att->Type == GL_NONE);
1425*61046927SAndroid Build Coastguard Worker continue;
1426*61046927SAndroid Build Coastguard Worker }
1427*61046927SAndroid Build Coastguard Worker
1428*61046927SAndroid Build Coastguard Worker if (i >= 0) {
1429*61046927SAndroid Build Coastguard Worker /* Color buffers. */
1430*61046927SAndroid Build Coastguard Worker if (numColorSamples < 0) {
1431*61046927SAndroid Build Coastguard Worker assert(numColorStorageSamples < 0);
1432*61046927SAndroid Build Coastguard Worker numColorSamples = attNumSamples;
1433*61046927SAndroid Build Coastguard Worker numColorStorageSamples = attNumStorageSamples;
1434*61046927SAndroid Build Coastguard Worker } else if (numColorSamples != attNumSamples ||
1435*61046927SAndroid Build Coastguard Worker numColorStorageSamples != attNumStorageSamples) {
1436*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
1437*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "inconsistent sample counts", -1);
1438*61046927SAndroid Build Coastguard Worker return;
1439*61046927SAndroid Build Coastguard Worker }
1440*61046927SAndroid Build Coastguard Worker } else {
1441*61046927SAndroid Build Coastguard Worker /* Depth/stencil buffers. */
1442*61046927SAndroid Build Coastguard Worker if (numDepthSamples < 0) {
1443*61046927SAndroid Build Coastguard Worker numDepthSamples = attNumSamples;
1444*61046927SAndroid Build Coastguard Worker } else if (numDepthSamples != attNumSamples) {
1445*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
1446*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "inconsistent sample counts", -1);
1447*61046927SAndroid Build Coastguard Worker return;
1448*61046927SAndroid Build Coastguard Worker }
1449*61046927SAndroid Build Coastguard Worker }
1450*61046927SAndroid Build Coastguard Worker
1451*61046927SAndroid Build Coastguard Worker /* Update flags describing color buffer datatypes */
1452*61046927SAndroid Build Coastguard Worker if (i >= 0) {
1453*61046927SAndroid Build Coastguard Worker GLenum type = _mesa_get_format_datatype(attFormat);
1454*61046927SAndroid Build Coastguard Worker
1455*61046927SAndroid Build Coastguard Worker /* check if integer color */
1456*61046927SAndroid Build Coastguard Worker if (_mesa_is_format_integer_color(attFormat))
1457*61046927SAndroid Build Coastguard Worker fb->_IntegerBuffers |= (1 << i);
1458*61046927SAndroid Build Coastguard Worker
1459*61046927SAndroid Build Coastguard Worker if (baseFormat == GL_RGB)
1460*61046927SAndroid Build Coastguard Worker fb->_IsRGB |= (1 << i);
1461*61046927SAndroid Build Coastguard Worker
1462*61046927SAndroid Build Coastguard Worker if (ctx->st->has_indep_blend_func &&
1463*61046927SAndroid Build Coastguard Worker ((baseFormat == GL_RGB) ||
1464*61046927SAndroid Build Coastguard Worker (baseFormat == GL_LUMINANCE && !util_format_is_luminance(attFormat)) ||
1465*61046927SAndroid Build Coastguard Worker (baseFormat == GL_INTENSITY && !util_format_is_intensity(attFormat))))
1466*61046927SAndroid Build Coastguard Worker fb->_BlendForceAlphaToOne |= (1 << i);
1467*61046927SAndroid Build Coastguard Worker
1468*61046927SAndroid Build Coastguard Worker if (type == GL_FLOAT && _mesa_get_format_max_bits(attFormat) > 16)
1469*61046927SAndroid Build Coastguard Worker fb->_FP32Buffers |= (1 << i);
1470*61046927SAndroid Build Coastguard Worker
1471*61046927SAndroid Build Coastguard Worker fb->_AllColorBuffersFixedPoint =
1472*61046927SAndroid Build Coastguard Worker fb->_AllColorBuffersFixedPoint &&
1473*61046927SAndroid Build Coastguard Worker (type == GL_UNSIGNED_NORMALIZED || type == GL_SIGNED_NORMALIZED);
1474*61046927SAndroid Build Coastguard Worker
1475*61046927SAndroid Build Coastguard Worker fb->_HasSNormOrFloatColorBuffer =
1476*61046927SAndroid Build Coastguard Worker fb->_HasSNormOrFloatColorBuffer ||
1477*61046927SAndroid Build Coastguard Worker type == GL_SIGNED_NORMALIZED || type == GL_FLOAT;
1478*61046927SAndroid Build Coastguard Worker }
1479*61046927SAndroid Build Coastguard Worker
1480*61046927SAndroid Build Coastguard Worker /* Error-check width, height, format */
1481*61046927SAndroid Build Coastguard Worker if (numImages == 1) {
1482*61046927SAndroid Build Coastguard Worker /* save format */
1483*61046927SAndroid Build Coastguard Worker if (i >= 0) {
1484*61046927SAndroid Build Coastguard Worker intFormat = f;
1485*61046927SAndroid Build Coastguard Worker }
1486*61046927SAndroid Build Coastguard Worker }
1487*61046927SAndroid Build Coastguard Worker else {
1488*61046927SAndroid Build Coastguard Worker if (!_mesa_has_ARB_framebuffer_object(ctx) &&
1489*61046927SAndroid Build Coastguard Worker !_mesa_is_gles3(ctx)) {
1490*61046927SAndroid Build Coastguard Worker /* check that width, height, format are same */
1491*61046927SAndroid Build Coastguard Worker if (minWidth != maxWidth || minHeight != maxHeight) {
1492*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
1493*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "width or height mismatch", -1);
1494*61046927SAndroid Build Coastguard Worker return;
1495*61046927SAndroid Build Coastguard Worker }
1496*61046927SAndroid Build Coastguard Worker /* check that all color buffers are the same format */
1497*61046927SAndroid Build Coastguard Worker if (ctx->API != API_OPENGLES2 && intFormat != GL_NONE && f != intFormat) {
1498*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
1499*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "format mismatch", -1);
1500*61046927SAndroid Build Coastguard Worker return;
1501*61046927SAndroid Build Coastguard Worker }
1502*61046927SAndroid Build Coastguard Worker }
1503*61046927SAndroid Build Coastguard Worker }
1504*61046927SAndroid Build Coastguard Worker
1505*61046927SAndroid Build Coastguard Worker /* Check that the format is valid. (MESA_FORMAT_NONE means unsupported)
1506*61046927SAndroid Build Coastguard Worker */
1507*61046927SAndroid Build Coastguard Worker if (att->Type == GL_RENDERBUFFER &&
1508*61046927SAndroid Build Coastguard Worker att->Renderbuffer->Format == MESA_FORMAT_NONE) {
1509*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
1510*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "unsupported renderbuffer format", i);
1511*61046927SAndroid Build Coastguard Worker return;
1512*61046927SAndroid Build Coastguard Worker }
1513*61046927SAndroid Build Coastguard Worker
1514*61046927SAndroid Build Coastguard Worker /* Check that layered rendering is consistent. */
1515*61046927SAndroid Build Coastguard Worker if (att->Layered) {
1516*61046927SAndroid Build Coastguard Worker if (att_tex_target == GL_TEXTURE_CUBE_MAP) {
1517*61046927SAndroid Build Coastguard Worker /* Each layer's format and size must match to the base layer. */
1518*61046927SAndroid Build Coastguard Worker if (!_mesa_cube_complete(att->Texture)) {
1519*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
1520*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "attachment not cube complete", i);
1521*61046927SAndroid Build Coastguard Worker return;
1522*61046927SAndroid Build Coastguard Worker }
1523*61046927SAndroid Build Coastguard Worker att_layer_count = 6;
1524*61046927SAndroid Build Coastguard Worker } else if (att_tex_target == GL_TEXTURE_1D_ARRAY)
1525*61046927SAndroid Build Coastguard Worker att_layer_count = att->Renderbuffer->Height;
1526*61046927SAndroid Build Coastguard Worker else
1527*61046927SAndroid Build Coastguard Worker att_layer_count = att->Renderbuffer->Depth;
1528*61046927SAndroid Build Coastguard Worker
1529*61046927SAndroid Build Coastguard Worker /* From OpenGL ES 3.2 spec, chapter 9.4. FRAMEBUFFER COMPLETENESS:
1530*61046927SAndroid Build Coastguard Worker *
1531*61046927SAndroid Build Coastguard Worker * "If any framebuffer attachment is layered, all populated
1532*61046927SAndroid Build Coastguard Worker * attachments must be layered. Additionally, all populated color
1533*61046927SAndroid Build Coastguard Worker * attachments must be from textures of the same target
1534*61046927SAndroid Build Coastguard Worker * (three-dimensional, one- or two-dimensional array, cube map, or
1535*61046927SAndroid Build Coastguard Worker * cube map array textures)."
1536*61046927SAndroid Build Coastguard Worker *
1537*61046927SAndroid Build Coastguard Worker * Same text can be found from OpenGL 4.6 spec.
1538*61046927SAndroid Build Coastguard Worker *
1539*61046927SAndroid Build Coastguard Worker * Setup the checked layer target with first color attachment here
1540*61046927SAndroid Build Coastguard Worker * so that mismatch check below will not trigger between depth,
1541*61046927SAndroid Build Coastguard Worker * stencil, only between color attachments.
1542*61046927SAndroid Build Coastguard Worker */
1543*61046927SAndroid Build Coastguard Worker if (i == 0)
1544*61046927SAndroid Build Coastguard Worker layer_tex_target = att_tex_target;
1545*61046927SAndroid Build Coastguard Worker
1546*61046927SAndroid Build Coastguard Worker } else {
1547*61046927SAndroid Build Coastguard Worker att_layer_count = 0;
1548*61046927SAndroid Build Coastguard Worker }
1549*61046927SAndroid Build Coastguard Worker if (!layer_info_valid) {
1550*61046927SAndroid Build Coastguard Worker is_layered = att->Layered;
1551*61046927SAndroid Build Coastguard Worker max_layer_count = att_layer_count;
1552*61046927SAndroid Build Coastguard Worker layer_info_valid = true;
1553*61046927SAndroid Build Coastguard Worker } else if (max_layer_count > 0 && layer_tex_target &&
1554*61046927SAndroid Build Coastguard Worker layer_tex_target != att_tex_target) {
1555*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS;
1556*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "layered framebuffer has mismatched targets", i);
1557*61046927SAndroid Build Coastguard Worker return;
1558*61046927SAndroid Build Coastguard Worker } else if (is_layered != att->Layered) {
1559*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS;
1560*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx,
1561*61046927SAndroid Build Coastguard Worker "framebuffer attachment layer mode is inconsistent",
1562*61046927SAndroid Build Coastguard Worker i);
1563*61046927SAndroid Build Coastguard Worker return;
1564*61046927SAndroid Build Coastguard Worker } else if (att_layer_count > max_layer_count) {
1565*61046927SAndroid Build Coastguard Worker max_layer_count = att_layer_count;
1566*61046927SAndroid Build Coastguard Worker }
1567*61046927SAndroid Build Coastguard Worker
1568*61046927SAndroid Build Coastguard Worker /*
1569*61046927SAndroid Build Coastguard Worker * The extension GL_ARB_framebuffer_no_attachments places additional
1570*61046927SAndroid Build Coastguard Worker * requirement on each attachment. Those additional requirements are
1571*61046927SAndroid Build Coastguard Worker * tighter that those of previous versions of GL. In interest of better
1572*61046927SAndroid Build Coastguard Worker * compatibility, we will not enforce these restrictions. For the record
1573*61046927SAndroid Build Coastguard Worker * those additional restrictions are quoted below:
1574*61046927SAndroid Build Coastguard Worker *
1575*61046927SAndroid Build Coastguard Worker * "The width and height of image are greater than zero and less than or
1576*61046927SAndroid Build Coastguard Worker * equal to the values of the implementation-dependent limits
1577*61046927SAndroid Build Coastguard Worker * MAX_FRAMEBUFFER_WIDTH and MAX_FRAMEBUFFER_HEIGHT, respectively."
1578*61046927SAndroid Build Coastguard Worker *
1579*61046927SAndroid Build Coastguard Worker * "If <image> is a three-dimensional texture or a one- or two-dimensional
1580*61046927SAndroid Build Coastguard Worker * array texture and the attachment is layered, the depth or layer count
1581*61046927SAndroid Build Coastguard Worker * of the texture is less than or equal to the implementation-dependent
1582*61046927SAndroid Build Coastguard Worker * limit MAX_FRAMEBUFFER_LAYERS."
1583*61046927SAndroid Build Coastguard Worker *
1584*61046927SAndroid Build Coastguard Worker * "If image has multiple samples, its sample count is less than or equal
1585*61046927SAndroid Build Coastguard Worker * to the value of the implementation-dependent limit
1586*61046927SAndroid Build Coastguard Worker * MAX_FRAMEBUFFER_SAMPLES."
1587*61046927SAndroid Build Coastguard Worker *
1588*61046927SAndroid Build Coastguard Worker * The same requirements are also in place for GL 4.5,
1589*61046927SAndroid Build Coastguard Worker * Section 9.4.1 "Framebuffer Attachment Completeness", pg 310-311
1590*61046927SAndroid Build Coastguard Worker */
1591*61046927SAndroid Build Coastguard Worker }
1592*61046927SAndroid Build Coastguard Worker
1593*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.AMD_framebuffer_multisample_advanced) {
1594*61046927SAndroid Build Coastguard Worker /* See if non-matching sample counts are supported. */
1595*61046927SAndroid Build Coastguard Worker if (numColorSamples >= 0 && numDepthSamples >= 0) {
1596*61046927SAndroid Build Coastguard Worker bool found = false;
1597*61046927SAndroid Build Coastguard Worker
1598*61046927SAndroid Build Coastguard Worker assert(numColorStorageSamples != -1);
1599*61046927SAndroid Build Coastguard Worker
1600*61046927SAndroid Build Coastguard Worker numColorSamples = MAX2(numColorSamples, 1);
1601*61046927SAndroid Build Coastguard Worker numColorStorageSamples = MAX2(numColorStorageSamples, 1);
1602*61046927SAndroid Build Coastguard Worker numDepthSamples = MAX2(numDepthSamples, 1);
1603*61046927SAndroid Build Coastguard Worker
1604*61046927SAndroid Build Coastguard Worker if (numColorSamples == 1 && numColorStorageSamples == 1 &&
1605*61046927SAndroid Build Coastguard Worker numDepthSamples == 1) {
1606*61046927SAndroid Build Coastguard Worker found = true;
1607*61046927SAndroid Build Coastguard Worker } else {
1608*61046927SAndroid Build Coastguard Worker for (i = 0; i < ctx->Const.NumSupportedMultisampleModes; i++) {
1609*61046927SAndroid Build Coastguard Worker GLint *counts =
1610*61046927SAndroid Build Coastguard Worker &ctx->Const.SupportedMultisampleModes[i].NumColorSamples;
1611*61046927SAndroid Build Coastguard Worker
1612*61046927SAndroid Build Coastguard Worker if (counts[0] == numColorSamples &&
1613*61046927SAndroid Build Coastguard Worker counts[1] == numColorStorageSamples &&
1614*61046927SAndroid Build Coastguard Worker counts[2] == numDepthSamples) {
1615*61046927SAndroid Build Coastguard Worker found = true;
1616*61046927SAndroid Build Coastguard Worker break;
1617*61046927SAndroid Build Coastguard Worker }
1618*61046927SAndroid Build Coastguard Worker }
1619*61046927SAndroid Build Coastguard Worker }
1620*61046927SAndroid Build Coastguard Worker
1621*61046927SAndroid Build Coastguard Worker if (!found) {
1622*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
1623*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "unsupported sample counts", -1);
1624*61046927SAndroid Build Coastguard Worker return;
1625*61046927SAndroid Build Coastguard Worker }
1626*61046927SAndroid Build Coastguard Worker }
1627*61046927SAndroid Build Coastguard Worker } else {
1628*61046927SAndroid Build Coastguard Worker /* If the extension is unsupported, all sample counts must be equal. */
1629*61046927SAndroid Build Coastguard Worker if (numColorSamples >= 0 &&
1630*61046927SAndroid Build Coastguard Worker (numColorSamples != numColorStorageSamples ||
1631*61046927SAndroid Build Coastguard Worker (numDepthSamples >= 0 && numColorSamples != numDepthSamples))) {
1632*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
1633*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "inconsistent sample counts", -1);
1634*61046927SAndroid Build Coastguard Worker return;
1635*61046927SAndroid Build Coastguard Worker }
1636*61046927SAndroid Build Coastguard Worker }
1637*61046927SAndroid Build Coastguard Worker
1638*61046927SAndroid Build Coastguard Worker fb->MaxNumLayers = max_layer_count;
1639*61046927SAndroid Build Coastguard Worker
1640*61046927SAndroid Build Coastguard Worker if (numImages == 0) {
1641*61046927SAndroid Build Coastguard Worker fb->_HasAttachments = false;
1642*61046927SAndroid Build Coastguard Worker
1643*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
1644*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
1645*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "no attachments", -1);
1646*61046927SAndroid Build Coastguard Worker return;
1647*61046927SAndroid Build Coastguard Worker }
1648*61046927SAndroid Build Coastguard Worker
1649*61046927SAndroid Build Coastguard Worker if (fb->DefaultGeometry.Width == 0 || fb->DefaultGeometry.Height == 0) {
1650*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
1651*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "no attachments and default width or height is 0", -1);
1652*61046927SAndroid Build Coastguard Worker return;
1653*61046927SAndroid Build Coastguard Worker }
1654*61046927SAndroid Build Coastguard Worker }
1655*61046927SAndroid Build Coastguard Worker
1656*61046927SAndroid Build Coastguard Worker if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) {
1657*61046927SAndroid Build Coastguard Worker /* Check that all DrawBuffers are present */
1658*61046927SAndroid Build Coastguard Worker for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) {
1659*61046927SAndroid Build Coastguard Worker if (fb->ColorDrawBuffer[j] != GL_NONE) {
1660*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *att
1661*61046927SAndroid Build Coastguard Worker = get_attachment(ctx, fb, fb->ColorDrawBuffer[j], NULL);
1662*61046927SAndroid Build Coastguard Worker assert(att);
1663*61046927SAndroid Build Coastguard Worker if (att->Type == GL_NONE) {
1664*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
1665*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "missing drawbuffer", j);
1666*61046927SAndroid Build Coastguard Worker return;
1667*61046927SAndroid Build Coastguard Worker }
1668*61046927SAndroid Build Coastguard Worker }
1669*61046927SAndroid Build Coastguard Worker }
1670*61046927SAndroid Build Coastguard Worker
1671*61046927SAndroid Build Coastguard Worker /* Check that the ReadBuffer is present */
1672*61046927SAndroid Build Coastguard Worker if (fb->ColorReadBuffer != GL_NONE) {
1673*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *att
1674*61046927SAndroid Build Coastguard Worker = get_attachment(ctx, fb, fb->ColorReadBuffer, NULL);
1675*61046927SAndroid Build Coastguard Worker assert(att);
1676*61046927SAndroid Build Coastguard Worker if (att->Type == GL_NONE) {
1677*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
1678*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "missing readbuffer", -1);
1679*61046927SAndroid Build Coastguard Worker return;
1680*61046927SAndroid Build Coastguard Worker }
1681*61046927SAndroid Build Coastguard Worker }
1682*61046927SAndroid Build Coastguard Worker }
1683*61046927SAndroid Build Coastguard Worker
1684*61046927SAndroid Build Coastguard Worker /* The OpenGL ES3 spec, in chapter 9.4. FRAMEBUFFER COMPLETENESS, says:
1685*61046927SAndroid Build Coastguard Worker *
1686*61046927SAndroid Build Coastguard Worker * "Depth and stencil attachments, if present, are the same image."
1687*61046927SAndroid Build Coastguard Worker *
1688*61046927SAndroid Build Coastguard Worker * This restriction is not present in the OpenGL ES2 spec.
1689*61046927SAndroid Build Coastguard Worker */
1690*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles3(ctx) &&
1691*61046927SAndroid Build Coastguard Worker has_stencil_attachment && has_depth_attachment &&
1692*61046927SAndroid Build Coastguard Worker !_mesa_has_depthstencil_combined(fb)) {
1693*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
1694*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "Depth and stencil attachments must be the same image", -1);
1695*61046927SAndroid Build Coastguard Worker return;
1696*61046927SAndroid Build Coastguard Worker }
1697*61046927SAndroid Build Coastguard Worker
1698*61046927SAndroid Build Coastguard Worker /* Provisionally set status = COMPLETE ... */
1699*61046927SAndroid Build Coastguard Worker fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
1700*61046927SAndroid Build Coastguard Worker
1701*61046927SAndroid Build Coastguard Worker /* ... but the driver may say the FB is incomplete.
1702*61046927SAndroid Build Coastguard Worker * Drivers will most likely set the status to GL_FRAMEBUFFER_UNSUPPORTED
1703*61046927SAndroid Build Coastguard Worker * if anything.
1704*61046927SAndroid Build Coastguard Worker */
1705*61046927SAndroid Build Coastguard Worker do_validate_framebuffer(ctx, fb);
1706*61046927SAndroid Build Coastguard Worker if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1707*61046927SAndroid Build Coastguard Worker fbo_incomplete(ctx, "driver marked FBO as incomplete", -1);
1708*61046927SAndroid Build Coastguard Worker return;
1709*61046927SAndroid Build Coastguard Worker }
1710*61046927SAndroid Build Coastguard Worker
1711*61046927SAndroid Build Coastguard Worker /*
1712*61046927SAndroid Build Coastguard Worker * Note that if ARB_framebuffer_object is supported and the attached
1713*61046927SAndroid Build Coastguard Worker * renderbuffers/textures are different sizes, the framebuffer
1714*61046927SAndroid Build Coastguard Worker * width/height will be set to the smallest width/height.
1715*61046927SAndroid Build Coastguard Worker */
1716*61046927SAndroid Build Coastguard Worker if (numImages != 0) {
1717*61046927SAndroid Build Coastguard Worker fb->Width = minWidth;
1718*61046927SAndroid Build Coastguard Worker fb->Height = minHeight;
1719*61046927SAndroid Build Coastguard Worker }
1720*61046927SAndroid Build Coastguard Worker
1721*61046927SAndroid Build Coastguard Worker /* finally, update the visual info for the framebuffer */
1722*61046927SAndroid Build Coastguard Worker _mesa_update_framebuffer_visual(ctx, fb);
1723*61046927SAndroid Build Coastguard Worker }
1724*61046927SAndroid Build Coastguard Worker
1725*61046927SAndroid Build Coastguard Worker
1726*61046927SAndroid Build Coastguard Worker GLboolean GLAPIENTRY
_mesa_IsRenderbuffer(GLuint renderbuffer)1727*61046927SAndroid Build Coastguard Worker _mesa_IsRenderbuffer(GLuint renderbuffer)
1728*61046927SAndroid Build Coastguard Worker {
1729*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb;
1730*61046927SAndroid Build Coastguard Worker
1731*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1732*61046927SAndroid Build Coastguard Worker
1733*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
1734*61046927SAndroid Build Coastguard Worker
1735*61046927SAndroid Build Coastguard Worker rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
1736*61046927SAndroid Build Coastguard Worker return rb != NULL && rb != &DummyRenderbuffer;
1737*61046927SAndroid Build Coastguard Worker }
1738*61046927SAndroid Build Coastguard Worker
1739*61046927SAndroid Build Coastguard Worker
1740*61046927SAndroid Build Coastguard Worker static struct gl_renderbuffer *
allocate_renderbuffer_locked(struct gl_context * ctx,GLuint renderbuffer,const char * func)1741*61046927SAndroid Build Coastguard Worker allocate_renderbuffer_locked(struct gl_context *ctx, GLuint renderbuffer,
1742*61046927SAndroid Build Coastguard Worker const char *func)
1743*61046927SAndroid Build Coastguard Worker {
1744*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *newRb;
1745*61046927SAndroid Build Coastguard Worker
1746*61046927SAndroid Build Coastguard Worker /* create new renderbuffer object */
1747*61046927SAndroid Build Coastguard Worker newRb = new_renderbuffer(ctx, renderbuffer);
1748*61046927SAndroid Build Coastguard Worker if (!newRb) {
1749*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
1750*61046927SAndroid Build Coastguard Worker return NULL;
1751*61046927SAndroid Build Coastguard Worker }
1752*61046927SAndroid Build Coastguard Worker assert(newRb->AllocStorage);
1753*61046927SAndroid Build Coastguard Worker _mesa_HashInsertLocked(&ctx->Shared->RenderBuffers, renderbuffer,
1754*61046927SAndroid Build Coastguard Worker newRb);
1755*61046927SAndroid Build Coastguard Worker
1756*61046927SAndroid Build Coastguard Worker return newRb;
1757*61046927SAndroid Build Coastguard Worker }
1758*61046927SAndroid Build Coastguard Worker
1759*61046927SAndroid Build Coastguard Worker
1760*61046927SAndroid Build Coastguard Worker static void
bind_renderbuffer(GLenum target,GLuint renderbuffer)1761*61046927SAndroid Build Coastguard Worker bind_renderbuffer(GLenum target, GLuint renderbuffer)
1762*61046927SAndroid Build Coastguard Worker {
1763*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *newRb;
1764*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1765*61046927SAndroid Build Coastguard Worker
1766*61046927SAndroid Build Coastguard Worker if (target != GL_RENDERBUFFER_EXT) {
1767*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glBindRenderbufferEXT(target)");
1768*61046927SAndroid Build Coastguard Worker return;
1769*61046927SAndroid Build Coastguard Worker }
1770*61046927SAndroid Build Coastguard Worker
1771*61046927SAndroid Build Coastguard Worker /* No need to flush here since the render buffer binding has no
1772*61046927SAndroid Build Coastguard Worker * effect on rendering state.
1773*61046927SAndroid Build Coastguard Worker */
1774*61046927SAndroid Build Coastguard Worker
1775*61046927SAndroid Build Coastguard Worker if (renderbuffer) {
1776*61046927SAndroid Build Coastguard Worker newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
1777*61046927SAndroid Build Coastguard Worker if (newRb == &DummyRenderbuffer) {
1778*61046927SAndroid Build Coastguard Worker /* ID was reserved, but no real renderbuffer object made yet */
1779*61046927SAndroid Build Coastguard Worker newRb = NULL;
1780*61046927SAndroid Build Coastguard Worker }
1781*61046927SAndroid Build Coastguard Worker else if (!newRb && _mesa_is_desktop_gl_core(ctx)) {
1782*61046927SAndroid Build Coastguard Worker /* All RB IDs must be Gen'd */
1783*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
1784*61046927SAndroid Build Coastguard Worker "glBindRenderbuffer(non-gen name)");
1785*61046927SAndroid Build Coastguard Worker return;
1786*61046927SAndroid Build Coastguard Worker }
1787*61046927SAndroid Build Coastguard Worker
1788*61046927SAndroid Build Coastguard Worker if (!newRb) {
1789*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(&ctx->Shared->RenderBuffers);
1790*61046927SAndroid Build Coastguard Worker newRb = allocate_renderbuffer_locked(ctx, renderbuffer,
1791*61046927SAndroid Build Coastguard Worker "glBindRenderbufferEXT");
1792*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers);
1793*61046927SAndroid Build Coastguard Worker }
1794*61046927SAndroid Build Coastguard Worker }
1795*61046927SAndroid Build Coastguard Worker else {
1796*61046927SAndroid Build Coastguard Worker newRb = NULL;
1797*61046927SAndroid Build Coastguard Worker }
1798*61046927SAndroid Build Coastguard Worker
1799*61046927SAndroid Build Coastguard Worker assert(newRb != &DummyRenderbuffer);
1800*61046927SAndroid Build Coastguard Worker
1801*61046927SAndroid Build Coastguard Worker _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
1802*61046927SAndroid Build Coastguard Worker }
1803*61046927SAndroid Build Coastguard Worker
1804*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindRenderbuffer(GLenum target,GLuint renderbuffer)1805*61046927SAndroid Build Coastguard Worker _mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer)
1806*61046927SAndroid Build Coastguard Worker {
1807*61046927SAndroid Build Coastguard Worker /* OpenGL ES glBindRenderbuffer and glBindRenderbufferOES use this same
1808*61046927SAndroid Build Coastguard Worker * entry point, but they allow the use of user-generated names.
1809*61046927SAndroid Build Coastguard Worker */
1810*61046927SAndroid Build Coastguard Worker bind_renderbuffer(target, renderbuffer);
1811*61046927SAndroid Build Coastguard Worker }
1812*61046927SAndroid Build Coastguard Worker
1813*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindRenderbufferEXT(GLenum target,GLuint renderbuffer)1814*61046927SAndroid Build Coastguard Worker _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
1815*61046927SAndroid Build Coastguard Worker {
1816*61046927SAndroid Build Coastguard Worker bind_renderbuffer(target, renderbuffer);
1817*61046927SAndroid Build Coastguard Worker }
1818*61046927SAndroid Build Coastguard Worker
1819*61046927SAndroid Build Coastguard Worker /**
1820*61046927SAndroid Build Coastguard Worker * ARB_framebuffer_no_attachment and ARB_sample_locations - Application passes
1821*61046927SAndroid Build Coastguard Worker * requested param's here. NOTE: NumSamples requested need not be _NumSamples
1822*61046927SAndroid Build Coastguard Worker * which is what the hw supports.
1823*61046927SAndroid Build Coastguard Worker */
1824*61046927SAndroid Build Coastguard Worker static void
framebuffer_parameteri(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum pname,GLint param,const char * func)1825*61046927SAndroid Build Coastguard Worker framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
1826*61046927SAndroid Build Coastguard Worker GLenum pname, GLint param, const char *func)
1827*61046927SAndroid Build Coastguard Worker {
1828*61046927SAndroid Build Coastguard Worker bool cannot_be_winsys_fbo = false;
1829*61046927SAndroid Build Coastguard Worker
1830*61046927SAndroid Build Coastguard Worker switch (pname) {
1831*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1832*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1833*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_LAYERS:
1834*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1835*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1836*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_framebuffer_no_attachments)
1837*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
1838*61046927SAndroid Build Coastguard Worker cannot_be_winsys_fbo = true;
1839*61046927SAndroid Build Coastguard Worker break;
1840*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
1841*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
1842*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_sample_locations)
1843*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
1844*61046927SAndroid Build Coastguard Worker break;
1845*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_FLIP_Y_MESA:
1846*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.MESA_framebuffer_flip_y)
1847*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
1848*61046927SAndroid Build Coastguard Worker cannot_be_winsys_fbo = true;
1849*61046927SAndroid Build Coastguard Worker break;
1850*61046927SAndroid Build Coastguard Worker default:
1851*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
1852*61046927SAndroid Build Coastguard Worker }
1853*61046927SAndroid Build Coastguard Worker
1854*61046927SAndroid Build Coastguard Worker if (cannot_be_winsys_fbo && _mesa_is_winsys_fbo(fb)) {
1855*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
1856*61046927SAndroid Build Coastguard Worker "%s(invalid pname=0x%x for default framebuffer)", func, pname);
1857*61046927SAndroid Build Coastguard Worker return;
1858*61046927SAndroid Build Coastguard Worker }
1859*61046927SAndroid Build Coastguard Worker
1860*61046927SAndroid Build Coastguard Worker switch (pname) {
1861*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1862*61046927SAndroid Build Coastguard Worker if (param < 0 || param > ctx->Const.MaxFramebufferWidth)
1863*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
1864*61046927SAndroid Build Coastguard Worker else
1865*61046927SAndroid Build Coastguard Worker fb->DefaultGeometry.Width = param;
1866*61046927SAndroid Build Coastguard Worker break;
1867*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1868*61046927SAndroid Build Coastguard Worker if (param < 0 || param > ctx->Const.MaxFramebufferHeight)
1869*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
1870*61046927SAndroid Build Coastguard Worker else
1871*61046927SAndroid Build Coastguard Worker fb->DefaultGeometry.Height = param;
1872*61046927SAndroid Build Coastguard Worker break;
1873*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_LAYERS:
1874*61046927SAndroid Build Coastguard Worker /*
1875*61046927SAndroid Build Coastguard Worker * According to the OpenGL ES 3.1 specification section 9.2.1, the
1876*61046927SAndroid Build Coastguard Worker * GL_FRAMEBUFFER_DEFAULT_LAYERS parameter name is not supported.
1877*61046927SAndroid Build Coastguard Worker */
1878*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles31(ctx) && !ctx->Extensions.OES_geometry_shader) {
1879*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
1880*61046927SAndroid Build Coastguard Worker break;
1881*61046927SAndroid Build Coastguard Worker }
1882*61046927SAndroid Build Coastguard Worker if (param < 0 || param > ctx->Const.MaxFramebufferLayers)
1883*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
1884*61046927SAndroid Build Coastguard Worker else
1885*61046927SAndroid Build Coastguard Worker fb->DefaultGeometry.Layers = param;
1886*61046927SAndroid Build Coastguard Worker break;
1887*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1888*61046927SAndroid Build Coastguard Worker if (param < 0 || param > ctx->Const.MaxFramebufferSamples)
1889*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
1890*61046927SAndroid Build Coastguard Worker else
1891*61046927SAndroid Build Coastguard Worker fb->DefaultGeometry.NumSamples = param;
1892*61046927SAndroid Build Coastguard Worker break;
1893*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1894*61046927SAndroid Build Coastguard Worker fb->DefaultGeometry.FixedSampleLocations = param;
1895*61046927SAndroid Build Coastguard Worker break;
1896*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
1897*61046927SAndroid Build Coastguard Worker fb->ProgrammableSampleLocations = !!param;
1898*61046927SAndroid Build Coastguard Worker break;
1899*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
1900*61046927SAndroid Build Coastguard Worker fb->SampleLocationPixelGrid = !!param;
1901*61046927SAndroid Build Coastguard Worker break;
1902*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_FLIP_Y_MESA:
1903*61046927SAndroid Build Coastguard Worker fb->FlipY = param;
1904*61046927SAndroid Build Coastguard Worker break;
1905*61046927SAndroid Build Coastguard Worker }
1906*61046927SAndroid Build Coastguard Worker
1907*61046927SAndroid Build Coastguard Worker switch (pname) {
1908*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
1909*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
1910*61046927SAndroid Build Coastguard Worker if (fb == ctx->DrawBuffer)
1911*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_SAMPLE_STATE;
1912*61046927SAndroid Build Coastguard Worker break;
1913*61046927SAndroid Build Coastguard Worker default:
1914*61046927SAndroid Build Coastguard Worker invalidate_framebuffer(fb);
1915*61046927SAndroid Build Coastguard Worker ctx->NewState |= _NEW_BUFFERS;
1916*61046927SAndroid Build Coastguard Worker break;
1917*61046927SAndroid Build Coastguard Worker }
1918*61046927SAndroid Build Coastguard Worker
1919*61046927SAndroid Build Coastguard Worker return;
1920*61046927SAndroid Build Coastguard Worker
1921*61046927SAndroid Build Coastguard Worker invalid_pname_enum:
1922*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
1923*61046927SAndroid Build Coastguard Worker }
1924*61046927SAndroid Build Coastguard Worker
1925*61046927SAndroid Build Coastguard Worker static bool
validate_framebuffer_parameter_extensions(GLenum pname,const char * func)1926*61046927SAndroid Build Coastguard Worker validate_framebuffer_parameter_extensions(GLenum pname, const char *func)
1927*61046927SAndroid Build Coastguard Worker {
1928*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1929*61046927SAndroid Build Coastguard Worker
1930*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_framebuffer_no_attachments &&
1931*61046927SAndroid Build Coastguard Worker !ctx->Extensions.ARB_sample_locations &&
1932*61046927SAndroid Build Coastguard Worker !ctx->Extensions.MESA_framebuffer_flip_y) {
1933*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
1934*61046927SAndroid Build Coastguard Worker "%s not supported "
1935*61046927SAndroid Build Coastguard Worker "(none of ARB_framebuffer_no_attachments,"
1936*61046927SAndroid Build Coastguard Worker " ARB_sample_locations, or"
1937*61046927SAndroid Build Coastguard Worker " MESA_framebuffer_flip_y extensions are available)",
1938*61046927SAndroid Build Coastguard Worker func);
1939*61046927SAndroid Build Coastguard Worker return false;
1940*61046927SAndroid Build Coastguard Worker }
1941*61046927SAndroid Build Coastguard Worker
1942*61046927SAndroid Build Coastguard Worker /*
1943*61046927SAndroid Build Coastguard Worker * If only the MESA_framebuffer_flip_y extension is enabled
1944*61046927SAndroid Build Coastguard Worker * pname can only be GL_FRAMEBUFFER_FLIP_Y_MESA
1945*61046927SAndroid Build Coastguard Worker */
1946*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.MESA_framebuffer_flip_y &&
1947*61046927SAndroid Build Coastguard Worker pname != GL_FRAMEBUFFER_FLIP_Y_MESA &&
1948*61046927SAndroid Build Coastguard Worker !(ctx->Extensions.ARB_framebuffer_no_attachments ||
1949*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_sample_locations)) {
1950*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
1951*61046927SAndroid Build Coastguard Worker return false;
1952*61046927SAndroid Build Coastguard Worker }
1953*61046927SAndroid Build Coastguard Worker
1954*61046927SAndroid Build Coastguard Worker return true;
1955*61046927SAndroid Build Coastguard Worker }
1956*61046927SAndroid Build Coastguard Worker
1957*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferParameteri(GLenum target,GLenum pname,GLint param)1958*61046927SAndroid Build Coastguard Worker _mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param)
1959*61046927SAndroid Build Coastguard Worker {
1960*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1961*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
1962*61046927SAndroid Build Coastguard Worker
1963*61046927SAndroid Build Coastguard Worker if (!validate_framebuffer_parameter_extensions(pname,
1964*61046927SAndroid Build Coastguard Worker "glFramebufferParameteri")) {
1965*61046927SAndroid Build Coastguard Worker return;
1966*61046927SAndroid Build Coastguard Worker }
1967*61046927SAndroid Build Coastguard Worker
1968*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
1969*61046927SAndroid Build Coastguard Worker if (!fb) {
1970*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
1971*61046927SAndroid Build Coastguard Worker "glFramebufferParameteri(target=0x%x)", target);
1972*61046927SAndroid Build Coastguard Worker return;
1973*61046927SAndroid Build Coastguard Worker }
1974*61046927SAndroid Build Coastguard Worker
1975*61046927SAndroid Build Coastguard Worker framebuffer_parameteri(ctx, fb, pname, param, "glFramebufferParameteri");
1976*61046927SAndroid Build Coastguard Worker }
1977*61046927SAndroid Build Coastguard Worker
1978*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferParameteriMESA(GLenum target,GLenum pname,GLint param)1979*61046927SAndroid Build Coastguard Worker _mesa_FramebufferParameteriMESA(GLenum target, GLenum pname, GLint param)
1980*61046927SAndroid Build Coastguard Worker {
1981*61046927SAndroid Build Coastguard Worker _mesa_FramebufferParameteri(target, pname, param);
1982*61046927SAndroid Build Coastguard Worker }
1983*61046927SAndroid Build Coastguard Worker
1984*61046927SAndroid Build Coastguard Worker static bool
validate_get_framebuffer_parameteriv_pname(struct gl_context * ctx,struct gl_framebuffer * fb,GLuint pname,const char * func)1985*61046927SAndroid Build Coastguard Worker validate_get_framebuffer_parameteriv_pname(struct gl_context *ctx,
1986*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
1987*61046927SAndroid Build Coastguard Worker GLuint pname, const char *func)
1988*61046927SAndroid Build Coastguard Worker {
1989*61046927SAndroid Build Coastguard Worker bool cannot_be_winsys_fbo = true;
1990*61046927SAndroid Build Coastguard Worker
1991*61046927SAndroid Build Coastguard Worker switch (pname) {
1992*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_LAYERS:
1993*61046927SAndroid Build Coastguard Worker /*
1994*61046927SAndroid Build Coastguard Worker * According to the OpenGL ES 3.1 specification section 9.2.3, the
1995*61046927SAndroid Build Coastguard Worker * GL_FRAMEBUFFER_LAYERS parameter name is not supported.
1996*61046927SAndroid Build Coastguard Worker */
1997*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles31(ctx) && !ctx->Extensions.OES_geometry_shader) {
1998*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
1999*61046927SAndroid Build Coastguard Worker return false;
2000*61046927SAndroid Build Coastguard Worker }
2001*61046927SAndroid Build Coastguard Worker break;
2002*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_WIDTH:
2003*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
2004*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
2005*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
2006*61046927SAndroid Build Coastguard Worker break;
2007*61046927SAndroid Build Coastguard Worker case GL_DOUBLEBUFFER:
2008*61046927SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2009*61046927SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2010*61046927SAndroid Build Coastguard Worker case GL_SAMPLES:
2011*61046927SAndroid Build Coastguard Worker case GL_SAMPLE_BUFFERS:
2012*61046927SAndroid Build Coastguard Worker case GL_STEREO:
2013*61046927SAndroid Build Coastguard Worker /* From OpenGL 4.5 spec, section 9.2.3 "Framebuffer Object Queries:
2014*61046927SAndroid Build Coastguard Worker *
2015*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated by GetFramebufferParameteriv
2016*61046927SAndroid Build Coastguard Worker * if the default framebuffer is bound to target and pname is not one
2017*61046927SAndroid Build Coastguard Worker * of the accepted values from table 23.73, other than
2018*61046927SAndroid Build Coastguard Worker * SAMPLE_POSITION."
2019*61046927SAndroid Build Coastguard Worker *
2020*61046927SAndroid Build Coastguard Worker * For OpenGL ES, using default framebuffer raises INVALID_OPERATION
2021*61046927SAndroid Build Coastguard Worker * for any pname.
2022*61046927SAndroid Build Coastguard Worker */
2023*61046927SAndroid Build Coastguard Worker cannot_be_winsys_fbo = !_mesa_is_desktop_gl(ctx);
2024*61046927SAndroid Build Coastguard Worker break;
2025*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
2026*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
2027*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_sample_locations)
2028*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
2029*61046927SAndroid Build Coastguard Worker cannot_be_winsys_fbo = false;
2030*61046927SAndroid Build Coastguard Worker break;
2031*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_FLIP_Y_MESA:
2032*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.MESA_framebuffer_flip_y) {
2033*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
2034*61046927SAndroid Build Coastguard Worker return false;
2035*61046927SAndroid Build Coastguard Worker }
2036*61046927SAndroid Build Coastguard Worker break;
2037*61046927SAndroid Build Coastguard Worker default:
2038*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
2039*61046927SAndroid Build Coastguard Worker }
2040*61046927SAndroid Build Coastguard Worker
2041*61046927SAndroid Build Coastguard Worker if (cannot_be_winsys_fbo && _mesa_is_winsys_fbo(fb)) {
2042*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
2043*61046927SAndroid Build Coastguard Worker "%s(invalid pname=0x%x for default framebuffer)", func, pname);
2044*61046927SAndroid Build Coastguard Worker return false;
2045*61046927SAndroid Build Coastguard Worker }
2046*61046927SAndroid Build Coastguard Worker
2047*61046927SAndroid Build Coastguard Worker return true;
2048*61046927SAndroid Build Coastguard Worker
2049*61046927SAndroid Build Coastguard Worker invalid_pname_enum:
2050*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
2051*61046927SAndroid Build Coastguard Worker return false;
2052*61046927SAndroid Build Coastguard Worker }
2053*61046927SAndroid Build Coastguard Worker
2054*61046927SAndroid Build Coastguard Worker static void
get_framebuffer_parameteriv(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum pname,GLint * params,const char * func)2055*61046927SAndroid Build Coastguard Worker get_framebuffer_parameteriv(struct gl_context *ctx, struct gl_framebuffer *fb,
2056*61046927SAndroid Build Coastguard Worker GLenum pname, GLint *params, const char *func)
2057*61046927SAndroid Build Coastguard Worker {
2058*61046927SAndroid Build Coastguard Worker if (!validate_get_framebuffer_parameteriv_pname(ctx, fb, pname, func))
2059*61046927SAndroid Build Coastguard Worker return;
2060*61046927SAndroid Build Coastguard Worker
2061*61046927SAndroid Build Coastguard Worker switch (pname) {
2062*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_WIDTH:
2063*61046927SAndroid Build Coastguard Worker *params = fb->DefaultGeometry.Width;
2064*61046927SAndroid Build Coastguard Worker break;
2065*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
2066*61046927SAndroid Build Coastguard Worker *params = fb->DefaultGeometry.Height;
2067*61046927SAndroid Build Coastguard Worker break;
2068*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_LAYERS:
2069*61046927SAndroid Build Coastguard Worker *params = fb->DefaultGeometry.Layers;
2070*61046927SAndroid Build Coastguard Worker break;
2071*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
2072*61046927SAndroid Build Coastguard Worker *params = fb->DefaultGeometry.NumSamples;
2073*61046927SAndroid Build Coastguard Worker break;
2074*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
2075*61046927SAndroid Build Coastguard Worker *params = fb->DefaultGeometry.FixedSampleLocations;
2076*61046927SAndroid Build Coastguard Worker break;
2077*61046927SAndroid Build Coastguard Worker case GL_DOUBLEBUFFER:
2078*61046927SAndroid Build Coastguard Worker *params = fb->Visual.doubleBufferMode;
2079*61046927SAndroid Build Coastguard Worker break;
2080*61046927SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2081*61046927SAndroid Build Coastguard Worker *params = _mesa_get_color_read_format(ctx, fb, func);
2082*61046927SAndroid Build Coastguard Worker break;
2083*61046927SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2084*61046927SAndroid Build Coastguard Worker *params = _mesa_get_color_read_type(ctx, fb, func);
2085*61046927SAndroid Build Coastguard Worker break;
2086*61046927SAndroid Build Coastguard Worker case GL_SAMPLES:
2087*61046927SAndroid Build Coastguard Worker *params = _mesa_geometric_samples(fb);
2088*61046927SAndroid Build Coastguard Worker break;
2089*61046927SAndroid Build Coastguard Worker case GL_SAMPLE_BUFFERS:
2090*61046927SAndroid Build Coastguard Worker *params = _mesa_geometric_samples(fb) > 0;
2091*61046927SAndroid Build Coastguard Worker break;
2092*61046927SAndroid Build Coastguard Worker case GL_STEREO:
2093*61046927SAndroid Build Coastguard Worker *params = fb->Visual.stereoMode;
2094*61046927SAndroid Build Coastguard Worker break;
2095*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
2096*61046927SAndroid Build Coastguard Worker *params = fb->ProgrammableSampleLocations;
2097*61046927SAndroid Build Coastguard Worker break;
2098*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
2099*61046927SAndroid Build Coastguard Worker *params = fb->SampleLocationPixelGrid;
2100*61046927SAndroid Build Coastguard Worker break;
2101*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_FLIP_Y_MESA:
2102*61046927SAndroid Build Coastguard Worker *params = fb->FlipY;
2103*61046927SAndroid Build Coastguard Worker break;
2104*61046927SAndroid Build Coastguard Worker }
2105*61046927SAndroid Build Coastguard Worker }
2106*61046927SAndroid Build Coastguard Worker
2107*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetFramebufferParameteriv(GLenum target,GLenum pname,GLint * params)2108*61046927SAndroid Build Coastguard Worker _mesa_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
2109*61046927SAndroid Build Coastguard Worker {
2110*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2111*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
2112*61046927SAndroid Build Coastguard Worker
2113*61046927SAndroid Build Coastguard Worker if (!validate_framebuffer_parameter_extensions(pname,
2114*61046927SAndroid Build Coastguard Worker "glGetFramebufferParameteriv")) {
2115*61046927SAndroid Build Coastguard Worker return;
2116*61046927SAndroid Build Coastguard Worker }
2117*61046927SAndroid Build Coastguard Worker
2118*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
2119*61046927SAndroid Build Coastguard Worker if (!fb) {
2120*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
2121*61046927SAndroid Build Coastguard Worker "glGetFramebufferParameteriv(target=0x%x)", target);
2122*61046927SAndroid Build Coastguard Worker return;
2123*61046927SAndroid Build Coastguard Worker }
2124*61046927SAndroid Build Coastguard Worker
2125*61046927SAndroid Build Coastguard Worker get_framebuffer_parameteriv(ctx, fb, pname, params,
2126*61046927SAndroid Build Coastguard Worker "glGetFramebufferParameteriv");
2127*61046927SAndroid Build Coastguard Worker }
2128*61046927SAndroid Build Coastguard Worker
2129*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetFramebufferParameterivMESA(GLenum target,GLenum pname,GLint * params)2130*61046927SAndroid Build Coastguard Worker _mesa_GetFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params)
2131*61046927SAndroid Build Coastguard Worker {
2132*61046927SAndroid Build Coastguard Worker _mesa_GetFramebufferParameteriv(target, pname, params);
2133*61046927SAndroid Build Coastguard Worker }
2134*61046927SAndroid Build Coastguard Worker
2135*61046927SAndroid Build Coastguard Worker /**
2136*61046927SAndroid Build Coastguard Worker * Remove the specified renderbuffer or texture from any attachment point in
2137*61046927SAndroid Build Coastguard Worker * the framebuffer.
2138*61046927SAndroid Build Coastguard Worker *
2139*61046927SAndroid Build Coastguard Worker * \returns
2140*61046927SAndroid Build Coastguard Worker * \c true if the renderbuffer was detached from an attachment point. \c
2141*61046927SAndroid Build Coastguard Worker * false otherwise.
2142*61046927SAndroid Build Coastguard Worker */
2143*61046927SAndroid Build Coastguard Worker bool
_mesa_detach_renderbuffer(struct gl_context * ctx,struct gl_framebuffer * fb,const void * att)2144*61046927SAndroid Build Coastguard Worker _mesa_detach_renderbuffer(struct gl_context *ctx,
2145*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
2146*61046927SAndroid Build Coastguard Worker const void *att)
2147*61046927SAndroid Build Coastguard Worker {
2148*61046927SAndroid Build Coastguard Worker unsigned i;
2149*61046927SAndroid Build Coastguard Worker bool progress = false;
2150*61046927SAndroid Build Coastguard Worker
2151*61046927SAndroid Build Coastguard Worker for (i = 0; i < BUFFER_COUNT; i++) {
2152*61046927SAndroid Build Coastguard Worker if (fb->Attachment[i].Texture == att
2153*61046927SAndroid Build Coastguard Worker || fb->Attachment[i].Renderbuffer == att) {
2154*61046927SAndroid Build Coastguard Worker remove_attachment(ctx, &fb->Attachment[i]);
2155*61046927SAndroid Build Coastguard Worker progress = true;
2156*61046927SAndroid Build Coastguard Worker }
2157*61046927SAndroid Build Coastguard Worker }
2158*61046927SAndroid Build Coastguard Worker
2159*61046927SAndroid Build Coastguard Worker /* Section 4.4.4 (Framebuffer Completeness), subsection "Whole Framebuffer
2160*61046927SAndroid Build Coastguard Worker * Completeness," of the OpenGL 3.1 spec says:
2161*61046927SAndroid Build Coastguard Worker *
2162*61046927SAndroid Build Coastguard Worker * "Performing any of the following actions may change whether the
2163*61046927SAndroid Build Coastguard Worker * framebuffer is considered complete or incomplete:
2164*61046927SAndroid Build Coastguard Worker *
2165*61046927SAndroid Build Coastguard Worker * ...
2166*61046927SAndroid Build Coastguard Worker *
2167*61046927SAndroid Build Coastguard Worker * - Deleting, with DeleteTextures or DeleteRenderbuffers, an object
2168*61046927SAndroid Build Coastguard Worker * containing an image that is attached to a framebuffer object
2169*61046927SAndroid Build Coastguard Worker * that is bound to the framebuffer."
2170*61046927SAndroid Build Coastguard Worker */
2171*61046927SAndroid Build Coastguard Worker if (progress)
2172*61046927SAndroid Build Coastguard Worker invalidate_framebuffer(fb);
2173*61046927SAndroid Build Coastguard Worker
2174*61046927SAndroid Build Coastguard Worker return progress;
2175*61046927SAndroid Build Coastguard Worker }
2176*61046927SAndroid Build Coastguard Worker
2177*61046927SAndroid Build Coastguard Worker
2178*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DeleteRenderbuffers(GLsizei n,const GLuint * renderbuffers)2179*61046927SAndroid Build Coastguard Worker _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
2180*61046927SAndroid Build Coastguard Worker {
2181*61046927SAndroid Build Coastguard Worker GLint i;
2182*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2183*61046927SAndroid Build Coastguard Worker
2184*61046927SAndroid Build Coastguard Worker if (n < 0) {
2185*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteRenderbuffers(n < 0)");
2186*61046927SAndroid Build Coastguard Worker return;
2187*61046927SAndroid Build Coastguard Worker }
2188*61046927SAndroid Build Coastguard Worker
2189*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
2190*61046927SAndroid Build Coastguard Worker
2191*61046927SAndroid Build Coastguard Worker for (i = 0; i < n; i++) {
2192*61046927SAndroid Build Coastguard Worker if (renderbuffers[i] > 0) {
2193*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb;
2194*61046927SAndroid Build Coastguard Worker rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
2195*61046927SAndroid Build Coastguard Worker if (rb) {
2196*61046927SAndroid Build Coastguard Worker /* check if deleting currently bound renderbuffer object */
2197*61046927SAndroid Build Coastguard Worker if (rb == ctx->CurrentRenderbuffer) {
2198*61046927SAndroid Build Coastguard Worker /* bind default */
2199*61046927SAndroid Build Coastguard Worker assert(rb->RefCount >= 2);
2200*61046927SAndroid Build Coastguard Worker _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
2201*61046927SAndroid Build Coastguard Worker }
2202*61046927SAndroid Build Coastguard Worker
2203*61046927SAndroid Build Coastguard Worker /* Section 4.4.2 (Attaching Images to Framebuffer Objects),
2204*61046927SAndroid Build Coastguard Worker * subsection "Attaching Renderbuffer Images to a Framebuffer,"
2205*61046927SAndroid Build Coastguard Worker * of the OpenGL 3.1 spec says:
2206*61046927SAndroid Build Coastguard Worker *
2207*61046927SAndroid Build Coastguard Worker * "If a renderbuffer object is deleted while its image is
2208*61046927SAndroid Build Coastguard Worker * attached to one or more attachment points in the currently
2209*61046927SAndroid Build Coastguard Worker * bound framebuffer, then it is as if FramebufferRenderbuffer
2210*61046927SAndroid Build Coastguard Worker * had been called, with a renderbuffer of 0, for each
2211*61046927SAndroid Build Coastguard Worker * attachment point to which this image was attached in the
2212*61046927SAndroid Build Coastguard Worker * currently bound framebuffer. In other words, this
2213*61046927SAndroid Build Coastguard Worker * renderbuffer image is first detached from all attachment
2214*61046927SAndroid Build Coastguard Worker * points in the currently bound framebuffer. Note that the
2215*61046927SAndroid Build Coastguard Worker * renderbuffer image is specifically not detached from any
2216*61046927SAndroid Build Coastguard Worker * non-bound framebuffers. Detaching the image from any
2217*61046927SAndroid Build Coastguard Worker * non-bound framebuffers is the responsibility of the
2218*61046927SAndroid Build Coastguard Worker * application.
2219*61046927SAndroid Build Coastguard Worker */
2220*61046927SAndroid Build Coastguard Worker if (_mesa_is_user_fbo(ctx->DrawBuffer)) {
2221*61046927SAndroid Build Coastguard Worker _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
2222*61046927SAndroid Build Coastguard Worker }
2223*61046927SAndroid Build Coastguard Worker if (_mesa_is_user_fbo(ctx->ReadBuffer)
2224*61046927SAndroid Build Coastguard Worker && ctx->ReadBuffer != ctx->DrawBuffer) {
2225*61046927SAndroid Build Coastguard Worker _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
2226*61046927SAndroid Build Coastguard Worker }
2227*61046927SAndroid Build Coastguard Worker
2228*61046927SAndroid Build Coastguard Worker /* Remove from hash table immediately, to free the ID.
2229*61046927SAndroid Build Coastguard Worker * But the object will not be freed until it's no longer
2230*61046927SAndroid Build Coastguard Worker * referenced anywhere else.
2231*61046927SAndroid Build Coastguard Worker */
2232*61046927SAndroid Build Coastguard Worker _mesa_HashRemove(&ctx->Shared->RenderBuffers, renderbuffers[i]);
2233*61046927SAndroid Build Coastguard Worker
2234*61046927SAndroid Build Coastguard Worker if (rb != &DummyRenderbuffer) {
2235*61046927SAndroid Build Coastguard Worker /* no longer referenced by hash table */
2236*61046927SAndroid Build Coastguard Worker _mesa_reference_renderbuffer(&rb, NULL);
2237*61046927SAndroid Build Coastguard Worker }
2238*61046927SAndroid Build Coastguard Worker }
2239*61046927SAndroid Build Coastguard Worker }
2240*61046927SAndroid Build Coastguard Worker }
2241*61046927SAndroid Build Coastguard Worker }
2242*61046927SAndroid Build Coastguard Worker
2243*61046927SAndroid Build Coastguard Worker static void
create_render_buffers(struct gl_context * ctx,GLsizei n,GLuint * renderbuffers,bool dsa)2244*61046927SAndroid Build Coastguard Worker create_render_buffers(struct gl_context *ctx, GLsizei n, GLuint *renderbuffers,
2245*61046927SAndroid Build Coastguard Worker bool dsa)
2246*61046927SAndroid Build Coastguard Worker {
2247*61046927SAndroid Build Coastguard Worker const char *func = dsa ? "glCreateRenderbuffers" : "glGenRenderbuffers";
2248*61046927SAndroid Build Coastguard Worker GLint i;
2249*61046927SAndroid Build Coastguard Worker
2250*61046927SAndroid Build Coastguard Worker if (!renderbuffers)
2251*61046927SAndroid Build Coastguard Worker return;
2252*61046927SAndroid Build Coastguard Worker
2253*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(&ctx->Shared->RenderBuffers);
2254*61046927SAndroid Build Coastguard Worker
2255*61046927SAndroid Build Coastguard Worker _mesa_HashFindFreeKeys(&ctx->Shared->RenderBuffers, renderbuffers, n);
2256*61046927SAndroid Build Coastguard Worker
2257*61046927SAndroid Build Coastguard Worker for (i = 0; i < n; i++) {
2258*61046927SAndroid Build Coastguard Worker if (dsa) {
2259*61046927SAndroid Build Coastguard Worker allocate_renderbuffer_locked(ctx, renderbuffers[i], func);
2260*61046927SAndroid Build Coastguard Worker } else {
2261*61046927SAndroid Build Coastguard Worker /* insert a dummy renderbuffer into the hash table */
2262*61046927SAndroid Build Coastguard Worker _mesa_HashInsertLocked(&ctx->Shared->RenderBuffers, renderbuffers[i],
2263*61046927SAndroid Build Coastguard Worker &DummyRenderbuffer);
2264*61046927SAndroid Build Coastguard Worker }
2265*61046927SAndroid Build Coastguard Worker }
2266*61046927SAndroid Build Coastguard Worker
2267*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers);
2268*61046927SAndroid Build Coastguard Worker }
2269*61046927SAndroid Build Coastguard Worker
2270*61046927SAndroid Build Coastguard Worker
2271*61046927SAndroid Build Coastguard Worker static void
create_render_buffers_err(struct gl_context * ctx,GLsizei n,GLuint * renderbuffers,bool dsa)2272*61046927SAndroid Build Coastguard Worker create_render_buffers_err(struct gl_context *ctx, GLsizei n,
2273*61046927SAndroid Build Coastguard Worker GLuint *renderbuffers, bool dsa)
2274*61046927SAndroid Build Coastguard Worker {
2275*61046927SAndroid Build Coastguard Worker const char *func = dsa ? "glCreateRenderbuffers" : "glGenRenderbuffers";
2276*61046927SAndroid Build Coastguard Worker
2277*61046927SAndroid Build Coastguard Worker if (n < 0) {
2278*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", func);
2279*61046927SAndroid Build Coastguard Worker return;
2280*61046927SAndroid Build Coastguard Worker }
2281*61046927SAndroid Build Coastguard Worker
2282*61046927SAndroid Build Coastguard Worker create_render_buffers(ctx, n, renderbuffers, dsa);
2283*61046927SAndroid Build Coastguard Worker }
2284*61046927SAndroid Build Coastguard Worker
2285*61046927SAndroid Build Coastguard Worker
2286*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GenRenderbuffers_no_error(GLsizei n,GLuint * renderbuffers)2287*61046927SAndroid Build Coastguard Worker _mesa_GenRenderbuffers_no_error(GLsizei n, GLuint *renderbuffers)
2288*61046927SAndroid Build Coastguard Worker {
2289*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2290*61046927SAndroid Build Coastguard Worker create_render_buffers(ctx, n, renderbuffers, false);
2291*61046927SAndroid Build Coastguard Worker }
2292*61046927SAndroid Build Coastguard Worker
2293*61046927SAndroid Build Coastguard Worker
2294*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GenRenderbuffers(GLsizei n,GLuint * renderbuffers)2295*61046927SAndroid Build Coastguard Worker _mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers)
2296*61046927SAndroid Build Coastguard Worker {
2297*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2298*61046927SAndroid Build Coastguard Worker create_render_buffers_err(ctx, n, renderbuffers, false);
2299*61046927SAndroid Build Coastguard Worker }
2300*61046927SAndroid Build Coastguard Worker
2301*61046927SAndroid Build Coastguard Worker
2302*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CreateRenderbuffers_no_error(GLsizei n,GLuint * renderbuffers)2303*61046927SAndroid Build Coastguard Worker _mesa_CreateRenderbuffers_no_error(GLsizei n, GLuint *renderbuffers)
2304*61046927SAndroid Build Coastguard Worker {
2305*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2306*61046927SAndroid Build Coastguard Worker create_render_buffers(ctx, n, renderbuffers, true);
2307*61046927SAndroid Build Coastguard Worker }
2308*61046927SAndroid Build Coastguard Worker
2309*61046927SAndroid Build Coastguard Worker
2310*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CreateRenderbuffers(GLsizei n,GLuint * renderbuffers)2311*61046927SAndroid Build Coastguard Worker _mesa_CreateRenderbuffers(GLsizei n, GLuint *renderbuffers)
2312*61046927SAndroid Build Coastguard Worker {
2313*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2314*61046927SAndroid Build Coastguard Worker create_render_buffers_err(ctx, n, renderbuffers, true);
2315*61046927SAndroid Build Coastguard Worker }
2316*61046927SAndroid Build Coastguard Worker
2317*61046927SAndroid Build Coastguard Worker
2318*61046927SAndroid Build Coastguard Worker /**
2319*61046927SAndroid Build Coastguard Worker * Given an internal format token for a render buffer, return the
2320*61046927SAndroid Build Coastguard Worker * corresponding base format (one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX,
2321*61046927SAndroid Build Coastguard Worker * GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL_EXT, GL_ALPHA, GL_LUMINANCE,
2322*61046927SAndroid Build Coastguard Worker * GL_LUMINANCE_ALPHA, GL_INTENSITY, etc).
2323*61046927SAndroid Build Coastguard Worker *
2324*61046927SAndroid Build Coastguard Worker * This is similar to _mesa_base_tex_format() but the set of valid
2325*61046927SAndroid Build Coastguard Worker * internal formats is different.
2326*61046927SAndroid Build Coastguard Worker *
2327*61046927SAndroid Build Coastguard Worker * Note that even if a format is determined to be legal here, validation
2328*61046927SAndroid Build Coastguard Worker * of the FBO may fail if the format is not supported by the driver/GPU.
2329*61046927SAndroid Build Coastguard Worker *
2330*61046927SAndroid Build Coastguard Worker * \param internalFormat as passed to glRenderbufferStorage()
2331*61046927SAndroid Build Coastguard Worker * \return the base internal format, or 0 if internalFormat is illegal
2332*61046927SAndroid Build Coastguard Worker */
2333*61046927SAndroid Build Coastguard Worker GLenum
_mesa_base_fbo_format(const struct gl_context * ctx,GLenum internalFormat)2334*61046927SAndroid Build Coastguard Worker _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat)
2335*61046927SAndroid Build Coastguard Worker {
2336*61046927SAndroid Build Coastguard Worker /*
2337*61046927SAndroid Build Coastguard Worker * Notes: some formats such as alpha, luminance, etc. were added
2338*61046927SAndroid Build Coastguard Worker * with GL_ARB_framebuffer_object.
2339*61046927SAndroid Build Coastguard Worker */
2340*61046927SAndroid Build Coastguard Worker switch (internalFormat) {
2341*61046927SAndroid Build Coastguard Worker case GL_ALPHA:
2342*61046927SAndroid Build Coastguard Worker case GL_ALPHA4:
2343*61046927SAndroid Build Coastguard Worker case GL_ALPHA8:
2344*61046927SAndroid Build Coastguard Worker case GL_ALPHA12:
2345*61046927SAndroid Build Coastguard Worker case GL_ALPHA16:
2346*61046927SAndroid Build Coastguard Worker return (_mesa_is_desktop_gl_compat(ctx) &&
2347*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object) ? GL_ALPHA : 0;
2348*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE:
2349*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE4:
2350*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE8:
2351*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE12:
2352*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE16:
2353*61046927SAndroid Build Coastguard Worker return (_mesa_is_desktop_gl_compat(ctx) &&
2354*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object) ? GL_LUMINANCE : 0;
2355*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA:
2356*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE4_ALPHA4:
2357*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE6_ALPHA2:
2358*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE8_ALPHA8:
2359*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE12_ALPHA4:
2360*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE12_ALPHA12:
2361*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE16_ALPHA16:
2362*61046927SAndroid Build Coastguard Worker return (_mesa_is_desktop_gl_compat(ctx) &&
2363*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object) ? GL_LUMINANCE_ALPHA : 0;
2364*61046927SAndroid Build Coastguard Worker case GL_INTENSITY:
2365*61046927SAndroid Build Coastguard Worker case GL_INTENSITY4:
2366*61046927SAndroid Build Coastguard Worker case GL_INTENSITY8:
2367*61046927SAndroid Build Coastguard Worker case GL_INTENSITY12:
2368*61046927SAndroid Build Coastguard Worker case GL_INTENSITY16:
2369*61046927SAndroid Build Coastguard Worker return (_mesa_is_desktop_gl_compat(ctx) &&
2370*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object) ? GL_INTENSITY : 0;
2371*61046927SAndroid Build Coastguard Worker case GL_RGB8:
2372*61046927SAndroid Build Coastguard Worker return GL_RGB;
2373*61046927SAndroid Build Coastguard Worker case GL_RGB:
2374*61046927SAndroid Build Coastguard Worker case GL_R3_G3_B2:
2375*61046927SAndroid Build Coastguard Worker case GL_RGB4:
2376*61046927SAndroid Build Coastguard Worker case GL_RGB5:
2377*61046927SAndroid Build Coastguard Worker case GL_RGB10:
2378*61046927SAndroid Build Coastguard Worker case GL_RGB12:
2379*61046927SAndroid Build Coastguard Worker case GL_RGB16:
2380*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) ? GL_RGB : 0;
2381*61046927SAndroid Build Coastguard Worker case GL_SRGB8_EXT:
2382*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) ? GL_RGB : 0;
2383*61046927SAndroid Build Coastguard Worker case GL_RGBA4:
2384*61046927SAndroid Build Coastguard Worker case GL_RGB5_A1:
2385*61046927SAndroid Build Coastguard Worker case GL_RGBA8:
2386*61046927SAndroid Build Coastguard Worker return GL_RGBA;
2387*61046927SAndroid Build Coastguard Worker case GL_RGBA:
2388*61046927SAndroid Build Coastguard Worker case GL_RGBA2:
2389*61046927SAndroid Build Coastguard Worker case GL_RGBA12:
2390*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) ? GL_RGBA : 0;
2391*61046927SAndroid Build Coastguard Worker case GL_RGBA16:
2392*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) || _mesa_has_EXT_texture_norm16(ctx)
2393*61046927SAndroid Build Coastguard Worker ? GL_RGBA : 0;
2394*61046927SAndroid Build Coastguard Worker case GL_RGB10_A2:
2395*61046927SAndroid Build Coastguard Worker case GL_SRGB8_ALPHA8_EXT:
2396*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx) ? GL_RGBA : 0;
2397*61046927SAndroid Build Coastguard Worker case GL_STENCIL_INDEX:
2398*61046927SAndroid Build Coastguard Worker case GL_STENCIL_INDEX1_EXT:
2399*61046927SAndroid Build Coastguard Worker case GL_STENCIL_INDEX4_EXT:
2400*61046927SAndroid Build Coastguard Worker case GL_STENCIL_INDEX16_EXT:
2401*61046927SAndroid Build Coastguard Worker /* There are extensions for GL_STENCIL_INDEX1 and GL_STENCIL_INDEX4 in
2402*61046927SAndroid Build Coastguard Worker * OpenGL ES, but Mesa does not currently support them.
2403*61046927SAndroid Build Coastguard Worker */
2404*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) ? GL_STENCIL_INDEX : 0;
2405*61046927SAndroid Build Coastguard Worker case GL_STENCIL_INDEX8_EXT:
2406*61046927SAndroid Build Coastguard Worker return GL_STENCIL_INDEX;
2407*61046927SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT:
2408*61046927SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT32:
2409*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) ? GL_DEPTH_COMPONENT : 0;
2410*61046927SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT16:
2411*61046927SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT24:
2412*61046927SAndroid Build Coastguard Worker return GL_DEPTH_COMPONENT;
2413*61046927SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL:
2414*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) ? GL_DEPTH_STENCIL : 0;
2415*61046927SAndroid Build Coastguard Worker case GL_DEPTH24_STENCIL8:
2416*61046927SAndroid Build Coastguard Worker return GL_DEPTH_STENCIL;
2417*61046927SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT32F:
2418*61046927SAndroid Build Coastguard Worker return ctx->Version >= 30
2419*61046927SAndroid Build Coastguard Worker || (_mesa_is_desktop_gl_compat(ctx) &&
2420*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_depth_buffer_float)
2421*61046927SAndroid Build Coastguard Worker ? GL_DEPTH_COMPONENT : 0;
2422*61046927SAndroid Build Coastguard Worker case GL_DEPTH32F_STENCIL8:
2423*61046927SAndroid Build Coastguard Worker return ctx->Version >= 30
2424*61046927SAndroid Build Coastguard Worker || (_mesa_is_desktop_gl_compat(ctx) &&
2425*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_depth_buffer_float)
2426*61046927SAndroid Build Coastguard Worker ? GL_DEPTH_STENCIL : 0;
2427*61046927SAndroid Build Coastguard Worker case GL_RED:
2428*61046927SAndroid Build Coastguard Worker return _mesa_has_ARB_texture_rg(ctx) ? GL_RED : 0;
2429*61046927SAndroid Build Coastguard Worker case GL_R16:
2430*61046927SAndroid Build Coastguard Worker return _mesa_has_ARB_texture_rg(ctx) || _mesa_has_EXT_texture_norm16(ctx)
2431*61046927SAndroid Build Coastguard Worker ? GL_RED : 0;
2432*61046927SAndroid Build Coastguard Worker case GL_R8:
2433*61046927SAndroid Build Coastguard Worker return ctx->API != API_OPENGLES && ctx->Extensions.ARB_texture_rg
2434*61046927SAndroid Build Coastguard Worker ? GL_RED : 0;
2435*61046927SAndroid Build Coastguard Worker case GL_RG:
2436*61046927SAndroid Build Coastguard Worker return _mesa_has_ARB_texture_rg(ctx) ? GL_RG : 0;
2437*61046927SAndroid Build Coastguard Worker case GL_RG16:
2438*61046927SAndroid Build Coastguard Worker return _mesa_has_ARB_texture_rg(ctx) || _mesa_has_EXT_texture_norm16(ctx)
2439*61046927SAndroid Build Coastguard Worker ? GL_RG : 0;
2440*61046927SAndroid Build Coastguard Worker case GL_RG8:
2441*61046927SAndroid Build Coastguard Worker return ctx->API != API_OPENGLES && ctx->Extensions.ARB_texture_rg
2442*61046927SAndroid Build Coastguard Worker ? GL_RG : 0;
2443*61046927SAndroid Build Coastguard Worker /* signed normalized texture formats */
2444*61046927SAndroid Build Coastguard Worker case GL_R8_SNORM:
2445*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_snorm(ctx) || _mesa_has_EXT_render_snorm(ctx)
2446*61046927SAndroid Build Coastguard Worker ? GL_RED : 0;
2447*61046927SAndroid Build Coastguard Worker case GL_RED_SNORM:
2448*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_snorm(ctx) ? GL_RED : 0;
2449*61046927SAndroid Build Coastguard Worker case GL_R16_SNORM:
2450*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_snorm(ctx) ||
2451*61046927SAndroid Build Coastguard Worker (_mesa_has_EXT_render_snorm(ctx) &&
2452*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_texture_norm16(ctx))
2453*61046927SAndroid Build Coastguard Worker ? GL_RED : 0;
2454*61046927SAndroid Build Coastguard Worker case GL_RG8_SNORM:
2455*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_snorm(ctx) || _mesa_has_EXT_render_snorm(ctx)
2456*61046927SAndroid Build Coastguard Worker ? GL_RG : 0;
2457*61046927SAndroid Build Coastguard Worker case GL_RG_SNORM:
2458*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_snorm(ctx) ? GL_RG : 0;
2459*61046927SAndroid Build Coastguard Worker case GL_RG16_SNORM:
2460*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_snorm(ctx) ||
2461*61046927SAndroid Build Coastguard Worker (_mesa_has_EXT_render_snorm(ctx) &&
2462*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_texture_norm16(ctx))
2463*61046927SAndroid Build Coastguard Worker ? GL_RG : 0;
2464*61046927SAndroid Build Coastguard Worker case GL_RGB_SNORM:
2465*61046927SAndroid Build Coastguard Worker case GL_RGB8_SNORM:
2466*61046927SAndroid Build Coastguard Worker case GL_RGB16_SNORM:
2467*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm
2468*61046927SAndroid Build Coastguard Worker ? GL_RGB : 0;
2469*61046927SAndroid Build Coastguard Worker case GL_RGBA8_SNORM:
2470*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_snorm(ctx) || _mesa_has_EXT_render_snorm(ctx)
2471*61046927SAndroid Build Coastguard Worker ? GL_RGBA : 0;
2472*61046927SAndroid Build Coastguard Worker case GL_RGBA_SNORM:
2473*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_snorm(ctx) ? GL_RGBA : 0;
2474*61046927SAndroid Build Coastguard Worker case GL_RGBA16_SNORM:
2475*61046927SAndroid Build Coastguard Worker return _mesa_has_EXT_texture_snorm(ctx) ||
2476*61046927SAndroid Build Coastguard Worker (_mesa_has_EXT_render_snorm(ctx) &&
2477*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_texture_norm16(ctx))
2478*61046927SAndroid Build Coastguard Worker ? GL_RGBA : 0;
2479*61046927SAndroid Build Coastguard Worker case GL_ALPHA_SNORM:
2480*61046927SAndroid Build Coastguard Worker case GL_ALPHA8_SNORM:
2481*61046927SAndroid Build Coastguard Worker case GL_ALPHA16_SNORM:
2482*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
2483*61046927SAndroid Build Coastguard Worker ctx->Extensions.EXT_texture_snorm &&
2484*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0;
2485*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_SNORM:
2486*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE8_SNORM:
2487*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE16_SNORM:
2488*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm
2489*61046927SAndroid Build Coastguard Worker ? GL_LUMINANCE : 0;
2490*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA_SNORM:
2491*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE8_ALPHA8_SNORM:
2492*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE16_ALPHA16_SNORM:
2493*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm
2494*61046927SAndroid Build Coastguard Worker ? GL_LUMINANCE_ALPHA : 0;
2495*61046927SAndroid Build Coastguard Worker case GL_INTENSITY_SNORM:
2496*61046927SAndroid Build Coastguard Worker case GL_INTENSITY8_SNORM:
2497*61046927SAndroid Build Coastguard Worker case GL_INTENSITY16_SNORM:
2498*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm
2499*61046927SAndroid Build Coastguard Worker ? GL_INTENSITY : 0;
2500*61046927SAndroid Build Coastguard Worker
2501*61046927SAndroid Build Coastguard Worker case GL_R16F:
2502*61046927SAndroid Build Coastguard Worker return ((_mesa_is_desktop_gl(ctx) &&
2503*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_rg &&
2504*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_float) ||
2505*61046927SAndroid Build Coastguard Worker _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ ||
2506*61046927SAndroid Build Coastguard Worker (_mesa_has_EXT_color_buffer_half_float(ctx) &&
2507*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_texture_rg(ctx)))
2508*61046927SAndroid Build Coastguard Worker ? GL_RED : 0;
2509*61046927SAndroid Build Coastguard Worker case GL_R32F:
2510*61046927SAndroid Build Coastguard Worker return ((_mesa_is_desktop_gl(ctx) &&
2511*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_rg &&
2512*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_float) ||
2513*61046927SAndroid Build Coastguard Worker _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ )
2514*61046927SAndroid Build Coastguard Worker ? GL_RED : 0;
2515*61046927SAndroid Build Coastguard Worker case GL_RG16F:
2516*61046927SAndroid Build Coastguard Worker return ((_mesa_is_desktop_gl(ctx) &&
2517*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_rg &&
2518*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_float) ||
2519*61046927SAndroid Build Coastguard Worker _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ ||
2520*61046927SAndroid Build Coastguard Worker (_mesa_has_EXT_color_buffer_half_float(ctx) &&
2521*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_texture_rg(ctx)))
2522*61046927SAndroid Build Coastguard Worker ? GL_RG : 0;
2523*61046927SAndroid Build Coastguard Worker case GL_RG32F:
2524*61046927SAndroid Build Coastguard Worker return ((_mesa_is_desktop_gl(ctx) &&
2525*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_rg &&
2526*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_float) ||
2527*61046927SAndroid Build Coastguard Worker _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ )
2528*61046927SAndroid Build Coastguard Worker ? GL_RG : 0;
2529*61046927SAndroid Build Coastguard Worker case GL_RGB16F:
2530*61046927SAndroid Build Coastguard Worker return (_mesa_has_ARB_texture_float(ctx) ||
2531*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_color_buffer_half_float(ctx))
2532*61046927SAndroid Build Coastguard Worker ? GL_RGB : 0;
2533*61046927SAndroid Build Coastguard Worker case GL_RGB32F:
2534*61046927SAndroid Build Coastguard Worker return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_float)
2535*61046927SAndroid Build Coastguard Worker ? GL_RGB : 0;
2536*61046927SAndroid Build Coastguard Worker case GL_RGBA16F:
2537*61046927SAndroid Build Coastguard Worker return (_mesa_has_ARB_texture_float(ctx) ||
2538*61046927SAndroid Build Coastguard Worker _mesa_is_gles3(ctx) ||
2539*61046927SAndroid Build Coastguard Worker _mesa_has_EXT_color_buffer_half_float(ctx))
2540*61046927SAndroid Build Coastguard Worker ? GL_RGBA : 0;
2541*61046927SAndroid Build Coastguard Worker case GL_RGBA32F:
2542*61046927SAndroid Build Coastguard Worker return ((_mesa_is_desktop_gl(ctx) &&
2543*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_float) ||
2544*61046927SAndroid Build Coastguard Worker _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ )
2545*61046927SAndroid Build Coastguard Worker ? GL_RGBA : 0;
2546*61046927SAndroid Build Coastguard Worker case GL_RGB9_E5:
2547*61046927SAndroid Build Coastguard Worker return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_shared_exponent)
2548*61046927SAndroid Build Coastguard Worker ? GL_RGB: 0;
2549*61046927SAndroid Build Coastguard Worker case GL_ALPHA16F_ARB:
2550*61046927SAndroid Build Coastguard Worker case GL_ALPHA32F_ARB:
2551*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
2552*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_float &&
2553*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0;
2554*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE16F_ARB:
2555*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE32F_ARB:
2556*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
2557*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_float &&
2558*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0;
2559*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA16F_ARB:
2560*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA32F_ARB:
2561*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
2562*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_float &&
2563*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0;
2564*61046927SAndroid Build Coastguard Worker case GL_INTENSITY16F_ARB:
2565*61046927SAndroid Build Coastguard Worker case GL_INTENSITY32F_ARB:
2566*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
2567*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_float &&
2568*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
2569*61046927SAndroid Build Coastguard Worker case GL_R11F_G11F_B10F:
2570*61046927SAndroid Build Coastguard Worker return ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_packed_float) ||
2571*61046927SAndroid Build Coastguard Worker _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ )
2572*61046927SAndroid Build Coastguard Worker ? GL_RGB : 0;
2573*61046927SAndroid Build Coastguard Worker
2574*61046927SAndroid Build Coastguard Worker case GL_RGBA8UI_EXT:
2575*61046927SAndroid Build Coastguard Worker case GL_RGBA16UI_EXT:
2576*61046927SAndroid Build Coastguard Worker case GL_RGBA32UI_EXT:
2577*61046927SAndroid Build Coastguard Worker case GL_RGBA8I_EXT:
2578*61046927SAndroid Build Coastguard Worker case GL_RGBA16I_EXT:
2579*61046927SAndroid Build Coastguard Worker case GL_RGBA32I_EXT:
2580*61046927SAndroid Build Coastguard Worker return ctx->Version >= 30
2581*61046927SAndroid Build Coastguard Worker || (_mesa_is_desktop_gl(ctx) &&
2582*61046927SAndroid Build Coastguard Worker ctx->Extensions.EXT_texture_integer) ? GL_RGBA : 0;
2583*61046927SAndroid Build Coastguard Worker
2584*61046927SAndroid Build Coastguard Worker case GL_RGB8UI_EXT:
2585*61046927SAndroid Build Coastguard Worker case GL_RGB16UI_EXT:
2586*61046927SAndroid Build Coastguard Worker case GL_RGB32UI_EXT:
2587*61046927SAndroid Build Coastguard Worker case GL_RGB8I_EXT:
2588*61046927SAndroid Build Coastguard Worker case GL_RGB16I_EXT:
2589*61046927SAndroid Build Coastguard Worker case GL_RGB32I_EXT:
2590*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_integer
2591*61046927SAndroid Build Coastguard Worker ? GL_RGB : 0;
2592*61046927SAndroid Build Coastguard Worker case GL_R8UI:
2593*61046927SAndroid Build Coastguard Worker case GL_R8I:
2594*61046927SAndroid Build Coastguard Worker case GL_R16UI:
2595*61046927SAndroid Build Coastguard Worker case GL_R16I:
2596*61046927SAndroid Build Coastguard Worker case GL_R32UI:
2597*61046927SAndroid Build Coastguard Worker case GL_R32I:
2598*61046927SAndroid Build Coastguard Worker return ctx->Version >= 30
2599*61046927SAndroid Build Coastguard Worker || (_mesa_is_desktop_gl(ctx) &&
2600*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_rg &&
2601*61046927SAndroid Build Coastguard Worker ctx->Extensions.EXT_texture_integer) ? GL_RED : 0;
2602*61046927SAndroid Build Coastguard Worker
2603*61046927SAndroid Build Coastguard Worker case GL_RG8UI:
2604*61046927SAndroid Build Coastguard Worker case GL_RG8I:
2605*61046927SAndroid Build Coastguard Worker case GL_RG16UI:
2606*61046927SAndroid Build Coastguard Worker case GL_RG16I:
2607*61046927SAndroid Build Coastguard Worker case GL_RG32UI:
2608*61046927SAndroid Build Coastguard Worker case GL_RG32I:
2609*61046927SAndroid Build Coastguard Worker return ctx->Version >= 30
2610*61046927SAndroid Build Coastguard Worker || (_mesa_is_desktop_gl(ctx) &&
2611*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_rg &&
2612*61046927SAndroid Build Coastguard Worker ctx->Extensions.EXT_texture_integer) ? GL_RG : 0;
2613*61046927SAndroid Build Coastguard Worker
2614*61046927SAndroid Build Coastguard Worker case GL_INTENSITY8I_EXT:
2615*61046927SAndroid Build Coastguard Worker case GL_INTENSITY8UI_EXT:
2616*61046927SAndroid Build Coastguard Worker case GL_INTENSITY16I_EXT:
2617*61046927SAndroid Build Coastguard Worker case GL_INTENSITY16UI_EXT:
2618*61046927SAndroid Build Coastguard Worker case GL_INTENSITY32I_EXT:
2619*61046927SAndroid Build Coastguard Worker case GL_INTENSITY32UI_EXT:
2620*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
2621*61046927SAndroid Build Coastguard Worker ctx->Extensions.EXT_texture_integer &&
2622*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
2623*61046927SAndroid Build Coastguard Worker
2624*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE8I_EXT:
2625*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE8UI_EXT:
2626*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE16I_EXT:
2627*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE16UI_EXT:
2628*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE32I_EXT:
2629*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE32UI_EXT:
2630*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
2631*61046927SAndroid Build Coastguard Worker ctx->Extensions.EXT_texture_integer &&
2632*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0;
2633*61046927SAndroid Build Coastguard Worker
2634*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA8I_EXT:
2635*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA8UI_EXT:
2636*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA16I_EXT:
2637*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA16UI_EXT:
2638*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA32I_EXT:
2639*61046927SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA32UI_EXT:
2640*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
2641*61046927SAndroid Build Coastguard Worker ctx->Extensions.EXT_texture_integer &&
2642*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0;
2643*61046927SAndroid Build Coastguard Worker
2644*61046927SAndroid Build Coastguard Worker case GL_ALPHA8I_EXT:
2645*61046927SAndroid Build Coastguard Worker case GL_ALPHA8UI_EXT:
2646*61046927SAndroid Build Coastguard Worker case GL_ALPHA16I_EXT:
2647*61046927SAndroid Build Coastguard Worker case GL_ALPHA16UI_EXT:
2648*61046927SAndroid Build Coastguard Worker case GL_ALPHA32I_EXT:
2649*61046927SAndroid Build Coastguard Worker case GL_ALPHA32UI_EXT:
2650*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl_compat(ctx) &&
2651*61046927SAndroid Build Coastguard Worker ctx->Extensions.EXT_texture_integer &&
2652*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0;
2653*61046927SAndroid Build Coastguard Worker
2654*61046927SAndroid Build Coastguard Worker case GL_RGB10_A2UI:
2655*61046927SAndroid Build Coastguard Worker return (_mesa_is_desktop_gl(ctx) &&
2656*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_texture_rgb10_a2ui)
2657*61046927SAndroid Build Coastguard Worker || _mesa_is_gles3(ctx) ? GL_RGBA : 0;
2658*61046927SAndroid Build Coastguard Worker
2659*61046927SAndroid Build Coastguard Worker case GL_RGB565:
2660*61046927SAndroid Build Coastguard Worker return _mesa_is_gles(ctx) || ctx->Extensions.ARB_ES2_compatibility
2661*61046927SAndroid Build Coastguard Worker ? GL_RGB : 0;
2662*61046927SAndroid Build Coastguard Worker
2663*61046927SAndroid Build Coastguard Worker case GL_BGRA:
2664*61046927SAndroid Build Coastguard Worker case GL_BGRA8_EXT:
2665*61046927SAndroid Build Coastguard Worker /* EXT_texture_format_BGRA8888 only adds these as color-renderable for
2666*61046927SAndroid Build Coastguard Worker * GLES 2 and later
2667*61046927SAndroid Build Coastguard Worker */
2668*61046927SAndroid Build Coastguard Worker if (_mesa_has_EXT_texture_format_BGRA8888(ctx) && _mesa_is_gles2(ctx))
2669*61046927SAndroid Build Coastguard Worker return GL_RGBA;
2670*61046927SAndroid Build Coastguard Worker else
2671*61046927SAndroid Build Coastguard Worker return 0;
2672*61046927SAndroid Build Coastguard Worker
2673*61046927SAndroid Build Coastguard Worker default:
2674*61046927SAndroid Build Coastguard Worker return 0;
2675*61046927SAndroid Build Coastguard Worker }
2676*61046927SAndroid Build Coastguard Worker }
2677*61046927SAndroid Build Coastguard Worker
2678*61046927SAndroid Build Coastguard Worker
2679*61046927SAndroid Build Coastguard Worker /**
2680*61046927SAndroid Build Coastguard Worker * Invalidate a renderbuffer attachment. Called from _mesa_HashWalk().
2681*61046927SAndroid Build Coastguard Worker */
2682*61046927SAndroid Build Coastguard Worker static void
invalidate_rb(void * data,void * userData)2683*61046927SAndroid Build Coastguard Worker invalidate_rb(void *data, void *userData)
2684*61046927SAndroid Build Coastguard Worker {
2685*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
2686*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData;
2687*61046927SAndroid Build Coastguard Worker
2688*61046927SAndroid Build Coastguard Worker /* If this is a user-created FBO */
2689*61046927SAndroid Build Coastguard Worker if (_mesa_is_user_fbo(fb)) {
2690*61046927SAndroid Build Coastguard Worker GLuint i;
2691*61046927SAndroid Build Coastguard Worker for (i = 0; i < BUFFER_COUNT; i++) {
2692*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att = fb->Attachment + i;
2693*61046927SAndroid Build Coastguard Worker if (att->Type == GL_RENDERBUFFER &&
2694*61046927SAndroid Build Coastguard Worker att->Renderbuffer == rb) {
2695*61046927SAndroid Build Coastguard Worker /* Mark fb status as indeterminate to force re-validation */
2696*61046927SAndroid Build Coastguard Worker fb->_Status = 0;
2697*61046927SAndroid Build Coastguard Worker return;
2698*61046927SAndroid Build Coastguard Worker }
2699*61046927SAndroid Build Coastguard Worker }
2700*61046927SAndroid Build Coastguard Worker }
2701*61046927SAndroid Build Coastguard Worker }
2702*61046927SAndroid Build Coastguard Worker
2703*61046927SAndroid Build Coastguard Worker
2704*61046927SAndroid Build Coastguard Worker /** sentinal value, see below */
2705*61046927SAndroid Build Coastguard Worker #define NO_SAMPLES 1000
2706*61046927SAndroid Build Coastguard Worker
2707*61046927SAndroid Build Coastguard Worker void
_mesa_renderbuffer_storage(struct gl_context * ctx,struct gl_renderbuffer * rb,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei samples,GLsizei storageSamples)2708*61046927SAndroid Build Coastguard Worker _mesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
2709*61046927SAndroid Build Coastguard Worker GLenum internalFormat, GLsizei width,
2710*61046927SAndroid Build Coastguard Worker GLsizei height, GLsizei samples,
2711*61046927SAndroid Build Coastguard Worker GLsizei storageSamples)
2712*61046927SAndroid Build Coastguard Worker {
2713*61046927SAndroid Build Coastguard Worker const GLenum baseFormat = _mesa_base_fbo_format(ctx, internalFormat);
2714*61046927SAndroid Build Coastguard Worker
2715*61046927SAndroid Build Coastguard Worker assert(baseFormat != 0);
2716*61046927SAndroid Build Coastguard Worker assert(width >= 0 && width <= (GLsizei) ctx->Const.MaxRenderbufferSize);
2717*61046927SAndroid Build Coastguard Worker assert(height >= 0 && height <= (GLsizei) ctx->Const.MaxRenderbufferSize);
2718*61046927SAndroid Build Coastguard Worker assert(samples != NO_SAMPLES);
2719*61046927SAndroid Build Coastguard Worker if (samples != 0) {
2720*61046927SAndroid Build Coastguard Worker assert(samples > 0);
2721*61046927SAndroid Build Coastguard Worker assert(_mesa_check_sample_count(ctx, GL_RENDERBUFFER,
2722*61046927SAndroid Build Coastguard Worker internalFormat, samples,
2723*61046927SAndroid Build Coastguard Worker storageSamples) == GL_NO_ERROR);
2724*61046927SAndroid Build Coastguard Worker }
2725*61046927SAndroid Build Coastguard Worker
2726*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
2727*61046927SAndroid Build Coastguard Worker
2728*61046927SAndroid Build Coastguard Worker if (rb->InternalFormat == internalFormat &&
2729*61046927SAndroid Build Coastguard Worker rb->Width == (GLuint) width &&
2730*61046927SAndroid Build Coastguard Worker rb->Height == (GLuint) height &&
2731*61046927SAndroid Build Coastguard Worker rb->NumSamples == samples &&
2732*61046927SAndroid Build Coastguard Worker rb->NumStorageSamples == storageSamples) {
2733*61046927SAndroid Build Coastguard Worker /* no change in allocation needed */
2734*61046927SAndroid Build Coastguard Worker return;
2735*61046927SAndroid Build Coastguard Worker }
2736*61046927SAndroid Build Coastguard Worker
2737*61046927SAndroid Build Coastguard Worker /* These MUST get set by the AllocStorage func */
2738*61046927SAndroid Build Coastguard Worker rb->Format = MESA_FORMAT_NONE;
2739*61046927SAndroid Build Coastguard Worker rb->NumSamples = samples;
2740*61046927SAndroid Build Coastguard Worker rb->NumStorageSamples = storageSamples;
2741*61046927SAndroid Build Coastguard Worker
2742*61046927SAndroid Build Coastguard Worker /* Now allocate the storage */
2743*61046927SAndroid Build Coastguard Worker assert(rb->AllocStorage);
2744*61046927SAndroid Build Coastguard Worker if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) {
2745*61046927SAndroid Build Coastguard Worker /* No error - check/set fields now */
2746*61046927SAndroid Build Coastguard Worker /* If rb->Format == MESA_FORMAT_NONE, the format is unsupported. */
2747*61046927SAndroid Build Coastguard Worker assert(rb->Width == (GLuint) width);
2748*61046927SAndroid Build Coastguard Worker assert(rb->Height == (GLuint) height);
2749*61046927SAndroid Build Coastguard Worker rb->InternalFormat = internalFormat;
2750*61046927SAndroid Build Coastguard Worker rb->_BaseFormat = baseFormat;
2751*61046927SAndroid Build Coastguard Worker assert(rb->_BaseFormat != 0);
2752*61046927SAndroid Build Coastguard Worker }
2753*61046927SAndroid Build Coastguard Worker else {
2754*61046927SAndroid Build Coastguard Worker /* Probably ran out of memory - clear the fields */
2755*61046927SAndroid Build Coastguard Worker rb->Width = 0;
2756*61046927SAndroid Build Coastguard Worker rb->Height = 0;
2757*61046927SAndroid Build Coastguard Worker rb->Format = MESA_FORMAT_NONE;
2758*61046927SAndroid Build Coastguard Worker rb->InternalFormat = GL_NONE;
2759*61046927SAndroid Build Coastguard Worker rb->_BaseFormat = GL_NONE;
2760*61046927SAndroid Build Coastguard Worker rb->NumSamples = 0;
2761*61046927SAndroid Build Coastguard Worker rb->NumStorageSamples = 0;
2762*61046927SAndroid Build Coastguard Worker }
2763*61046927SAndroid Build Coastguard Worker
2764*61046927SAndroid Build Coastguard Worker /* Invalidate the framebuffers the renderbuffer is attached in. */
2765*61046927SAndroid Build Coastguard Worker if (rb->AttachedAnytime) {
2766*61046927SAndroid Build Coastguard Worker _mesa_HashWalk(&ctx->Shared->FrameBuffers, invalidate_rb, rb);
2767*61046927SAndroid Build Coastguard Worker }
2768*61046927SAndroid Build Coastguard Worker }
2769*61046927SAndroid Build Coastguard Worker
2770*61046927SAndroid Build Coastguard Worker /**
2771*61046927SAndroid Build Coastguard Worker * Helper function used by renderbuffer_storage_direct() and
2772*61046927SAndroid Build Coastguard Worker * renderbuffer_storage_target().
2773*61046927SAndroid Build Coastguard Worker * samples will be NO_SAMPLES if called by a non-multisample function.
2774*61046927SAndroid Build Coastguard Worker */
2775*61046927SAndroid Build Coastguard Worker static void
renderbuffer_storage(struct gl_context * ctx,struct gl_renderbuffer * rb,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei samples,GLsizei storageSamples,const char * func)2776*61046927SAndroid Build Coastguard Worker renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
2777*61046927SAndroid Build Coastguard Worker GLenum internalFormat, GLsizei width,
2778*61046927SAndroid Build Coastguard Worker GLsizei height, GLsizei samples, GLsizei storageSamples,
2779*61046927SAndroid Build Coastguard Worker const char *func)
2780*61046927SAndroid Build Coastguard Worker {
2781*61046927SAndroid Build Coastguard Worker GLenum baseFormat;
2782*61046927SAndroid Build Coastguard Worker GLenum sample_count_error;
2783*61046927SAndroid Build Coastguard Worker
2784*61046927SAndroid Build Coastguard Worker baseFormat = _mesa_base_fbo_format(ctx, internalFormat);
2785*61046927SAndroid Build Coastguard Worker if (baseFormat == 0) {
2786*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat=%s)",
2787*61046927SAndroid Build Coastguard Worker func, _mesa_enum_to_string(internalFormat));
2788*61046927SAndroid Build Coastguard Worker return;
2789*61046927SAndroid Build Coastguard Worker }
2790*61046927SAndroid Build Coastguard Worker
2791*61046927SAndroid Build Coastguard Worker if (width < 0 || width > (GLsizei) ctx->Const.MaxRenderbufferSize) {
2792*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid width %d)", func,
2793*61046927SAndroid Build Coastguard Worker width);
2794*61046927SAndroid Build Coastguard Worker return;
2795*61046927SAndroid Build Coastguard Worker }
2796*61046927SAndroid Build Coastguard Worker
2797*61046927SAndroid Build Coastguard Worker if (height < 0 || height > (GLsizei) ctx->Const.MaxRenderbufferSize) {
2798*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid height %d)", func,
2799*61046927SAndroid Build Coastguard Worker height);
2800*61046927SAndroid Build Coastguard Worker return;
2801*61046927SAndroid Build Coastguard Worker }
2802*61046927SAndroid Build Coastguard Worker
2803*61046927SAndroid Build Coastguard Worker if (samples == NO_SAMPLES) {
2804*61046927SAndroid Build Coastguard Worker /* NumSamples == 0 indicates non-multisampling */
2805*61046927SAndroid Build Coastguard Worker samples = 0;
2806*61046927SAndroid Build Coastguard Worker storageSamples = 0;
2807*61046927SAndroid Build Coastguard Worker }
2808*61046927SAndroid Build Coastguard Worker else {
2809*61046927SAndroid Build Coastguard Worker /* check the sample count;
2810*61046927SAndroid Build Coastguard Worker * note: driver may choose to use more samples than what's requested
2811*61046927SAndroid Build Coastguard Worker */
2812*61046927SAndroid Build Coastguard Worker sample_count_error = _mesa_check_sample_count(ctx, GL_RENDERBUFFER,
2813*61046927SAndroid Build Coastguard Worker internalFormat, samples, storageSamples);
2814*61046927SAndroid Build Coastguard Worker
2815*61046927SAndroid Build Coastguard Worker /* Section 2.5 (GL Errors) of OpenGL 3.0 specification, page 16:
2816*61046927SAndroid Build Coastguard Worker *
2817*61046927SAndroid Build Coastguard Worker * "If a negative number is provided where an argument of type sizei or
2818*61046927SAndroid Build Coastguard Worker * sizeiptr is specified, the error INVALID VALUE is generated."
2819*61046927SAndroid Build Coastguard Worker */
2820*61046927SAndroid Build Coastguard Worker if (samples < 0 || storageSamples < 0) {
2821*61046927SAndroid Build Coastguard Worker sample_count_error = GL_INVALID_VALUE;
2822*61046927SAndroid Build Coastguard Worker }
2823*61046927SAndroid Build Coastguard Worker
2824*61046927SAndroid Build Coastguard Worker if (sample_count_error != GL_NO_ERROR) {
2825*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, sample_count_error,
2826*61046927SAndroid Build Coastguard Worker "%s(samples=%d, storageSamples=%d)", func, samples,
2827*61046927SAndroid Build Coastguard Worker storageSamples);
2828*61046927SAndroid Build Coastguard Worker return;
2829*61046927SAndroid Build Coastguard Worker }
2830*61046927SAndroid Build Coastguard Worker }
2831*61046927SAndroid Build Coastguard Worker
2832*61046927SAndroid Build Coastguard Worker _mesa_renderbuffer_storage(ctx, rb, internalFormat, width, height, samples,
2833*61046927SAndroid Build Coastguard Worker storageSamples);
2834*61046927SAndroid Build Coastguard Worker }
2835*61046927SAndroid Build Coastguard Worker
2836*61046927SAndroid Build Coastguard Worker /**
2837*61046927SAndroid Build Coastguard Worker * Helper function used by _mesa_NamedRenderbufferStorage*().
2838*61046927SAndroid Build Coastguard Worker * samples will be NO_SAMPLES if called by a non-multisample function.
2839*61046927SAndroid Build Coastguard Worker */
2840*61046927SAndroid Build Coastguard Worker static void
renderbuffer_storage_named(GLuint renderbuffer,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei samples,GLsizei storageSamples,const char * func)2841*61046927SAndroid Build Coastguard Worker renderbuffer_storage_named(GLuint renderbuffer, GLenum internalFormat,
2842*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height, GLsizei samples,
2843*61046927SAndroid Build Coastguard Worker GLsizei storageSamples, const char *func)
2844*61046927SAndroid Build Coastguard Worker {
2845*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2846*61046927SAndroid Build Coastguard Worker
2847*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API) {
2848*61046927SAndroid Build Coastguard Worker if (samples == NO_SAMPLES)
2849*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "%s(%u, %s, %d, %d)\n",
2850*61046927SAndroid Build Coastguard Worker func, renderbuffer,
2851*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(internalFormat),
2852*61046927SAndroid Build Coastguard Worker width, height);
2853*61046927SAndroid Build Coastguard Worker else
2854*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "%s(%u, %s, %d, %d, %d)\n",
2855*61046927SAndroid Build Coastguard Worker func, renderbuffer,
2856*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(internalFormat),
2857*61046927SAndroid Build Coastguard Worker width, height, samples);
2858*61046927SAndroid Build Coastguard Worker }
2859*61046927SAndroid Build Coastguard Worker
2860*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
2861*61046927SAndroid Build Coastguard Worker if (!rb || rb == &DummyRenderbuffer) {
2862*61046927SAndroid Build Coastguard Worker /* ID was reserved, but no real renderbuffer object made yet */
2863*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid renderbuffer %u)",
2864*61046927SAndroid Build Coastguard Worker func, renderbuffer);
2865*61046927SAndroid Build Coastguard Worker return;
2866*61046927SAndroid Build Coastguard Worker }
2867*61046927SAndroid Build Coastguard Worker
2868*61046927SAndroid Build Coastguard Worker renderbuffer_storage(ctx, rb, internalFormat, width, height, samples,
2869*61046927SAndroid Build Coastguard Worker storageSamples, func);
2870*61046927SAndroid Build Coastguard Worker }
2871*61046927SAndroid Build Coastguard Worker
2872*61046927SAndroid Build Coastguard Worker /**
2873*61046927SAndroid Build Coastguard Worker * Helper function used by _mesa_RenderbufferStorage() and
2874*61046927SAndroid Build Coastguard Worker * _mesa_RenderbufferStorageMultisample().
2875*61046927SAndroid Build Coastguard Worker * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorage().
2876*61046927SAndroid Build Coastguard Worker */
2877*61046927SAndroid Build Coastguard Worker static void
renderbuffer_storage_target(GLenum target,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei samples,GLsizei storageSamples,const char * func)2878*61046927SAndroid Build Coastguard Worker renderbuffer_storage_target(GLenum target, GLenum internalFormat,
2879*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height, GLsizei samples,
2880*61046927SAndroid Build Coastguard Worker GLsizei storageSamples, const char *func)
2881*61046927SAndroid Build Coastguard Worker {
2882*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2883*61046927SAndroid Build Coastguard Worker
2884*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API) {
2885*61046927SAndroid Build Coastguard Worker if (samples == NO_SAMPLES)
2886*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "%s(%s, %s, %d, %d)\n",
2887*61046927SAndroid Build Coastguard Worker func,
2888*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target),
2889*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(internalFormat),
2890*61046927SAndroid Build Coastguard Worker width, height);
2891*61046927SAndroid Build Coastguard Worker else
2892*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "%s(%s, %s, %d, %d, %d)\n",
2893*61046927SAndroid Build Coastguard Worker func,
2894*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target),
2895*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(internalFormat),
2896*61046927SAndroid Build Coastguard Worker width, height, samples);
2897*61046927SAndroid Build Coastguard Worker }
2898*61046927SAndroid Build Coastguard Worker
2899*61046927SAndroid Build Coastguard Worker if (target != GL_RENDERBUFFER_EXT) {
2900*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
2901*61046927SAndroid Build Coastguard Worker return;
2902*61046927SAndroid Build Coastguard Worker }
2903*61046927SAndroid Build Coastguard Worker
2904*61046927SAndroid Build Coastguard Worker if (!ctx->CurrentRenderbuffer) {
2905*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no renderbuffer bound)",
2906*61046927SAndroid Build Coastguard Worker func);
2907*61046927SAndroid Build Coastguard Worker return;
2908*61046927SAndroid Build Coastguard Worker }
2909*61046927SAndroid Build Coastguard Worker
2910*61046927SAndroid Build Coastguard Worker renderbuffer_storage(ctx, ctx->CurrentRenderbuffer, internalFormat, width,
2911*61046927SAndroid Build Coastguard Worker height, samples, storageSamples, func);
2912*61046927SAndroid Build Coastguard Worker }
2913*61046927SAndroid Build Coastguard Worker
2914*61046927SAndroid Build Coastguard Worker
2915*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target,GLeglImageOES image)2916*61046927SAndroid Build Coastguard Worker _mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
2917*61046927SAndroid Build Coastguard Worker {
2918*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb;
2919*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2920*61046927SAndroid Build Coastguard Worker
2921*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.OES_EGL_image) {
2922*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
2923*61046927SAndroid Build Coastguard Worker "glEGLImageTargetRenderbufferStorageOES(unsupported)");
2924*61046927SAndroid Build Coastguard Worker return;
2925*61046927SAndroid Build Coastguard Worker }
2926*61046927SAndroid Build Coastguard Worker
2927*61046927SAndroid Build Coastguard Worker if (target != GL_RENDERBUFFER) {
2928*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
2929*61046927SAndroid Build Coastguard Worker "EGLImageTargetRenderbufferStorageOES");
2930*61046927SAndroid Build Coastguard Worker return;
2931*61046927SAndroid Build Coastguard Worker }
2932*61046927SAndroid Build Coastguard Worker
2933*61046927SAndroid Build Coastguard Worker rb = ctx->CurrentRenderbuffer;
2934*61046927SAndroid Build Coastguard Worker if (!rb) {
2935*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
2936*61046927SAndroid Build Coastguard Worker "EGLImageTargetRenderbufferStorageOES");
2937*61046927SAndroid Build Coastguard Worker return;
2938*61046927SAndroid Build Coastguard Worker }
2939*61046927SAndroid Build Coastguard Worker
2940*61046927SAndroid Build Coastguard Worker if (!image || !st_validate_egl_image(ctx, image)) {
2941*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
2942*61046927SAndroid Build Coastguard Worker "EGLImageTargetRenderbufferStorageOES");
2943*61046927SAndroid Build Coastguard Worker return;
2944*61046927SAndroid Build Coastguard Worker }
2945*61046927SAndroid Build Coastguard Worker
2946*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
2947*61046927SAndroid Build Coastguard Worker
2948*61046927SAndroid Build Coastguard Worker st_egl_image_target_renderbuffer_storage(ctx, rb, image);
2949*61046927SAndroid Build Coastguard Worker }
2950*61046927SAndroid Build Coastguard Worker
2951*61046927SAndroid Build Coastguard Worker
2952*61046927SAndroid Build Coastguard Worker /**
2953*61046927SAndroid Build Coastguard Worker * Helper function for _mesa_GetRenderbufferParameteriv() and
2954*61046927SAndroid Build Coastguard Worker * _mesa_GetFramebufferAttachmentParameteriv()
2955*61046927SAndroid Build Coastguard Worker * We have to be careful to respect the base format. For example, if a
2956*61046927SAndroid Build Coastguard Worker * renderbuffer/texture was created with internalFormat=GL_RGB but the
2957*61046927SAndroid Build Coastguard Worker * driver actually chose a GL_RGBA format, when the user queries ALPHA_SIZE
2958*61046927SAndroid Build Coastguard Worker * we need to return zero.
2959*61046927SAndroid Build Coastguard Worker */
2960*61046927SAndroid Build Coastguard Worker static GLint
get_component_bits(GLenum pname,GLenum baseFormat,mesa_format format)2961*61046927SAndroid Build Coastguard Worker get_component_bits(GLenum pname, GLenum baseFormat, mesa_format format)
2962*61046927SAndroid Build Coastguard Worker {
2963*61046927SAndroid Build Coastguard Worker if (_mesa_base_format_has_channel(baseFormat, pname))
2964*61046927SAndroid Build Coastguard Worker return _mesa_get_format_bits(format, pname);
2965*61046927SAndroid Build Coastguard Worker else
2966*61046927SAndroid Build Coastguard Worker return 0;
2967*61046927SAndroid Build Coastguard Worker }
2968*61046927SAndroid Build Coastguard Worker
2969*61046927SAndroid Build Coastguard Worker
2970*61046927SAndroid Build Coastguard Worker
2971*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_RenderbufferStorage(GLenum target,GLenum internalFormat,GLsizei width,GLsizei height)2972*61046927SAndroid Build Coastguard Worker _mesa_RenderbufferStorage(GLenum target, GLenum internalFormat,
2973*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height)
2974*61046927SAndroid Build Coastguard Worker {
2975*61046927SAndroid Build Coastguard Worker /* GL_ARB_fbo says calling this function is equivalent to calling
2976*61046927SAndroid Build Coastguard Worker * glRenderbufferStorageMultisample() with samples=0. We pass in
2977*61046927SAndroid Build Coastguard Worker * a token value here just for error reporting purposes.
2978*61046927SAndroid Build Coastguard Worker */
2979*61046927SAndroid Build Coastguard Worker renderbuffer_storage_target(target, internalFormat, width, height,
2980*61046927SAndroid Build Coastguard Worker NO_SAMPLES, 0, "glRenderbufferStorage");
2981*61046927SAndroid Build Coastguard Worker }
2982*61046927SAndroid Build Coastguard Worker
2983*61046927SAndroid Build Coastguard Worker
2984*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_RenderbufferStorageMultisample(GLenum target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height)2985*61046927SAndroid Build Coastguard Worker _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
2986*61046927SAndroid Build Coastguard Worker GLenum internalFormat,
2987*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height)
2988*61046927SAndroid Build Coastguard Worker {
2989*61046927SAndroid Build Coastguard Worker renderbuffer_storage_target(target, internalFormat, width, height,
2990*61046927SAndroid Build Coastguard Worker samples, samples,
2991*61046927SAndroid Build Coastguard Worker "glRenderbufferStorageMultisample");
2992*61046927SAndroid Build Coastguard Worker }
2993*61046927SAndroid Build Coastguard Worker
2994*61046927SAndroid Build Coastguard Worker
2995*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_RenderbufferStorageMultisampleAdvancedAMD(GLenum target,GLsizei samples,GLsizei storageSamples,GLenum internalFormat,GLsizei width,GLsizei height)2996*61046927SAndroid Build Coastguard Worker _mesa_RenderbufferStorageMultisampleAdvancedAMD(
2997*61046927SAndroid Build Coastguard Worker GLenum target, GLsizei samples, GLsizei storageSamples,
2998*61046927SAndroid Build Coastguard Worker GLenum internalFormat, GLsizei width, GLsizei height)
2999*61046927SAndroid Build Coastguard Worker {
3000*61046927SAndroid Build Coastguard Worker renderbuffer_storage_target(target, internalFormat, width, height,
3001*61046927SAndroid Build Coastguard Worker samples, storageSamples,
3002*61046927SAndroid Build Coastguard Worker "glRenderbufferStorageMultisampleAdvancedAMD");
3003*61046927SAndroid Build Coastguard Worker }
3004*61046927SAndroid Build Coastguard Worker
3005*61046927SAndroid Build Coastguard Worker
3006*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedRenderbufferStorage(GLuint renderbuffer,GLenum internalformat,GLsizei width,GLsizei height)3007*61046927SAndroid Build Coastguard Worker _mesa_NamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat,
3008*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height)
3009*61046927SAndroid Build Coastguard Worker {
3010*61046927SAndroid Build Coastguard Worker /* GL_ARB_fbo says calling this function is equivalent to calling
3011*61046927SAndroid Build Coastguard Worker * glRenderbufferStorageMultisample() with samples=0. We pass in
3012*61046927SAndroid Build Coastguard Worker * a token value here just for error reporting purposes.
3013*61046927SAndroid Build Coastguard Worker */
3014*61046927SAndroid Build Coastguard Worker renderbuffer_storage_named(renderbuffer, internalformat, width, height,
3015*61046927SAndroid Build Coastguard Worker NO_SAMPLES, 0, "glNamedRenderbufferStorage");
3016*61046927SAndroid Build Coastguard Worker }
3017*61046927SAndroid Build Coastguard Worker
3018*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedRenderbufferStorageEXT(GLuint renderbuffer,GLenum internalformat,GLsizei width,GLsizei height)3019*61046927SAndroid Build Coastguard Worker _mesa_NamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat,
3020*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height)
3021*61046927SAndroid Build Coastguard Worker {
3022*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3023*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
3024*61046927SAndroid Build Coastguard Worker if (!rb || rb == &DummyRenderbuffer) {
3025*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(&ctx->Shared->RenderBuffers);
3026*61046927SAndroid Build Coastguard Worker rb = allocate_renderbuffer_locked(ctx, renderbuffer,
3027*61046927SAndroid Build Coastguard Worker "glNamedRenderbufferStorageEXT");
3028*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers);
3029*61046927SAndroid Build Coastguard Worker }
3030*61046927SAndroid Build Coastguard Worker renderbuffer_storage(ctx, rb, internalformat, width, height, NO_SAMPLES,
3031*61046927SAndroid Build Coastguard Worker 0, "glNamedRenderbufferStorageEXT");
3032*61046927SAndroid Build Coastguard Worker }
3033*61046927SAndroid Build Coastguard Worker
3034*61046927SAndroid Build Coastguard Worker
3035*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedRenderbufferStorageMultisample(GLuint renderbuffer,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)3036*61046927SAndroid Build Coastguard Worker _mesa_NamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples,
3037*61046927SAndroid Build Coastguard Worker GLenum internalformat,
3038*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height)
3039*61046927SAndroid Build Coastguard Worker {
3040*61046927SAndroid Build Coastguard Worker renderbuffer_storage_named(renderbuffer, internalformat, width, height,
3041*61046927SAndroid Build Coastguard Worker samples, samples,
3042*61046927SAndroid Build Coastguard Worker "glNamedRenderbufferStorageMultisample");
3043*61046927SAndroid Build Coastguard Worker }
3044*61046927SAndroid Build Coastguard Worker
3045*61046927SAndroid Build Coastguard Worker
3046*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)3047*61046927SAndroid Build Coastguard Worker _mesa_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei samples,
3048*61046927SAndroid Build Coastguard Worker GLenum internalformat,
3049*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height)
3050*61046927SAndroid Build Coastguard Worker {
3051*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3052*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
3053*61046927SAndroid Build Coastguard Worker if (!rb || rb == &DummyRenderbuffer) {
3054*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(&ctx->Shared->RenderBuffers);
3055*61046927SAndroid Build Coastguard Worker rb = allocate_renderbuffer_locked(ctx, renderbuffer,
3056*61046927SAndroid Build Coastguard Worker "glNamedRenderbufferStorageMultisampleEXT");
3057*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers);
3058*61046927SAndroid Build Coastguard Worker }
3059*61046927SAndroid Build Coastguard Worker renderbuffer_storage(ctx, rb, internalformat, width, height,
3060*61046927SAndroid Build Coastguard Worker samples, samples,
3061*61046927SAndroid Build Coastguard Worker "glNamedRenderbufferStorageMultisample");
3062*61046927SAndroid Build Coastguard Worker }
3063*61046927SAndroid Build Coastguard Worker
3064*61046927SAndroid Build Coastguard Worker
3065*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedRenderbufferStorageMultisampleAdvancedAMD(GLuint renderbuffer,GLsizei samples,GLsizei storageSamples,GLenum internalformat,GLsizei width,GLsizei height)3066*61046927SAndroid Build Coastguard Worker _mesa_NamedRenderbufferStorageMultisampleAdvancedAMD(
3067*61046927SAndroid Build Coastguard Worker GLuint renderbuffer, GLsizei samples, GLsizei storageSamples,
3068*61046927SAndroid Build Coastguard Worker GLenum internalformat, GLsizei width, GLsizei height)
3069*61046927SAndroid Build Coastguard Worker {
3070*61046927SAndroid Build Coastguard Worker renderbuffer_storage_named(renderbuffer, internalformat, width, height,
3071*61046927SAndroid Build Coastguard Worker samples, storageSamples,
3072*61046927SAndroid Build Coastguard Worker "glNamedRenderbufferStorageMultisampleAdvancedAMD");
3073*61046927SAndroid Build Coastguard Worker }
3074*61046927SAndroid Build Coastguard Worker
3075*61046927SAndroid Build Coastguard Worker
3076*61046927SAndroid Build Coastguard Worker static void
get_render_buffer_parameteriv(struct gl_context * ctx,struct gl_renderbuffer * rb,GLenum pname,GLint * params,const char * func)3077*61046927SAndroid Build Coastguard Worker get_render_buffer_parameteriv(struct gl_context *ctx,
3078*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb, GLenum pname,
3079*61046927SAndroid Build Coastguard Worker GLint *params, const char *func)
3080*61046927SAndroid Build Coastguard Worker {
3081*61046927SAndroid Build Coastguard Worker /* No need to flush here since we're just quering state which is
3082*61046927SAndroid Build Coastguard Worker * not effected by rendering.
3083*61046927SAndroid Build Coastguard Worker */
3084*61046927SAndroid Build Coastguard Worker
3085*61046927SAndroid Build Coastguard Worker switch (pname) {
3086*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_WIDTH_EXT:
3087*61046927SAndroid Build Coastguard Worker *params = rb->Width;
3088*61046927SAndroid Build Coastguard Worker return;
3089*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_HEIGHT_EXT:
3090*61046927SAndroid Build Coastguard Worker *params = rb->Height;
3091*61046927SAndroid Build Coastguard Worker return;
3092*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
3093*61046927SAndroid Build Coastguard Worker *params = rb->InternalFormat;
3094*61046927SAndroid Build Coastguard Worker return;
3095*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_RED_SIZE_EXT:
3096*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_GREEN_SIZE_EXT:
3097*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_BLUE_SIZE_EXT:
3098*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
3099*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
3100*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
3101*61046927SAndroid Build Coastguard Worker *params = get_component_bits(pname, rb->_BaseFormat, rb->Format);
3102*61046927SAndroid Build Coastguard Worker return;
3103*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_SAMPLES:
3104*61046927SAndroid Build Coastguard Worker if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_framebuffer_object)
3105*61046927SAndroid Build Coastguard Worker || _mesa_is_gles3(ctx)) {
3106*61046927SAndroid Build Coastguard Worker *params = rb->NumSamples;
3107*61046927SAndroid Build Coastguard Worker return;
3108*61046927SAndroid Build Coastguard Worker }
3109*61046927SAndroid Build Coastguard Worker break;
3110*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER_STORAGE_SAMPLES_AMD:
3111*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.AMD_framebuffer_multisample_advanced) {
3112*61046927SAndroid Build Coastguard Worker *params = rb->NumStorageSamples;
3113*61046927SAndroid Build Coastguard Worker return;
3114*61046927SAndroid Build Coastguard Worker }
3115*61046927SAndroid Build Coastguard Worker break;
3116*61046927SAndroid Build Coastguard Worker }
3117*61046927SAndroid Build Coastguard Worker
3118*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname=%s)", func,
3119*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
3120*61046927SAndroid Build Coastguard Worker }
3121*61046927SAndroid Build Coastguard Worker
3122*61046927SAndroid Build Coastguard Worker
3123*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)3124*61046927SAndroid Build Coastguard Worker _mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
3125*61046927SAndroid Build Coastguard Worker {
3126*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3127*61046927SAndroid Build Coastguard Worker
3128*61046927SAndroid Build Coastguard Worker if (target != GL_RENDERBUFFER_EXT) {
3129*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
3130*61046927SAndroid Build Coastguard Worker "glGetRenderbufferParameterivEXT(target)");
3131*61046927SAndroid Build Coastguard Worker return;
3132*61046927SAndroid Build Coastguard Worker }
3133*61046927SAndroid Build Coastguard Worker
3134*61046927SAndroid Build Coastguard Worker if (!ctx->CurrentRenderbuffer) {
3135*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glGetRenderbufferParameterivEXT"
3136*61046927SAndroid Build Coastguard Worker "(no renderbuffer bound)");
3137*61046927SAndroid Build Coastguard Worker return;
3138*61046927SAndroid Build Coastguard Worker }
3139*61046927SAndroid Build Coastguard Worker
3140*61046927SAndroid Build Coastguard Worker get_render_buffer_parameteriv(ctx, ctx->CurrentRenderbuffer, pname,
3141*61046927SAndroid Build Coastguard Worker params, "glGetRenderbufferParameteriv");
3142*61046927SAndroid Build Coastguard Worker }
3143*61046927SAndroid Build Coastguard Worker
3144*61046927SAndroid Build Coastguard Worker
3145*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer,GLenum pname,GLint * params)3146*61046927SAndroid Build Coastguard Worker _mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname,
3147*61046927SAndroid Build Coastguard Worker GLint *params)
3148*61046927SAndroid Build Coastguard Worker {
3149*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3150*61046927SAndroid Build Coastguard Worker
3151*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
3152*61046927SAndroid Build Coastguard Worker if (!rb || rb == &DummyRenderbuffer) {
3153*61046927SAndroid Build Coastguard Worker /* ID was reserved, but no real renderbuffer object made yet */
3154*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glGetNamedRenderbufferParameteriv"
3155*61046927SAndroid Build Coastguard Worker "(invalid renderbuffer %i)", renderbuffer);
3156*61046927SAndroid Build Coastguard Worker return;
3157*61046927SAndroid Build Coastguard Worker }
3158*61046927SAndroid Build Coastguard Worker
3159*61046927SAndroid Build Coastguard Worker get_render_buffer_parameteriv(ctx, rb, pname, params,
3160*61046927SAndroid Build Coastguard Worker "glGetNamedRenderbufferParameteriv");
3161*61046927SAndroid Build Coastguard Worker }
3162*61046927SAndroid Build Coastguard Worker
3163*61046927SAndroid Build Coastguard Worker
3164*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedRenderbufferParameterivEXT(GLuint renderbuffer,GLenum pname,GLint * params)3165*61046927SAndroid Build Coastguard Worker _mesa_GetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname,
3166*61046927SAndroid Build Coastguard Worker GLint *params)
3167*61046927SAndroid Build Coastguard Worker {
3168*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3169*61046927SAndroid Build Coastguard Worker
3170*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
3171*61046927SAndroid Build Coastguard Worker if (!rb || rb == &DummyRenderbuffer) {
3172*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(&ctx->Shared->RenderBuffers);
3173*61046927SAndroid Build Coastguard Worker rb = allocate_renderbuffer_locked(ctx, renderbuffer,
3174*61046927SAndroid Build Coastguard Worker "glGetNamedRenderbufferParameterivEXT");
3175*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers);
3176*61046927SAndroid Build Coastguard Worker }
3177*61046927SAndroid Build Coastguard Worker
3178*61046927SAndroid Build Coastguard Worker get_render_buffer_parameteriv(ctx, rb, pname, params,
3179*61046927SAndroid Build Coastguard Worker "glGetNamedRenderbufferParameterivEXT");
3180*61046927SAndroid Build Coastguard Worker }
3181*61046927SAndroid Build Coastguard Worker
3182*61046927SAndroid Build Coastguard Worker
3183*61046927SAndroid Build Coastguard Worker GLboolean GLAPIENTRY
_mesa_IsFramebuffer(GLuint framebuffer)3184*61046927SAndroid Build Coastguard Worker _mesa_IsFramebuffer(GLuint framebuffer)
3185*61046927SAndroid Build Coastguard Worker {
3186*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3187*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
3188*61046927SAndroid Build Coastguard Worker if (framebuffer) {
3189*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer);
3190*61046927SAndroid Build Coastguard Worker if (rb != NULL && rb != &DummyFramebuffer)
3191*61046927SAndroid Build Coastguard Worker return GL_TRUE;
3192*61046927SAndroid Build Coastguard Worker }
3193*61046927SAndroid Build Coastguard Worker return GL_FALSE;
3194*61046927SAndroid Build Coastguard Worker }
3195*61046927SAndroid Build Coastguard Worker
3196*61046927SAndroid Build Coastguard Worker
3197*61046927SAndroid Build Coastguard Worker /**
3198*61046927SAndroid Build Coastguard Worker * Check if any of the attachments of the given framebuffer are textures
3199*61046927SAndroid Build Coastguard Worker * (render to texture). Call ctx->Driver.RenderTexture() for such
3200*61046927SAndroid Build Coastguard Worker * attachments.
3201*61046927SAndroid Build Coastguard Worker */
3202*61046927SAndroid Build Coastguard Worker static void
check_begin_texture_render(struct gl_context * ctx,struct gl_framebuffer * fb)3203*61046927SAndroid Build Coastguard Worker check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
3204*61046927SAndroid Build Coastguard Worker {
3205*61046927SAndroid Build Coastguard Worker GLuint i;
3206*61046927SAndroid Build Coastguard Worker
3207*61046927SAndroid Build Coastguard Worker if (_mesa_is_winsys_fbo(fb))
3208*61046927SAndroid Build Coastguard Worker return; /* can't render to texture with winsys framebuffers */
3209*61046927SAndroid Build Coastguard Worker
3210*61046927SAndroid Build Coastguard Worker for (i = 0; i < BUFFER_COUNT; i++) {
3211*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att = fb->Attachment + i;
3212*61046927SAndroid Build Coastguard Worker if (att->Texture && att->Renderbuffer->TexImage
3213*61046927SAndroid Build Coastguard Worker && driver_RenderTexture_is_safe(att)) {
3214*61046927SAndroid Build Coastguard Worker render_texture(ctx, fb, att);
3215*61046927SAndroid Build Coastguard Worker }
3216*61046927SAndroid Build Coastguard Worker }
3217*61046927SAndroid Build Coastguard Worker }
3218*61046927SAndroid Build Coastguard Worker
3219*61046927SAndroid Build Coastguard Worker
3220*61046927SAndroid Build Coastguard Worker /**
3221*61046927SAndroid Build Coastguard Worker * Examine all the framebuffer's attachments to see if any are textures.
3222*61046927SAndroid Build Coastguard Worker * If so, call ctx->Driver.FinishRenderTexture() for each texture to
3223*61046927SAndroid Build Coastguard Worker * notify the device driver that the texture image may have changed.
3224*61046927SAndroid Build Coastguard Worker */
3225*61046927SAndroid Build Coastguard Worker static void
check_end_texture_render(struct gl_context * ctx,struct gl_framebuffer * fb)3226*61046927SAndroid Build Coastguard Worker check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
3227*61046927SAndroid Build Coastguard Worker {
3228*61046927SAndroid Build Coastguard Worker if (_mesa_is_winsys_fbo(fb))
3229*61046927SAndroid Build Coastguard Worker return;
3230*61046927SAndroid Build Coastguard Worker
3231*61046927SAndroid Build Coastguard Worker GLuint i;
3232*61046927SAndroid Build Coastguard Worker for (i = 0; i < BUFFER_COUNT; i++) {
3233*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att = fb->Attachment + i;
3234*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = att->Renderbuffer;
3235*61046927SAndroid Build Coastguard Worker if (rb) {
3236*61046927SAndroid Build Coastguard Worker finish_render_texture(ctx, rb);
3237*61046927SAndroid Build Coastguard Worker }
3238*61046927SAndroid Build Coastguard Worker }
3239*61046927SAndroid Build Coastguard Worker }
3240*61046927SAndroid Build Coastguard Worker
3241*61046927SAndroid Build Coastguard Worker
3242*61046927SAndroid Build Coastguard Worker static void
bind_framebuffer(GLenum target,GLuint framebuffer)3243*61046927SAndroid Build Coastguard Worker bind_framebuffer(GLenum target, GLuint framebuffer)
3244*61046927SAndroid Build Coastguard Worker {
3245*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *newDrawFb, *newReadFb;
3246*61046927SAndroid Build Coastguard Worker GLboolean bindReadBuf, bindDrawBuf;
3247*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3248*61046927SAndroid Build Coastguard Worker
3249*61046927SAndroid Build Coastguard Worker switch (target) {
3250*61046927SAndroid Build Coastguard Worker case GL_DRAW_FRAMEBUFFER_EXT:
3251*61046927SAndroid Build Coastguard Worker bindDrawBuf = GL_TRUE;
3252*61046927SAndroid Build Coastguard Worker bindReadBuf = GL_FALSE;
3253*61046927SAndroid Build Coastguard Worker break;
3254*61046927SAndroid Build Coastguard Worker case GL_READ_FRAMEBUFFER_EXT:
3255*61046927SAndroid Build Coastguard Worker bindDrawBuf = GL_FALSE;
3256*61046927SAndroid Build Coastguard Worker bindReadBuf = GL_TRUE;
3257*61046927SAndroid Build Coastguard Worker break;
3258*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_EXT:
3259*61046927SAndroid Build Coastguard Worker bindDrawBuf = GL_TRUE;
3260*61046927SAndroid Build Coastguard Worker bindReadBuf = GL_TRUE;
3261*61046927SAndroid Build Coastguard Worker break;
3262*61046927SAndroid Build Coastguard Worker default:
3263*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
3264*61046927SAndroid Build Coastguard Worker return;
3265*61046927SAndroid Build Coastguard Worker }
3266*61046927SAndroid Build Coastguard Worker
3267*61046927SAndroid Build Coastguard Worker if (framebuffer) {
3268*61046927SAndroid Build Coastguard Worker /* Binding a user-created framebuffer object */
3269*61046927SAndroid Build Coastguard Worker newDrawFb = _mesa_lookup_framebuffer(ctx, framebuffer);
3270*61046927SAndroid Build Coastguard Worker if (newDrawFb == &DummyFramebuffer) {
3271*61046927SAndroid Build Coastguard Worker /* ID was reserved, but no real framebuffer object made yet */
3272*61046927SAndroid Build Coastguard Worker newDrawFb = NULL;
3273*61046927SAndroid Build Coastguard Worker }
3274*61046927SAndroid Build Coastguard Worker else if (!newDrawFb && _mesa_is_desktop_gl_core(ctx)) {
3275*61046927SAndroid Build Coastguard Worker /* All FBO IDs must be Gen'd */
3276*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3277*61046927SAndroid Build Coastguard Worker "glBindFramebuffer(non-gen name)");
3278*61046927SAndroid Build Coastguard Worker return;
3279*61046927SAndroid Build Coastguard Worker }
3280*61046927SAndroid Build Coastguard Worker
3281*61046927SAndroid Build Coastguard Worker if (!newDrawFb) {
3282*61046927SAndroid Build Coastguard Worker /* create new framebuffer object */
3283*61046927SAndroid Build Coastguard Worker newDrawFb = _mesa_new_framebuffer(ctx, framebuffer);
3284*61046927SAndroid Build Coastguard Worker if (!newDrawFb) {
3285*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
3286*61046927SAndroid Build Coastguard Worker return;
3287*61046927SAndroid Build Coastguard Worker }
3288*61046927SAndroid Build Coastguard Worker _mesa_HashInsert(&ctx->Shared->FrameBuffers, framebuffer, newDrawFb);
3289*61046927SAndroid Build Coastguard Worker }
3290*61046927SAndroid Build Coastguard Worker newReadFb = newDrawFb;
3291*61046927SAndroid Build Coastguard Worker }
3292*61046927SAndroid Build Coastguard Worker else {
3293*61046927SAndroid Build Coastguard Worker /* Binding the window system framebuffer (which was originally set
3294*61046927SAndroid Build Coastguard Worker * with MakeCurrent).
3295*61046927SAndroid Build Coastguard Worker */
3296*61046927SAndroid Build Coastguard Worker if (bindDrawBuf)
3297*61046927SAndroid Build Coastguard Worker newDrawFb = ctx->WinSysDrawBuffer;
3298*61046927SAndroid Build Coastguard Worker if (bindReadBuf)
3299*61046927SAndroid Build Coastguard Worker newReadFb = ctx->WinSysReadBuffer;
3300*61046927SAndroid Build Coastguard Worker }
3301*61046927SAndroid Build Coastguard Worker
3302*61046927SAndroid Build Coastguard Worker _mesa_bind_framebuffers(ctx,
3303*61046927SAndroid Build Coastguard Worker bindDrawBuf ? newDrawFb : ctx->DrawBuffer,
3304*61046927SAndroid Build Coastguard Worker bindReadBuf ? newReadFb : ctx->ReadBuffer);
3305*61046927SAndroid Build Coastguard Worker }
3306*61046927SAndroid Build Coastguard Worker
3307*61046927SAndroid Build Coastguard Worker void
_mesa_bind_framebuffers(struct gl_context * ctx,struct gl_framebuffer * newDrawFb,struct gl_framebuffer * newReadFb)3308*61046927SAndroid Build Coastguard Worker _mesa_bind_framebuffers(struct gl_context *ctx,
3309*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *newDrawFb,
3310*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *newReadFb)
3311*61046927SAndroid Build Coastguard Worker {
3312*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *const oldDrawFb = ctx->DrawBuffer;
3313*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *const oldReadFb = ctx->ReadBuffer;
3314*61046927SAndroid Build Coastguard Worker const bool bindDrawBuf = oldDrawFb != newDrawFb;
3315*61046927SAndroid Build Coastguard Worker const bool bindReadBuf = oldReadFb != newReadFb;
3316*61046927SAndroid Build Coastguard Worker
3317*61046927SAndroid Build Coastguard Worker assert(newDrawFb);
3318*61046927SAndroid Build Coastguard Worker assert(newDrawFb != &DummyFramebuffer);
3319*61046927SAndroid Build Coastguard Worker
3320*61046927SAndroid Build Coastguard Worker /*
3321*61046927SAndroid Build Coastguard Worker * OK, now bind the new Draw/Read framebuffers, if they're changing.
3322*61046927SAndroid Build Coastguard Worker *
3323*61046927SAndroid Build Coastguard Worker * We also check if we're beginning and/or ending render-to-texture.
3324*61046927SAndroid Build Coastguard Worker * When a framebuffer with texture attachments is unbound, call
3325*61046927SAndroid Build Coastguard Worker * ctx->Driver.FinishRenderTexture().
3326*61046927SAndroid Build Coastguard Worker * When a framebuffer with texture attachments is bound, call
3327*61046927SAndroid Build Coastguard Worker * ctx->Driver.RenderTexture().
3328*61046927SAndroid Build Coastguard Worker *
3329*61046927SAndroid Build Coastguard Worker * Note that if the ReadBuffer has texture attachments we don't consider
3330*61046927SAndroid Build Coastguard Worker * that a render-to-texture case.
3331*61046927SAndroid Build Coastguard Worker */
3332*61046927SAndroid Build Coastguard Worker if (bindReadBuf) {
3333*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
3334*61046927SAndroid Build Coastguard Worker
3335*61046927SAndroid Build Coastguard Worker _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb);
3336*61046927SAndroid Build Coastguard Worker }
3337*61046927SAndroid Build Coastguard Worker
3338*61046927SAndroid Build Coastguard Worker if (bindDrawBuf) {
3339*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
3340*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_SAMPLE_STATE;
3341*61046927SAndroid Build Coastguard Worker
3342*61046927SAndroid Build Coastguard Worker /* check if old framebuffer had any texture attachments */
3343*61046927SAndroid Build Coastguard Worker if (oldDrawFb)
3344*61046927SAndroid Build Coastguard Worker check_end_texture_render(ctx, oldDrawFb);
3345*61046927SAndroid Build Coastguard Worker
3346*61046927SAndroid Build Coastguard Worker /* check if newly bound framebuffer has any texture attachments */
3347*61046927SAndroid Build Coastguard Worker check_begin_texture_render(ctx, newDrawFb);
3348*61046927SAndroid Build Coastguard Worker
3349*61046927SAndroid Build Coastguard Worker _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb);
3350*61046927SAndroid Build Coastguard Worker _mesa_update_allow_draw_out_of_order(ctx);
3351*61046927SAndroid Build Coastguard Worker _mesa_update_valid_to_render_state(ctx);
3352*61046927SAndroid Build Coastguard Worker }
3353*61046927SAndroid Build Coastguard Worker }
3354*61046927SAndroid Build Coastguard Worker
3355*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindFramebuffer(GLenum target,GLuint framebuffer)3356*61046927SAndroid Build Coastguard Worker _mesa_BindFramebuffer(GLenum target, GLuint framebuffer)
3357*61046927SAndroid Build Coastguard Worker {
3358*61046927SAndroid Build Coastguard Worker /* OpenGL ES glBindFramebuffer and glBindFramebufferOES use this same entry
3359*61046927SAndroid Build Coastguard Worker * point, but they allow the use of user-generated names.
3360*61046927SAndroid Build Coastguard Worker */
3361*61046927SAndroid Build Coastguard Worker bind_framebuffer(target, framebuffer);
3362*61046927SAndroid Build Coastguard Worker }
3363*61046927SAndroid Build Coastguard Worker
3364*61046927SAndroid Build Coastguard Worker
3365*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindFramebufferEXT(GLenum target,GLuint framebuffer)3366*61046927SAndroid Build Coastguard Worker _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
3367*61046927SAndroid Build Coastguard Worker {
3368*61046927SAndroid Build Coastguard Worker bind_framebuffer(target, framebuffer);
3369*61046927SAndroid Build Coastguard Worker }
3370*61046927SAndroid Build Coastguard Worker
3371*61046927SAndroid Build Coastguard Worker
3372*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DeleteFramebuffers(GLsizei n,const GLuint * framebuffers)3373*61046927SAndroid Build Coastguard Worker _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
3374*61046927SAndroid Build Coastguard Worker {
3375*61046927SAndroid Build Coastguard Worker GLint i;
3376*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3377*61046927SAndroid Build Coastguard Worker
3378*61046927SAndroid Build Coastguard Worker if (n < 0) {
3379*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteFramebuffers(n < 0)");
3380*61046927SAndroid Build Coastguard Worker return;
3381*61046927SAndroid Build Coastguard Worker }
3382*61046927SAndroid Build Coastguard Worker
3383*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
3384*61046927SAndroid Build Coastguard Worker
3385*61046927SAndroid Build Coastguard Worker for (i = 0; i < n; i++) {
3386*61046927SAndroid Build Coastguard Worker if (framebuffers[i] > 0) {
3387*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
3388*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
3389*61046927SAndroid Build Coastguard Worker if (fb) {
3390*61046927SAndroid Build Coastguard Worker assert(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
3391*61046927SAndroid Build Coastguard Worker
3392*61046927SAndroid Build Coastguard Worker /* check if deleting currently bound framebuffer object */
3393*61046927SAndroid Build Coastguard Worker if (fb == ctx->DrawBuffer) {
3394*61046927SAndroid Build Coastguard Worker /* bind default */
3395*61046927SAndroid Build Coastguard Worker assert(fb->RefCount >= 2);
3396*61046927SAndroid Build Coastguard Worker _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3397*61046927SAndroid Build Coastguard Worker }
3398*61046927SAndroid Build Coastguard Worker if (fb == ctx->ReadBuffer) {
3399*61046927SAndroid Build Coastguard Worker /* bind default */
3400*61046927SAndroid Build Coastguard Worker assert(fb->RefCount >= 2);
3401*61046927SAndroid Build Coastguard Worker _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
3402*61046927SAndroid Build Coastguard Worker }
3403*61046927SAndroid Build Coastguard Worker
3404*61046927SAndroid Build Coastguard Worker /* remove from hash table immediately, to free the ID */
3405*61046927SAndroid Build Coastguard Worker _mesa_HashRemove(&ctx->Shared->FrameBuffers, framebuffers[i]);
3406*61046927SAndroid Build Coastguard Worker
3407*61046927SAndroid Build Coastguard Worker if (fb != &DummyFramebuffer) {
3408*61046927SAndroid Build Coastguard Worker /* But the object will not be freed until it's no longer
3409*61046927SAndroid Build Coastguard Worker * bound in any context.
3410*61046927SAndroid Build Coastguard Worker */
3411*61046927SAndroid Build Coastguard Worker _mesa_reference_framebuffer(&fb, NULL);
3412*61046927SAndroid Build Coastguard Worker }
3413*61046927SAndroid Build Coastguard Worker }
3414*61046927SAndroid Build Coastguard Worker }
3415*61046927SAndroid Build Coastguard Worker }
3416*61046927SAndroid Build Coastguard Worker }
3417*61046927SAndroid Build Coastguard Worker
3418*61046927SAndroid Build Coastguard Worker
3419*61046927SAndroid Build Coastguard Worker /**
3420*61046927SAndroid Build Coastguard Worker * This is the implementation for glGenFramebuffers and glCreateFramebuffers.
3421*61046927SAndroid Build Coastguard Worker * It is not exposed to the rest of Mesa to encourage the use of
3422*61046927SAndroid Build Coastguard Worker * nameless buffers in driver internals.
3423*61046927SAndroid Build Coastguard Worker */
3424*61046927SAndroid Build Coastguard Worker static void
create_framebuffers(GLsizei n,GLuint * framebuffers,bool dsa)3425*61046927SAndroid Build Coastguard Worker create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa)
3426*61046927SAndroid Build Coastguard Worker {
3427*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3428*61046927SAndroid Build Coastguard Worker GLint i;
3429*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
3430*61046927SAndroid Build Coastguard Worker
3431*61046927SAndroid Build Coastguard Worker const char *func = dsa ? "glCreateFramebuffers" : "glGenFramebuffers";
3432*61046927SAndroid Build Coastguard Worker
3433*61046927SAndroid Build Coastguard Worker if (n < 0) {
3434*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
3435*61046927SAndroid Build Coastguard Worker return;
3436*61046927SAndroid Build Coastguard Worker }
3437*61046927SAndroid Build Coastguard Worker
3438*61046927SAndroid Build Coastguard Worker if (!framebuffers)
3439*61046927SAndroid Build Coastguard Worker return;
3440*61046927SAndroid Build Coastguard Worker
3441*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(&ctx->Shared->FrameBuffers);
3442*61046927SAndroid Build Coastguard Worker
3443*61046927SAndroid Build Coastguard Worker _mesa_HashFindFreeKeys(&ctx->Shared->FrameBuffers, framebuffers, n);
3444*61046927SAndroid Build Coastguard Worker
3445*61046927SAndroid Build Coastguard Worker for (i = 0; i < n; i++) {
3446*61046927SAndroid Build Coastguard Worker if (dsa) {
3447*61046927SAndroid Build Coastguard Worker fb = _mesa_new_framebuffer(ctx, framebuffers[i]);
3448*61046927SAndroid Build Coastguard Worker if (!fb) {
3449*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(&ctx->Shared->FrameBuffers);
3450*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
3451*61046927SAndroid Build Coastguard Worker return;
3452*61046927SAndroid Build Coastguard Worker }
3453*61046927SAndroid Build Coastguard Worker }
3454*61046927SAndroid Build Coastguard Worker else
3455*61046927SAndroid Build Coastguard Worker fb = &DummyFramebuffer;
3456*61046927SAndroid Build Coastguard Worker
3457*61046927SAndroid Build Coastguard Worker _mesa_HashInsertLocked(&ctx->Shared->FrameBuffers, framebuffers[i], fb);
3458*61046927SAndroid Build Coastguard Worker }
3459*61046927SAndroid Build Coastguard Worker
3460*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(&ctx->Shared->FrameBuffers);
3461*61046927SAndroid Build Coastguard Worker }
3462*61046927SAndroid Build Coastguard Worker
3463*61046927SAndroid Build Coastguard Worker
3464*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GenFramebuffers(GLsizei n,GLuint * framebuffers)3465*61046927SAndroid Build Coastguard Worker _mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
3466*61046927SAndroid Build Coastguard Worker {
3467*61046927SAndroid Build Coastguard Worker create_framebuffers(n, framebuffers, false);
3468*61046927SAndroid Build Coastguard Worker }
3469*61046927SAndroid Build Coastguard Worker
3470*61046927SAndroid Build Coastguard Worker
3471*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CreateFramebuffers(GLsizei n,GLuint * framebuffers)3472*61046927SAndroid Build Coastguard Worker _mesa_CreateFramebuffers(GLsizei n, GLuint *framebuffers)
3473*61046927SAndroid Build Coastguard Worker {
3474*61046927SAndroid Build Coastguard Worker create_framebuffers(n, framebuffers, true);
3475*61046927SAndroid Build Coastguard Worker }
3476*61046927SAndroid Build Coastguard Worker
3477*61046927SAndroid Build Coastguard Worker
3478*61046927SAndroid Build Coastguard Worker GLenum
_mesa_check_framebuffer_status(struct gl_context * ctx,struct gl_framebuffer * buffer)3479*61046927SAndroid Build Coastguard Worker _mesa_check_framebuffer_status(struct gl_context *ctx,
3480*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *buffer)
3481*61046927SAndroid Build Coastguard Worker {
3482*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
3483*61046927SAndroid Build Coastguard Worker
3484*61046927SAndroid Build Coastguard Worker if (_mesa_is_winsys_fbo(buffer)) {
3485*61046927SAndroid Build Coastguard Worker /* EGL_KHR_surfaceless_context allows the winsys FBO to be incomplete. */
3486*61046927SAndroid Build Coastguard Worker if (buffer != &IncompleteFramebuffer) {
3487*61046927SAndroid Build Coastguard Worker return GL_FRAMEBUFFER_COMPLETE_EXT;
3488*61046927SAndroid Build Coastguard Worker } else {
3489*61046927SAndroid Build Coastguard Worker return GL_FRAMEBUFFER_UNDEFINED;
3490*61046927SAndroid Build Coastguard Worker }
3491*61046927SAndroid Build Coastguard Worker }
3492*61046927SAndroid Build Coastguard Worker
3493*61046927SAndroid Build Coastguard Worker /* No need to flush here */
3494*61046927SAndroid Build Coastguard Worker
3495*61046927SAndroid Build Coastguard Worker if (buffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
3496*61046927SAndroid Build Coastguard Worker _mesa_test_framebuffer_completeness(ctx, buffer);
3497*61046927SAndroid Build Coastguard Worker }
3498*61046927SAndroid Build Coastguard Worker
3499*61046927SAndroid Build Coastguard Worker return buffer->_Status;
3500*61046927SAndroid Build Coastguard Worker }
3501*61046927SAndroid Build Coastguard Worker
3502*61046927SAndroid Build Coastguard Worker
3503*61046927SAndroid Build Coastguard Worker GLenum GLAPIENTRY
_mesa_CheckFramebufferStatus_no_error(GLenum target)3504*61046927SAndroid Build Coastguard Worker _mesa_CheckFramebufferStatus_no_error(GLenum target)
3505*61046927SAndroid Build Coastguard Worker {
3506*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3507*61046927SAndroid Build Coastguard Worker
3508*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb = get_framebuffer_target(ctx, target);
3509*61046927SAndroid Build Coastguard Worker return _mesa_check_framebuffer_status(ctx, fb);
3510*61046927SAndroid Build Coastguard Worker }
3511*61046927SAndroid Build Coastguard Worker
3512*61046927SAndroid Build Coastguard Worker
3513*61046927SAndroid Build Coastguard Worker GLenum GLAPIENTRY
_mesa_CheckFramebufferStatus(GLenum target)3514*61046927SAndroid Build Coastguard Worker _mesa_CheckFramebufferStatus(GLenum target)
3515*61046927SAndroid Build Coastguard Worker {
3516*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
3517*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3518*61046927SAndroid Build Coastguard Worker
3519*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
3520*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glCheckFramebufferStatus(%s)\n",
3521*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
3522*61046927SAndroid Build Coastguard Worker
3523*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
3524*61046927SAndroid Build Coastguard Worker if (!fb) {
3525*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
3526*61046927SAndroid Build Coastguard Worker "glCheckFramebufferStatus(invalid target %s)",
3527*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
3528*61046927SAndroid Build Coastguard Worker return 0;
3529*61046927SAndroid Build Coastguard Worker }
3530*61046927SAndroid Build Coastguard Worker
3531*61046927SAndroid Build Coastguard Worker return _mesa_check_framebuffer_status(ctx, fb);
3532*61046927SAndroid Build Coastguard Worker }
3533*61046927SAndroid Build Coastguard Worker
3534*61046927SAndroid Build Coastguard Worker
3535*61046927SAndroid Build Coastguard Worker GLenum GLAPIENTRY
_mesa_CheckNamedFramebufferStatus(GLuint framebuffer,GLenum target)3536*61046927SAndroid Build Coastguard Worker _mesa_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target)
3537*61046927SAndroid Build Coastguard Worker {
3538*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
3539*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3540*61046927SAndroid Build Coastguard Worker
3541*61046927SAndroid Build Coastguard Worker /* Validate the target (for conformance's sake) and grab a reference to the
3542*61046927SAndroid Build Coastguard Worker * default framebuffer in case framebuffer = 0.
3543*61046927SAndroid Build Coastguard Worker * Section 9.4 Framebuffer Completeness of the OpenGL 4.5 core spec
3544*61046927SAndroid Build Coastguard Worker * (30.10.2014, PDF page 336) says:
3545*61046927SAndroid Build Coastguard Worker * "If framebuffer is zero, then the status of the default read or
3546*61046927SAndroid Build Coastguard Worker * draw framebuffer (as determined by target) is returned."
3547*61046927SAndroid Build Coastguard Worker */
3548*61046927SAndroid Build Coastguard Worker switch (target) {
3549*61046927SAndroid Build Coastguard Worker case GL_DRAW_FRAMEBUFFER:
3550*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER:
3551*61046927SAndroid Build Coastguard Worker fb = ctx->WinSysDrawBuffer;
3552*61046927SAndroid Build Coastguard Worker break;
3553*61046927SAndroid Build Coastguard Worker case GL_READ_FRAMEBUFFER:
3554*61046927SAndroid Build Coastguard Worker fb = ctx->WinSysReadBuffer;
3555*61046927SAndroid Build Coastguard Worker break;
3556*61046927SAndroid Build Coastguard Worker default:
3557*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
3558*61046927SAndroid Build Coastguard Worker "glCheckNamedFramebufferStatus(invalid target %s)",
3559*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
3560*61046927SAndroid Build Coastguard Worker return 0;
3561*61046927SAndroid Build Coastguard Worker }
3562*61046927SAndroid Build Coastguard Worker
3563*61046927SAndroid Build Coastguard Worker if (framebuffer) {
3564*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
3565*61046927SAndroid Build Coastguard Worker "glCheckNamedFramebufferStatus");
3566*61046927SAndroid Build Coastguard Worker if (!fb)
3567*61046927SAndroid Build Coastguard Worker return 0;
3568*61046927SAndroid Build Coastguard Worker }
3569*61046927SAndroid Build Coastguard Worker
3570*61046927SAndroid Build Coastguard Worker return _mesa_check_framebuffer_status(ctx, fb);
3571*61046927SAndroid Build Coastguard Worker }
3572*61046927SAndroid Build Coastguard Worker
3573*61046927SAndroid Build Coastguard Worker
3574*61046927SAndroid Build Coastguard Worker GLenum GLAPIENTRY
_mesa_CheckNamedFramebufferStatusEXT(GLuint framebuffer,GLenum target)3575*61046927SAndroid Build Coastguard Worker _mesa_CheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target)
3576*61046927SAndroid Build Coastguard Worker {
3577*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
3578*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3579*61046927SAndroid Build Coastguard Worker
3580*61046927SAndroid Build Coastguard Worker switch (target) {
3581*61046927SAndroid Build Coastguard Worker case GL_DRAW_FRAMEBUFFER:
3582*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER:
3583*61046927SAndroid Build Coastguard Worker case GL_READ_FRAMEBUFFER:
3584*61046927SAndroid Build Coastguard Worker break;
3585*61046927SAndroid Build Coastguard Worker default:
3586*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
3587*61046927SAndroid Build Coastguard Worker "glCheckNamedFramebufferStatusEXT(invalid target %s)",
3588*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
3589*61046927SAndroid Build Coastguard Worker return 0;
3590*61046927SAndroid Build Coastguard Worker }
3591*61046927SAndroid Build Coastguard Worker
3592*61046927SAndroid Build Coastguard Worker if (framebuffer == 0) {
3593*61046927SAndroid Build Coastguard Worker return _mesa_CheckNamedFramebufferStatus(0, target);
3594*61046927SAndroid Build Coastguard Worker }
3595*61046927SAndroid Build Coastguard Worker
3596*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_dsa(ctx, framebuffer,
3597*61046927SAndroid Build Coastguard Worker "glCheckNamedFramebufferStatusEXT");
3598*61046927SAndroid Build Coastguard Worker if (!fb)
3599*61046927SAndroid Build Coastguard Worker return 0;
3600*61046927SAndroid Build Coastguard Worker
3601*61046927SAndroid Build Coastguard Worker return _mesa_check_framebuffer_status(ctx, fb);
3602*61046927SAndroid Build Coastguard Worker }
3603*61046927SAndroid Build Coastguard Worker
3604*61046927SAndroid Build Coastguard Worker
3605*61046927SAndroid Build Coastguard Worker /**
3606*61046927SAndroid Build Coastguard Worker * Replicate the src attachment point. Used by framebuffer_texture() when
3607*61046927SAndroid Build Coastguard Worker * the same texture is attached at GL_DEPTH_ATTACHMENT and
3608*61046927SAndroid Build Coastguard Worker * GL_STENCIL_ATTACHMENT.
3609*61046927SAndroid Build Coastguard Worker */
3610*61046927SAndroid Build Coastguard Worker static void
reuse_framebuffer_texture_attachment(struct gl_framebuffer * fb,gl_buffer_index dst,gl_buffer_index src)3611*61046927SAndroid Build Coastguard Worker reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
3612*61046927SAndroid Build Coastguard Worker gl_buffer_index dst,
3613*61046927SAndroid Build Coastguard Worker gl_buffer_index src)
3614*61046927SAndroid Build Coastguard Worker {
3615*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *dst_att = &fb->Attachment[dst];
3616*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *src_att = &fb->Attachment[src];
3617*61046927SAndroid Build Coastguard Worker
3618*61046927SAndroid Build Coastguard Worker assert(src_att->Texture != NULL);
3619*61046927SAndroid Build Coastguard Worker assert(src_att->Renderbuffer != NULL);
3620*61046927SAndroid Build Coastguard Worker
3621*61046927SAndroid Build Coastguard Worker _mesa_reference_texobj(&dst_att->Texture, src_att->Texture);
3622*61046927SAndroid Build Coastguard Worker _mesa_reference_renderbuffer(&dst_att->Renderbuffer, src_att->Renderbuffer);
3623*61046927SAndroid Build Coastguard Worker dst_att->Type = src_att->Type;
3624*61046927SAndroid Build Coastguard Worker dst_att->Complete = src_att->Complete;
3625*61046927SAndroid Build Coastguard Worker dst_att->TextureLevel = src_att->TextureLevel;
3626*61046927SAndroid Build Coastguard Worker dst_att->CubeMapFace = src_att->CubeMapFace;
3627*61046927SAndroid Build Coastguard Worker dst_att->Zoffset = src_att->Zoffset;
3628*61046927SAndroid Build Coastguard Worker dst_att->Layered = src_att->Layered;
3629*61046927SAndroid Build Coastguard Worker }
3630*61046927SAndroid Build Coastguard Worker
3631*61046927SAndroid Build Coastguard Worker
3632*61046927SAndroid Build Coastguard Worker static struct gl_texture_object *
get_texture_for_framebuffer(struct gl_context * ctx,GLuint texture)3633*61046927SAndroid Build Coastguard Worker get_texture_for_framebuffer(struct gl_context *ctx, GLuint texture)
3634*61046927SAndroid Build Coastguard Worker {
3635*61046927SAndroid Build Coastguard Worker if (!texture)
3636*61046927SAndroid Build Coastguard Worker return NULL;
3637*61046927SAndroid Build Coastguard Worker
3638*61046927SAndroid Build Coastguard Worker return _mesa_lookup_texture(ctx, texture);
3639*61046927SAndroid Build Coastguard Worker }
3640*61046927SAndroid Build Coastguard Worker
3641*61046927SAndroid Build Coastguard Worker
3642*61046927SAndroid Build Coastguard Worker /**
3643*61046927SAndroid Build Coastguard Worker * Common code called by gl*FramebufferTexture*() to retrieve the correct
3644*61046927SAndroid Build Coastguard Worker * texture object pointer.
3645*61046927SAndroid Build Coastguard Worker *
3646*61046927SAndroid Build Coastguard Worker * \param texObj where the pointer to the texture object is returned. Note
3647*61046927SAndroid Build Coastguard Worker * that a successful call may return texObj = NULL.
3648*61046927SAndroid Build Coastguard Worker *
3649*61046927SAndroid Build Coastguard Worker * \return true if no errors, false if errors
3650*61046927SAndroid Build Coastguard Worker */
3651*61046927SAndroid Build Coastguard Worker static bool
get_texture_for_framebuffer_err(struct gl_context * ctx,GLuint texture,bool layered,const char * caller,struct gl_texture_object ** texObj)3652*61046927SAndroid Build Coastguard Worker get_texture_for_framebuffer_err(struct gl_context *ctx, GLuint texture,
3653*61046927SAndroid Build Coastguard Worker bool layered, const char *caller,
3654*61046927SAndroid Build Coastguard Worker struct gl_texture_object **texObj)
3655*61046927SAndroid Build Coastguard Worker {
3656*61046927SAndroid Build Coastguard Worker *texObj = NULL; /* This will get returned if texture = 0. */
3657*61046927SAndroid Build Coastguard Worker
3658*61046927SAndroid Build Coastguard Worker if (!texture)
3659*61046927SAndroid Build Coastguard Worker return true;
3660*61046927SAndroid Build Coastguard Worker
3661*61046927SAndroid Build Coastguard Worker *texObj = _mesa_lookup_texture(ctx, texture);
3662*61046927SAndroid Build Coastguard Worker if (*texObj == NULL || (*texObj)->Target == 0) {
3663*61046927SAndroid Build Coastguard Worker /* Can't render to a non-existent texture object.
3664*61046927SAndroid Build Coastguard Worker *
3665*61046927SAndroid Build Coastguard Worker * The OpenGL 4.5 core spec (02.02.2015) in Section 9.2 Binding and
3666*61046927SAndroid Build Coastguard Worker * Managing Framebuffer Objects specifies a different error
3667*61046927SAndroid Build Coastguard Worker * depending upon the calling function (PDF pages 325-328).
3668*61046927SAndroid Build Coastguard Worker * *FramebufferTexture (where layered = GL_TRUE) throws invalid
3669*61046927SAndroid Build Coastguard Worker * value, while the other commands throw invalid operation (where
3670*61046927SAndroid Build Coastguard Worker * layered = GL_FALSE).
3671*61046927SAndroid Build Coastguard Worker */
3672*61046927SAndroid Build Coastguard Worker const GLenum error = layered ? GL_INVALID_VALUE :
3673*61046927SAndroid Build Coastguard Worker GL_INVALID_OPERATION;
3674*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, error,
3675*61046927SAndroid Build Coastguard Worker "%s(non-existent texture %u)", caller, texture);
3676*61046927SAndroid Build Coastguard Worker return false;
3677*61046927SAndroid Build Coastguard Worker }
3678*61046927SAndroid Build Coastguard Worker
3679*61046927SAndroid Build Coastguard Worker return true;
3680*61046927SAndroid Build Coastguard Worker }
3681*61046927SAndroid Build Coastguard Worker
3682*61046927SAndroid Build Coastguard Worker
3683*61046927SAndroid Build Coastguard Worker /**
3684*61046927SAndroid Build Coastguard Worker * Common code called by gl*FramebufferTexture() to verify the texture target
3685*61046927SAndroid Build Coastguard Worker * and decide whether or not the attachment should truly be considered
3686*61046927SAndroid Build Coastguard Worker * layered.
3687*61046927SAndroid Build Coastguard Worker *
3688*61046927SAndroid Build Coastguard Worker * \param layered true if attachment should be considered layered, false if
3689*61046927SAndroid Build Coastguard Worker * not
3690*61046927SAndroid Build Coastguard Worker *
3691*61046927SAndroid Build Coastguard Worker * \return true if no errors, false if errors
3692*61046927SAndroid Build Coastguard Worker */
3693*61046927SAndroid Build Coastguard Worker static bool
check_layered_texture_target(struct gl_context * ctx,GLenum target,const char * caller,GLboolean * layered)3694*61046927SAndroid Build Coastguard Worker check_layered_texture_target(struct gl_context *ctx, GLenum target,
3695*61046927SAndroid Build Coastguard Worker const char *caller, GLboolean *layered)
3696*61046927SAndroid Build Coastguard Worker {
3697*61046927SAndroid Build Coastguard Worker *layered = GL_TRUE;
3698*61046927SAndroid Build Coastguard Worker
3699*61046927SAndroid Build Coastguard Worker switch (target) {
3700*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
3701*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D_ARRAY_EXT:
3702*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY_EXT:
3703*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
3704*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_ARRAY:
3705*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3706*61046927SAndroid Build Coastguard Worker return true;
3707*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D:
3708*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
3709*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_RECTANGLE:
3710*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE:
3711*61046927SAndroid Build Coastguard Worker /* These texture types are valid to pass to
3712*61046927SAndroid Build Coastguard Worker * glFramebufferTexture(), but since they aren't layered, it
3713*61046927SAndroid Build Coastguard Worker * is equivalent to calling glFramebufferTexture{1D,2D}().
3714*61046927SAndroid Build Coastguard Worker */
3715*61046927SAndroid Build Coastguard Worker *layered = GL_FALSE;
3716*61046927SAndroid Build Coastguard Worker return true;
3717*61046927SAndroid Build Coastguard Worker }
3718*61046927SAndroid Build Coastguard Worker
3719*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3720*61046927SAndroid Build Coastguard Worker "%s(invalid texture target %s)", caller,
3721*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
3722*61046927SAndroid Build Coastguard Worker return false;
3723*61046927SAndroid Build Coastguard Worker }
3724*61046927SAndroid Build Coastguard Worker
3725*61046927SAndroid Build Coastguard Worker
3726*61046927SAndroid Build Coastguard Worker /**
3727*61046927SAndroid Build Coastguard Worker * Common code called by gl*FramebufferTextureMultiviewOVR() to verify the texture target
3728*61046927SAndroid Build Coastguard Worker *
3729*61046927SAndroid Build Coastguard Worker * \return true if no errors, false if errors
3730*61046927SAndroid Build Coastguard Worker */
3731*61046927SAndroid Build Coastguard Worker static bool
check_multiview_texture_target(struct gl_context * ctx,GLuint texture,GLenum target,GLint level,GLint baseViewIndex,GLsizei numViews,const char * caller)3732*61046927SAndroid Build Coastguard Worker check_multiview_texture_target(struct gl_context *ctx, GLuint texture, GLenum target, GLint level,
3733*61046927SAndroid Build Coastguard Worker GLint baseViewIndex, GLsizei numViews, const char *caller)
3734*61046927SAndroid Build Coastguard Worker {
3735*61046927SAndroid Build Coastguard Worker bool ret = true;
3736*61046927SAndroid Build Coastguard Worker if (target != GL_TEXTURE_2D_ARRAY)
3737*61046927SAndroid Build Coastguard Worker {
3738*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3739*61046927SAndroid Build Coastguard Worker "%s(invalid texture target %s), only 2D_ARRAY is supported", caller,
3740*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
3741*61046927SAndroid Build Coastguard Worker ret = false;
3742*61046927SAndroid Build Coastguard Worker }
3743*61046927SAndroid Build Coastguard Worker else if (level > 0)
3744*61046927SAndroid Build Coastguard Worker {
3745*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3746*61046927SAndroid Build Coastguard Worker "%s(invalid texture target %s), multisample is supported by OVR_multiview2", caller,
3747*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
3748*61046927SAndroid Build Coastguard Worker ret = false;
3749*61046927SAndroid Build Coastguard Worker }
3750*61046927SAndroid Build Coastguard Worker else if ((numViews > MAX_VIEWS_OVR) || (numViews <= 0))
3751*61046927SAndroid Build Coastguard Worker {
3752*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3753*61046927SAndroid Build Coastguard Worker "%s numViews is less than 1 or greater than MAX_VIEWS_OVR)", caller);
3754*61046927SAndroid Build Coastguard Worker ret = false;
3755*61046927SAndroid Build Coastguard Worker }
3756*61046927SAndroid Build Coastguard Worker else if ((texture > 0) && (baseViewIndex < 0))
3757*61046927SAndroid Build Coastguard Worker {
3758*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3759*61046927SAndroid Build Coastguard Worker "%s baseViewIndex is less than 0)", caller);
3760*61046927SAndroid Build Coastguard Worker ret = false;
3761*61046927SAndroid Build Coastguard Worker }
3762*61046927SAndroid Build Coastguard Worker
3763*61046927SAndroid Build Coastguard Worker return ret;
3764*61046927SAndroid Build Coastguard Worker }
3765*61046927SAndroid Build Coastguard Worker
3766*61046927SAndroid Build Coastguard Worker
3767*61046927SAndroid Build Coastguard Worker /**
3768*61046927SAndroid Build Coastguard Worker * Common code called by gl*FramebufferTextureLayer() to verify the texture
3769*61046927SAndroid Build Coastguard Worker * target.
3770*61046927SAndroid Build Coastguard Worker *
3771*61046927SAndroid Build Coastguard Worker * \return true if no errors, false if errors
3772*61046927SAndroid Build Coastguard Worker */
3773*61046927SAndroid Build Coastguard Worker static bool
check_texture_target(struct gl_context * ctx,GLenum target,const char * caller)3774*61046927SAndroid Build Coastguard Worker check_texture_target(struct gl_context *ctx, GLenum target,
3775*61046927SAndroid Build Coastguard Worker const char *caller)
3776*61046927SAndroid Build Coastguard Worker {
3777*61046927SAndroid Build Coastguard Worker /* We're being called by glFramebufferTextureLayer().
3778*61046927SAndroid Build Coastguard Worker * The only legal texture types for that function are 3D,
3779*61046927SAndroid Build Coastguard Worker * cube-map, and 1D/2D/cube-map array textures.
3780*61046927SAndroid Build Coastguard Worker *
3781*61046927SAndroid Build Coastguard Worker * We don't need to check for GL_ARB_texture_cube_map_array because the
3782*61046927SAndroid Build Coastguard Worker * application wouldn't have been able to create a texture with a
3783*61046927SAndroid Build Coastguard Worker * GL_TEXTURE_CUBE_MAP_ARRAY target if the extension were not enabled.
3784*61046927SAndroid Build Coastguard Worker */
3785*61046927SAndroid Build Coastguard Worker switch (target) {
3786*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
3787*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D_ARRAY:
3788*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY:
3789*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_ARRAY:
3790*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3791*61046927SAndroid Build Coastguard Worker return true;
3792*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
3793*61046927SAndroid Build Coastguard Worker /* GL_TEXTURE_CUBE_MAP is only allowed by OpenGL 4.5 here, which
3794*61046927SAndroid Build Coastguard Worker * includes the DSA API.
3795*61046927SAndroid Build Coastguard Worker *
3796*61046927SAndroid Build Coastguard Worker * Because DSA is only enabled for GL 3.1+ and this can be called
3797*61046927SAndroid Build Coastguard Worker * from _mesa_FramebufferTextureLayer in compatibility profile,
3798*61046927SAndroid Build Coastguard Worker * we need to check the version.
3799*61046927SAndroid Build Coastguard Worker */
3800*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx) && ctx->Version >= 31;
3801*61046927SAndroid Build Coastguard Worker }
3802*61046927SAndroid Build Coastguard Worker
3803*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3804*61046927SAndroid Build Coastguard Worker "%s(invalid texture target %s)", caller,
3805*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
3806*61046927SAndroid Build Coastguard Worker return false;
3807*61046927SAndroid Build Coastguard Worker }
3808*61046927SAndroid Build Coastguard Worker
3809*61046927SAndroid Build Coastguard Worker
3810*61046927SAndroid Build Coastguard Worker /**
3811*61046927SAndroid Build Coastguard Worker * Common code called by glFramebufferTexture*D() to verify the texture
3812*61046927SAndroid Build Coastguard Worker * target.
3813*61046927SAndroid Build Coastguard Worker *
3814*61046927SAndroid Build Coastguard Worker * \return true if no errors, false if errors
3815*61046927SAndroid Build Coastguard Worker */
3816*61046927SAndroid Build Coastguard Worker static bool
check_textarget(struct gl_context * ctx,int dims,GLenum target,GLenum textarget,const char * caller)3817*61046927SAndroid Build Coastguard Worker check_textarget(struct gl_context *ctx, int dims, GLenum target,
3818*61046927SAndroid Build Coastguard Worker GLenum textarget, const char *caller)
3819*61046927SAndroid Build Coastguard Worker {
3820*61046927SAndroid Build Coastguard Worker bool err = false;
3821*61046927SAndroid Build Coastguard Worker
3822*61046927SAndroid Build Coastguard Worker switch (textarget) {
3823*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D:
3824*61046927SAndroid Build Coastguard Worker err = dims != 1;
3825*61046927SAndroid Build Coastguard Worker break;
3826*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D_ARRAY:
3827*61046927SAndroid Build Coastguard Worker err = dims != 1 || !ctx->Extensions.EXT_texture_array;
3828*61046927SAndroid Build Coastguard Worker break;
3829*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
3830*61046927SAndroid Build Coastguard Worker err = dims != 2;
3831*61046927SAndroid Build Coastguard Worker break;
3832*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY:
3833*61046927SAndroid Build Coastguard Worker err = dims != 2 || !ctx->Extensions.EXT_texture_array ||
3834*61046927SAndroid Build Coastguard Worker (_mesa_is_gles(ctx) && ctx->Version < 30);
3835*61046927SAndroid Build Coastguard Worker break;
3836*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE:
3837*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3838*61046927SAndroid Build Coastguard Worker err = dims != 2 ||
3839*61046927SAndroid Build Coastguard Worker !ctx->Extensions.ARB_texture_multisample ||
3840*61046927SAndroid Build Coastguard Worker (_mesa_is_gles(ctx) && ctx->Version < 31);
3841*61046927SAndroid Build Coastguard Worker break;
3842*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_RECTANGLE:
3843*61046927SAndroid Build Coastguard Worker err = dims != 2 || _mesa_is_gles(ctx) ||
3844*61046927SAndroid Build Coastguard Worker !ctx->Extensions.NV_texture_rectangle;
3845*61046927SAndroid Build Coastguard Worker break;
3846*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
3847*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_ARRAY:
3848*61046927SAndroid Build Coastguard Worker err = true;
3849*61046927SAndroid Build Coastguard Worker break;
3850*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3851*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3852*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3853*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3854*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3855*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3856*61046927SAndroid Build Coastguard Worker err = dims != 2;
3857*61046927SAndroid Build Coastguard Worker break;
3858*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
3859*61046927SAndroid Build Coastguard Worker err = dims != 3 ||
3860*61046927SAndroid Build Coastguard Worker (_mesa_is_gles2(ctx) && !ctx->Extensions.OES_texture_3D);
3861*61046927SAndroid Build Coastguard Worker break;
3862*61046927SAndroid Build Coastguard Worker default:
3863*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
3864*61046927SAndroid Build Coastguard Worker "%s(unknown textarget 0x%x)", caller, textarget);
3865*61046927SAndroid Build Coastguard Worker return false;
3866*61046927SAndroid Build Coastguard Worker }
3867*61046927SAndroid Build Coastguard Worker
3868*61046927SAndroid Build Coastguard Worker if (err) {
3869*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3870*61046927SAndroid Build Coastguard Worker "%s(invalid textarget %s)",
3871*61046927SAndroid Build Coastguard Worker caller, _mesa_enum_to_string(textarget));
3872*61046927SAndroid Build Coastguard Worker return false;
3873*61046927SAndroid Build Coastguard Worker }
3874*61046927SAndroid Build Coastguard Worker
3875*61046927SAndroid Build Coastguard Worker /* Make sure textarget is consistent with the texture's type */
3876*61046927SAndroid Build Coastguard Worker err = (target == GL_TEXTURE_CUBE_MAP) ?
3877*61046927SAndroid Build Coastguard Worker !_mesa_is_cube_face(textarget): (target != textarget);
3878*61046927SAndroid Build Coastguard Worker
3879*61046927SAndroid Build Coastguard Worker if (err) {
3880*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3881*61046927SAndroid Build Coastguard Worker "%s(mismatched texture target)", caller);
3882*61046927SAndroid Build Coastguard Worker return false;
3883*61046927SAndroid Build Coastguard Worker }
3884*61046927SAndroid Build Coastguard Worker
3885*61046927SAndroid Build Coastguard Worker return true;
3886*61046927SAndroid Build Coastguard Worker }
3887*61046927SAndroid Build Coastguard Worker
3888*61046927SAndroid Build Coastguard Worker
3889*61046927SAndroid Build Coastguard Worker /**
3890*61046927SAndroid Build Coastguard Worker * Common code called by gl*FramebufferTextureLayer() and
3891*61046927SAndroid Build Coastguard Worker * glFramebufferTexture3D() to validate the layer.
3892*61046927SAndroid Build Coastguard Worker *
3893*61046927SAndroid Build Coastguard Worker * \return true if no errors, false if errors
3894*61046927SAndroid Build Coastguard Worker */
3895*61046927SAndroid Build Coastguard Worker static bool
check_layer(struct gl_context * ctx,GLenum target,GLint layer,const char * caller)3896*61046927SAndroid Build Coastguard Worker check_layer(struct gl_context *ctx, GLenum target, GLint layer,
3897*61046927SAndroid Build Coastguard Worker const char *caller)
3898*61046927SAndroid Build Coastguard Worker {
3899*61046927SAndroid Build Coastguard Worker /* Page 306 (page 328 of the PDF) of the OpenGL 4.5 (Core Profile)
3900*61046927SAndroid Build Coastguard Worker * spec says:
3901*61046927SAndroid Build Coastguard Worker *
3902*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated if texture is non-zero
3903*61046927SAndroid Build Coastguard Worker * and layer is negative."
3904*61046927SAndroid Build Coastguard Worker */
3905*61046927SAndroid Build Coastguard Worker if (layer < 0) {
3906*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(layer %d < 0)", caller, layer);
3907*61046927SAndroid Build Coastguard Worker return false;
3908*61046927SAndroid Build Coastguard Worker }
3909*61046927SAndroid Build Coastguard Worker
3910*61046927SAndroid Build Coastguard Worker if (target == GL_TEXTURE_3D) {
3911*61046927SAndroid Build Coastguard Worker const GLuint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
3912*61046927SAndroid Build Coastguard Worker if (layer >= maxSize) {
3913*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3914*61046927SAndroid Build Coastguard Worker "%s(invalid layer %u)", caller, layer);
3915*61046927SAndroid Build Coastguard Worker return false;
3916*61046927SAndroid Build Coastguard Worker }
3917*61046927SAndroid Build Coastguard Worker }
3918*61046927SAndroid Build Coastguard Worker else if ((target == GL_TEXTURE_1D_ARRAY) ||
3919*61046927SAndroid Build Coastguard Worker (target == GL_TEXTURE_2D_ARRAY) ||
3920*61046927SAndroid Build Coastguard Worker (target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
3921*61046927SAndroid Build Coastguard Worker (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
3922*61046927SAndroid Build Coastguard Worker if (layer >= ctx->Const.MaxArrayTextureLayers) {
3923*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3924*61046927SAndroid Build Coastguard Worker "%s(layer %u >= GL_MAX_ARRAY_TEXTURE_LAYERS)",
3925*61046927SAndroid Build Coastguard Worker caller, layer);
3926*61046927SAndroid Build Coastguard Worker return false;
3927*61046927SAndroid Build Coastguard Worker }
3928*61046927SAndroid Build Coastguard Worker }
3929*61046927SAndroid Build Coastguard Worker else if (target == GL_TEXTURE_CUBE_MAP) {
3930*61046927SAndroid Build Coastguard Worker if (layer >= 6) {
3931*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3932*61046927SAndroid Build Coastguard Worker "%s(layer %u >= 6)", caller, layer);
3933*61046927SAndroid Build Coastguard Worker return false;
3934*61046927SAndroid Build Coastguard Worker }
3935*61046927SAndroid Build Coastguard Worker }
3936*61046927SAndroid Build Coastguard Worker
3937*61046927SAndroid Build Coastguard Worker return true;
3938*61046927SAndroid Build Coastguard Worker }
3939*61046927SAndroid Build Coastguard Worker
3940*61046927SAndroid Build Coastguard Worker
3941*61046927SAndroid Build Coastguard Worker /**
3942*61046927SAndroid Build Coastguard Worker * Common code called by all gl*FramebufferTexture*() entry points to verify
3943*61046927SAndroid Build Coastguard Worker * the level.
3944*61046927SAndroid Build Coastguard Worker *
3945*61046927SAndroid Build Coastguard Worker * \return true if no errors, false if errors
3946*61046927SAndroid Build Coastguard Worker */
3947*61046927SAndroid Build Coastguard Worker static bool
check_level(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum target,GLint level,const char * caller)3948*61046927SAndroid Build Coastguard Worker check_level(struct gl_context *ctx, struct gl_texture_object *texObj,
3949*61046927SAndroid Build Coastguard Worker GLenum target, GLint level, const char *caller)
3950*61046927SAndroid Build Coastguard Worker {
3951*61046927SAndroid Build Coastguard Worker /* Section 9.2.8 of the OpenGL 4.6 specification says:
3952*61046927SAndroid Build Coastguard Worker *
3953*61046927SAndroid Build Coastguard Worker * "If texture refers to an immutable-format texture, level must be
3954*61046927SAndroid Build Coastguard Worker * greater than or equal to zero and smaller than the value of
3955*61046927SAndroid Build Coastguard Worker * TEXTURE_VIEW_NUM_LEVELS for texture."
3956*61046927SAndroid Build Coastguard Worker */
3957*61046927SAndroid Build Coastguard Worker const int max_levels = texObj->Immutable ? texObj->Attrib.ImmutableLevels :
3958*61046927SAndroid Build Coastguard Worker _mesa_max_texture_levels(ctx, target);
3959*61046927SAndroid Build Coastguard Worker
3960*61046927SAndroid Build Coastguard Worker if (level < 0 || level >= max_levels) {
3961*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3962*61046927SAndroid Build Coastguard Worker "%s(invalid level %d)", caller, level);
3963*61046927SAndroid Build Coastguard Worker return false;
3964*61046927SAndroid Build Coastguard Worker }
3965*61046927SAndroid Build Coastguard Worker
3966*61046927SAndroid Build Coastguard Worker return true;
3967*61046927SAndroid Build Coastguard Worker }
3968*61046927SAndroid Build Coastguard Worker
3969*61046927SAndroid Build Coastguard Worker
3970*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *
_mesa_get_and_validate_attachment(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum attachment,const char * caller)3971*61046927SAndroid Build Coastguard Worker _mesa_get_and_validate_attachment(struct gl_context *ctx,
3972*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
3973*61046927SAndroid Build Coastguard Worker GLenum attachment, const char *caller)
3974*61046927SAndroid Build Coastguard Worker {
3975*61046927SAndroid Build Coastguard Worker /* The window-system framebuffer object is immutable */
3976*61046927SAndroid Build Coastguard Worker if (_mesa_is_winsys_fbo(fb)) {
3977*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(window-system framebuffer)",
3978*61046927SAndroid Build Coastguard Worker caller);
3979*61046927SAndroid Build Coastguard Worker return NULL;
3980*61046927SAndroid Build Coastguard Worker }
3981*61046927SAndroid Build Coastguard Worker
3982*61046927SAndroid Build Coastguard Worker /* Not a hash lookup, so we can afford to get the attachment here. */
3983*61046927SAndroid Build Coastguard Worker bool is_color_attachment;
3984*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att =
3985*61046927SAndroid Build Coastguard Worker get_attachment(ctx, fb, attachment, &is_color_attachment);
3986*61046927SAndroid Build Coastguard Worker if (att == NULL) {
3987*61046927SAndroid Build Coastguard Worker if (is_color_attachment) {
3988*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3989*61046927SAndroid Build Coastguard Worker "%s(invalid color attachment %s)", caller,
3990*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(attachment));
3991*61046927SAndroid Build Coastguard Worker } else {
3992*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
3993*61046927SAndroid Build Coastguard Worker "%s(invalid attachment %s)", caller,
3994*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(attachment));
3995*61046927SAndroid Build Coastguard Worker }
3996*61046927SAndroid Build Coastguard Worker return NULL;
3997*61046927SAndroid Build Coastguard Worker }
3998*61046927SAndroid Build Coastguard Worker
3999*61046927SAndroid Build Coastguard Worker return att;
4000*61046927SAndroid Build Coastguard Worker }
4001*61046927SAndroid Build Coastguard Worker
4002*61046927SAndroid Build Coastguard Worker
4003*61046927SAndroid Build Coastguard Worker void
_mesa_framebuffer_texture(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum attachment,struct gl_renderbuffer_attachment * att,struct gl_texture_object * texObj,GLenum textarget,GLint level,GLsizei samples,GLuint layer,GLboolean layered,GLsizei numviews)4004*61046927SAndroid Build Coastguard Worker _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
4005*61046927SAndroid Build Coastguard Worker GLenum attachment,
4006*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att,
4007*61046927SAndroid Build Coastguard Worker struct gl_texture_object *texObj, GLenum textarget,
4008*61046927SAndroid Build Coastguard Worker GLint level, GLsizei samples,
4009*61046927SAndroid Build Coastguard Worker GLuint layer, GLboolean layered, GLsizei numviews)
4010*61046927SAndroid Build Coastguard Worker {
4011*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
4012*61046927SAndroid Build Coastguard Worker
4013*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&fb->Mutex);
4014*61046927SAndroid Build Coastguard Worker if (texObj) {
4015*61046927SAndroid Build Coastguard Worker if (attachment == GL_DEPTH_ATTACHMENT &&
4016*61046927SAndroid Build Coastguard Worker texObj == fb->Attachment[BUFFER_STENCIL].Texture &&
4017*61046927SAndroid Build Coastguard Worker level == fb->Attachment[BUFFER_STENCIL].TextureLevel &&
4018*61046927SAndroid Build Coastguard Worker _mesa_tex_target_to_face(textarget) ==
4019*61046927SAndroid Build Coastguard Worker fb->Attachment[BUFFER_STENCIL].CubeMapFace &&
4020*61046927SAndroid Build Coastguard Worker samples == fb->Attachment[BUFFER_STENCIL].NumSamples &&
4021*61046927SAndroid Build Coastguard Worker layer == fb->Attachment[BUFFER_STENCIL].Zoffset) {
4022*61046927SAndroid Build Coastguard Worker /* The texture object is already attached to the stencil attachment
4023*61046927SAndroid Build Coastguard Worker * point. Don't create a new renderbuffer; just reuse the stencil
4024*61046927SAndroid Build Coastguard Worker * attachment's. This is required to prevent a GL error in
4025*61046927SAndroid Build Coastguard Worker * glGetFramebufferAttachmentParameteriv(GL_DEPTH_STENCIL).
4026*61046927SAndroid Build Coastguard Worker */
4027*61046927SAndroid Build Coastguard Worker reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH,
4028*61046927SAndroid Build Coastguard Worker BUFFER_STENCIL);
4029*61046927SAndroid Build Coastguard Worker } else if (attachment == GL_STENCIL_ATTACHMENT &&
4030*61046927SAndroid Build Coastguard Worker texObj == fb->Attachment[BUFFER_DEPTH].Texture &&
4031*61046927SAndroid Build Coastguard Worker level == fb->Attachment[BUFFER_DEPTH].TextureLevel &&
4032*61046927SAndroid Build Coastguard Worker _mesa_tex_target_to_face(textarget) ==
4033*61046927SAndroid Build Coastguard Worker fb->Attachment[BUFFER_DEPTH].CubeMapFace &&
4034*61046927SAndroid Build Coastguard Worker samples == fb->Attachment[BUFFER_DEPTH].NumSamples &&
4035*61046927SAndroid Build Coastguard Worker layer == fb->Attachment[BUFFER_DEPTH].Zoffset) {
4036*61046927SAndroid Build Coastguard Worker /* As above, but with depth and stencil transposed. */
4037*61046927SAndroid Build Coastguard Worker reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL,
4038*61046927SAndroid Build Coastguard Worker BUFFER_DEPTH);
4039*61046927SAndroid Build Coastguard Worker } else {
4040*61046927SAndroid Build Coastguard Worker set_texture_attachment(ctx, fb, att, texObj, textarget,
4041*61046927SAndroid Build Coastguard Worker level, samples, layer, layered, numviews);
4042*61046927SAndroid Build Coastguard Worker
4043*61046927SAndroid Build Coastguard Worker if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
4044*61046927SAndroid Build Coastguard Worker /* Above we created a new renderbuffer and attached it to the
4045*61046927SAndroid Build Coastguard Worker * depth attachment point. Now attach it to the stencil attachment
4046*61046927SAndroid Build Coastguard Worker * point too.
4047*61046927SAndroid Build Coastguard Worker */
4048*61046927SAndroid Build Coastguard Worker assert(att == &fb->Attachment[BUFFER_DEPTH]);
4049*61046927SAndroid Build Coastguard Worker reuse_framebuffer_texture_attachment(fb,BUFFER_STENCIL,
4050*61046927SAndroid Build Coastguard Worker BUFFER_DEPTH);
4051*61046927SAndroid Build Coastguard Worker }
4052*61046927SAndroid Build Coastguard Worker }
4053*61046927SAndroid Build Coastguard Worker
4054*61046927SAndroid Build Coastguard Worker /* Set the render-to-texture flag. We'll check this flag in
4055*61046927SAndroid Build Coastguard Worker * glTexImage() and friends to determine if we need to revalidate
4056*61046927SAndroid Build Coastguard Worker * any FBOs that might be rendering into this texture.
4057*61046927SAndroid Build Coastguard Worker * This flag never gets cleared since it's non-trivial to determine
4058*61046927SAndroid Build Coastguard Worker * when all FBOs might be done rendering to this texture. That's OK
4059*61046927SAndroid Build Coastguard Worker * though since it's uncommon to render to a texture then repeatedly
4060*61046927SAndroid Build Coastguard Worker * call glTexImage() to change images in the texture.
4061*61046927SAndroid Build Coastguard Worker */
4062*61046927SAndroid Build Coastguard Worker texObj->_RenderToTexture = GL_TRUE;
4063*61046927SAndroid Build Coastguard Worker }
4064*61046927SAndroid Build Coastguard Worker else {
4065*61046927SAndroid Build Coastguard Worker remove_attachment(ctx, att);
4066*61046927SAndroid Build Coastguard Worker if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
4067*61046927SAndroid Build Coastguard Worker assert(att == &fb->Attachment[BUFFER_DEPTH]);
4068*61046927SAndroid Build Coastguard Worker remove_attachment(ctx, &fb->Attachment[BUFFER_STENCIL]);
4069*61046927SAndroid Build Coastguard Worker }
4070*61046927SAndroid Build Coastguard Worker }
4071*61046927SAndroid Build Coastguard Worker
4072*61046927SAndroid Build Coastguard Worker invalidate_framebuffer(fb);
4073*61046927SAndroid Build Coastguard Worker
4074*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&fb->Mutex);
4075*61046927SAndroid Build Coastguard Worker }
4076*61046927SAndroid Build Coastguard Worker
4077*61046927SAndroid Build Coastguard Worker
4078*61046927SAndroid Build Coastguard Worker static void
framebuffer_texture_with_dims_no_error(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint layer)4079*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims_no_error(GLenum target, GLenum attachment,
4080*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture,
4081*61046927SAndroid Build Coastguard Worker GLint level, GLint layer)
4082*61046927SAndroid Build Coastguard Worker {
4083*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4084*61046927SAndroid Build Coastguard Worker
4085*61046927SAndroid Build Coastguard Worker /* Get the framebuffer object */
4086*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb = get_framebuffer_target(ctx, target);
4087*61046927SAndroid Build Coastguard Worker
4088*61046927SAndroid Build Coastguard Worker /* Get the texture object */
4089*61046927SAndroid Build Coastguard Worker struct gl_texture_object *texObj =
4090*61046927SAndroid Build Coastguard Worker get_texture_for_framebuffer(ctx, texture);
4091*61046927SAndroid Build Coastguard Worker
4092*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att =
4093*61046927SAndroid Build Coastguard Worker get_attachment(ctx, fb, attachment, NULL);
4094*61046927SAndroid Build Coastguard Worker
4095*61046927SAndroid Build Coastguard Worker _mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget,
4096*61046927SAndroid Build Coastguard Worker level, 0, layer, GL_FALSE, 0);
4097*61046927SAndroid Build Coastguard Worker }
4098*61046927SAndroid Build Coastguard Worker
4099*61046927SAndroid Build Coastguard Worker
4100*61046927SAndroid Build Coastguard Worker static void
framebuffer_texture_with_dims(int dims,GLenum target,GLuint framebuffer,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLsizei samples,GLint layer,const char * caller,bool dsa)4101*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims(int dims, GLenum target, GLuint framebuffer,
4102*61046927SAndroid Build Coastguard Worker GLenum attachment, GLenum textarget,
4103*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level, GLsizei samples,
4104*61046927SAndroid Build Coastguard Worker GLint layer, const char *caller, bool dsa)
4105*61046927SAndroid Build Coastguard Worker {
4106*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4107*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
4108*61046927SAndroid Build Coastguard Worker struct gl_texture_object *texObj;
4109*61046927SAndroid Build Coastguard Worker
4110*61046927SAndroid Build Coastguard Worker /* Get the framebuffer object */
4111*61046927SAndroid Build Coastguard Worker if (dsa) {
4112*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_dsa(ctx, framebuffer, caller);
4113*61046927SAndroid Build Coastguard Worker } else {
4114*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
4115*61046927SAndroid Build Coastguard Worker }
4116*61046927SAndroid Build Coastguard Worker if (!fb) {
4117*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller,
4118*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
4119*61046927SAndroid Build Coastguard Worker return;
4120*61046927SAndroid Build Coastguard Worker }
4121*61046927SAndroid Build Coastguard Worker
4122*61046927SAndroid Build Coastguard Worker /* Get the texture object */
4123*61046927SAndroid Build Coastguard Worker if (!get_texture_for_framebuffer_err(ctx, texture, false, caller, &texObj))
4124*61046927SAndroid Build Coastguard Worker return;
4125*61046927SAndroid Build Coastguard Worker
4126*61046927SAndroid Build Coastguard Worker if (texObj) {
4127*61046927SAndroid Build Coastguard Worker if (!check_textarget(ctx, dims, texObj->Target, textarget, caller))
4128*61046927SAndroid Build Coastguard Worker return;
4129*61046927SAndroid Build Coastguard Worker
4130*61046927SAndroid Build Coastguard Worker if ((dims == 3) && !check_layer(ctx, texObj->Target, layer, caller))
4131*61046927SAndroid Build Coastguard Worker return;
4132*61046927SAndroid Build Coastguard Worker
4133*61046927SAndroid Build Coastguard Worker if (!check_level(ctx, texObj, textarget, level, caller))
4134*61046927SAndroid Build Coastguard Worker return;
4135*61046927SAndroid Build Coastguard Worker }
4136*61046927SAndroid Build Coastguard Worker
4137*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att =
4138*61046927SAndroid Build Coastguard Worker _mesa_get_and_validate_attachment(ctx, fb, attachment, caller);
4139*61046927SAndroid Build Coastguard Worker if (!att)
4140*61046927SAndroid Build Coastguard Worker return;
4141*61046927SAndroid Build Coastguard Worker
4142*61046927SAndroid Build Coastguard Worker _mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget,
4143*61046927SAndroid Build Coastguard Worker level, samples, layer, GL_FALSE, 0);
4144*61046927SAndroid Build Coastguard Worker }
4145*61046927SAndroid Build Coastguard Worker
4146*61046927SAndroid Build Coastguard Worker
4147*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTexture1D_no_error(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)4148*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTexture1D_no_error(GLenum target, GLenum attachment,
4149*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture,
4150*61046927SAndroid Build Coastguard Worker GLint level)
4151*61046927SAndroid Build Coastguard Worker {
4152*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims_no_error(target, attachment, textarget,
4153*61046927SAndroid Build Coastguard Worker texture, level, 0);
4154*61046927SAndroid Build Coastguard Worker }
4155*61046927SAndroid Build Coastguard Worker
4156*61046927SAndroid Build Coastguard Worker
4157*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTexture1D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)4158*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
4159*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture, GLint level)
4160*61046927SAndroid Build Coastguard Worker {
4161*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims(1, target, 0, attachment, textarget, texture,
4162*61046927SAndroid Build Coastguard Worker level, 0, 0, "glFramebufferTexture1D", false);
4163*61046927SAndroid Build Coastguard Worker }
4164*61046927SAndroid Build Coastguard Worker
4165*61046927SAndroid Build Coastguard Worker
4166*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTexture2D_no_error(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)4167*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTexture2D_no_error(GLenum target, GLenum attachment,
4168*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture,
4169*61046927SAndroid Build Coastguard Worker GLint level)
4170*61046927SAndroid Build Coastguard Worker {
4171*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims_no_error(target, attachment, textarget,
4172*61046927SAndroid Build Coastguard Worker texture, level, 0);
4173*61046927SAndroid Build Coastguard Worker }
4174*61046927SAndroid Build Coastguard Worker
4175*61046927SAndroid Build Coastguard Worker
4176*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)4177*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
4178*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture, GLint level)
4179*61046927SAndroid Build Coastguard Worker {
4180*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims(2, target, 0, attachment, textarget, texture,
4181*61046927SAndroid Build Coastguard Worker level, 0, 0, "glFramebufferTexture2D", false);
4182*61046927SAndroid Build Coastguard Worker }
4183*61046927SAndroid Build Coastguard Worker
4184*61046927SAndroid Build Coastguard Worker
4185*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTexture2DMultisampleEXT(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLsizei samples)4186*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment,
4187*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture,
4188*61046927SAndroid Build Coastguard Worker GLint level, GLsizei samples)
4189*61046927SAndroid Build Coastguard Worker {
4190*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims(2, target, 0, attachment, textarget, texture,
4191*61046927SAndroid Build Coastguard Worker level, samples, 0,
4192*61046927SAndroid Build Coastguard Worker "glFramebufferTexture2DMultisampleEXT",
4193*61046927SAndroid Build Coastguard Worker false);
4194*61046927SAndroid Build Coastguard Worker }
4195*61046927SAndroid Build Coastguard Worker
4196*61046927SAndroid Build Coastguard Worker
4197*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTexture3D_no_error(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint layer)4198*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTexture3D_no_error(GLenum target, GLenum attachment,
4199*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture,
4200*61046927SAndroid Build Coastguard Worker GLint level, GLint layer)
4201*61046927SAndroid Build Coastguard Worker {
4202*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims_no_error(target, attachment, textarget,
4203*61046927SAndroid Build Coastguard Worker texture, level, layer);
4204*61046927SAndroid Build Coastguard Worker }
4205*61046927SAndroid Build Coastguard Worker
4206*61046927SAndroid Build Coastguard Worker
4207*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTexture3D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint layer)4208*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTexture3D(GLenum target, GLenum attachment,
4209*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture,
4210*61046927SAndroid Build Coastguard Worker GLint level, GLint layer)
4211*61046927SAndroid Build Coastguard Worker {
4212*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims(3, target, 0, attachment, textarget, texture,
4213*61046927SAndroid Build Coastguard Worker level, 0, layer, "glFramebufferTexture3D", false);
4214*61046927SAndroid Build Coastguard Worker }
4215*61046927SAndroid Build Coastguard Worker
4216*61046927SAndroid Build Coastguard Worker
4217*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
frame_buffer_texture(GLuint framebuffer,GLenum target,GLenum attachment,GLuint texture,GLint level,GLint layer,const char * func,bool dsa,bool no_error,bool check_layered,GLsizei numviews)4218*61046927SAndroid Build Coastguard Worker frame_buffer_texture(GLuint framebuffer, GLenum target,
4219*61046927SAndroid Build Coastguard Worker GLenum attachment, GLuint texture,
4220*61046927SAndroid Build Coastguard Worker GLint level, GLint layer, const char *func,
4221*61046927SAndroid Build Coastguard Worker bool dsa, bool no_error, bool check_layered, GLsizei numviews)
4222*61046927SAndroid Build Coastguard Worker {
4223*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4224*61046927SAndroid Build Coastguard Worker GLboolean layered = GL_FALSE;
4225*61046927SAndroid Build Coastguard Worker
4226*61046927SAndroid Build Coastguard Worker if (!no_error && check_layered) {
4227*61046927SAndroid Build Coastguard Worker if (!_mesa_has_geometry_shaders(ctx)) {
4228*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4229*61046927SAndroid Build Coastguard Worker "unsupported function (%s) called", func);
4230*61046927SAndroid Build Coastguard Worker return;
4231*61046927SAndroid Build Coastguard Worker }
4232*61046927SAndroid Build Coastguard Worker }
4233*61046927SAndroid Build Coastguard Worker
4234*61046927SAndroid Build Coastguard Worker /* Get the framebuffer object */
4235*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
4236*61046927SAndroid Build Coastguard Worker if (no_error) {
4237*61046927SAndroid Build Coastguard Worker if (dsa) {
4238*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer(ctx, framebuffer);
4239*61046927SAndroid Build Coastguard Worker } else {
4240*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
4241*61046927SAndroid Build Coastguard Worker }
4242*61046927SAndroid Build Coastguard Worker } else {
4243*61046927SAndroid Build Coastguard Worker if (dsa) {
4244*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, func);
4245*61046927SAndroid Build Coastguard Worker if (!fb)
4246*61046927SAndroid Build Coastguard Worker return;
4247*61046927SAndroid Build Coastguard Worker } else {
4248*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
4249*61046927SAndroid Build Coastguard Worker if (!fb) {
4250*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)",
4251*61046927SAndroid Build Coastguard Worker func, _mesa_enum_to_string(target));
4252*61046927SAndroid Build Coastguard Worker return;
4253*61046927SAndroid Build Coastguard Worker }
4254*61046927SAndroid Build Coastguard Worker }
4255*61046927SAndroid Build Coastguard Worker }
4256*61046927SAndroid Build Coastguard Worker
4257*61046927SAndroid Build Coastguard Worker /* Get the texture object and framebuffer attachment*/
4258*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att;
4259*61046927SAndroid Build Coastguard Worker struct gl_texture_object *texObj;
4260*61046927SAndroid Build Coastguard Worker if (no_error) {
4261*61046927SAndroid Build Coastguard Worker texObj = get_texture_for_framebuffer(ctx, texture);
4262*61046927SAndroid Build Coastguard Worker att = get_attachment(ctx, fb, attachment, NULL);
4263*61046927SAndroid Build Coastguard Worker } else {
4264*61046927SAndroid Build Coastguard Worker if (!get_texture_for_framebuffer_err(ctx, texture, check_layered, func,
4265*61046927SAndroid Build Coastguard Worker &texObj))
4266*61046927SAndroid Build Coastguard Worker return;
4267*61046927SAndroid Build Coastguard Worker
4268*61046927SAndroid Build Coastguard Worker att = _mesa_get_and_validate_attachment(ctx, fb, attachment, func);
4269*61046927SAndroid Build Coastguard Worker if (!att)
4270*61046927SAndroid Build Coastguard Worker return;
4271*61046927SAndroid Build Coastguard Worker }
4272*61046927SAndroid Build Coastguard Worker
4273*61046927SAndroid Build Coastguard Worker GLenum textarget = 0;
4274*61046927SAndroid Build Coastguard Worker if (texObj) {
4275*61046927SAndroid Build Coastguard Worker if (check_layered) {
4276*61046927SAndroid Build Coastguard Worker /* We do this regardless of no_error because this sets layered */
4277*61046927SAndroid Build Coastguard Worker if (!check_layered_texture_target(ctx, texObj->Target, func,
4278*61046927SAndroid Build Coastguard Worker &layered))
4279*61046927SAndroid Build Coastguard Worker return;
4280*61046927SAndroid Build Coastguard Worker }
4281*61046927SAndroid Build Coastguard Worker
4282*61046927SAndroid Build Coastguard Worker if (numviews > 1) {
4283*61046927SAndroid Build Coastguard Worker /* We do this regardless of no_error because this sets multiviews */
4284*61046927SAndroid Build Coastguard Worker if (!check_multiview_texture_target(ctx, texture, texObj->Target, level, layer, numviews, func))
4285*61046927SAndroid Build Coastguard Worker {
4286*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)",
4287*61046927SAndroid Build Coastguard Worker func, _mesa_enum_to_string(target));
4288*61046927SAndroid Build Coastguard Worker return;
4289*61046927SAndroid Build Coastguard Worker }
4290*61046927SAndroid Build Coastguard Worker }
4291*61046927SAndroid Build Coastguard Worker
4292*61046927SAndroid Build Coastguard Worker if (!no_error) {
4293*61046927SAndroid Build Coastguard Worker if (!check_layered) {
4294*61046927SAndroid Build Coastguard Worker if (!check_texture_target(ctx, texObj->Target, func))
4295*61046927SAndroid Build Coastguard Worker return;
4296*61046927SAndroid Build Coastguard Worker
4297*61046927SAndroid Build Coastguard Worker if (!check_layer(ctx, texObj->Target, layer, func))
4298*61046927SAndroid Build Coastguard Worker return;
4299*61046927SAndroid Build Coastguard Worker }
4300*61046927SAndroid Build Coastguard Worker
4301*61046927SAndroid Build Coastguard Worker if (!check_level(ctx, texObj, texObj->Target, level, func))
4302*61046927SAndroid Build Coastguard Worker return;
4303*61046927SAndroid Build Coastguard Worker }
4304*61046927SAndroid Build Coastguard Worker
4305*61046927SAndroid Build Coastguard Worker if (!check_layered && texObj->Target == GL_TEXTURE_CUBE_MAP) {
4306*61046927SAndroid Build Coastguard Worker assert(layer >= 0 && layer < 6);
4307*61046927SAndroid Build Coastguard Worker textarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
4308*61046927SAndroid Build Coastguard Worker layer = 0;
4309*61046927SAndroid Build Coastguard Worker }
4310*61046927SAndroid Build Coastguard Worker }
4311*61046927SAndroid Build Coastguard Worker
4312*61046927SAndroid Build Coastguard Worker _mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget,
4313*61046927SAndroid Build Coastguard Worker level, 0, layer, layered, numviews);
4314*61046927SAndroid Build Coastguard Worker }
4315*61046927SAndroid Build Coastguard Worker
4316*61046927SAndroid Build Coastguard Worker
4317*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTextureLayer_no_error(GLenum target,GLenum attachment,GLuint texture,GLint level,GLint layer)4318*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment,
4319*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level,
4320*61046927SAndroid Build Coastguard Worker GLint layer)
4321*61046927SAndroid Build Coastguard Worker {
4322*61046927SAndroid Build Coastguard Worker frame_buffer_texture(0, target, attachment, texture, level, layer,
4323*61046927SAndroid Build Coastguard Worker "glFramebufferTextureLayer", false, true, false, 0);
4324*61046927SAndroid Build Coastguard Worker }
4325*61046927SAndroid Build Coastguard Worker
4326*61046927SAndroid Build Coastguard Worker
4327*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTextureLayer(GLenum target,GLenum attachment,GLuint texture,GLint level,GLint layer)4328*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
4329*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level, GLint layer)
4330*61046927SAndroid Build Coastguard Worker {
4331*61046927SAndroid Build Coastguard Worker frame_buffer_texture(0, target, attachment, texture, level, layer,
4332*61046927SAndroid Build Coastguard Worker "glFramebufferTextureLayer", false, false, false, 0);
4333*61046927SAndroid Build Coastguard Worker }
4334*61046927SAndroid Build Coastguard Worker
4335*61046927SAndroid Build Coastguard Worker
4336*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferTextureLayer_no_error(GLuint framebuffer,GLenum attachment,GLuint texture,GLint level,GLint layer)4337*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferTextureLayer_no_error(GLuint framebuffer,
4338*61046927SAndroid Build Coastguard Worker GLenum attachment,
4339*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level,
4340*61046927SAndroid Build Coastguard Worker GLint layer)
4341*61046927SAndroid Build Coastguard Worker {
4342*61046927SAndroid Build Coastguard Worker frame_buffer_texture(framebuffer, 0, attachment, texture, level, layer,
4343*61046927SAndroid Build Coastguard Worker "glNamedFramebufferTextureLayer", true, true, false, 0);
4344*61046927SAndroid Build Coastguard Worker }
4345*61046927SAndroid Build Coastguard Worker
4346*61046927SAndroid Build Coastguard Worker
4347*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferTextureLayer(GLuint framebuffer,GLenum attachment,GLuint texture,GLint level,GLint layer)4348*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment,
4349*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level, GLint layer)
4350*61046927SAndroid Build Coastguard Worker {
4351*61046927SAndroid Build Coastguard Worker frame_buffer_texture(framebuffer, 0, attachment, texture, level, layer,
4352*61046927SAndroid Build Coastguard Worker "glNamedFramebufferTextureLayer", true, false, false, 0);
4353*61046927SAndroid Build Coastguard Worker }
4354*61046927SAndroid Build Coastguard Worker
4355*61046927SAndroid Build Coastguard Worker
4356*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTextureMultiviewOVR_no_error(GLenum target,GLenum attachment,GLuint texture,GLint level,GLint baseViewIndex,GLsizei numViews)4357*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTextureMultiviewOVR_no_error(GLenum target, GLenum attachment,
4358*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level,
4359*61046927SAndroid Build Coastguard Worker GLint baseViewIndex, GLsizei numViews)
4360*61046927SAndroid Build Coastguard Worker {
4361*61046927SAndroid Build Coastguard Worker frame_buffer_texture(0, target, attachment, texture, level, baseViewIndex,
4362*61046927SAndroid Build Coastguard Worker "glFramebufferTexture", false, true, false, numViews);
4363*61046927SAndroid Build Coastguard Worker }
4364*61046927SAndroid Build Coastguard Worker
4365*61046927SAndroid Build Coastguard Worker
4366*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTextureMultiviewOVR(GLenum target,GLenum attachment,GLuint texture,GLint level,GLint baseViewIndex,GLsizei numViews)4367*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTextureMultiviewOVR(GLenum target, GLenum attachment,
4368*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level,
4369*61046927SAndroid Build Coastguard Worker GLint baseViewIndex, GLsizei numViews)
4370*61046927SAndroid Build Coastguard Worker {
4371*61046927SAndroid Build Coastguard Worker frame_buffer_texture(0, target, attachment, texture, level, baseViewIndex,
4372*61046927SAndroid Build Coastguard Worker "glFramebufferTexture", false, false, false, numViews);
4373*61046927SAndroid Build Coastguard Worker }
4374*61046927SAndroid Build Coastguard Worker
4375*61046927SAndroid Build Coastguard Worker
4376*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferTextureMultiviewOVR_no_error(GLuint framebuffer,GLenum attachment,GLuint texture,GLint level,GLint baseViewIndex,GLsizei numViews)4377*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferTextureMultiviewOVR_no_error(GLuint framebuffer, GLenum attachment,
4378*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level,
4379*61046927SAndroid Build Coastguard Worker GLint baseViewIndex, GLsizei numViews)
4380*61046927SAndroid Build Coastguard Worker {
4381*61046927SAndroid Build Coastguard Worker frame_buffer_texture(framebuffer, 0, attachment, texture, level, baseViewIndex,
4382*61046927SAndroid Build Coastguard Worker "glFramebufferTexture", true, true, false, numViews);
4383*61046927SAndroid Build Coastguard Worker }
4384*61046927SAndroid Build Coastguard Worker
4385*61046927SAndroid Build Coastguard Worker
4386*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferTextureMultiviewOVR(GLuint framebuffer,GLenum attachment,GLuint texture,GLint level,GLint baseViewIndex,GLsizei numViews)4387*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferTextureMultiviewOVR(GLuint framebuffer, GLenum attachment,
4388*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level,
4389*61046927SAndroid Build Coastguard Worker GLint baseViewIndex, GLsizei numViews)
4390*61046927SAndroid Build Coastguard Worker {
4391*61046927SAndroid Build Coastguard Worker frame_buffer_texture(framebuffer, 0, attachment, texture, level, baseViewIndex,
4392*61046927SAndroid Build Coastguard Worker "glFramebufferTexture", true, false, false, numViews);
4393*61046927SAndroid Build Coastguard Worker }
4394*61046927SAndroid Build Coastguard Worker
4395*61046927SAndroid Build Coastguard Worker
4396*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTexture_no_error(GLenum target,GLenum attachment,GLuint texture,GLint level)4397*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTexture_no_error(GLenum target, GLenum attachment,
4398*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level)
4399*61046927SAndroid Build Coastguard Worker {
4400*61046927SAndroid Build Coastguard Worker frame_buffer_texture(0, target, attachment, texture, level, 0,
4401*61046927SAndroid Build Coastguard Worker "glFramebufferTexture", false, true, true, 0);
4402*61046927SAndroid Build Coastguard Worker }
4403*61046927SAndroid Build Coastguard Worker
4404*61046927SAndroid Build Coastguard Worker
4405*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferTexture(GLenum target,GLenum attachment,GLuint texture,GLint level)4406*61046927SAndroid Build Coastguard Worker _mesa_FramebufferTexture(GLenum target, GLenum attachment,
4407*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level)
4408*61046927SAndroid Build Coastguard Worker {
4409*61046927SAndroid Build Coastguard Worker frame_buffer_texture(0, target, attachment, texture, level, 0,
4410*61046927SAndroid Build Coastguard Worker "glFramebufferTexture", false, false, true, 0);
4411*61046927SAndroid Build Coastguard Worker }
4412*61046927SAndroid Build Coastguard Worker
4413*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferTexture_no_error(GLuint framebuffer,GLenum attachment,GLuint texture,GLint level)4414*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferTexture_no_error(GLuint framebuffer, GLenum attachment,
4415*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level)
4416*61046927SAndroid Build Coastguard Worker {
4417*61046927SAndroid Build Coastguard Worker frame_buffer_texture(framebuffer, 0, attachment, texture, level, 0,
4418*61046927SAndroid Build Coastguard Worker "glNamedFramebufferTexture", true, true, true, 0);
4419*61046927SAndroid Build Coastguard Worker }
4420*61046927SAndroid Build Coastguard Worker
4421*61046927SAndroid Build Coastguard Worker
4422*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferTexture(GLuint framebuffer,GLenum attachment,GLuint texture,GLint level)4423*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment,
4424*61046927SAndroid Build Coastguard Worker GLuint texture, GLint level)
4425*61046927SAndroid Build Coastguard Worker {
4426*61046927SAndroid Build Coastguard Worker frame_buffer_texture(framebuffer, 0, attachment, texture, level, 0,
4427*61046927SAndroid Build Coastguard Worker "glNamedFramebufferTexture", true, false, true, 0);
4428*61046927SAndroid Build Coastguard Worker }
4429*61046927SAndroid Build Coastguard Worker
4430*61046927SAndroid Build Coastguard Worker
4431*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferTexture1DEXT(GLuint framebuffer,GLenum attachment,GLenum textarget,GLuint texture,GLint level)4432*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment,
4433*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture, GLint level)
4434*61046927SAndroid Build Coastguard Worker {
4435*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims(1, GL_FRAMEBUFFER, framebuffer, attachment,
4436*61046927SAndroid Build Coastguard Worker textarget, texture, level, 0, 0,
4437*61046927SAndroid Build Coastguard Worker "glNamedFramebufferTexture1DEXT", true);
4438*61046927SAndroid Build Coastguard Worker }
4439*61046927SAndroid Build Coastguard Worker
4440*61046927SAndroid Build Coastguard Worker
4441*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferTexture2DEXT(GLuint framebuffer,GLenum attachment,GLenum textarget,GLuint texture,GLint level)4442*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment,
4443*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture, GLint level)
4444*61046927SAndroid Build Coastguard Worker {
4445*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims(2, GL_FRAMEBUFFER, framebuffer, attachment,
4446*61046927SAndroid Build Coastguard Worker textarget, texture, level, 0, 0,
4447*61046927SAndroid Build Coastguard Worker "glNamedFramebufferTexture2DEXT", true);
4448*61046927SAndroid Build Coastguard Worker }
4449*61046927SAndroid Build Coastguard Worker
4450*61046927SAndroid Build Coastguard Worker
4451*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferTexture3DEXT(GLuint framebuffer,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint zoffset)4452*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment,
4453*61046927SAndroid Build Coastguard Worker GLenum textarget, GLuint texture,
4454*61046927SAndroid Build Coastguard Worker GLint level, GLint zoffset)
4455*61046927SAndroid Build Coastguard Worker {
4456*61046927SAndroid Build Coastguard Worker framebuffer_texture_with_dims(3, GL_FRAMEBUFFER, framebuffer, attachment,
4457*61046927SAndroid Build Coastguard Worker textarget, texture, level, 0, zoffset,
4458*61046927SAndroid Build Coastguard Worker "glNamedFramebufferTexture3DEXT", true);
4459*61046927SAndroid Build Coastguard Worker }
4460*61046927SAndroid Build Coastguard Worker
4461*61046927SAndroid Build Coastguard Worker
4462*61046927SAndroid Build Coastguard Worker void
_mesa_framebuffer_renderbuffer(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum attachment,struct gl_renderbuffer * rb)4463*61046927SAndroid Build Coastguard Worker _mesa_framebuffer_renderbuffer(struct gl_context *ctx,
4464*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
4465*61046927SAndroid Build Coastguard Worker GLenum attachment,
4466*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb)
4467*61046927SAndroid Build Coastguard Worker {
4468*61046927SAndroid Build Coastguard Worker assert(!_mesa_is_winsys_fbo(fb));
4469*61046927SAndroid Build Coastguard Worker
4470*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
4471*61046927SAndroid Build Coastguard Worker
4472*61046927SAndroid Build Coastguard Worker _mesa_FramebufferRenderbuffer_sw(ctx, fb, attachment, rb);
4473*61046927SAndroid Build Coastguard Worker
4474*61046927SAndroid Build Coastguard Worker /* Some subsequent GL commands may depend on the framebuffer's visual
4475*61046927SAndroid Build Coastguard Worker * after the binding is updated. Update visual info now.
4476*61046927SAndroid Build Coastguard Worker */
4477*61046927SAndroid Build Coastguard Worker _mesa_update_framebuffer_visual(ctx, fb);
4478*61046927SAndroid Build Coastguard Worker }
4479*61046927SAndroid Build Coastguard Worker
4480*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
framebuffer_renderbuffer(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer,const char * func,bool no_error)4481*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
4482*61046927SAndroid Build Coastguard Worker GLenum attachment, GLenum renderbuffertarget,
4483*61046927SAndroid Build Coastguard Worker GLuint renderbuffer, const char *func, bool no_error)
4484*61046927SAndroid Build Coastguard Worker {
4485*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att;
4486*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb;
4487*61046927SAndroid Build Coastguard Worker bool is_color_attachment;
4488*61046927SAndroid Build Coastguard Worker
4489*61046927SAndroid Build Coastguard Worker if (!no_error && renderbuffertarget != GL_RENDERBUFFER) {
4490*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
4491*61046927SAndroid Build Coastguard Worker "%s(renderbuffertarget is not GL_RENDERBUFFER)", func);
4492*61046927SAndroid Build Coastguard Worker return;
4493*61046927SAndroid Build Coastguard Worker }
4494*61046927SAndroid Build Coastguard Worker
4495*61046927SAndroid Build Coastguard Worker if (renderbuffer) {
4496*61046927SAndroid Build Coastguard Worker if (!no_error) {
4497*61046927SAndroid Build Coastguard Worker rb = _mesa_lookup_renderbuffer_err(ctx, renderbuffer, func);
4498*61046927SAndroid Build Coastguard Worker if (!rb)
4499*61046927SAndroid Build Coastguard Worker return;
4500*61046927SAndroid Build Coastguard Worker } else {
4501*61046927SAndroid Build Coastguard Worker rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
4502*61046927SAndroid Build Coastguard Worker }
4503*61046927SAndroid Build Coastguard Worker } else {
4504*61046927SAndroid Build Coastguard Worker /* remove renderbuffer attachment */
4505*61046927SAndroid Build Coastguard Worker rb = NULL;
4506*61046927SAndroid Build Coastguard Worker }
4507*61046927SAndroid Build Coastguard Worker
4508*61046927SAndroid Build Coastguard Worker if (!no_error) {
4509*61046927SAndroid Build Coastguard Worker if (_mesa_is_winsys_fbo(fb)) {
4510*61046927SAndroid Build Coastguard Worker /* Can't attach new renderbuffers to a window system framebuffer */
4511*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4512*61046927SAndroid Build Coastguard Worker "%s(window-system framebuffer)", func);
4513*61046927SAndroid Build Coastguard Worker return;
4514*61046927SAndroid Build Coastguard Worker }
4515*61046927SAndroid Build Coastguard Worker
4516*61046927SAndroid Build Coastguard Worker att = get_attachment(ctx, fb, attachment, &is_color_attachment);
4517*61046927SAndroid Build Coastguard Worker if (att == NULL) {
4518*61046927SAndroid Build Coastguard Worker /*
4519*61046927SAndroid Build Coastguard Worker * From OpenGL 4.5 spec, section 9.2.7 "Attaching Renderbuffer Images
4520*61046927SAndroid Build Coastguard Worker * to a Framebuffer":
4521*61046927SAndroid Build Coastguard Worker *
4522*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if attachment is
4523*61046927SAndroid Build Coastguard Worker * COLOR_- ATTACHMENTm where m is greater than or equal to the
4524*61046927SAndroid Build Coastguard Worker * value of MAX_COLOR_- ATTACHMENTS ."
4525*61046927SAndroid Build Coastguard Worker *
4526*61046927SAndroid Build Coastguard Worker * If we are at this point, is because the attachment is not valid, so
4527*61046927SAndroid Build Coastguard Worker * if is_color_attachment is true, is because of the previous reason.
4528*61046927SAndroid Build Coastguard Worker */
4529*61046927SAndroid Build Coastguard Worker if (is_color_attachment) {
4530*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4531*61046927SAndroid Build Coastguard Worker "%s(invalid color attachment %s)", func,
4532*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(attachment));
4533*61046927SAndroid Build Coastguard Worker } else {
4534*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
4535*61046927SAndroid Build Coastguard Worker "%s(invalid attachment %s)", func,
4536*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(attachment));
4537*61046927SAndroid Build Coastguard Worker }
4538*61046927SAndroid Build Coastguard Worker
4539*61046927SAndroid Build Coastguard Worker return;
4540*61046927SAndroid Build Coastguard Worker }
4541*61046927SAndroid Build Coastguard Worker
4542*61046927SAndroid Build Coastguard Worker if (attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
4543*61046927SAndroid Build Coastguard Worker rb && rb->Format != MESA_FORMAT_NONE) {
4544*61046927SAndroid Build Coastguard Worker /* make sure the renderbuffer is a depth/stencil format */
4545*61046927SAndroid Build Coastguard Worker const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
4546*61046927SAndroid Build Coastguard Worker if (baseFormat != GL_DEPTH_STENCIL) {
4547*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4548*61046927SAndroid Build Coastguard Worker "%s(renderbuffer is not DEPTH_STENCIL format)", func);
4549*61046927SAndroid Build Coastguard Worker return;
4550*61046927SAndroid Build Coastguard Worker }
4551*61046927SAndroid Build Coastguard Worker }
4552*61046927SAndroid Build Coastguard Worker }
4553*61046927SAndroid Build Coastguard Worker
4554*61046927SAndroid Build Coastguard Worker _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
4555*61046927SAndroid Build Coastguard Worker }
4556*61046927SAndroid Build Coastguard Worker
4557*61046927SAndroid Build Coastguard Worker static void
framebuffer_renderbuffer_error(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer,const char * func)4558*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer_error(struct gl_context *ctx,
4559*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb, GLenum attachment,
4560*61046927SAndroid Build Coastguard Worker GLenum renderbuffertarget,
4561*61046927SAndroid Build Coastguard Worker GLuint renderbuffer, const char *func)
4562*61046927SAndroid Build Coastguard Worker {
4563*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer(ctx, fb, attachment, renderbuffertarget,
4564*61046927SAndroid Build Coastguard Worker renderbuffer, func, false);
4565*61046927SAndroid Build Coastguard Worker }
4566*61046927SAndroid Build Coastguard Worker
4567*61046927SAndroid Build Coastguard Worker static void
framebuffer_renderbuffer_no_error(struct gl_context * ctx,struct gl_framebuffer * fb,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer,const char * func)4568*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer_no_error(struct gl_context *ctx,
4569*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb, GLenum attachment,
4570*61046927SAndroid Build Coastguard Worker GLenum renderbuffertarget,
4571*61046927SAndroid Build Coastguard Worker GLuint renderbuffer, const char *func)
4572*61046927SAndroid Build Coastguard Worker {
4573*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer(ctx, fb, attachment, renderbuffertarget,
4574*61046927SAndroid Build Coastguard Worker renderbuffer, func, true);
4575*61046927SAndroid Build Coastguard Worker }
4576*61046927SAndroid Build Coastguard Worker
4577*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferRenderbuffer_no_error(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)4578*61046927SAndroid Build Coastguard Worker _mesa_FramebufferRenderbuffer_no_error(GLenum target, GLenum attachment,
4579*61046927SAndroid Build Coastguard Worker GLenum renderbuffertarget,
4580*61046927SAndroid Build Coastguard Worker GLuint renderbuffer)
4581*61046927SAndroid Build Coastguard Worker {
4582*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4583*61046927SAndroid Build Coastguard Worker
4584*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb = get_framebuffer_target(ctx, target);
4585*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer_no_error(ctx, fb, attachment, renderbuffertarget,
4586*61046927SAndroid Build Coastguard Worker renderbuffer, "glFramebufferRenderbuffer");
4587*61046927SAndroid Build Coastguard Worker }
4588*61046927SAndroid Build Coastguard Worker
4589*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)4590*61046927SAndroid Build Coastguard Worker _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
4591*61046927SAndroid Build Coastguard Worker GLenum renderbuffertarget,
4592*61046927SAndroid Build Coastguard Worker GLuint renderbuffer)
4593*61046927SAndroid Build Coastguard Worker {
4594*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
4595*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4596*61046927SAndroid Build Coastguard Worker
4597*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
4598*61046927SAndroid Build Coastguard Worker if (!fb) {
4599*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
4600*61046927SAndroid Build Coastguard Worker "glFramebufferRenderbuffer(invalid target %s)",
4601*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
4602*61046927SAndroid Build Coastguard Worker return;
4603*61046927SAndroid Build Coastguard Worker }
4604*61046927SAndroid Build Coastguard Worker
4605*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer_error(ctx, fb, attachment, renderbuffertarget,
4606*61046927SAndroid Build Coastguard Worker renderbuffer, "glFramebufferRenderbuffer");
4607*61046927SAndroid Build Coastguard Worker }
4608*61046927SAndroid Build Coastguard Worker
4609*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferRenderbuffer_no_error(GLuint framebuffer,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)4610*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferRenderbuffer_no_error(GLuint framebuffer,
4611*61046927SAndroid Build Coastguard Worker GLenum attachment,
4612*61046927SAndroid Build Coastguard Worker GLenum renderbuffertarget,
4613*61046927SAndroid Build Coastguard Worker GLuint renderbuffer)
4614*61046927SAndroid Build Coastguard Worker {
4615*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4616*61046927SAndroid Build Coastguard Worker
4617*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb = _mesa_lookup_framebuffer(ctx, framebuffer);
4618*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer_no_error(ctx, fb, attachment, renderbuffertarget,
4619*61046927SAndroid Build Coastguard Worker renderbuffer,
4620*61046927SAndroid Build Coastguard Worker "glNamedFramebufferRenderbuffer");
4621*61046927SAndroid Build Coastguard Worker }
4622*61046927SAndroid Build Coastguard Worker
4623*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferRenderbuffer(GLuint framebuffer,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)4624*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment,
4625*61046927SAndroid Build Coastguard Worker GLenum renderbuffertarget,
4626*61046927SAndroid Build Coastguard Worker GLuint renderbuffer)
4627*61046927SAndroid Build Coastguard Worker {
4628*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
4629*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4630*61046927SAndroid Build Coastguard Worker
4631*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
4632*61046927SAndroid Build Coastguard Worker "glNamedFramebufferRenderbuffer");
4633*61046927SAndroid Build Coastguard Worker if (!fb)
4634*61046927SAndroid Build Coastguard Worker return;
4635*61046927SAndroid Build Coastguard Worker
4636*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer_error(ctx, fb, attachment, renderbuffertarget,
4637*61046927SAndroid Build Coastguard Worker renderbuffer,
4638*61046927SAndroid Build Coastguard Worker "glNamedFramebufferRenderbuffer");
4639*61046927SAndroid Build Coastguard Worker }
4640*61046927SAndroid Build Coastguard Worker
4641*61046927SAndroid Build Coastguard Worker
4642*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferRenderbufferEXT(GLuint framebuffer,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)4643*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment,
4644*61046927SAndroid Build Coastguard Worker GLenum renderbuffertarget,
4645*61046927SAndroid Build Coastguard Worker GLuint renderbuffer)
4646*61046927SAndroid Build Coastguard Worker {
4647*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
4648*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4649*61046927SAndroid Build Coastguard Worker
4650*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_dsa(ctx, framebuffer,
4651*61046927SAndroid Build Coastguard Worker "glNamedFramebufferRenderbufferEXT");
4652*61046927SAndroid Build Coastguard Worker if (!fb)
4653*61046927SAndroid Build Coastguard Worker return;
4654*61046927SAndroid Build Coastguard Worker
4655*61046927SAndroid Build Coastguard Worker framebuffer_renderbuffer_error(ctx, fb, attachment, renderbuffertarget,
4656*61046927SAndroid Build Coastguard Worker renderbuffer,
4657*61046927SAndroid Build Coastguard Worker "glNamedFramebufferRenderbuffer");
4658*61046927SAndroid Build Coastguard Worker }
4659*61046927SAndroid Build Coastguard Worker
4660*61046927SAndroid Build Coastguard Worker
4661*61046927SAndroid Build Coastguard Worker static void
get_framebuffer_attachment_parameter(struct gl_context * ctx,struct gl_framebuffer * buffer,GLenum attachment,GLenum pname,GLint * params,const char * caller)4662*61046927SAndroid Build Coastguard Worker get_framebuffer_attachment_parameter(struct gl_context *ctx,
4663*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *buffer,
4664*61046927SAndroid Build Coastguard Worker GLenum attachment, GLenum pname,
4665*61046927SAndroid Build Coastguard Worker GLint *params, const char *caller)
4666*61046927SAndroid Build Coastguard Worker {
4667*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *att;
4668*61046927SAndroid Build Coastguard Worker bool is_color_attachment = false;
4669*61046927SAndroid Build Coastguard Worker GLenum err;
4670*61046927SAndroid Build Coastguard Worker
4671*61046927SAndroid Build Coastguard Worker /* The error code for an attachment type of GL_NONE differs between APIs.
4672*61046927SAndroid Build Coastguard Worker *
4673*61046927SAndroid Build Coastguard Worker * From the ES 2.0.25 specification, page 127:
4674*61046927SAndroid Build Coastguard Worker * "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, then
4675*61046927SAndroid Build Coastguard Worker * querying any other pname will generate INVALID_ENUM."
4676*61046927SAndroid Build Coastguard Worker *
4677*61046927SAndroid Build Coastguard Worker * From the OpenGL 3.0 specification, page 337, or identically,
4678*61046927SAndroid Build Coastguard Worker * the OpenGL ES 3.0.4 specification, page 240:
4679*61046927SAndroid Build Coastguard Worker *
4680*61046927SAndroid Build Coastguard Worker * "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, no
4681*61046927SAndroid Build Coastguard Worker * framebuffer is bound to target. In this case querying pname
4682*61046927SAndroid Build Coastguard Worker * FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero, and all other
4683*61046927SAndroid Build Coastguard Worker * queries will generate an INVALID_OPERATION error."
4684*61046927SAndroid Build Coastguard Worker */
4685*61046927SAndroid Build Coastguard Worker err = _mesa_is_gles2(ctx) && ctx->Version < 30 ?
4686*61046927SAndroid Build Coastguard Worker GL_INVALID_ENUM : GL_INVALID_OPERATION;
4687*61046927SAndroid Build Coastguard Worker
4688*61046927SAndroid Build Coastguard Worker if (_mesa_is_winsys_fbo(buffer)) {
4689*61046927SAndroid Build Coastguard Worker /* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec
4690*61046927SAndroid Build Coastguard Worker * says:
4691*61046927SAndroid Build Coastguard Worker *
4692*61046927SAndroid Build Coastguard Worker * "If the framebuffer currently bound to target is zero, then
4693*61046927SAndroid Build Coastguard Worker * INVALID_OPERATION is generated."
4694*61046927SAndroid Build Coastguard Worker *
4695*61046927SAndroid Build Coastguard Worker * The EXT_framebuffer_object spec has the same wording, and the
4696*61046927SAndroid Build Coastguard Worker * OES_framebuffer_object spec refers to the EXT_framebuffer_object
4697*61046927SAndroid Build Coastguard Worker * spec.
4698*61046927SAndroid Build Coastguard Worker */
4699*61046927SAndroid Build Coastguard Worker if ((!_mesa_is_desktop_gl(ctx) ||
4700*61046927SAndroid Build Coastguard Worker !ctx->Extensions.ARB_framebuffer_object)
4701*61046927SAndroid Build Coastguard Worker && !_mesa_is_gles3(ctx)) {
4702*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4703*61046927SAndroid Build Coastguard Worker "%s(window-system framebuffer)", caller);
4704*61046927SAndroid Build Coastguard Worker return;
4705*61046927SAndroid Build Coastguard Worker }
4706*61046927SAndroid Build Coastguard Worker
4707*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles3(ctx) && attachment != GL_BACK &&
4708*61046927SAndroid Build Coastguard Worker attachment != GL_DEPTH && attachment != GL_STENCIL) {
4709*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
4710*61046927SAndroid Build Coastguard Worker "%s(invalid attachment %s)", caller,
4711*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(attachment));
4712*61046927SAndroid Build Coastguard Worker return;
4713*61046927SAndroid Build Coastguard Worker }
4714*61046927SAndroid Build Coastguard Worker
4715*61046927SAndroid Build Coastguard Worker /* The specs are not clear about how to handle
4716*61046927SAndroid Build Coastguard Worker * GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME with the default framebuffer,
4717*61046927SAndroid Build Coastguard Worker * but dEQP-GLES3 expects an INVALID_ENUM error. This has also been
4718*61046927SAndroid Build Coastguard Worker * discussed in:
4719*61046927SAndroid Build Coastguard Worker *
4720*61046927SAndroid Build Coastguard Worker * https://cvs.khronos.org/bugzilla/show_bug.cgi?id=12928#c1
4721*61046927SAndroid Build Coastguard Worker * and https://bugs.freedesktop.org/show_bug.cgi?id=31947
4722*61046927SAndroid Build Coastguard Worker */
4723*61046927SAndroid Build Coastguard Worker if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
4724*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
4725*61046927SAndroid Build Coastguard Worker "%s(requesting GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME "
4726*61046927SAndroid Build Coastguard Worker "when GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is "
4727*61046927SAndroid Build Coastguard Worker "GL_FRAMEBUFFER_DEFAULT is not allowed)", caller);
4728*61046927SAndroid Build Coastguard Worker return;
4729*61046927SAndroid Build Coastguard Worker }
4730*61046927SAndroid Build Coastguard Worker
4731*61046927SAndroid Build Coastguard Worker /* the default / window-system FBO */
4732*61046927SAndroid Build Coastguard Worker att = get_fb0_attachment(ctx, buffer, attachment);
4733*61046927SAndroid Build Coastguard Worker }
4734*61046927SAndroid Build Coastguard Worker else {
4735*61046927SAndroid Build Coastguard Worker /* user-created framebuffer FBO */
4736*61046927SAndroid Build Coastguard Worker att = get_attachment(ctx, buffer, attachment, &is_color_attachment);
4737*61046927SAndroid Build Coastguard Worker }
4738*61046927SAndroid Build Coastguard Worker
4739*61046927SAndroid Build Coastguard Worker if (att == NULL) {
4740*61046927SAndroid Build Coastguard Worker /*
4741*61046927SAndroid Build Coastguard Worker * From OpenGL 4.5 spec, section 9.2.3 "Framebuffer Object Queries":
4742*61046927SAndroid Build Coastguard Worker *
4743*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if a framebuffer object
4744*61046927SAndroid Build Coastguard Worker * is bound to target and attachment is COLOR_ATTACHMENTm where m is
4745*61046927SAndroid Build Coastguard Worker * greater than or equal to the value of MAX_COLOR_ATTACHMENTS."
4746*61046927SAndroid Build Coastguard Worker *
4747*61046927SAndroid Build Coastguard Worker * If we are at this point, is because the attachment is not valid, so
4748*61046927SAndroid Build Coastguard Worker * if is_color_attachment is true, is because of the previous reason.
4749*61046927SAndroid Build Coastguard Worker */
4750*61046927SAndroid Build Coastguard Worker if (is_color_attachment) {
4751*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid color attachment %s)",
4752*61046927SAndroid Build Coastguard Worker caller, _mesa_enum_to_string(attachment));
4753*61046927SAndroid Build Coastguard Worker } else {
4754*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", caller,
4755*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(attachment));
4756*61046927SAndroid Build Coastguard Worker }
4757*61046927SAndroid Build Coastguard Worker return;
4758*61046927SAndroid Build Coastguard Worker }
4759*61046927SAndroid Build Coastguard Worker
4760*61046927SAndroid Build Coastguard Worker if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
4761*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer_attachment *depthAtt, *stencilAtt;
4762*61046927SAndroid Build Coastguard Worker if (pname == GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE) {
4763*61046927SAndroid Build Coastguard Worker /* This behavior is first specified in OpenGL 4.4 specification.
4764*61046927SAndroid Build Coastguard Worker *
4765*61046927SAndroid Build Coastguard Worker * From the OpenGL 4.4 spec page 275:
4766*61046927SAndroid Build Coastguard Worker * "This query cannot be performed for a combined depth+stencil
4767*61046927SAndroid Build Coastguard Worker * attachment, since it does not have a single format."
4768*61046927SAndroid Build Coastguard Worker */
4769*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4770*61046927SAndroid Build Coastguard Worker "%s(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"
4771*61046927SAndroid Build Coastguard Worker " is invalid for depth+stencil attachment)", caller);
4772*61046927SAndroid Build Coastguard Worker return;
4773*61046927SAndroid Build Coastguard Worker }
4774*61046927SAndroid Build Coastguard Worker /* the depth and stencil attachments must point to the same buffer */
4775*61046927SAndroid Build Coastguard Worker depthAtt = get_attachment(ctx, buffer, GL_DEPTH_ATTACHMENT, NULL);
4776*61046927SAndroid Build Coastguard Worker stencilAtt = get_attachment(ctx, buffer, GL_STENCIL_ATTACHMENT, NULL);
4777*61046927SAndroid Build Coastguard Worker if (depthAtt->Renderbuffer != stencilAtt->Renderbuffer) {
4778*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4779*61046927SAndroid Build Coastguard Worker "%s(DEPTH/STENCIL attachments differ)", caller);
4780*61046927SAndroid Build Coastguard Worker return;
4781*61046927SAndroid Build Coastguard Worker }
4782*61046927SAndroid Build Coastguard Worker }
4783*61046927SAndroid Build Coastguard Worker
4784*61046927SAndroid Build Coastguard Worker /* No need to flush here */
4785*61046927SAndroid Build Coastguard Worker
4786*61046927SAndroid Build Coastguard Worker switch (pname) {
4787*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
4788*61046927SAndroid Build Coastguard Worker /* From the OpenGL spec, 9.2. Binding and Managing Framebuffer Objects:
4789*61046927SAndroid Build Coastguard Worker *
4790*61046927SAndroid Build Coastguard Worker * "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, then
4791*61046927SAndroid Build Coastguard Worker * either no framebuffer is bound to target; or the default framebuffer
4792*61046927SAndroid Build Coastguard Worker * is bound, attachment is DEPTH or STENCIL, and the number of depth or
4793*61046927SAndroid Build Coastguard Worker * stencil bits, respectively, is zero."
4794*61046927SAndroid Build Coastguard Worker *
4795*61046927SAndroid Build Coastguard Worker * Note that we don't need explicit checks on DEPTH and STENCIL, because
4796*61046927SAndroid Build Coastguard Worker * on the case the spec is pointing, att->Type is already NONE, so we
4797*61046927SAndroid Build Coastguard Worker * just need to check att->Type.
4798*61046927SAndroid Build Coastguard Worker */
4799*61046927SAndroid Build Coastguard Worker *params = (_mesa_is_winsys_fbo(buffer) && att->Type != GL_NONE) ?
4800*61046927SAndroid Build Coastguard Worker GL_FRAMEBUFFER_DEFAULT : att->Type;
4801*61046927SAndroid Build Coastguard Worker return;
4802*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
4803*61046927SAndroid Build Coastguard Worker if (att->Type == GL_RENDERBUFFER_EXT) {
4804*61046927SAndroid Build Coastguard Worker *params = att->Renderbuffer->Name;
4805*61046927SAndroid Build Coastguard Worker }
4806*61046927SAndroid Build Coastguard Worker else if (att->Type == GL_TEXTURE) {
4807*61046927SAndroid Build Coastguard Worker *params = att->Texture->Name;
4808*61046927SAndroid Build Coastguard Worker }
4809*61046927SAndroid Build Coastguard Worker else {
4810*61046927SAndroid Build Coastguard Worker assert(att->Type == GL_NONE);
4811*61046927SAndroid Build Coastguard Worker if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
4812*61046927SAndroid Build Coastguard Worker *params = 0;
4813*61046927SAndroid Build Coastguard Worker } else {
4814*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4815*61046927SAndroid Build Coastguard Worker }
4816*61046927SAndroid Build Coastguard Worker }
4817*61046927SAndroid Build Coastguard Worker return;
4818*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
4819*61046927SAndroid Build Coastguard Worker if (att->Type == GL_TEXTURE) {
4820*61046927SAndroid Build Coastguard Worker *params = att->TextureLevel;
4821*61046927SAndroid Build Coastguard Worker }
4822*61046927SAndroid Build Coastguard Worker else if (att->Type == GL_NONE) {
4823*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
4824*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
4825*61046927SAndroid Build Coastguard Worker }
4826*61046927SAndroid Build Coastguard Worker else {
4827*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4828*61046927SAndroid Build Coastguard Worker }
4829*61046927SAndroid Build Coastguard Worker return;
4830*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
4831*61046927SAndroid Build Coastguard Worker if (att->Type == GL_TEXTURE) {
4832*61046927SAndroid Build Coastguard Worker if (att->Texture && att->Texture->Target == GL_TEXTURE_CUBE_MAP) {
4833*61046927SAndroid Build Coastguard Worker *params = GL_TEXTURE_CUBE_MAP_POSITIVE_X + att->CubeMapFace;
4834*61046927SAndroid Build Coastguard Worker }
4835*61046927SAndroid Build Coastguard Worker else {
4836*61046927SAndroid Build Coastguard Worker *params = 0;
4837*61046927SAndroid Build Coastguard Worker }
4838*61046927SAndroid Build Coastguard Worker }
4839*61046927SAndroid Build Coastguard Worker else if (att->Type == GL_NONE) {
4840*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
4841*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
4842*61046927SAndroid Build Coastguard Worker }
4843*61046927SAndroid Build Coastguard Worker else {
4844*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4845*61046927SAndroid Build Coastguard Worker }
4846*61046927SAndroid Build Coastguard Worker return;
4847*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
4848*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles1(ctx)) {
4849*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4850*61046927SAndroid Build Coastguard Worker } else if (att->Type == GL_NONE) {
4851*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
4852*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
4853*61046927SAndroid Build Coastguard Worker } else if (att->Type == GL_TEXTURE) {
4854*61046927SAndroid Build Coastguard Worker if (att->Texture && (att->Texture->Target == GL_TEXTURE_3D ||
4855*61046927SAndroid Build Coastguard Worker att->Texture->Target == GL_TEXTURE_2D_ARRAY)) {
4856*61046927SAndroid Build Coastguard Worker *params = att->Zoffset;
4857*61046927SAndroid Build Coastguard Worker }
4858*61046927SAndroid Build Coastguard Worker else {
4859*61046927SAndroid Build Coastguard Worker *params = 0;
4860*61046927SAndroid Build Coastguard Worker }
4861*61046927SAndroid Build Coastguard Worker }
4862*61046927SAndroid Build Coastguard Worker else {
4863*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4864*61046927SAndroid Build Coastguard Worker }
4865*61046927SAndroid Build Coastguard Worker return;
4866*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
4867*61046927SAndroid Build Coastguard Worker if ((!_mesa_is_desktop_gl(ctx) ||
4868*61046927SAndroid Build Coastguard Worker !ctx->Extensions.ARB_framebuffer_object)
4869*61046927SAndroid Build Coastguard Worker && !_mesa_is_gles3(ctx)) {
4870*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4871*61046927SAndroid Build Coastguard Worker }
4872*61046927SAndroid Build Coastguard Worker else if (att->Type == GL_NONE) {
4873*61046927SAndroid Build Coastguard Worker if (_mesa_is_winsys_fbo(buffer) &&
4874*61046927SAndroid Build Coastguard Worker (attachment == GL_DEPTH || attachment == GL_STENCIL)) {
4875*61046927SAndroid Build Coastguard Worker *params = GL_LINEAR;
4876*61046927SAndroid Build Coastguard Worker } else {
4877*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
4878*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
4879*61046927SAndroid Build Coastguard Worker }
4880*61046927SAndroid Build Coastguard Worker }
4881*61046927SAndroid Build Coastguard Worker else {
4882*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.EXT_sRGB) {
4883*61046927SAndroid Build Coastguard Worker *params = (_mesa_is_format_srgb(att->Renderbuffer->Format) ?
4884*61046927SAndroid Build Coastguard Worker GL_SRGB : GL_LINEAR);
4885*61046927SAndroid Build Coastguard Worker }
4886*61046927SAndroid Build Coastguard Worker else {
4887*61046927SAndroid Build Coastguard Worker /* According to ARB_framebuffer_sRGB, we should return LINEAR
4888*61046927SAndroid Build Coastguard Worker * if the sRGB conversion is unsupported. */
4889*61046927SAndroid Build Coastguard Worker *params = GL_LINEAR;
4890*61046927SAndroid Build Coastguard Worker }
4891*61046927SAndroid Build Coastguard Worker }
4892*61046927SAndroid Build Coastguard Worker return;
4893*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4894*61046927SAndroid Build Coastguard Worker if ((ctx->API != API_OPENGL_COMPAT ||
4895*61046927SAndroid Build Coastguard Worker !ctx->Extensions.ARB_framebuffer_object)
4896*61046927SAndroid Build Coastguard Worker && ctx->API != API_OPENGL_CORE
4897*61046927SAndroid Build Coastguard Worker && !_mesa_is_gles3(ctx)) {
4898*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4899*61046927SAndroid Build Coastguard Worker }
4900*61046927SAndroid Build Coastguard Worker else if (att->Type == GL_NONE) {
4901*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
4902*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
4903*61046927SAndroid Build Coastguard Worker }
4904*61046927SAndroid Build Coastguard Worker else {
4905*61046927SAndroid Build Coastguard Worker mesa_format format = att->Renderbuffer->Format;
4906*61046927SAndroid Build Coastguard Worker
4907*61046927SAndroid Build Coastguard Worker /* Page 235 (page 247 of the PDF) in section 6.1.13 of the OpenGL ES
4908*61046927SAndroid Build Coastguard Worker * 3.0.1 spec says:
4909*61046927SAndroid Build Coastguard Worker *
4910*61046927SAndroid Build Coastguard Worker * "If pname is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE.... If
4911*61046927SAndroid Build Coastguard Worker * attachment is DEPTH_STENCIL_ATTACHMENT the query will fail and
4912*61046927SAndroid Build Coastguard Worker * generate an INVALID_OPERATION error.
4913*61046927SAndroid Build Coastguard Worker */
4914*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles3(ctx) &&
4915*61046927SAndroid Build Coastguard Worker attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
4916*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4917*61046927SAndroid Build Coastguard Worker "%s(cannot query "
4918*61046927SAndroid Build Coastguard Worker "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE of "
4919*61046927SAndroid Build Coastguard Worker "GL_DEPTH_STENCIL_ATTACHMENT)", caller);
4920*61046927SAndroid Build Coastguard Worker return;
4921*61046927SAndroid Build Coastguard Worker }
4922*61046927SAndroid Build Coastguard Worker
4923*61046927SAndroid Build Coastguard Worker if (format == MESA_FORMAT_S_UINT8) {
4924*61046927SAndroid Build Coastguard Worker /* special cases */
4925*61046927SAndroid Build Coastguard Worker *params = GL_INDEX;
4926*61046927SAndroid Build Coastguard Worker }
4927*61046927SAndroid Build Coastguard Worker else if (format == MESA_FORMAT_Z32_FLOAT_S8X24_UINT) {
4928*61046927SAndroid Build Coastguard Worker /* depends on the attachment parameter */
4929*61046927SAndroid Build Coastguard Worker if (attachment == GL_STENCIL_ATTACHMENT) {
4930*61046927SAndroid Build Coastguard Worker *params = GL_INDEX;
4931*61046927SAndroid Build Coastguard Worker }
4932*61046927SAndroid Build Coastguard Worker else {
4933*61046927SAndroid Build Coastguard Worker *params = GL_FLOAT;
4934*61046927SAndroid Build Coastguard Worker }
4935*61046927SAndroid Build Coastguard Worker }
4936*61046927SAndroid Build Coastguard Worker else {
4937*61046927SAndroid Build Coastguard Worker *params = _mesa_get_format_datatype(format);
4938*61046927SAndroid Build Coastguard Worker }
4939*61046927SAndroid Build Coastguard Worker }
4940*61046927SAndroid Build Coastguard Worker return;
4941*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
4942*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
4943*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
4944*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
4945*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
4946*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
4947*61046927SAndroid Build Coastguard Worker if ((!_mesa_is_desktop_gl(ctx) ||
4948*61046927SAndroid Build Coastguard Worker !ctx->Extensions.ARB_framebuffer_object)
4949*61046927SAndroid Build Coastguard Worker && !_mesa_is_gles3(ctx)) {
4950*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4951*61046927SAndroid Build Coastguard Worker }
4952*61046927SAndroid Build Coastguard Worker else if (att->Texture) {
4953*61046927SAndroid Build Coastguard Worker const struct gl_texture_image *texImage =
4954*61046927SAndroid Build Coastguard Worker _mesa_select_tex_image(att->Texture, att->Texture->Target,
4955*61046927SAndroid Build Coastguard Worker att->TextureLevel);
4956*61046927SAndroid Build Coastguard Worker if (texImage) {
4957*61046927SAndroid Build Coastguard Worker *params = get_component_bits(pname, texImage->_BaseFormat,
4958*61046927SAndroid Build Coastguard Worker texImage->TexFormat);
4959*61046927SAndroid Build Coastguard Worker }
4960*61046927SAndroid Build Coastguard Worker else {
4961*61046927SAndroid Build Coastguard Worker *params = 0;
4962*61046927SAndroid Build Coastguard Worker }
4963*61046927SAndroid Build Coastguard Worker }
4964*61046927SAndroid Build Coastguard Worker else if (att->Renderbuffer) {
4965*61046927SAndroid Build Coastguard Worker *params = get_component_bits(pname, att->Renderbuffer->_BaseFormat,
4966*61046927SAndroid Build Coastguard Worker att->Renderbuffer->Format);
4967*61046927SAndroid Build Coastguard Worker }
4968*61046927SAndroid Build Coastguard Worker else {
4969*61046927SAndroid Build Coastguard Worker assert(att->Type == GL_NONE);
4970*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
4971*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
4972*61046927SAndroid Build Coastguard Worker }
4973*61046927SAndroid Build Coastguard Worker return;
4974*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_LAYERED:
4975*61046927SAndroid Build Coastguard Worker if (!_mesa_has_geometry_shaders(ctx)) {
4976*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4977*61046927SAndroid Build Coastguard Worker } else if (att->Type == GL_TEXTURE) {
4978*61046927SAndroid Build Coastguard Worker *params = att->Layered;
4979*61046927SAndroid Build Coastguard Worker } else if (att->Type == GL_NONE) {
4980*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
4981*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
4982*61046927SAndroid Build Coastguard Worker } else {
4983*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4984*61046927SAndroid Build Coastguard Worker }
4985*61046927SAndroid Build Coastguard Worker return;
4986*61046927SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
4987*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.EXT_multisampled_render_to_texture) {
4988*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4989*61046927SAndroid Build Coastguard Worker } else if (att->Type == GL_TEXTURE) {
4990*61046927SAndroid Build Coastguard Worker *params = att->NumSamples;
4991*61046927SAndroid Build Coastguard Worker } else if (att->Type == GL_NONE) {
4992*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
4993*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
4994*61046927SAndroid Build Coastguard Worker } else {
4995*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
4996*61046927SAndroid Build Coastguard Worker }
4997*61046927SAndroid Build Coastguard Worker return;
4998*61046927SAndroid Build Coastguard Worker default:
4999*61046927SAndroid Build Coastguard Worker goto invalid_pname_enum;
5000*61046927SAndroid Build Coastguard Worker }
5001*61046927SAndroid Build Coastguard Worker
5002*61046927SAndroid Build Coastguard Worker return;
5003*61046927SAndroid Build Coastguard Worker
5004*61046927SAndroid Build Coastguard Worker invalid_pname_enum:
5005*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname %s)", caller,
5006*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
5007*61046927SAndroid Build Coastguard Worker return;
5008*61046927SAndroid Build Coastguard Worker }
5009*61046927SAndroid Build Coastguard Worker
5010*61046927SAndroid Build Coastguard Worker
5011*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)5012*61046927SAndroid Build Coastguard Worker _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
5013*61046927SAndroid Build Coastguard Worker GLenum pname, GLint *params)
5014*61046927SAndroid Build Coastguard Worker {
5015*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5016*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *buffer;
5017*61046927SAndroid Build Coastguard Worker
5018*61046927SAndroid Build Coastguard Worker buffer = get_framebuffer_target(ctx, target);
5019*61046927SAndroid Build Coastguard Worker if (!buffer) {
5020*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
5021*61046927SAndroid Build Coastguard Worker "glGetFramebufferAttachmentParameteriv(invalid target %s)",
5022*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
5023*61046927SAndroid Build Coastguard Worker return;
5024*61046927SAndroid Build Coastguard Worker }
5025*61046927SAndroid Build Coastguard Worker
5026*61046927SAndroid Build Coastguard Worker get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname,
5027*61046927SAndroid Build Coastguard Worker params,
5028*61046927SAndroid Build Coastguard Worker "glGetFramebufferAttachmentParameteriv");
5029*61046927SAndroid Build Coastguard Worker }
5030*61046927SAndroid Build Coastguard Worker
5031*61046927SAndroid Build Coastguard Worker
5032*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer,GLenum attachment,GLenum pname,GLint * params)5033*61046927SAndroid Build Coastguard Worker _mesa_GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer,
5034*61046927SAndroid Build Coastguard Worker GLenum attachment,
5035*61046927SAndroid Build Coastguard Worker GLenum pname, GLint *params)
5036*61046927SAndroid Build Coastguard Worker {
5037*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5038*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *buffer;
5039*61046927SAndroid Build Coastguard Worker
5040*61046927SAndroid Build Coastguard Worker if (framebuffer) {
5041*61046927SAndroid Build Coastguard Worker buffer = _mesa_lookup_framebuffer_err(ctx, framebuffer,
5042*61046927SAndroid Build Coastguard Worker "glGetNamedFramebufferAttachmentParameteriv");
5043*61046927SAndroid Build Coastguard Worker if (!buffer)
5044*61046927SAndroid Build Coastguard Worker return;
5045*61046927SAndroid Build Coastguard Worker }
5046*61046927SAndroid Build Coastguard Worker else {
5047*61046927SAndroid Build Coastguard Worker /*
5048*61046927SAndroid Build Coastguard Worker * Section 9.2 Binding and Managing Framebuffer Objects of the OpenGL
5049*61046927SAndroid Build Coastguard Worker * 4.5 core spec (30.10.2014, PDF page 314):
5050*61046927SAndroid Build Coastguard Worker * "If framebuffer is zero, then the default draw framebuffer is
5051*61046927SAndroid Build Coastguard Worker * queried."
5052*61046927SAndroid Build Coastguard Worker */
5053*61046927SAndroid Build Coastguard Worker buffer = ctx->WinSysDrawBuffer;
5054*61046927SAndroid Build Coastguard Worker }
5055*61046927SAndroid Build Coastguard Worker
5056*61046927SAndroid Build Coastguard Worker get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname,
5057*61046927SAndroid Build Coastguard Worker params,
5058*61046927SAndroid Build Coastguard Worker "glGetNamedFramebufferAttachmentParameteriv");
5059*61046927SAndroid Build Coastguard Worker }
5060*61046927SAndroid Build Coastguard Worker
5061*61046927SAndroid Build Coastguard Worker
5062*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer,GLenum attachment,GLenum pname,GLint * params)5063*61046927SAndroid Build Coastguard Worker _mesa_GetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer,
5064*61046927SAndroid Build Coastguard Worker GLenum attachment,
5065*61046927SAndroid Build Coastguard Worker GLenum pname, GLint *params)
5066*61046927SAndroid Build Coastguard Worker {
5067*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5068*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *buffer;
5069*61046927SAndroid Build Coastguard Worker
5070*61046927SAndroid Build Coastguard Worker if (framebuffer) {
5071*61046927SAndroid Build Coastguard Worker buffer = _mesa_lookup_framebuffer_dsa(ctx, framebuffer,
5072*61046927SAndroid Build Coastguard Worker "glGetNamedFramebufferAttachmentParameterivEXT");
5073*61046927SAndroid Build Coastguard Worker if (!buffer)
5074*61046927SAndroid Build Coastguard Worker return;
5075*61046927SAndroid Build Coastguard Worker }
5076*61046927SAndroid Build Coastguard Worker else {
5077*61046927SAndroid Build Coastguard Worker /*
5078*61046927SAndroid Build Coastguard Worker * Section 9.2 Binding and Managing Framebuffer Objects of the OpenGL
5079*61046927SAndroid Build Coastguard Worker * 4.5 core spec (30.10.2014, PDF page 314):
5080*61046927SAndroid Build Coastguard Worker * "If framebuffer is zero, then the default draw framebuffer is
5081*61046927SAndroid Build Coastguard Worker * queried."
5082*61046927SAndroid Build Coastguard Worker */
5083*61046927SAndroid Build Coastguard Worker buffer = ctx->WinSysDrawBuffer;
5084*61046927SAndroid Build Coastguard Worker }
5085*61046927SAndroid Build Coastguard Worker
5086*61046927SAndroid Build Coastguard Worker get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname,
5087*61046927SAndroid Build Coastguard Worker params,
5088*61046927SAndroid Build Coastguard Worker "glGetNamedFramebufferAttachmentParameterivEXT");
5089*61046927SAndroid Build Coastguard Worker }
5090*61046927SAndroid Build Coastguard Worker
5091*61046927SAndroid Build Coastguard Worker
5092*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferParameteri(GLuint framebuffer,GLenum pname,GLint param)5093*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferParameteri(GLuint framebuffer, GLenum pname,
5094*61046927SAndroid Build Coastguard Worker GLint param)
5095*61046927SAndroid Build Coastguard Worker {
5096*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5097*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb = NULL;
5098*61046927SAndroid Build Coastguard Worker
5099*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_framebuffer_no_attachments &&
5100*61046927SAndroid Build Coastguard Worker !ctx->Extensions.ARB_sample_locations) {
5101*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
5102*61046927SAndroid Build Coastguard Worker "glNamedFramebufferParameteri("
5103*61046927SAndroid Build Coastguard Worker "neither ARB_framebuffer_no_attachments nor "
5104*61046927SAndroid Build Coastguard Worker "ARB_sample_locations is available)");
5105*61046927SAndroid Build Coastguard Worker return;
5106*61046927SAndroid Build Coastguard Worker }
5107*61046927SAndroid Build Coastguard Worker
5108*61046927SAndroid Build Coastguard Worker if (framebuffer) {
5109*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
5110*61046927SAndroid Build Coastguard Worker "glNamedFramebufferParameteri");
5111*61046927SAndroid Build Coastguard Worker } else {
5112*61046927SAndroid Build Coastguard Worker fb = ctx->WinSysDrawBuffer;
5113*61046927SAndroid Build Coastguard Worker }
5114*61046927SAndroid Build Coastguard Worker
5115*61046927SAndroid Build Coastguard Worker if (fb) {
5116*61046927SAndroid Build Coastguard Worker framebuffer_parameteri(ctx, fb, pname, param,
5117*61046927SAndroid Build Coastguard Worker "glNamedFramebufferParameteriv");
5118*61046927SAndroid Build Coastguard Worker }
5119*61046927SAndroid Build Coastguard Worker }
5120*61046927SAndroid Build Coastguard Worker
5121*61046927SAndroid Build Coastguard Worker
5122*61046927SAndroid Build Coastguard Worker /* Helper function for ARB_framebuffer_no_attachments functions interacting with EXT_direct_state_access */
5123*61046927SAndroid Build Coastguard Worker static struct gl_framebuffer *
lookup_named_framebuffer_ext_dsa(struct gl_context * ctx,GLuint framebuffer,const char * caller)5124*61046927SAndroid Build Coastguard Worker lookup_named_framebuffer_ext_dsa(struct gl_context *ctx, GLuint framebuffer, const char* caller)
5125*61046927SAndroid Build Coastguard Worker {
5126*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb = NULL;
5127*61046927SAndroid Build Coastguard Worker
5128*61046927SAndroid Build Coastguard Worker if (framebuffer) {
5129*61046927SAndroid Build Coastguard Worker /* The ARB_framebuffer_no_attachments spec says:
5130*61046927SAndroid Build Coastguard Worker *
5131*61046927SAndroid Build Coastguard Worker * "The error INVALID_VALUE is generated if <framebuffer> is not
5132*61046927SAndroid Build Coastguard Worker * a name returned by GenFramebuffers. If a framebuffer object
5133*61046927SAndroid Build Coastguard Worker * named <framebuffer> does not yet exist, it will be created."
5134*61046927SAndroid Build Coastguard Worker *
5135*61046927SAndroid Build Coastguard Worker * This is different from the EXT_direct_state_access spec which says:
5136*61046927SAndroid Build Coastguard Worker *
5137*61046927SAndroid Build Coastguard Worker * "If the framebuffer object named by the framebuffer parameter has not
5138*61046927SAndroid Build Coastguard Worker * been previously bound or has been deleted since the last binding,
5139*61046927SAndroid Build Coastguard Worker * the GL first creates a new state vector in the same manner as when
5140*61046927SAndroid Build Coastguard Worker * BindFramebuffer creates a new framebuffer object"
5141*61046927SAndroid Build Coastguard Worker *
5142*61046927SAndroid Build Coastguard Worker * So first we verify that the name exists.
5143*61046927SAndroid Build Coastguard Worker */
5144*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer(ctx, framebuffer);
5145*61046927SAndroid Build Coastguard Worker if (!fb) {
5146*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(frameBuffer)", caller);
5147*61046927SAndroid Build Coastguard Worker return NULL;
5148*61046927SAndroid Build Coastguard Worker }
5149*61046927SAndroid Build Coastguard Worker /* Then, make sure it's initialized */
5150*61046927SAndroid Build Coastguard Worker if (fb == &DummyFramebuffer) {
5151*61046927SAndroid Build Coastguard Worker fb = _mesa_new_framebuffer(ctx, framebuffer);
5152*61046927SAndroid Build Coastguard Worker _mesa_HashInsert(&ctx->Shared->FrameBuffers, framebuffer, fb);
5153*61046927SAndroid Build Coastguard Worker }
5154*61046927SAndroid Build Coastguard Worker }
5155*61046927SAndroid Build Coastguard Worker else
5156*61046927SAndroid Build Coastguard Worker fb = ctx->WinSysDrawBuffer;
5157*61046927SAndroid Build Coastguard Worker
5158*61046927SAndroid Build Coastguard Worker return fb;
5159*61046927SAndroid Build Coastguard Worker }
5160*61046927SAndroid Build Coastguard Worker
5161*61046927SAndroid Build Coastguard Worker
5162*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferParameteriEXT(GLuint framebuffer,GLenum pname,GLint param)5163*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferParameteriEXT(GLuint framebuffer, GLenum pname,
5164*61046927SAndroid Build Coastguard Worker GLint param)
5165*61046927SAndroid Build Coastguard Worker {
5166*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5167*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb =
5168*61046927SAndroid Build Coastguard Worker lookup_named_framebuffer_ext_dsa(ctx, framebuffer,
5169*61046927SAndroid Build Coastguard Worker "glNamedFramebufferParameteriEXT");
5170*61046927SAndroid Build Coastguard Worker
5171*61046927SAndroid Build Coastguard Worker if (!fb)
5172*61046927SAndroid Build Coastguard Worker return;
5173*61046927SAndroid Build Coastguard Worker
5174*61046927SAndroid Build Coastguard Worker framebuffer_parameteri(ctx, fb, pname, param,
5175*61046927SAndroid Build Coastguard Worker "glNamedFramebufferParameteriEXT");
5176*61046927SAndroid Build Coastguard Worker }
5177*61046927SAndroid Build Coastguard Worker
5178*61046927SAndroid Build Coastguard Worker
5179*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetFramebufferParameterivEXT(GLuint framebuffer,GLenum pname,GLint * param)5180*61046927SAndroid Build Coastguard Worker _mesa_GetFramebufferParameterivEXT(GLuint framebuffer, GLenum pname,
5181*61046927SAndroid Build Coastguard Worker GLint *param)
5182*61046927SAndroid Build Coastguard Worker {
5183*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5184*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5185*61046927SAndroid Build Coastguard Worker
5186*61046927SAndroid Build Coastguard Worker if (framebuffer)
5187*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_dsa(ctx, framebuffer,
5188*61046927SAndroid Build Coastguard Worker "glGetFramebufferParameterivEXT");
5189*61046927SAndroid Build Coastguard Worker else
5190*61046927SAndroid Build Coastguard Worker fb = ctx->WinSysDrawBuffer;
5191*61046927SAndroid Build Coastguard Worker
5192*61046927SAndroid Build Coastguard Worker if (fb) {
5193*61046927SAndroid Build Coastguard Worker /* The GL_EXT_direct_state_access says:
5194*61046927SAndroid Build Coastguard Worker *
5195*61046927SAndroid Build Coastguard Worker * The pname parameter must be one of framebuffer dependent values
5196*61046927SAndroid Build Coastguard Worker * listed in either table 4.nnn (namely DRAW_BUFFER, READ_BUFFER,
5197*61046927SAndroid Build Coastguard Worker * or DRAW_BUFFER0 through DRAW_BUFFER15).
5198*61046927SAndroid Build Coastguard Worker */
5199*61046927SAndroid Build Coastguard Worker if (pname == GL_DRAW_BUFFER) {
5200*61046927SAndroid Build Coastguard Worker *param = fb->ColorDrawBuffer[0];
5201*61046927SAndroid Build Coastguard Worker
5202*61046927SAndroid Build Coastguard Worker }
5203*61046927SAndroid Build Coastguard Worker else if (pname == GL_READ_BUFFER) {
5204*61046927SAndroid Build Coastguard Worker *param = fb->ColorReadBuffer;
5205*61046927SAndroid Build Coastguard Worker }
5206*61046927SAndroid Build Coastguard Worker else if (GL_DRAW_BUFFER0 <= pname && pname <= GL_DRAW_BUFFER15) {
5207*61046927SAndroid Build Coastguard Worker unsigned buffer = pname - GL_DRAW_BUFFER0;
5208*61046927SAndroid Build Coastguard Worker if (buffer < ARRAY_SIZE(fb->ColorDrawBuffer))
5209*61046927SAndroid Build Coastguard Worker *param = fb->ColorDrawBuffer[buffer];
5210*61046927SAndroid Build Coastguard Worker else
5211*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetFramebufferParameterivEXT(pname)");
5212*61046927SAndroid Build Coastguard Worker }
5213*61046927SAndroid Build Coastguard Worker else {
5214*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetFramebufferParameterivEXT(pname)");
5215*61046927SAndroid Build Coastguard Worker }
5216*61046927SAndroid Build Coastguard Worker }
5217*61046927SAndroid Build Coastguard Worker }
5218*61046927SAndroid Build Coastguard Worker
5219*61046927SAndroid Build Coastguard Worker
5220*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedFramebufferParameteriv(GLuint framebuffer,GLenum pname,GLint * param)5221*61046927SAndroid Build Coastguard Worker _mesa_GetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname,
5222*61046927SAndroid Build Coastguard Worker GLint *param)
5223*61046927SAndroid Build Coastguard Worker {
5224*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5225*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5226*61046927SAndroid Build Coastguard Worker
5227*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
5228*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
5229*61046927SAndroid Build Coastguard Worker "glNamedFramebufferParameteriv("
5230*61046927SAndroid Build Coastguard Worker "neither ARB_framebuffer_no_attachments nor ARB_sample_locations"
5231*61046927SAndroid Build Coastguard Worker " is available)");
5232*61046927SAndroid Build Coastguard Worker return;
5233*61046927SAndroid Build Coastguard Worker }
5234*61046927SAndroid Build Coastguard Worker
5235*61046927SAndroid Build Coastguard Worker if (framebuffer)
5236*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
5237*61046927SAndroid Build Coastguard Worker "glGetNamedFramebufferParameteriv");
5238*61046927SAndroid Build Coastguard Worker else
5239*61046927SAndroid Build Coastguard Worker fb = ctx->WinSysDrawBuffer;
5240*61046927SAndroid Build Coastguard Worker
5241*61046927SAndroid Build Coastguard Worker if (fb) {
5242*61046927SAndroid Build Coastguard Worker get_framebuffer_parameteriv(ctx, fb, pname, param,
5243*61046927SAndroid Build Coastguard Worker "glGetNamedFramebufferParameteriv");
5244*61046927SAndroid Build Coastguard Worker }
5245*61046927SAndroid Build Coastguard Worker }
5246*61046927SAndroid Build Coastguard Worker
5247*61046927SAndroid Build Coastguard Worker
5248*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedFramebufferParameterivEXT(GLuint framebuffer,GLenum pname,GLint * param)5249*61046927SAndroid Build Coastguard Worker _mesa_GetNamedFramebufferParameterivEXT(GLuint framebuffer, GLenum pname,
5250*61046927SAndroid Build Coastguard Worker GLint *param)
5251*61046927SAndroid Build Coastguard Worker {
5252*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5253*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb =
5254*61046927SAndroid Build Coastguard Worker lookup_named_framebuffer_ext_dsa(ctx, framebuffer,
5255*61046927SAndroid Build Coastguard Worker "glGetNamedFramebufferParameterivEXT");
5256*61046927SAndroid Build Coastguard Worker
5257*61046927SAndroid Build Coastguard Worker if (!fb)
5258*61046927SAndroid Build Coastguard Worker return;
5259*61046927SAndroid Build Coastguard Worker
5260*61046927SAndroid Build Coastguard Worker get_framebuffer_parameteriv(ctx, fb, pname, param,
5261*61046927SAndroid Build Coastguard Worker "glGetNamedFramebufferParameterivEXT");
5262*61046927SAndroid Build Coastguard Worker }
5263*61046927SAndroid Build Coastguard Worker
5264*61046927SAndroid Build Coastguard Worker
5265*61046927SAndroid Build Coastguard Worker static void
invalidate_framebuffer_storage(struct gl_context * ctx,struct gl_framebuffer * fb,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height,const char * name)5266*61046927SAndroid Build Coastguard Worker invalidate_framebuffer_storage(struct gl_context *ctx,
5267*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
5268*61046927SAndroid Build Coastguard Worker GLsizei numAttachments,
5269*61046927SAndroid Build Coastguard Worker const GLenum *attachments, GLint x, GLint y,
5270*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height, const char *name)
5271*61046927SAndroid Build Coastguard Worker {
5272*61046927SAndroid Build Coastguard Worker int i;
5273*61046927SAndroid Build Coastguard Worker
5274*61046927SAndroid Build Coastguard Worker /* Section 17.4 Whole Framebuffer Operations of the OpenGL 4.5 Core
5275*61046927SAndroid Build Coastguard Worker * Spec (2.2.2015, PDF page 522) says:
5276*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated if numAttachments, width, or
5277*61046927SAndroid Build Coastguard Worker * height is negative."
5278*61046927SAndroid Build Coastguard Worker */
5279*61046927SAndroid Build Coastguard Worker if (numAttachments < 0) {
5280*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
5281*61046927SAndroid Build Coastguard Worker "%s(numAttachments < 0)", name);
5282*61046927SAndroid Build Coastguard Worker return;
5283*61046927SAndroid Build Coastguard Worker }
5284*61046927SAndroid Build Coastguard Worker
5285*61046927SAndroid Build Coastguard Worker if (width < 0) {
5286*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
5287*61046927SAndroid Build Coastguard Worker "%s(width < 0)", name);
5288*61046927SAndroid Build Coastguard Worker return;
5289*61046927SAndroid Build Coastguard Worker }
5290*61046927SAndroid Build Coastguard Worker
5291*61046927SAndroid Build Coastguard Worker if (height < 0) {
5292*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
5293*61046927SAndroid Build Coastguard Worker "%s(height < 0)", name);
5294*61046927SAndroid Build Coastguard Worker return;
5295*61046927SAndroid Build Coastguard Worker }
5296*61046927SAndroid Build Coastguard Worker
5297*61046927SAndroid Build Coastguard Worker /* The GL_ARB_invalidate_subdata spec says:
5298*61046927SAndroid Build Coastguard Worker *
5299*61046927SAndroid Build Coastguard Worker * "If an attachment is specified that does not exist in the
5300*61046927SAndroid Build Coastguard Worker * framebuffer bound to <target>, it is ignored."
5301*61046927SAndroid Build Coastguard Worker *
5302*61046927SAndroid Build Coastguard Worker * It also says:
5303*61046927SAndroid Build Coastguard Worker *
5304*61046927SAndroid Build Coastguard Worker * "If <attachments> contains COLOR_ATTACHMENTm and m is greater than
5305*61046927SAndroid Build Coastguard Worker * or equal to the value of MAX_COLOR_ATTACHMENTS, then the error
5306*61046927SAndroid Build Coastguard Worker * INVALID_OPERATION is generated."
5307*61046927SAndroid Build Coastguard Worker *
5308*61046927SAndroid Build Coastguard Worker * No mention is made of GL_AUXi being out of range. Therefore, we allow
5309*61046927SAndroid Build Coastguard Worker * any enum that can be allowed by the API (OpenGL ES 3.0 has a different
5310*61046927SAndroid Build Coastguard Worker * set of retrictions).
5311*61046927SAndroid Build Coastguard Worker */
5312*61046927SAndroid Build Coastguard Worker for (i = 0; i < numAttachments; i++) {
5313*61046927SAndroid Build Coastguard Worker if (_mesa_is_winsys_fbo(fb)) {
5314*61046927SAndroid Build Coastguard Worker switch (attachments[i]) {
5315*61046927SAndroid Build Coastguard Worker case GL_ACCUM:
5316*61046927SAndroid Build Coastguard Worker case GL_AUX0:
5317*61046927SAndroid Build Coastguard Worker case GL_AUX1:
5318*61046927SAndroid Build Coastguard Worker case GL_AUX2:
5319*61046927SAndroid Build Coastguard Worker case GL_AUX3:
5320*61046927SAndroid Build Coastguard Worker /* Accumulation buffers and auxilary buffers were removed in
5321*61046927SAndroid Build Coastguard Worker * OpenGL 3.1, and they never existed in OpenGL ES.
5322*61046927SAndroid Build Coastguard Worker */
5323*61046927SAndroid Build Coastguard Worker if (ctx->API != API_OPENGL_COMPAT)
5324*61046927SAndroid Build Coastguard Worker goto invalid_enum;
5325*61046927SAndroid Build Coastguard Worker break;
5326*61046927SAndroid Build Coastguard Worker case GL_COLOR:
5327*61046927SAndroid Build Coastguard Worker case GL_DEPTH:
5328*61046927SAndroid Build Coastguard Worker case GL_STENCIL:
5329*61046927SAndroid Build Coastguard Worker break;
5330*61046927SAndroid Build Coastguard Worker case GL_BACK_LEFT:
5331*61046927SAndroid Build Coastguard Worker case GL_BACK_RIGHT:
5332*61046927SAndroid Build Coastguard Worker case GL_FRONT_LEFT:
5333*61046927SAndroid Build Coastguard Worker case GL_FRONT_RIGHT:
5334*61046927SAndroid Build Coastguard Worker if (!_mesa_is_desktop_gl(ctx))
5335*61046927SAndroid Build Coastguard Worker goto invalid_enum;
5336*61046927SAndroid Build Coastguard Worker break;
5337*61046927SAndroid Build Coastguard Worker default:
5338*61046927SAndroid Build Coastguard Worker goto invalid_enum;
5339*61046927SAndroid Build Coastguard Worker }
5340*61046927SAndroid Build Coastguard Worker } else {
5341*61046927SAndroid Build Coastguard Worker switch (attachments[i]) {
5342*61046927SAndroid Build Coastguard Worker case GL_DEPTH_ATTACHMENT:
5343*61046927SAndroid Build Coastguard Worker case GL_STENCIL_ATTACHMENT:
5344*61046927SAndroid Build Coastguard Worker break;
5345*61046927SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_ATTACHMENT:
5346*61046927SAndroid Build Coastguard Worker /* GL_DEPTH_STENCIL_ATTACHMENT is a valid attachment point only
5347*61046927SAndroid Build Coastguard Worker * in desktop and ES 3.0 profiles. Note that OES_packed_depth_stencil
5348*61046927SAndroid Build Coastguard Worker * extension does not make this attachment point valid on ES 2.0.
5349*61046927SAndroid Build Coastguard Worker */
5350*61046927SAndroid Build Coastguard Worker if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx))
5351*61046927SAndroid Build Coastguard Worker break;
5352*61046927SAndroid Build Coastguard Worker FALLTHROUGH;
5353*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT0:
5354*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT1:
5355*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT2:
5356*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT3:
5357*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT4:
5358*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT5:
5359*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT6:
5360*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT7:
5361*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT8:
5362*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT9:
5363*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT10:
5364*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT11:
5365*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT12:
5366*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT13:
5367*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT14:
5368*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT15: {
5369*61046927SAndroid Build Coastguard Worker unsigned k = attachments[i] - GL_COLOR_ATTACHMENT0;
5370*61046927SAndroid Build Coastguard Worker if (k >= ctx->Const.MaxColorAttachments) {
5371*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
5372*61046927SAndroid Build Coastguard Worker "%s(attachment >= max. color attachments)", name);
5373*61046927SAndroid Build Coastguard Worker return;
5374*61046927SAndroid Build Coastguard Worker }
5375*61046927SAndroid Build Coastguard Worker break;
5376*61046927SAndroid Build Coastguard Worker }
5377*61046927SAndroid Build Coastguard Worker default:
5378*61046927SAndroid Build Coastguard Worker goto invalid_enum;
5379*61046927SAndroid Build Coastguard Worker }
5380*61046927SAndroid Build Coastguard Worker }
5381*61046927SAndroid Build Coastguard Worker }
5382*61046927SAndroid Build Coastguard Worker
5383*61046927SAndroid Build Coastguard Worker /* We don't actually do anything for this yet. Just return after
5384*61046927SAndroid Build Coastguard Worker * validating the parameters and generating the required errors.
5385*61046927SAndroid Build Coastguard Worker */
5386*61046927SAndroid Build Coastguard Worker return;
5387*61046927SAndroid Build Coastguard Worker
5388*61046927SAndroid Build Coastguard Worker invalid_enum:
5389*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", name,
5390*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(attachments[i]));
5391*61046927SAndroid Build Coastguard Worker return;
5392*61046927SAndroid Build Coastguard Worker }
5393*61046927SAndroid Build Coastguard Worker
5394*61046927SAndroid Build Coastguard Worker static gl_buffer_index
get_fb_attachment_index(struct gl_context * ctx,struct gl_framebuffer * fb,const GLenum attachment)5395*61046927SAndroid Build Coastguard Worker get_fb_attachment_index(struct gl_context *ctx, struct gl_framebuffer *fb,
5396*61046927SAndroid Build Coastguard Worker const GLenum attachment)
5397*61046927SAndroid Build Coastguard Worker {
5398*61046927SAndroid Build Coastguard Worker switch (attachment) {
5399*61046927SAndroid Build Coastguard Worker case GL_COLOR:
5400*61046927SAndroid Build Coastguard Worker return BUFFER_BACK_LEFT;
5401*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT0:
5402*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT1:
5403*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT2:
5404*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT3:
5405*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT4:
5406*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT5:
5407*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT6:
5408*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT7:
5409*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT8:
5410*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT9:
5411*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT10:
5412*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT11:
5413*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT12:
5414*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT13:
5415*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT14:
5416*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT15: {
5417*61046927SAndroid Build Coastguard Worker const unsigned i = attachment - GL_COLOR_ATTACHMENT0;
5418*61046927SAndroid Build Coastguard Worker if (i >= ctx->Const.MaxColorAttachments)
5419*61046927SAndroid Build Coastguard Worker return BUFFER_NONE;
5420*61046927SAndroid Build Coastguard Worker assert(BUFFER_COLOR0 + i < ARRAY_SIZE(fb->Attachment));
5421*61046927SAndroid Build Coastguard Worker return BUFFER_COLOR0 + i;
5422*61046927SAndroid Build Coastguard Worker }
5423*61046927SAndroid Build Coastguard Worker case GL_DEPTH:
5424*61046927SAndroid Build Coastguard Worker case GL_DEPTH_ATTACHMENT:
5425*61046927SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_ATTACHMENT:
5426*61046927SAndroid Build Coastguard Worker return BUFFER_DEPTH;
5427*61046927SAndroid Build Coastguard Worker case GL_STENCIL:
5428*61046927SAndroid Build Coastguard Worker case GL_STENCIL_ATTACHMENT:
5429*61046927SAndroid Build Coastguard Worker return BUFFER_STENCIL;
5430*61046927SAndroid Build Coastguard Worker default:
5431*61046927SAndroid Build Coastguard Worker return BUFFER_NONE;
5432*61046927SAndroid Build Coastguard Worker }
5433*61046927SAndroid Build Coastguard Worker }
5434*61046927SAndroid Build Coastguard Worker
5435*61046927SAndroid Build Coastguard Worker static void
do_discard_framebuffer(struct gl_context * ctx,struct gl_framebuffer * fb,struct gl_renderbuffer_attachment * att)5436*61046927SAndroid Build Coastguard Worker do_discard_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
5437*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att)
5438*61046927SAndroid Build Coastguard Worker {
5439*61046927SAndroid Build Coastguard Worker struct pipe_resource *prsc;
5440*61046927SAndroid Build Coastguard Worker
5441*61046927SAndroid Build Coastguard Worker if (!att->Renderbuffer || !att->Complete)
5442*61046927SAndroid Build Coastguard Worker return;
5443*61046927SAndroid Build Coastguard Worker
5444*61046927SAndroid Build Coastguard Worker prsc = att->Renderbuffer->surface->texture;
5445*61046927SAndroid Build Coastguard Worker
5446*61046927SAndroid Build Coastguard Worker /* using invalidate_resource will only work for simple 2D resources */
5447*61046927SAndroid Build Coastguard Worker if (prsc->depth0 != 1 || prsc->array_size != 1 || prsc->last_level != 0)
5448*61046927SAndroid Build Coastguard Worker return;
5449*61046927SAndroid Build Coastguard Worker
5450*61046927SAndroid Build Coastguard Worker if (ctx->pipe->invalidate_resource)
5451*61046927SAndroid Build Coastguard Worker ctx->pipe->invalidate_resource(ctx->pipe, prsc);
5452*61046927SAndroid Build Coastguard Worker }
5453*61046927SAndroid Build Coastguard Worker
5454*61046927SAndroid Build Coastguard Worker static void
discard_attachments(struct gl_context * ctx,struct gl_framebuffer * fb,uint32_t mask)5455*61046927SAndroid Build Coastguard Worker discard_attachments(struct gl_context *ctx, struct gl_framebuffer *fb,
5456*61046927SAndroid Build Coastguard Worker uint32_t mask)
5457*61046927SAndroid Build Coastguard Worker {
5458*61046927SAndroid Build Coastguard Worker const uint32_t zsmask = BITFIELD_BIT(BUFFER_DEPTH) | BITFIELD_BIT(BUFFER_STENCIL);
5459*61046927SAndroid Build Coastguard Worker
5460*61046927SAndroid Build Coastguard Worker /* If we're asked to invalidate just depth or just stencil, but the
5461*61046927SAndroid Build Coastguard Worker * attachment is packed depth/stencil, then we can only use
5462*61046927SAndroid Build Coastguard Worker * DiscardFramebuffer if the attachments list includes both depth
5463*61046927SAndroid Build Coastguard Worker * and stencil and they both point at the same renderbuffer.
5464*61046927SAndroid Build Coastguard Worker *
5465*61046927SAndroid Build Coastguard Worker * Note EXT_discard_framebuffer says that discarding only one component
5466*61046927SAndroid Build Coastguard Worker * of a packed z/s implicitly discards both. But glInvalidateFramebuffer
5467*61046927SAndroid Build Coastguard Worker * does not appear to specify the behavior. So this may be overly
5468*61046927SAndroid Build Coastguard Worker * conservative.
5469*61046927SAndroid Build Coastguard Worker */
5470*61046927SAndroid Build Coastguard Worker if ((mask & zsmask) && ((mask & zsmask) != zsmask) &&
5471*61046927SAndroid Build Coastguard Worker (fb->Attachment[BUFFER_DEPTH].Renderbuffer ==
5472*61046927SAndroid Build Coastguard Worker fb->Attachment[BUFFER_STENCIL].Renderbuffer)) {
5473*61046927SAndroid Build Coastguard Worker mask &= ~zsmask;
5474*61046927SAndroid Build Coastguard Worker }
5475*61046927SAndroid Build Coastguard Worker
5476*61046927SAndroid Build Coastguard Worker u_foreach_bit (b, mask) {
5477*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer_attachment *att = &fb->Attachment[b];
5478*61046927SAndroid Build Coastguard Worker
5479*61046927SAndroid Build Coastguard Worker do_discard_framebuffer(ctx, fb, att);
5480*61046927SAndroid Build Coastguard Worker }
5481*61046927SAndroid Build Coastguard Worker }
5482*61046927SAndroid Build Coastguard Worker
5483*61046927SAndroid Build Coastguard Worker static void
discard_framebuffer(struct gl_context * ctx,struct gl_framebuffer * fb,GLsizei numAttachments,const GLenum * attachments)5484*61046927SAndroid Build Coastguard Worker discard_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
5485*61046927SAndroid Build Coastguard Worker GLsizei numAttachments, const GLenum *attachments)
5486*61046927SAndroid Build Coastguard Worker {
5487*61046927SAndroid Build Coastguard Worker uint32_t mask = 0;
5488*61046927SAndroid Build Coastguard Worker
5489*61046927SAndroid Build Coastguard Worker if (unlikely(ctx->st_opts->ignore_discard_framebuffer))
5490*61046927SAndroid Build Coastguard Worker return;
5491*61046927SAndroid Build Coastguard Worker
5492*61046927SAndroid Build Coastguard Worker for (int i = 0; i < numAttachments; i++) {
5493*61046927SAndroid Build Coastguard Worker GLenum att = attachments[i];
5494*61046927SAndroid Build Coastguard Worker
5495*61046927SAndroid Build Coastguard Worker /* A couple enums need special handling, because gl.. */
5496*61046927SAndroid Build Coastguard Worker if (!_mesa_is_user_fbo(fb)) {
5497*61046927SAndroid Build Coastguard Worker if (att == GL_DEPTH) {
5498*61046927SAndroid Build Coastguard Worker att = GL_DEPTH_ATTACHMENT;
5499*61046927SAndroid Build Coastguard Worker } else if (att == GL_STENCIL) {
5500*61046927SAndroid Build Coastguard Worker att = GL_STENCIL_ATTACHMENT;
5501*61046927SAndroid Build Coastguard Worker }
5502*61046927SAndroid Build Coastguard Worker }
5503*61046927SAndroid Build Coastguard Worker
5504*61046927SAndroid Build Coastguard Worker if (att == GL_DEPTH_STENCIL_ATTACHMENT) {
5505*61046927SAndroid Build Coastguard Worker mask |= BITFIELD_BIT(BUFFER_DEPTH) | BITFIELD_BIT(BUFFER_STENCIL);
5506*61046927SAndroid Build Coastguard Worker continue;
5507*61046927SAndroid Build Coastguard Worker }
5508*61046927SAndroid Build Coastguard Worker
5509*61046927SAndroid Build Coastguard Worker gl_buffer_index idx = get_fb_attachment_index(ctx, fb, att);
5510*61046927SAndroid Build Coastguard Worker if (idx != BUFFER_NONE)
5511*61046927SAndroid Build Coastguard Worker mask |= BITFIELD_BIT(idx);
5512*61046927SAndroid Build Coastguard Worker }
5513*61046927SAndroid Build Coastguard Worker
5514*61046927SAndroid Build Coastguard Worker discard_attachments(ctx, fb, mask);
5515*61046927SAndroid Build Coastguard Worker }
5516*61046927SAndroid Build Coastguard Worker
5517*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateSubFramebuffer_no_error(GLenum target,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)5518*61046927SAndroid Build Coastguard Worker _mesa_InvalidateSubFramebuffer_no_error(GLenum target, GLsizei numAttachments,
5519*61046927SAndroid Build Coastguard Worker const GLenum *attachments, GLint x,
5520*61046927SAndroid Build Coastguard Worker GLint y, GLsizei width, GLsizei height)
5521*61046927SAndroid Build Coastguard Worker {
5522*61046927SAndroid Build Coastguard Worker /* no-op */
5523*61046927SAndroid Build Coastguard Worker }
5524*61046927SAndroid Build Coastguard Worker
5525*61046927SAndroid Build Coastguard Worker
5526*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateSubFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)5527*61046927SAndroid Build Coastguard Worker _mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
5528*61046927SAndroid Build Coastguard Worker const GLenum *attachments, GLint x, GLint y,
5529*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height)
5530*61046927SAndroid Build Coastguard Worker {
5531*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5532*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5533*61046927SAndroid Build Coastguard Worker
5534*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
5535*61046927SAndroid Build Coastguard Worker if (!fb) {
5536*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
5537*61046927SAndroid Build Coastguard Worker "glInvalidateSubFramebuffer(invalid target %s)",
5538*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
5539*61046927SAndroid Build Coastguard Worker return;
5540*61046927SAndroid Build Coastguard Worker }
5541*61046927SAndroid Build Coastguard Worker
5542*61046927SAndroid Build Coastguard Worker invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
5543*61046927SAndroid Build Coastguard Worker x, y, width, height,
5544*61046927SAndroid Build Coastguard Worker "glInvalidateSubFramebuffer");
5545*61046927SAndroid Build Coastguard Worker }
5546*61046927SAndroid Build Coastguard Worker
5547*61046927SAndroid Build Coastguard Worker
5548*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateNamedFramebufferSubData(GLuint framebuffer,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)5549*61046927SAndroid Build Coastguard Worker _mesa_InvalidateNamedFramebufferSubData(GLuint framebuffer,
5550*61046927SAndroid Build Coastguard Worker GLsizei numAttachments,
5551*61046927SAndroid Build Coastguard Worker const GLenum *attachments,
5552*61046927SAndroid Build Coastguard Worker GLint x, GLint y,
5553*61046927SAndroid Build Coastguard Worker GLsizei width, GLsizei height)
5554*61046927SAndroid Build Coastguard Worker {
5555*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5556*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5557*61046927SAndroid Build Coastguard Worker
5558*61046927SAndroid Build Coastguard Worker /* The OpenGL 4.5 core spec (02.02.2015) says (in Section 17.4 Whole
5559*61046927SAndroid Build Coastguard Worker * Framebuffer Operations, PDF page 522): "If framebuffer is zero, the
5560*61046927SAndroid Build Coastguard Worker * default draw framebuffer is affected."
5561*61046927SAndroid Build Coastguard Worker */
5562*61046927SAndroid Build Coastguard Worker if (framebuffer) {
5563*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
5564*61046927SAndroid Build Coastguard Worker "glInvalidateNamedFramebufferSubData");
5565*61046927SAndroid Build Coastguard Worker if (!fb)
5566*61046927SAndroid Build Coastguard Worker return;
5567*61046927SAndroid Build Coastguard Worker }
5568*61046927SAndroid Build Coastguard Worker else
5569*61046927SAndroid Build Coastguard Worker fb = ctx->WinSysDrawBuffer;
5570*61046927SAndroid Build Coastguard Worker
5571*61046927SAndroid Build Coastguard Worker invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
5572*61046927SAndroid Build Coastguard Worker x, y, width, height,
5573*61046927SAndroid Build Coastguard Worker "glInvalidateNamedFramebufferSubData");
5574*61046927SAndroid Build Coastguard Worker }
5575*61046927SAndroid Build Coastguard Worker
5576*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateFramebuffer_no_error(GLenum target,GLsizei numAttachments,const GLenum * attachments)5577*61046927SAndroid Build Coastguard Worker _mesa_InvalidateFramebuffer_no_error(GLenum target, GLsizei numAttachments,
5578*61046927SAndroid Build Coastguard Worker const GLenum *attachments)
5579*61046927SAndroid Build Coastguard Worker {
5580*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5581*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5582*61046927SAndroid Build Coastguard Worker
5583*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
5584*61046927SAndroid Build Coastguard Worker if (!fb)
5585*61046927SAndroid Build Coastguard Worker return;
5586*61046927SAndroid Build Coastguard Worker
5587*61046927SAndroid Build Coastguard Worker discard_framebuffer(ctx, fb, numAttachments, attachments);
5588*61046927SAndroid Build Coastguard Worker }
5589*61046927SAndroid Build Coastguard Worker
5590*61046927SAndroid Build Coastguard Worker
5591*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments)5592*61046927SAndroid Build Coastguard Worker _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
5593*61046927SAndroid Build Coastguard Worker const GLenum *attachments)
5594*61046927SAndroid Build Coastguard Worker {
5595*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5596*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5597*61046927SAndroid Build Coastguard Worker
5598*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
5599*61046927SAndroid Build Coastguard Worker if (!fb) {
5600*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
5601*61046927SAndroid Build Coastguard Worker "glInvalidateFramebuffer(invalid target %s)",
5602*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
5603*61046927SAndroid Build Coastguard Worker return;
5604*61046927SAndroid Build Coastguard Worker }
5605*61046927SAndroid Build Coastguard Worker
5606*61046927SAndroid Build Coastguard Worker /* The GL_ARB_invalidate_subdata spec says:
5607*61046927SAndroid Build Coastguard Worker *
5608*61046927SAndroid Build Coastguard Worker * "The command
5609*61046927SAndroid Build Coastguard Worker *
5610*61046927SAndroid Build Coastguard Worker * void InvalidateFramebuffer(enum target,
5611*61046927SAndroid Build Coastguard Worker * sizei numAttachments,
5612*61046927SAndroid Build Coastguard Worker * const enum *attachments);
5613*61046927SAndroid Build Coastguard Worker *
5614*61046927SAndroid Build Coastguard Worker * is equivalent to the command InvalidateSubFramebuffer with <x>, <y>,
5615*61046927SAndroid Build Coastguard Worker * <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>,
5616*61046927SAndroid Build Coastguard Worker * <MAX_VIEWPORT_DIMS[1]> respectively."
5617*61046927SAndroid Build Coastguard Worker */
5618*61046927SAndroid Build Coastguard Worker invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
5619*61046927SAndroid Build Coastguard Worker 0, 0,
5620*61046927SAndroid Build Coastguard Worker ctx->Const.MaxViewportWidth,
5621*61046927SAndroid Build Coastguard Worker ctx->Const.MaxViewportHeight,
5622*61046927SAndroid Build Coastguard Worker "glInvalidateFramebuffer");
5623*61046927SAndroid Build Coastguard Worker
5624*61046927SAndroid Build Coastguard Worker discard_framebuffer(ctx, fb, numAttachments, attachments);
5625*61046927SAndroid Build Coastguard Worker }
5626*61046927SAndroid Build Coastguard Worker
5627*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InternalInvalidateFramebufferAncillaryMESA(void)5628*61046927SAndroid Build Coastguard Worker _mesa_InternalInvalidateFramebufferAncillaryMESA(void)
5629*61046927SAndroid Build Coastguard Worker {
5630*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5631*61046927SAndroid Build Coastguard Worker
5632*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb = get_framebuffer_target(ctx, GL_FRAMEBUFFER);
5633*61046927SAndroid Build Coastguard Worker discard_attachments(ctx, fb, BITFIELD_BIT(BUFFER_DEPTH) | BITFIELD_BIT(BUFFER_STENCIL));
5634*61046927SAndroid Build Coastguard Worker }
5635*61046927SAndroid Build Coastguard Worker
5636*61046927SAndroid Build Coastguard Worker
5637*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateNamedFramebufferData(GLuint framebuffer,GLsizei numAttachments,const GLenum * attachments)5638*61046927SAndroid Build Coastguard Worker _mesa_InvalidateNamedFramebufferData(GLuint framebuffer,
5639*61046927SAndroid Build Coastguard Worker GLsizei numAttachments,
5640*61046927SAndroid Build Coastguard Worker const GLenum *attachments)
5641*61046927SAndroid Build Coastguard Worker {
5642*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5643*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5644*61046927SAndroid Build Coastguard Worker
5645*61046927SAndroid Build Coastguard Worker /* The OpenGL 4.5 core spec (02.02.2015) says (in Section 17.4 Whole
5646*61046927SAndroid Build Coastguard Worker * Framebuffer Operations, PDF page 522): "If framebuffer is zero, the
5647*61046927SAndroid Build Coastguard Worker * default draw framebuffer is affected."
5648*61046927SAndroid Build Coastguard Worker */
5649*61046927SAndroid Build Coastguard Worker if (framebuffer) {
5650*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
5651*61046927SAndroid Build Coastguard Worker "glInvalidateNamedFramebufferData");
5652*61046927SAndroid Build Coastguard Worker if (!fb)
5653*61046927SAndroid Build Coastguard Worker return;
5654*61046927SAndroid Build Coastguard Worker }
5655*61046927SAndroid Build Coastguard Worker else
5656*61046927SAndroid Build Coastguard Worker fb = ctx->WinSysDrawBuffer;
5657*61046927SAndroid Build Coastguard Worker
5658*61046927SAndroid Build Coastguard Worker /* The GL_ARB_invalidate_subdata spec says:
5659*61046927SAndroid Build Coastguard Worker *
5660*61046927SAndroid Build Coastguard Worker * "The command
5661*61046927SAndroid Build Coastguard Worker *
5662*61046927SAndroid Build Coastguard Worker * void InvalidateFramebuffer(enum target,
5663*61046927SAndroid Build Coastguard Worker * sizei numAttachments,
5664*61046927SAndroid Build Coastguard Worker * const enum *attachments);
5665*61046927SAndroid Build Coastguard Worker *
5666*61046927SAndroid Build Coastguard Worker * is equivalent to the command InvalidateSubFramebuffer with <x>, <y>,
5667*61046927SAndroid Build Coastguard Worker * <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>,
5668*61046927SAndroid Build Coastguard Worker * <MAX_VIEWPORT_DIMS[1]> respectively."
5669*61046927SAndroid Build Coastguard Worker */
5670*61046927SAndroid Build Coastguard Worker invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
5671*61046927SAndroid Build Coastguard Worker 0, 0,
5672*61046927SAndroid Build Coastguard Worker ctx->Const.MaxViewportWidth,
5673*61046927SAndroid Build Coastguard Worker ctx->Const.MaxViewportHeight,
5674*61046927SAndroid Build Coastguard Worker "glInvalidateNamedFramebufferData");
5675*61046927SAndroid Build Coastguard Worker }
5676*61046927SAndroid Build Coastguard Worker
5677*61046927SAndroid Build Coastguard Worker
5678*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DiscardFramebufferEXT(GLenum target,GLsizei numAttachments,const GLenum * attachments)5679*61046927SAndroid Build Coastguard Worker _mesa_DiscardFramebufferEXT(GLenum target, GLsizei numAttachments,
5680*61046927SAndroid Build Coastguard Worker const GLenum *attachments)
5681*61046927SAndroid Build Coastguard Worker {
5682*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5683*61046927SAndroid Build Coastguard Worker GLint i;
5684*61046927SAndroid Build Coastguard Worker
5685*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5686*61046927SAndroid Build Coastguard Worker
5687*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
5688*61046927SAndroid Build Coastguard Worker if (!fb) {
5689*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
5690*61046927SAndroid Build Coastguard Worker "glDiscardFramebufferEXT(target %s)",
5691*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
5692*61046927SAndroid Build Coastguard Worker return;
5693*61046927SAndroid Build Coastguard Worker }
5694*61046927SAndroid Build Coastguard Worker
5695*61046927SAndroid Build Coastguard Worker if (numAttachments < 0) {
5696*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
5697*61046927SAndroid Build Coastguard Worker "glDiscardFramebufferEXT(numAttachments < 0)");
5698*61046927SAndroid Build Coastguard Worker return;
5699*61046927SAndroid Build Coastguard Worker }
5700*61046927SAndroid Build Coastguard Worker
5701*61046927SAndroid Build Coastguard Worker for (i = 0; i < numAttachments; i++) {
5702*61046927SAndroid Build Coastguard Worker switch (attachments[i]) {
5703*61046927SAndroid Build Coastguard Worker case GL_COLOR:
5704*61046927SAndroid Build Coastguard Worker case GL_DEPTH:
5705*61046927SAndroid Build Coastguard Worker case GL_STENCIL:
5706*61046927SAndroid Build Coastguard Worker if (_mesa_is_user_fbo(fb))
5707*61046927SAndroid Build Coastguard Worker goto invalid_enum;
5708*61046927SAndroid Build Coastguard Worker break;
5709*61046927SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT0:
5710*61046927SAndroid Build Coastguard Worker case GL_DEPTH_ATTACHMENT:
5711*61046927SAndroid Build Coastguard Worker case GL_STENCIL_ATTACHMENT:
5712*61046927SAndroid Build Coastguard Worker if (_mesa_is_winsys_fbo(fb))
5713*61046927SAndroid Build Coastguard Worker goto invalid_enum;
5714*61046927SAndroid Build Coastguard Worker break;
5715*61046927SAndroid Build Coastguard Worker default:
5716*61046927SAndroid Build Coastguard Worker goto invalid_enum;
5717*61046927SAndroid Build Coastguard Worker }
5718*61046927SAndroid Build Coastguard Worker }
5719*61046927SAndroid Build Coastguard Worker
5720*61046927SAndroid Build Coastguard Worker discard_framebuffer(ctx, fb, numAttachments, attachments);
5721*61046927SAndroid Build Coastguard Worker
5722*61046927SAndroid Build Coastguard Worker return;
5723*61046927SAndroid Build Coastguard Worker
5724*61046927SAndroid Build Coastguard Worker invalid_enum:
5725*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
5726*61046927SAndroid Build Coastguard Worker "glDiscardFramebufferEXT(attachment %s)",
5727*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(attachments[i]));
5728*61046927SAndroid Build Coastguard Worker }
5729*61046927SAndroid Build Coastguard Worker
5730*61046927SAndroid Build Coastguard Worker static void
sample_locations(struct gl_context * ctx,struct gl_framebuffer * fb,GLuint start,GLsizei count,const GLfloat * v,bool no_error,const char * name)5731*61046927SAndroid Build Coastguard Worker sample_locations(struct gl_context *ctx, struct gl_framebuffer *fb,
5732*61046927SAndroid Build Coastguard Worker GLuint start, GLsizei count, const GLfloat *v, bool no_error,
5733*61046927SAndroid Build Coastguard Worker const char *name)
5734*61046927SAndroid Build Coastguard Worker {
5735*61046927SAndroid Build Coastguard Worker GLsizei i;
5736*61046927SAndroid Build Coastguard Worker
5737*61046927SAndroid Build Coastguard Worker if (!no_error) {
5738*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_sample_locations) {
5739*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
5740*61046927SAndroid Build Coastguard Worker "%s not supported "
5741*61046927SAndroid Build Coastguard Worker "(ARB_sample_locations not available)", name);
5742*61046927SAndroid Build Coastguard Worker return;
5743*61046927SAndroid Build Coastguard Worker }
5744*61046927SAndroid Build Coastguard Worker
5745*61046927SAndroid Build Coastguard Worker if (start + count > MAX_SAMPLE_LOCATION_TABLE_SIZE) {
5746*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
5747*61046927SAndroid Build Coastguard Worker "%s(start+size > sample location table size)", name);
5748*61046927SAndroid Build Coastguard Worker return;
5749*61046927SAndroid Build Coastguard Worker }
5750*61046927SAndroid Build Coastguard Worker }
5751*61046927SAndroid Build Coastguard Worker
5752*61046927SAndroid Build Coastguard Worker if (!fb->SampleLocationTable) {
5753*61046927SAndroid Build Coastguard Worker size_t size = MAX_SAMPLE_LOCATION_TABLE_SIZE * 2 * sizeof(GLfloat);
5754*61046927SAndroid Build Coastguard Worker fb->SampleLocationTable = malloc(size);
5755*61046927SAndroid Build Coastguard Worker if (!fb->SampleLocationTable) {
5756*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY,
5757*61046927SAndroid Build Coastguard Worker "Cannot allocate sample location table");
5758*61046927SAndroid Build Coastguard Worker return;
5759*61046927SAndroid Build Coastguard Worker }
5760*61046927SAndroid Build Coastguard Worker for (i = 0; i < MAX_SAMPLE_LOCATION_TABLE_SIZE * 2; i++)
5761*61046927SAndroid Build Coastguard Worker fb->SampleLocationTable[i] = 0.5f;
5762*61046927SAndroid Build Coastguard Worker }
5763*61046927SAndroid Build Coastguard Worker
5764*61046927SAndroid Build Coastguard Worker for (i = 0; i < count * 2; i++) {
5765*61046927SAndroid Build Coastguard Worker /* The ARB_sample_locations spec says:
5766*61046927SAndroid Build Coastguard Worker *
5767*61046927SAndroid Build Coastguard Worker * Sample locations outside of [0,1] result in undefined
5768*61046927SAndroid Build Coastguard Worker * behavior.
5769*61046927SAndroid Build Coastguard Worker *
5770*61046927SAndroid Build Coastguard Worker * To simplify driver implementations, we choose to clamp to
5771*61046927SAndroid Build Coastguard Worker * [0,1] and change NaN into 0.5.
5772*61046927SAndroid Build Coastguard Worker */
5773*61046927SAndroid Build Coastguard Worker if (isnan(v[i]) || v[i] < 0.0f || v[i] > 1.0f) {
5774*61046927SAndroid Build Coastguard Worker static GLuint msg_id = 0;
5775*61046927SAndroid Build Coastguard Worker static const char* msg = "Invalid sample location specified";
5776*61046927SAndroid Build Coastguard Worker _mesa_debug_get_id(&msg_id);
5777*61046927SAndroid Build Coastguard Worker
5778*61046927SAndroid Build Coastguard Worker _mesa_log_msg(ctx, MESA_DEBUG_SOURCE_API, MESA_DEBUG_TYPE_UNDEFINED,
5779*61046927SAndroid Build Coastguard Worker msg_id, MESA_DEBUG_SEVERITY_HIGH, strlen(msg), msg);
5780*61046927SAndroid Build Coastguard Worker }
5781*61046927SAndroid Build Coastguard Worker
5782*61046927SAndroid Build Coastguard Worker if (isnan(v[i]))
5783*61046927SAndroid Build Coastguard Worker fb->SampleLocationTable[start * 2 + i] = 0.5f;
5784*61046927SAndroid Build Coastguard Worker else
5785*61046927SAndroid Build Coastguard Worker fb->SampleLocationTable[start * 2 + i] = SATURATE(v[i]);
5786*61046927SAndroid Build Coastguard Worker }
5787*61046927SAndroid Build Coastguard Worker
5788*61046927SAndroid Build Coastguard Worker if (fb == ctx->DrawBuffer)
5789*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_SAMPLE_STATE;
5790*61046927SAndroid Build Coastguard Worker }
5791*61046927SAndroid Build Coastguard Worker
5792*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferSampleLocationsfvARB(GLenum target,GLuint start,GLsizei count,const GLfloat * v)5793*61046927SAndroid Build Coastguard Worker _mesa_FramebufferSampleLocationsfvARB(GLenum target, GLuint start,
5794*61046927SAndroid Build Coastguard Worker GLsizei count, const GLfloat *v)
5795*61046927SAndroid Build Coastguard Worker {
5796*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5797*61046927SAndroid Build Coastguard Worker
5798*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5799*61046927SAndroid Build Coastguard Worker
5800*61046927SAndroid Build Coastguard Worker fb = get_framebuffer_target(ctx, target);
5801*61046927SAndroid Build Coastguard Worker if (!fb) {
5802*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
5803*61046927SAndroid Build Coastguard Worker "glFramebufferSampleLocationsfvARB(target %s)",
5804*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
5805*61046927SAndroid Build Coastguard Worker return;
5806*61046927SAndroid Build Coastguard Worker }
5807*61046927SAndroid Build Coastguard Worker
5808*61046927SAndroid Build Coastguard Worker sample_locations(ctx, fb, start, count, v, false,
5809*61046927SAndroid Build Coastguard Worker "glFramebufferSampleLocationsfvARB");
5810*61046927SAndroid Build Coastguard Worker }
5811*61046927SAndroid Build Coastguard Worker
5812*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferSampleLocationsfvARB(GLuint framebuffer,GLuint start,GLsizei count,const GLfloat * v)5813*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferSampleLocationsfvARB(GLuint framebuffer, GLuint start,
5814*61046927SAndroid Build Coastguard Worker GLsizei count, const GLfloat *v)
5815*61046927SAndroid Build Coastguard Worker {
5816*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb;
5817*61046927SAndroid Build Coastguard Worker
5818*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5819*61046927SAndroid Build Coastguard Worker
5820*61046927SAndroid Build Coastguard Worker if (framebuffer) {
5821*61046927SAndroid Build Coastguard Worker fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
5822*61046927SAndroid Build Coastguard Worker "glNamedFramebufferSampleLocationsfvARB");
5823*61046927SAndroid Build Coastguard Worker if (!fb)
5824*61046927SAndroid Build Coastguard Worker return;
5825*61046927SAndroid Build Coastguard Worker }
5826*61046927SAndroid Build Coastguard Worker else
5827*61046927SAndroid Build Coastguard Worker fb = ctx->WinSysDrawBuffer;
5828*61046927SAndroid Build Coastguard Worker
5829*61046927SAndroid Build Coastguard Worker sample_locations(ctx, fb, start, count, v, false,
5830*61046927SAndroid Build Coastguard Worker "glNamedFramebufferSampleLocationsfvARB");
5831*61046927SAndroid Build Coastguard Worker }
5832*61046927SAndroid Build Coastguard Worker
5833*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FramebufferSampleLocationsfvARB_no_error(GLenum target,GLuint start,GLsizei count,const GLfloat * v)5834*61046927SAndroid Build Coastguard Worker _mesa_FramebufferSampleLocationsfvARB_no_error(GLenum target, GLuint start,
5835*61046927SAndroid Build Coastguard Worker GLsizei count, const GLfloat *v)
5836*61046927SAndroid Build Coastguard Worker {
5837*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5838*61046927SAndroid Build Coastguard Worker sample_locations(ctx, get_framebuffer_target(ctx, target), start,
5839*61046927SAndroid Build Coastguard Worker count, v, true, "glFramebufferSampleLocationsfvARB");
5840*61046927SAndroid Build Coastguard Worker }
5841*61046927SAndroid Build Coastguard Worker
5842*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedFramebufferSampleLocationsfvARB_no_error(GLuint framebuffer,GLuint start,GLsizei count,const GLfloat * v)5843*61046927SAndroid Build Coastguard Worker _mesa_NamedFramebufferSampleLocationsfvARB_no_error(GLuint framebuffer,
5844*61046927SAndroid Build Coastguard Worker GLuint start, GLsizei count,
5845*61046927SAndroid Build Coastguard Worker const GLfloat *v)
5846*61046927SAndroid Build Coastguard Worker {
5847*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5848*61046927SAndroid Build Coastguard Worker sample_locations(ctx, _mesa_lookup_framebuffer(ctx, framebuffer), start,
5849*61046927SAndroid Build Coastguard Worker count, v, true, "glNamedFramebufferSampleLocationsfvARB");
5850*61046927SAndroid Build Coastguard Worker }
5851*61046927SAndroid Build Coastguard Worker
5852*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_EvaluateDepthValuesARB(void)5853*61046927SAndroid Build Coastguard Worker _mesa_EvaluateDepthValuesARB(void)
5854*61046927SAndroid Build Coastguard Worker {
5855*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5856*61046927SAndroid Build Coastguard Worker
5857*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_sample_locations) {
5858*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
5859*61046927SAndroid Build Coastguard Worker "EvaluateDepthValuesARB not supported (neither "
5860*61046927SAndroid Build Coastguard Worker "ARB_sample_locations nor NV_sample_locations is available)");
5861*61046927SAndroid Build Coastguard Worker return;
5862*61046927SAndroid Build Coastguard Worker }
5863*61046927SAndroid Build Coastguard Worker
5864*61046927SAndroid Build Coastguard Worker st_validate_state(st_context(ctx), ST_PIPELINE_UPDATE_FB_STATE_MASK);
5865*61046927SAndroid Build Coastguard Worker
5866*61046927SAndroid Build Coastguard Worker ctx->pipe->evaluate_depth_buffer(ctx->pipe);
5867*61046927SAndroid Build Coastguard Worker }
5868