2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 /* XXX these are temporary here! */
32 #define GL_FRAMEBUFFER_EXT 0x8D40
33 #define GL_RENDERBUFFER_EXT 0x8D41
34 #define GL_STENCIL_INDEX_EXT 0x8D45
35 #define GL_STENCIL_INDEX1_EXT 0x8D46
36 #define GL_STENCIL_INDEX4_EXT 0x8D47
37 #define GL_STENCIL_INDEX8_EXT 0x8D48
38 #define GL_STENCIL_INDEX16_EXT 0x8D49
39 #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
40 #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
41 #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
42 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
43 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
44 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
45 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
46 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
47 #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
48 #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
49 #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
50 #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
51 #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
52 #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
53 #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
54 #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
55 #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
56 #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
57 #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
58 #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
59 #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
60 #define GL_COLOR_ATTACHMENT13_EXT 0x8CED
61 #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
62 #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
63 #define GL_DEPTH_ATTACHMENT_EXT 0x8D00
64 #define GL_STENCIL_ATTACHMENT_EXT 0x8D20
65 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
66 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
67 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
68 #define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8
69 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
70 #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
71 #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
72 #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
73 #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
74 #define GL_FRAMEBUFFER_STATUS_ERROR_EXT 0x8CDE
75 #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
76 #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
77 #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
78 #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
79 #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
82 struct gl_render_buffer_object
91 struct gl_frame_buffer_object
101 * Helper routine for getting a gl_render_buffer_object.
103 static struct gl_render_buffer_object *
104 LookupRenderbuffer(GLcontext *ctx, GLuint id)
106 struct gl_render_buffer_object *rb;
111 rb = (struct gl_render_buffer_object *)
112 _mesa_HashLookup(ctx->Shared->RenderBuffers, id);
118 * Helper routine for getting a gl_frame_buffer_object.
120 static struct gl_frame_buffer_object *
121 LookupFramebuffer(GLcontext *ctx, GLuint id)
123 struct gl_frame_buffer_object *rb;
128 rb = (struct gl_frame_buffer_object *)
129 _mesa_HashLookup(ctx->Shared->FrameBuffers, id);
135 * Allocate a new gl_render_buffer_object.
136 * XXX make this a device driver function.
138 static struct gl_render_buffer_object *
139 NewRenderBuffer(GLcontext *ctx, GLuint name)
141 struct gl_render_buffer_object *rb = CALLOC_STRUCT(gl_render_buffer_object);
151 * Allocate a new gl_frame_buffer_object.
152 * XXX make this a device driver function.
154 static struct gl_frame_buffer_object *
155 NewFrameBuffer(GLcontext *ctx, GLuint name)
157 struct gl_frame_buffer_object *fb = CALLOC_STRUCT(gl_frame_buffer_object);
168 _mesa_IsRenderbufferEXT(GLuint renderbuffer)
170 struct gl_render_buffer_object *rb;
171 GET_CURRENT_CONTEXT(ctx);
173 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
175 rb = LookupRenderbuffer(ctx, renderbuffer);
176 return rb ? GL_TRUE : GL_FALSE;
181 _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
183 struct gl_render_buffer_object *rb;
184 GET_CURRENT_CONTEXT(ctx);
186 ASSERT_OUTSIDE_BEGIN_END(ctx);
189 case GL_RENDERBUFFER_EXT:
191 case GL_FRAMEBUFFER_EXT:
194 _mesa_error(ctx, GL_INVALID_ENUM, "glBindRenderbufferEXT(target)");
198 rb = LookupRenderbuffer(ctx, renderbuffer);
200 _mesa_error(ctx, GL_INVALID_VALUE, "glIsRenderbufferEXT(renderbuffer)");
209 _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
212 GET_CURRENT_CONTEXT(ctx);
214 ASSERT_OUTSIDE_BEGIN_END(ctx);
216 for (i = 0; i < n; i++) {
217 struct gl_render_buffer_object *rb;
218 rb = LookupRenderbuffer(ctx, renderbuffers[i]);
220 /* remove from hash table immediately, to free the ID */
221 _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
223 /* But the object will not be freed until it's no longer bound in
227 if (rb->RefCount == 0) {
228 _mesa_free(rb); /* XXX call device driver function */
236 _mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
238 GET_CURRENT_CONTEXT(ctx);
242 ASSERT_OUTSIDE_BEGIN_END(ctx);
245 _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
252 first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n);
254 for (i = 0; i < n; i++) {
255 struct gl_render_buffer_object *rb;
256 GLuint name = first + i;
257 rb = NewRenderBuffer(ctx, name);
259 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenRenderbuffersEXT");
263 /* insert into hash table */
264 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
265 _mesa_HashInsert(ctx->Shared->RenderBuffers, name, rb);
266 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
268 renderbuffers[i] = name;
275 _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
276 GLsizei width, GLsizei height)
278 GET_CURRENT_CONTEXT(ctx);
280 ASSERT_OUTSIDE_BEGIN_END(ctx);
283 case GL_RENDERBUFFER_EXT:
286 _mesa_error(ctx, GL_INVALID_ENUM, "glRenderbufferStorageEXT(target)");
290 switch (internalFormat) {
291 case GL_STENCIL_INDEX_EXT:
292 case GL_STENCIL_INDEX1_EXT:
293 case GL_STENCIL_INDEX4_EXT:
294 case GL_STENCIL_INDEX8_EXT:
295 case GL_STENCIL_INDEX16_EXT:
298 _mesa_error(ctx, GL_INVALID_ENUM,
299 "glRenderbufferStorageEXT(internalFormat)");
304 if (width > 0 /*value of MAX_RENDERBUFFER_SIZE_EXT*/) {
305 _mesa_error(ctx, GL_INVALID_VALUE, "glRenderbufferStorageEXT(width)");
309 if (height > 0 /*value of MAX_RENDERBUFFER_SIZE_EXT*/) {
310 _mesa_error(ctx, GL_INVALID_VALUE, "glRenderbufferStorageEXT(height)");
321 _mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
323 GET_CURRENT_CONTEXT(ctx);
325 ASSERT_OUTSIDE_BEGIN_END(ctx);
328 case GL_RENDERBUFFER_EXT:
331 _mesa_error(ctx, GL_INVALID_ENUM,
332 "glGetRenderbufferParameterivEXT(target)");
337 case GL_RENDERBUFFER_WIDTH_EXT:
338 case GL_RENDERBUFFER_HEIGHT_EXT:
339 case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
342 _mesa_error(ctx, GL_INVALID_ENUM,
343 "glGetRenderbufferParameterivEXT(target)");
347 if (1/*GL_RENDERBUFFER_BINDING_EXT is zero*/) {
348 _mesa_error(ctx, GL_INVALID_OPERATION,
349 "glGetRenderbufferParameterivEXT");
359 _mesa_IsFramebufferEXT(GLuint framebuffer)
361 struct gl_frame_buffer_object *fb;
362 GET_CURRENT_CONTEXT(ctx);
364 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
366 fb = LookupFramebuffer(ctx, framebuffer);
367 return fb ? GL_TRUE : GL_FALSE;
372 _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
374 GET_CURRENT_CONTEXT(ctx);
376 ASSERT_OUTSIDE_BEGIN_END(ctx);
379 case GL_FRAMEBUFFER_EXT:
382 _mesa_error(ctx, GL_INVALID_ENUM,
383 "glBindFramebufferEXT(target)");
392 _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
395 GET_CURRENT_CONTEXT(ctx);
397 ASSERT_OUTSIDE_BEGIN_END(ctx);
399 for (i = 0; i < n; i++) {
400 struct gl_frame_buffer_object *fb;
401 fb = LookupFramebuffer(ctx, framebuffers[i]);
403 /* remove from hash table immediately, to free the ID */
404 _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
406 /* But the object will not be freed until it's no longer bound in
410 if (fb->RefCount == 0) {
411 _mesa_free(fb); /* XXX call device driver function */
419 _mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
421 GET_CURRENT_CONTEXT(ctx);
425 ASSERT_OUTSIDE_BEGIN_END(ctx);
428 _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
435 first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n);
437 for (i = 0; i < n; i++) {
438 struct gl_frame_buffer_object *fb;
439 GLuint name = first + i;
440 fb = NewFrameBuffer(ctx, name);
442 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenFramebuffersEXT");
446 /* insert into hash table */
447 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
448 _mesa_HashInsert(ctx->Shared->FrameBuffers, name, fb);
449 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
451 framebuffers[i] = name;
458 _mesa_CheckFramebufferStatusEXT(GLenum target)
460 GET_CURRENT_CONTEXT(ctx);
462 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FRAMEBUFFER_STATUS_ERROR_EXT);
465 case GL_FRAMEBUFFER_EXT:
468 _mesa_error(ctx, GL_INVALID_ENUM,
469 "glCheckFramebufferStatus(target)");
470 return GL_FRAMEBUFFER_STATUS_ERROR_EXT;
474 GL_FRAMEBUFFER_COMPLETE_EXT
475 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
476 GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
477 GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
478 GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
479 GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
480 GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
481 GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
482 GL_FRAMEBUFFER_UNSUPPORTED_EXT
483 GL_FRAMEBUFFER_STATUS_ERROR_EXT
485 return GL_FRAMEBUFFER_STATUS_ERROR_EXT;
491 * Do error checking common to glFramebufferTexture1D/2D/3DEXT.
492 * \return GL_TRUE if any error, GL_FALSE otherwise
495 error_check_framebuffer_texture(GLcontext *ctx,
496 GLuint dims, GLenum target, GLenum attachment,
499 if (target != GL_FRAMEBUFFER_EXT) {
500 _mesa_error(ctx, GL_INVALID_ENUM,
501 "glFramebufferTexture%dDEXT(target)", dims);
505 switch (attachment) {
506 case GL_COLOR_ATTACHMENT0_EXT:
507 case GL_COLOR_ATTACHMENT1_EXT:
508 case GL_COLOR_ATTACHMENT2_EXT:
509 case GL_COLOR_ATTACHMENT3_EXT:
510 case GL_COLOR_ATTACHMENT4_EXT:
511 case GL_COLOR_ATTACHMENT5_EXT:
512 case GL_COLOR_ATTACHMENT6_EXT:
513 case GL_COLOR_ATTACHMENT7_EXT:
514 case GL_COLOR_ATTACHMENT8_EXT:
515 case GL_COLOR_ATTACHMENT9_EXT:
516 case GL_COLOR_ATTACHMENT10_EXT:
517 case GL_COLOR_ATTACHMENT11_EXT:
518 case GL_COLOR_ATTACHMENT12_EXT:
519 case GL_COLOR_ATTACHMENT13_EXT:
520 case GL_COLOR_ATTACHMENT14_EXT:
521 case GL_COLOR_ATTACHMENT15_EXT:
522 case GL_DEPTH_ATTACHMENT_EXT:
523 case GL_STENCIL_ATTACHMENT_EXT:
526 _mesa_error(ctx, GL_INVALID_ENUM,
527 "glFramebufferTexture%dDEXT(level)", dims);
531 if (level < 0 /* || level too large */) {
532 _mesa_error(ctx, GL_INVALID_VALUE,
533 "glFramebufferTexture%dDEXT(level)", dims);
537 if (target == GL_TEXTURE_RECTANGLE_ARB && level != 0) {
538 _mesa_error(ctx, GL_INVALID_VALUE,
539 "glFramebufferTexture%dDEXT(level)", dims);
548 _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
549 GLenum textarget, GLuint texture, GLint level)
551 GET_CURRENT_CONTEXT(ctx);
553 ASSERT_OUTSIDE_BEGIN_END(ctx);
555 if (error_check_framebuffer_texture(ctx, 1, target, attachment, level))
562 _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
563 GLenum textarget, GLuint texture, GLint level)
565 GET_CURRENT_CONTEXT(ctx);
567 ASSERT_OUTSIDE_BEGIN_END(ctx);
569 if (error_check_framebuffer_texture(ctx, 1, target, attachment, level))
575 _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
576 GLenum textarget, GLuint texture,
577 GLint level, GLint zoffset)
579 GET_CURRENT_CONTEXT(ctx);
581 ASSERT_OUTSIDE_BEGIN_END(ctx);
583 if (error_check_framebuffer_texture(ctx, 1, target, attachment, level))
586 /* check that zoffset isn't too large */
592 _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
593 GLenum renderbufferTarget,
596 GET_CURRENT_CONTEXT(ctx);
598 ASSERT_OUTSIDE_BEGIN_END(ctx);
600 if (target != GL_FRAMEBUFFER_EXT) {
601 _mesa_error(ctx, GL_INVALID_ENUM,
602 "glFramebufferRenderbufferEXT(target)");
606 switch (attachment) {
607 case GL_COLOR_ATTACHMENT0_EXT:
608 case GL_COLOR_ATTACHMENT1_EXT:
609 case GL_COLOR_ATTACHMENT2_EXT:
610 case GL_COLOR_ATTACHMENT3_EXT:
611 case GL_COLOR_ATTACHMENT4_EXT:
612 case GL_COLOR_ATTACHMENT5_EXT:
613 case GL_COLOR_ATTACHMENT6_EXT:
614 case GL_COLOR_ATTACHMENT7_EXT:
615 case GL_COLOR_ATTACHMENT8_EXT:
616 case GL_COLOR_ATTACHMENT9_EXT:
617 case GL_COLOR_ATTACHMENT10_EXT:
618 case GL_COLOR_ATTACHMENT11_EXT:
619 case GL_COLOR_ATTACHMENT12_EXT:
620 case GL_COLOR_ATTACHMENT13_EXT:
621 case GL_COLOR_ATTACHMENT14_EXT:
622 case GL_COLOR_ATTACHMENT15_EXT:
623 case GL_DEPTH_ATTACHMENT_EXT:
624 case GL_STENCIL_ATTACHMENT_EXT:
627 _mesa_error(ctx, GL_INVALID_ENUM,
628 "glFramebufferRenderbufferEXT(attachment)");
632 if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
633 _mesa_error(ctx, GL_INVALID_ENUM,
634 "glFramebufferRenderbufferEXT(renderbufferTarget)");
644 _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
645 GLenum pname, GLint *params)
647 GET_CURRENT_CONTEXT(ctx);
649 ASSERT_OUTSIDE_BEGIN_END(ctx);
651 if (target != GL_FRAMEBUFFER_EXT) {
652 _mesa_error(ctx, GL_INVALID_ENUM,
653 "glGetFramebufferAttachmentParameterivEXT(target)");
657 switch (attachment) {
658 case GL_COLOR_ATTACHMENT0_EXT:
659 case GL_COLOR_ATTACHMENT1_EXT:
660 case GL_COLOR_ATTACHMENT2_EXT:
661 case GL_COLOR_ATTACHMENT3_EXT:
662 case GL_COLOR_ATTACHMENT4_EXT:
663 case GL_COLOR_ATTACHMENT5_EXT:
664 case GL_COLOR_ATTACHMENT6_EXT:
665 case GL_COLOR_ATTACHMENT7_EXT:
666 case GL_COLOR_ATTACHMENT8_EXT:
667 case GL_COLOR_ATTACHMENT9_EXT:
668 case GL_COLOR_ATTACHMENT10_EXT:
669 case GL_COLOR_ATTACHMENT11_EXT:
670 case GL_COLOR_ATTACHMENT12_EXT:
671 case GL_COLOR_ATTACHMENT13_EXT:
672 case GL_COLOR_ATTACHMENT14_EXT:
673 case GL_COLOR_ATTACHMENT15_EXT:
674 case GL_DEPTH_ATTACHMENT_EXT:
675 case GL_STENCIL_ATTACHMENT_EXT:
678 _mesa_error(ctx, GL_INVALID_ENUM,
679 "glGetFramebufferAttachmentParameterivEXT(attachment)");
684 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
685 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
686 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
687 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
688 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
691 _mesa_error(ctx, GL_INVALID_ENUM,
692 "glGetFramebufferAttachmentParameterivEXT(pname)");
702 _mesa_GenerateMipmapEXT(GLenum target)
704 GET_CURRENT_CONTEXT(ctx);
706 ASSERT_OUTSIDE_BEGIN_END(ctx);
711 case GL_TEXTURE_CUBE_MAP:
715 _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)");