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