Some initial work on GL_EXT_framebuffer_object.
[profile/ivi/mesa.git] / src / mesa / main / fbobject.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.3
4  *
5  * Copyright (C) 1999-2005  Brian Paul   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  * 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.
23  */
24
25
26 #include "context.h"
27 #include "fbobject.h"
28 #include "hash.h"
29
30
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
80
81
82 struct gl_render_buffer_object
83 {
84    GLint RefCount;
85    GLuint Name;
86
87    GLuint width, height;
88 };
89
90
91 struct gl_frame_buffer_object
92 {
93    GLint RefCount;
94    GLuint Name;
95
96 };
97
98
99
100 /**
101  * Helper routine for getting a gl_render_buffer_object.
102  */
103 static struct gl_render_buffer_object *
104 LookupRenderbuffer(GLcontext *ctx, GLuint id)
105 {
106    struct gl_render_buffer_object *rb;
107
108    if (!id == 0)
109       return NULL;
110
111    rb = (struct gl_render_buffer_object *)
112       _mesa_HashLookup(ctx->Shared->RenderBuffers, id);
113    return rb;
114 }
115
116
117 /**
118  * Helper routine for getting a gl_frame_buffer_object.
119  */
120 static struct gl_frame_buffer_object *
121 LookupFramebuffer(GLcontext *ctx, GLuint id)
122 {
123    struct gl_frame_buffer_object *rb;
124
125    if (!id == 0)
126       return NULL;
127
128    rb = (struct gl_frame_buffer_object *)
129       _mesa_HashLookup(ctx->Shared->FrameBuffers, id);
130    return rb;
131 }
132
133
134 /**
135  * Allocate a new gl_render_buffer_object.
136  * XXX make this a device driver function.
137  */
138 static struct gl_render_buffer_object *
139 NewRenderBuffer(GLcontext *ctx, GLuint name)
140 {
141    struct gl_render_buffer_object *rb = CALLOC_STRUCT(gl_render_buffer_object);
142    if (rb) {
143       rb->Name = name;
144       rb->RefCount = 1;
145    }
146    return rb;
147 }
148
149
150 /**
151  * Allocate a new gl_frame_buffer_object.
152  * XXX make this a device driver function.
153  */
154 static struct gl_frame_buffer_object *
155 NewFrameBuffer(GLcontext *ctx, GLuint name)
156 {
157    struct gl_frame_buffer_object *fb = CALLOC_STRUCT(gl_frame_buffer_object);
158    if (fb) {
159       fb->Name = name;
160       fb->RefCount = 1;
161    }
162    return fb;
163 }
164
165
166
167 GLboolean
168 _mesa_IsRenderbufferEXT(GLuint renderbuffer)
169 {
170    struct gl_render_buffer_object *rb;
171    GET_CURRENT_CONTEXT(ctx);
172
173    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
174
175    rb = LookupRenderbuffer(ctx, renderbuffer);
176    return rb ? GL_TRUE : GL_FALSE;
177 }
178
179
180 void
181 _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
182 {
183    struct gl_render_buffer_object *rb;
184    GET_CURRENT_CONTEXT(ctx);
185
186    ASSERT_OUTSIDE_BEGIN_END(ctx);
187
188    switch (target) {
189    case GL_RENDERBUFFER_EXT:
190       break;
191    case GL_FRAMEBUFFER_EXT:
192       break;
193    default:
194       _mesa_error(ctx, GL_INVALID_ENUM, "glBindRenderbufferEXT(target)");
195       return;
196    }
197
198    rb = LookupRenderbuffer(ctx, renderbuffer);
199    if (!rb) {
200       _mesa_error(ctx, GL_INVALID_VALUE, "glIsRenderbufferEXT(renderbuffer)");
201       return;
202    }
203
204
205 }
206
207
208 void
209 _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
210 {
211    GLint i;
212    GET_CURRENT_CONTEXT(ctx);
213
214    ASSERT_OUTSIDE_BEGIN_END(ctx);
215
216    for (i = 0; i < n; i++) {
217       struct gl_render_buffer_object *rb;
218       rb = LookupRenderbuffer(ctx, renderbuffers[i]);
219       if (rb) {
220          /* remove from hash table immediately, to free the ID */
221          _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
222
223          /* But the object will not be freed until it's no longer bound in
224           * any context.
225           */
226          rb->RefCount--;
227          if (rb->RefCount == 0) {
228             _mesa_free(rb); /* XXX call device driver function */
229          }
230       }
231    }
232 }
233
234
235 void
236 _mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
237 {
238    GET_CURRENT_CONTEXT(ctx);
239    GLuint first;
240    GLint i;
241
242    ASSERT_OUTSIDE_BEGIN_END(ctx);
243
244    if (n < 0) {
245       _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
246       return;
247    }
248
249    if (!renderbuffers)
250       return;
251
252    first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n);
253
254    for (i = 0; i < n; i++) {
255       struct gl_render_buffer_object *rb;
256       GLuint name = first + i;
257       rb = NewRenderBuffer(ctx, name);
258       if (!rb) {
259          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenRenderbuffersEXT");
260          return;
261       }
262
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);
267
268       renderbuffers[i] = name;
269    }
270 }
271
272
273
274 void
275 _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
276                              GLsizei width, GLsizei height)
277 {
278    GET_CURRENT_CONTEXT(ctx);
279
280    ASSERT_OUTSIDE_BEGIN_END(ctx);
281
282    switch (target) {
283    case GL_RENDERBUFFER_EXT:
284       break;
285    default:
286       _mesa_error(ctx, GL_INVALID_ENUM, "glRenderbufferStorageEXT(target)");
287       return;
288    }
289
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:
296       break;
297    default:
298       _mesa_error(ctx, GL_INVALID_ENUM,
299                   "glRenderbufferStorageEXT(internalFormat)");
300       return;
301    }
302
303
304    if (width > 0 /*value of MAX_RENDERBUFFER_SIZE_EXT*/) {
305       _mesa_error(ctx, GL_INVALID_VALUE, "glRenderbufferStorageEXT(width)");
306       return;
307    }
308
309    if (height > 0 /*value of MAX_RENDERBUFFER_SIZE_EXT*/) {
310       _mesa_error(ctx, GL_INVALID_VALUE, "glRenderbufferStorageEXT(height)");
311       return;
312    }
313
314
315
316 }
317
318
319
320 void
321 _mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
322 {
323    GET_CURRENT_CONTEXT(ctx);
324
325    ASSERT_OUTSIDE_BEGIN_END(ctx);
326
327    switch (target) {
328    case GL_RENDERBUFFER_EXT:
329       break;
330    default:
331       _mesa_error(ctx, GL_INVALID_ENUM,
332                   "glGetRenderbufferParameterivEXT(target)");
333       return;
334    }
335
336    switch (pname) {
337    case GL_RENDERBUFFER_WIDTH_EXT:
338    case GL_RENDERBUFFER_HEIGHT_EXT:
339    case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
340       break;
341    default:
342       _mesa_error(ctx, GL_INVALID_ENUM,
343                   "glGetRenderbufferParameterivEXT(target)");
344       return;
345    }
346
347    if (1/*GL_RENDERBUFFER_BINDING_EXT is zero*/) {
348       _mesa_error(ctx, GL_INVALID_OPERATION,
349                   "glGetRenderbufferParameterivEXT");
350       return;
351    }
352
353    *params = 0;
354 }
355
356
357
358 GLboolean
359 _mesa_IsFramebufferEXT(GLuint framebuffer)
360 {
361    struct gl_frame_buffer_object *fb;
362    GET_CURRENT_CONTEXT(ctx);
363
364    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
365
366    fb = LookupFramebuffer(ctx, framebuffer);
367    return fb ? GL_TRUE : GL_FALSE;
368 }
369
370
371 void
372 _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
373 {
374    GET_CURRENT_CONTEXT(ctx);
375
376    ASSERT_OUTSIDE_BEGIN_END(ctx);
377
378    switch (target) {
379    case GL_FRAMEBUFFER_EXT:
380       break;
381    default:
382       _mesa_error(ctx, GL_INVALID_ENUM,
383                   "glBindFramebufferEXT(target)");
384       return;
385    }
386
387
388 }
389
390
391 void
392 _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
393 {
394    GLint i;
395    GET_CURRENT_CONTEXT(ctx);
396
397    ASSERT_OUTSIDE_BEGIN_END(ctx);
398
399    for (i = 0; i < n; i++) {
400       struct gl_frame_buffer_object *fb;
401       fb = LookupFramebuffer(ctx, framebuffers[i]);
402       if (fb) {
403          /* remove from hash table immediately, to free the ID */
404          _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
405
406          /* But the object will not be freed until it's no longer bound in
407           * any context.
408           */
409          fb->RefCount--;
410          if (fb->RefCount == 0) {
411             _mesa_free(fb); /* XXX call device driver function */
412          }
413       }
414    }
415 }
416
417
418 void
419 _mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
420 {
421    GET_CURRENT_CONTEXT(ctx);
422    GLuint first;
423    GLint i;
424
425    ASSERT_OUTSIDE_BEGIN_END(ctx);
426
427    if (n < 0) {
428       _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
429       return;
430    }
431
432    if (!framebuffers)
433       return;
434
435    first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n);
436
437    for (i = 0; i < n; i++) {
438       struct gl_frame_buffer_object *fb;
439       GLuint name = first + i;
440       fb = NewFrameBuffer(ctx, name);
441       if (!fb) {
442          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenFramebuffersEXT");
443          return;
444       }
445
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);
450
451       framebuffers[i] = name;
452    }
453 }
454
455
456
457 GLenum
458 _mesa_CheckFramebufferStatusEXT(GLenum target)
459 {
460    GET_CURRENT_CONTEXT(ctx);
461
462    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FRAMEBUFFER_STATUS_ERROR_EXT);
463
464    switch (target) {
465    case GL_FRAMEBUFFER_EXT:
466       break;
467    default:
468       _mesa_error(ctx, GL_INVALID_ENUM,
469                   "glCheckFramebufferStatus(target)");
470       return GL_FRAMEBUFFER_STATUS_ERROR_EXT;
471    }
472
473    /* return one of:
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
484    */
485    return GL_FRAMEBUFFER_STATUS_ERROR_EXT;
486 }
487
488
489
490 /**
491  * Do error checking common to glFramebufferTexture1D/2D/3DEXT.
492  * \return GL_TRUE if any error, GL_FALSE otherwise
493  */
494 static GLboolean
495 error_check_framebuffer_texture(GLcontext *ctx,
496                                 GLuint dims, GLenum target, GLenum attachment,
497                                 GLint level)
498 {
499    if (target != GL_FRAMEBUFFER_EXT) {
500       _mesa_error(ctx, GL_INVALID_ENUM,
501                   "glFramebufferTexture%dDEXT(target)", dims);
502       return GL_TRUE;
503    }
504
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:
524       break;
525    default:
526       _mesa_error(ctx, GL_INVALID_ENUM,
527                   "glFramebufferTexture%dDEXT(level)", dims);
528       return GL_TRUE;
529    }
530
531    if (level < 0 /* || level too large */) {
532       _mesa_error(ctx, GL_INVALID_VALUE,
533                   "glFramebufferTexture%dDEXT(level)", dims);
534       return GL_TRUE;
535    }
536
537    if (target == GL_TEXTURE_RECTANGLE_ARB && level != 0) {
538       _mesa_error(ctx, GL_INVALID_VALUE,
539                   "glFramebufferTexture%dDEXT(level)", dims);
540       return GL_TRUE;
541    }
542
543    return GL_FALSE;
544 }
545
546
547 void
548 _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
549                               GLenum textarget, GLuint texture, GLint level)
550 {
551    GET_CURRENT_CONTEXT(ctx);
552
553    ASSERT_OUTSIDE_BEGIN_END(ctx);
554
555    if (error_check_framebuffer_texture(ctx, 1, target, attachment, level))
556       return;
557
558 }
559
560
561 void
562 _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
563                               GLenum textarget, GLuint texture, GLint level)
564 {
565    GET_CURRENT_CONTEXT(ctx);
566
567    ASSERT_OUTSIDE_BEGIN_END(ctx);
568
569    if (error_check_framebuffer_texture(ctx, 1, target, attachment, level))
570       return;
571 }
572
573
574 void
575 _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
576                               GLenum textarget, GLuint texture,
577                               GLint level, GLint zoffset)
578 {
579    GET_CURRENT_CONTEXT(ctx);
580
581    ASSERT_OUTSIDE_BEGIN_END(ctx);
582
583    if (error_check_framebuffer_texture(ctx, 1, target, attachment, level))
584       return;
585
586    /* check that zoffset isn't too large */
587 }
588
589
590
591 void
592 _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
593                                  GLenum renderbufferTarget,
594                                  GLuint renderbuffer)
595 {
596    GET_CURRENT_CONTEXT(ctx);
597
598    ASSERT_OUTSIDE_BEGIN_END(ctx);
599
600    if (target != GL_FRAMEBUFFER_EXT) {
601       _mesa_error(ctx, GL_INVALID_ENUM,
602                   "glFramebufferRenderbufferEXT(target)");
603       return;
604    }
605
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:
625       break;
626    default:
627       _mesa_error(ctx, GL_INVALID_ENUM,
628                  "glFramebufferRenderbufferEXT(attachment)");
629       return;
630    }
631
632    if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
633       _mesa_error(ctx, GL_INVALID_ENUM,
634                  "glFramebufferRenderbufferEXT(renderbufferTarget)");
635       return;
636    }
637
638
639 }
640
641
642
643 void
644 _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
645                                              GLenum pname, GLint *params)
646 {
647    GET_CURRENT_CONTEXT(ctx);
648
649    ASSERT_OUTSIDE_BEGIN_END(ctx);
650
651    if (target != GL_FRAMEBUFFER_EXT) {
652       _mesa_error(ctx, GL_INVALID_ENUM,
653                   "glGetFramebufferAttachmentParameterivEXT(target)");
654       return;
655    }
656
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:
676       break;
677    default:
678       _mesa_error(ctx, GL_INVALID_ENUM,
679                   "glGetFramebufferAttachmentParameterivEXT(attachment)");
680       return;
681    }
682
683    switch (pname) {
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:
689       break;
690    default:
691       _mesa_error(ctx, GL_INVALID_ENUM,
692                   "glGetFramebufferAttachmentParameterivEXT(pname)");
693       return;
694    }
695
696    *params = 0;
697 }
698
699
700
701 void
702 _mesa_GenerateMipmapEXT(GLenum target)
703 {
704    GET_CURRENT_CONTEXT(ctx);
705
706    ASSERT_OUTSIDE_BEGIN_END(ctx);
707
708    switch (target) {
709    case GL_TEXTURE_1D:
710    case GL_TEXTURE_2D:
711    case GL_TEXTURE_CUBE_MAP:
712    case GL_TEXTURE_3D:
713       break;
714    default:
715       _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)");
716       return;
717    }
718
719 }