2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2006 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.
27 * Functions for allocating/managing renderbuffers.
28 * Also, routines for reading/writing software-based renderbuffer data as
29 * ubytes, ushorts, uints, etc.
31 * The 'alpha8' renderbuffer is interesting. It's used to add a software-based
32 * alpha channel to RGB renderbuffers. This is done by wrapping the RGB
33 * renderbuffer with the alpha renderbuffer. We can do this because of the
34 * OO-nature of renderbuffers.
36 * Down the road we'll use this for run-time support of 8, 16 and 32-bit
37 * color channels. For example, Mesa may use 32-bit/float color channels
38 * internally (swrast) and use wrapper renderbuffers to convert 32-bit
39 * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
48 #include "renderbuffer.h"
51 /* 32-bit color index format. Not a public format. */
52 #define COLOR_INDEX32 0x424243
56 * Routines for get/put values in common buffer formats follow.
57 * Someday add support for arbitrary row stride to make them more
61 /**********************************************************************
62 * Functions for buffers of 1 X GLubyte values.
67 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
72 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
73 /* Can't assert _ActualFormat since these funcs may be used for serveral
74 * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
76 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
81 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
82 GLint x
, GLint y
, void *values
)
84 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
85 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
86 _mesa_memcpy(values
, src
, count
* sizeof(GLubyte
));
91 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
92 const GLint x
[], const GLint y
[], void *values
)
94 GLubyte
*dst
= (GLubyte
*) values
;
96 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
97 for (i
= 0; i
< count
; i
++) {
98 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
105 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
106 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
108 const GLubyte
*src
= (const GLubyte
*) values
;
109 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
110 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
113 for (i
= 0; i
< count
; i
++) {
120 _mesa_memcpy(dst
, values
, count
* sizeof(GLubyte
));
126 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
127 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
129 const GLubyte val
= *((const GLubyte
*) value
);
130 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
131 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
134 for (i
= 0; i
< count
; i
++) {
142 for (i
= 0; i
< count
; i
++) {
150 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
151 const GLint x
[], const GLint y
[],
152 const void *values
, const GLubyte
*mask
)
154 const GLubyte
*src
= (const GLubyte
*) values
;
156 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
157 for (i
= 0; i
< count
; i
++) {
158 if (!mask
|| mask
[i
]) {
159 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
167 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
168 const GLint x
[], const GLint y
[],
169 const void *value
, const GLubyte
*mask
)
171 const GLubyte val
= *((const GLubyte
*) value
);
173 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
174 for (i
= 0; i
< count
; i
++) {
175 if (!mask
|| mask
[i
]) {
176 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
183 /**********************************************************************
184 * Functions for buffers of 1 X GLushort values.
189 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
194 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
195 ASSERT(rb
->Width
> 0);
196 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
201 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
202 GLint x
, GLint y
, void *values
)
204 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
205 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
206 _mesa_memcpy(values
, src
, count
* sizeof(GLushort
));
211 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
212 const GLint x
[], const GLint y
[], void *values
)
214 GLushort
*dst
= (GLushort
*) values
;
216 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
217 for (i
= 0; i
< count
; i
++) {
218 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
225 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
226 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
228 const GLushort
*src
= (const GLushort
*) values
;
229 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
230 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
233 for (i
= 0; i
< count
; i
++) {
240 _mesa_memcpy(dst
, src
, count
* sizeof(GLushort
));
246 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
247 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
249 const GLushort val
= *((const GLushort
*) value
);
250 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
251 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
254 for (i
= 0; i
< count
; i
++) {
262 for (i
= 0; i
< count
; i
++) {
270 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
271 const GLint x
[], const GLint y
[], const void *values
,
274 const GLushort
*src
= (const GLushort
*) values
;
276 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
277 for (i
= 0; i
< count
; i
++) {
278 if (!mask
|| mask
[i
]) {
279 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
287 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
288 GLuint count
, const GLint x
[], const GLint y
[],
289 const void *value
, const GLubyte
*mask
)
291 const GLushort val
= *((const GLushort
*) value
);
292 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
295 for (i
= 0; i
< count
; i
++) {
297 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
304 for (i
= 0; i
< count
; i
++) {
305 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
312 /**********************************************************************
313 * Functions for buffers of 1 X GLuint values.
314 * Typically depth/Z or color index.
318 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
323 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
324 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
325 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
330 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
331 GLint x
, GLint y
, void *values
)
333 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
334 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
335 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
336 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
341 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
342 const GLint x
[], const GLint y
[], void *values
)
344 GLuint
*dst
= (GLuint
*) values
;
346 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
347 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
348 for (i
= 0; i
< count
; i
++) {
349 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
356 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
357 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
359 const GLuint
*src
= (const GLuint
*) values
;
360 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
361 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
362 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
365 for (i
= 0; i
< count
; i
++) {
372 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
378 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
379 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
381 const GLuint val
= *((const GLuint
*) value
);
382 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
383 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
384 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
387 for (i
= 0; i
< count
; i
++) {
395 for (i
= 0; i
< count
; i
++) {
403 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
404 const GLint x
[], const GLint y
[], const void *values
,
407 const GLuint
*src
= (const GLuint
*) values
;
409 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
410 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
411 for (i
= 0; i
< count
; i
++) {
412 if (!mask
|| mask
[i
]) {
413 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
421 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
422 const GLint x
[], const GLint y
[], const void *value
,
425 const GLuint val
= *((const GLuint
*) value
);
427 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
428 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
429 for (i
= 0; i
< count
; i
++) {
430 if (!mask
|| mask
[i
]) {
431 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
438 /**********************************************************************
439 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
440 * Typically color buffers.
441 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
442 * alpha values and return 255 for outgoing alpha values.
446 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
449 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
450 /* No direct access since this buffer is RGB but caller will be
451 * treating it as if it were RGBA.
458 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
459 GLint x
, GLint y
, void *values
)
461 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
462 GLubyte
*dst
= (GLubyte
*) values
;
464 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
465 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
466 for (i
= 0; i
< count
; i
++) {
467 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
468 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
469 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
470 dst
[i
* 4 + 3] = 255;
476 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
477 const GLint x
[], const GLint y
[], void *values
)
479 GLubyte
*dst
= (GLubyte
*) values
;
481 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
482 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
483 for (i
= 0; i
< count
; i
++) {
485 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
486 dst
[i
* 4 + 0] = src
[0];
487 dst
[i
* 4 + 1] = src
[1];
488 dst
[i
* 4 + 2] = src
[2];
489 dst
[i
* 4 + 3] = 255;
495 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
496 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
498 /* note: incoming values are RGB+A! */
499 const GLubyte
*src
= (const GLubyte
*) values
;
500 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
502 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
503 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
504 for (i
= 0; i
< count
; i
++) {
505 if (!mask
|| mask
[i
]) {
506 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
507 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
508 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
515 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
516 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
518 /* note: incoming values are RGB+A! */
519 const GLubyte
*src
= (const GLubyte
*) values
;
520 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
522 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
523 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
524 for (i
= 0; i
< count
; i
++) {
525 if (!mask
|| mask
[i
]) {
526 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
527 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
528 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
535 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
536 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
538 /* note: incoming value is RGB+A! */
539 const GLubyte val0
= ((const GLubyte
*) value
)[0];
540 const GLubyte val1
= ((const GLubyte
*) value
)[1];
541 const GLubyte val2
= ((const GLubyte
*) value
)[2];
542 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
543 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
544 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
545 if (!mask
&& val0
== val1
&& val1
== val2
) {
547 _mesa_memset(dst
, val0
, 3 * count
);
551 for (i
= 0; i
< count
; i
++) {
552 if (!mask
|| mask
[i
]) {
553 dst
[i
* 3 + 0] = val0
;
554 dst
[i
* 3 + 1] = val1
;
555 dst
[i
* 3 + 2] = val2
;
563 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
564 const GLint x
[], const GLint y
[], const void *values
,
567 /* note: incoming values are RGB+A! */
568 const GLubyte
*src
= (const GLubyte
*) values
;
570 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
571 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
572 for (i
= 0; i
< count
; i
++) {
573 if (!mask
|| mask
[i
]) {
574 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
575 dst
[0] = src
[i
* 4 + 0];
576 dst
[1] = src
[i
* 4 + 1];
577 dst
[2] = src
[i
* 4 + 2];
584 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
585 GLuint count
, const GLint x
[], const GLint y
[],
586 const void *value
, const GLubyte
*mask
)
588 /* note: incoming value is RGB+A! */
589 const GLubyte val0
= ((const GLubyte
*) value
)[0];
590 const GLubyte val1
= ((const GLubyte
*) value
)[1];
591 const GLubyte val2
= ((const GLubyte
*) value
)[2];
593 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
594 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
595 for (i
= 0; i
< count
; i
++) {
596 if (!mask
|| mask
[i
]) {
597 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
606 /**********************************************************************
607 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
608 * Typically color buffers.
612 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
617 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
618 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
619 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
624 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
625 GLint x
, GLint y
, void *values
)
627 const GLbyte
*src
= (const GLbyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
628 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
629 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
630 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLbyte
));
635 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
636 const GLint x
[], const GLint y
[], void *values
)
638 /* treat 4*GLubyte as 1*GLuint */
639 GLuint
*dst
= (GLuint
*) values
;
641 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
642 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
643 for (i
= 0; i
< count
; i
++) {
644 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
651 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
652 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
654 /* treat 4*GLubyte as 1*GLuint */
655 const GLuint
*src
= (const GLuint
*) values
;
656 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
657 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
658 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
661 for (i
= 0; i
< count
; i
++) {
668 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
674 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
675 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
677 /* Store RGB values in RGBA buffer */
678 const GLubyte
*src
= (const GLubyte
*) values
;
679 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
681 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
682 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
683 for (i
= 0; i
< count
; i
++) {
684 if (!mask
|| mask
[i
]) {
685 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
686 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
687 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
688 dst
[i
* 4 + 3] = 0xff;
695 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
696 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
698 /* treat 4*GLubyte as 1*GLuint */
699 const GLuint val
= *((const GLuint
*) value
);
700 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
701 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
702 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
703 if (!mask
&& val
== 0) {
705 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
711 for (i
= 0; i
< count
; i
++) {
719 for (i
= 0; i
< count
; i
++) {
728 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
729 const GLint x
[], const GLint y
[], const void *values
,
732 /* treat 4*GLubyte as 1*GLuint */
733 const GLuint
*src
= (const GLuint
*) values
;
735 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
736 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
737 for (i
= 0; i
< count
; i
++) {
738 if (!mask
|| mask
[i
]) {
739 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
747 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
748 GLuint count
, const GLint x
[], const GLint y
[],
749 const void *value
, const GLubyte
*mask
)
751 /* treat 4*GLubyte as 1*GLuint */
752 const GLuint val
= *((const GLuint
*) value
);
754 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
755 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
756 for (i
= 0; i
< count
; i
++) {
757 if (!mask
|| mask
[i
]) {
758 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
765 /**********************************************************************
766 * Functions for buffers of 4 X GLushort (or GLshort) values.
767 * Typically accum buffer.
771 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
776 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
777 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
782 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
783 GLint x
, GLint y
, void *values
)
785 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
786 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
787 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
792 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
793 const GLint x
[], const GLint y
[], void *values
)
795 GLushort
*dst
= (GLushort
*) values
;
797 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
798 for (i
= 0; i
< count
; i
++) {
800 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
807 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
808 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
810 const GLushort
*src
= (const GLushort
*) values
;
811 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
812 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
815 for (i
= 0; i
< count
; i
++) {
817 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
818 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
819 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
820 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
825 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
831 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
832 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
834 /* Put RGB values in RGBA buffer */
835 const GLushort
*src
= (const GLushort
*) values
;
836 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
837 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
840 for (i
= 0; i
< count
; i
++) {
842 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
843 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
844 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
845 dst
[i
* 4 + 3] = 0xffff;
850 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
856 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
857 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
859 const GLushort val0
= ((const GLushort
*) value
)[0];
860 const GLushort val1
= ((const GLushort
*) value
)[1];
861 const GLushort val2
= ((const GLushort
*) value
)[2];
862 const GLushort val3
= ((const GLushort
*) value
)[3];
863 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
864 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
865 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
866 /* common case for clearing accum buffer */
867 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
871 for (i
= 0; i
< count
; i
++) {
872 if (!mask
|| mask
[i
]) {
873 dst
[i
* 4 + 0] = val0
;
874 dst
[i
* 4 + 1] = val1
;
875 dst
[i
* 4 + 2] = val2
;
876 dst
[i
* 4 + 3] = val3
;
884 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
885 const GLint x
[], const GLint y
[], const void *values
,
888 const GLushort
*src
= (const GLushort
*) values
;
890 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
891 for (i
= 0; i
< count
; i
++) {
892 if (!mask
|| mask
[i
]) {
893 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
894 dst
[0] = src
[i
* 4 + 0];
895 dst
[1] = src
[i
* 4 + 1];
896 dst
[2] = src
[i
* 4 + 2];
897 dst
[3] = src
[i
* 4 + 3];
904 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
905 GLuint count
, const GLint x
[], const GLint y
[],
906 const void *value
, const GLubyte
*mask
)
908 const GLushort val0
= ((const GLushort
*) value
)[0];
909 const GLushort val1
= ((const GLushort
*) value
)[1];
910 const GLushort val2
= ((const GLushort
*) value
)[2];
911 const GLushort val3
= ((const GLushort
*) value
)[3];
913 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
914 for (i
= 0; i
< count
; i
++) {
915 if (!mask
|| mask
[i
]) {
916 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
928 * This is a software fallback for the gl_renderbuffer->AllocStorage
930 * Device drivers will typically override this function for the buffers
931 * which it manages (typically color buffers, Z and stencil).
932 * Other buffers (like software accumulation and aux buffers) which the driver
933 * doesn't manage can be handled with this function.
935 * This one multi-purpose function can allocate stencil, depth, accum, color
936 * or color-index buffers!
938 * This function also plugs in the appropriate GetPointer, Get/PutRow and
939 * Get/PutValues functions.
942 _mesa_soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
943 GLenum internalFormat
,
944 GLuint width
, GLuint height
)
948 /* first clear these fields */
957 switch (internalFormat
) {
966 rb
->_ActualFormat
= GL_RGB8
;
967 rb
->_BaseFormat
= GL_RGB
;
968 rb
->DataType
= GL_UNSIGNED_BYTE
;
969 rb
->GetPointer
= get_pointer_ubyte3
;
970 rb
->GetRow
= get_row_ubyte3
;
971 rb
->GetValues
= get_values_ubyte3
;
972 rb
->PutRow
= put_row_ubyte3
;
973 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
974 rb
->PutMonoRow
= put_mono_row_ubyte3
;
975 rb
->PutValues
= put_values_ubyte3
;
976 rb
->PutMonoValues
= put_mono_values_ubyte3
;
977 rb
->RedBits
= 8 * sizeof(GLubyte
);
978 rb
->GreenBits
= 8 * sizeof(GLubyte
);
979 rb
->BlueBits
= 8 * sizeof(GLubyte
);
981 pixelSize
= 3 * sizeof(GLubyte
);
988 rb
->_ActualFormat
= GL_RGBA8
;
989 rb
->_BaseFormat
= GL_RGBA
;
990 rb
->DataType
= GL_UNSIGNED_BYTE
;
991 rb
->GetPointer
= get_pointer_ubyte4
;
992 rb
->GetRow
= get_row_ubyte4
;
993 rb
->GetValues
= get_values_ubyte4
;
994 rb
->PutRow
= put_row_ubyte4
;
995 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
996 rb
->PutMonoRow
= put_mono_row_ubyte4
;
997 rb
->PutValues
= put_values_ubyte4
;
998 rb
->PutMonoValues
= put_mono_values_ubyte4
;
999 rb
->RedBits
= 8 * sizeof(GLubyte
);
1000 rb
->GreenBits
= 8 * sizeof(GLubyte
);
1001 rb
->BlueBits
= 8 * sizeof(GLubyte
);
1002 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1003 pixelSize
= 4 * sizeof(GLubyte
);
1008 rb
->_ActualFormat
= GL_RGBA16
;
1009 rb
->_BaseFormat
= GL_RGBA
;
1010 rb
->DataType
= GL_UNSIGNED_SHORT
;
1011 rb
->GetPointer
= get_pointer_ushort4
;
1012 rb
->GetRow
= get_row_ushort4
;
1013 rb
->GetValues
= get_values_ushort4
;
1014 rb
->PutRow
= put_row_ushort4
;
1015 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1016 rb
->PutMonoRow
= put_mono_row_ushort4
;
1017 rb
->PutValues
= put_values_ushort4
;
1018 rb
->PutMonoValues
= put_mono_values_ushort4
;
1019 rb
->RedBits
= 8 * sizeof(GLushort
);
1020 rb
->GreenBits
= 8 * sizeof(GLushort
);
1021 rb
->BlueBits
= 8 * sizeof(GLushort
);
1022 rb
->AlphaBits
= 8 * sizeof(GLushort
);
1023 pixelSize
= 4 * sizeof(GLushort
);
1027 rb
->_ActualFormat
= GL_ALPHA8
;
1028 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
1029 rb
->DataType
= GL_UNSIGNED_BYTE
;
1030 rb
->GetPointer
= get_pointer_alpha8
;
1031 rb
->GetRow
= get_row_alpha8
;
1032 rb
->GetValues
= get_values_alpha8
;
1033 rb
->PutRow
= put_row_alpha8
;
1034 rb
->PutRowRGB
= NULL
;
1035 rb
->PutMonoRow
= put_mono_row_alpha8
;
1036 rb
->PutValues
= put_values_alpha8
;
1037 rb
->PutMonoValues
= put_mono_values_alpha8
;
1038 rb
->RedBits
= 0; /*red*/
1039 rb
->GreenBits
= 0; /*green*/
1040 rb
->BlueBits
= 0; /*blue*/
1041 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1042 pixelSize
= sizeof(GLubyte
);
1045 case GL_STENCIL_INDEX
:
1046 case GL_STENCIL_INDEX1_EXT
:
1047 case GL_STENCIL_INDEX4_EXT
:
1048 case GL_STENCIL_INDEX8_EXT
:
1049 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1050 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1051 rb
->DataType
= GL_UNSIGNED_BYTE
;
1052 rb
->GetPointer
= get_pointer_ubyte
;
1053 rb
->GetRow
= get_row_ubyte
;
1054 rb
->GetValues
= get_values_ubyte
;
1055 rb
->PutRow
= put_row_ubyte
;
1056 rb
->PutRowRGB
= NULL
;
1057 rb
->PutMonoRow
= put_mono_row_ubyte
;
1058 rb
->PutValues
= put_values_ubyte
;
1059 rb
->PutMonoValues
= put_mono_values_ubyte
;
1060 rb
->StencilBits
= 8 * sizeof(GLubyte
);
1061 pixelSize
= sizeof(GLubyte
);
1063 case GL_STENCIL_INDEX16_EXT
:
1064 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1065 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1066 rb
->DataType
= GL_UNSIGNED_SHORT
;
1067 rb
->GetPointer
= get_pointer_ushort
;
1068 rb
->GetRow
= get_row_ushort
;
1069 rb
->GetValues
= get_values_ushort
;
1070 rb
->PutRow
= put_row_ushort
;
1071 rb
->PutRowRGB
= NULL
;
1072 rb
->PutMonoRow
= put_mono_row_ushort
;
1073 rb
->PutValues
= put_values_ushort
;
1074 rb
->PutMonoValues
= put_mono_values_ushort
;
1075 rb
->StencilBits
= 8 * sizeof(GLushort
);
1076 pixelSize
= sizeof(GLushort
);
1078 case GL_DEPTH_COMPONENT
:
1079 case GL_DEPTH_COMPONENT16
:
1080 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1081 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1082 rb
->DataType
= GL_UNSIGNED_SHORT
;
1083 rb
->GetPointer
= get_pointer_ushort
;
1084 rb
->GetRow
= get_row_ushort
;
1085 rb
->GetValues
= get_values_ushort
;
1086 rb
->PutRow
= put_row_ushort
;
1087 rb
->PutRowRGB
= NULL
;
1088 rb
->PutMonoRow
= put_mono_row_ushort
;
1089 rb
->PutValues
= put_values_ushort
;
1090 rb
->PutMonoValues
= put_mono_values_ushort
;
1091 rb
->DepthBits
= 8 * sizeof(GLushort
);
1092 pixelSize
= sizeof(GLushort
);
1094 case GL_DEPTH_COMPONENT24
:
1095 case GL_DEPTH_COMPONENT32
:
1096 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1097 rb
->DataType
= GL_UNSIGNED_INT
;
1098 rb
->GetPointer
= get_pointer_uint
;
1099 rb
->GetRow
= get_row_uint
;
1100 rb
->GetValues
= get_values_uint
;
1101 rb
->PutRow
= put_row_uint
;
1102 rb
->PutRowRGB
= NULL
;
1103 rb
->PutMonoRow
= put_mono_row_uint
;
1104 rb
->PutValues
= put_values_uint
;
1105 rb
->PutMonoValues
= put_mono_values_uint
;
1106 if (internalFormat
== GL_DEPTH_COMPONENT24
) {
1107 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1111 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1114 pixelSize
= sizeof(GLuint
);
1116 case GL_DEPTH_STENCIL_EXT
:
1117 case GL_DEPTH24_STENCIL8_EXT
:
1118 rb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
1119 rb
->_BaseFormat
= GL_DEPTH_STENCIL_EXT
;
1120 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1121 rb
->GetPointer
= get_pointer_uint
;
1122 rb
->GetRow
= get_row_uint
;
1123 rb
->GetValues
= get_values_uint
;
1124 rb
->PutRow
= put_row_uint
;
1125 rb
->PutRowRGB
= NULL
;
1126 rb
->PutMonoRow
= put_mono_row_uint
;
1127 rb
->PutValues
= put_values_uint
;
1128 rb
->PutMonoValues
= put_mono_values_uint
;
1130 rb
->StencilBits
= 8;
1131 pixelSize
= sizeof(GLuint
);
1133 case GL_COLOR_INDEX8_EXT
:
1134 rb
->_ActualFormat
= GL_COLOR_INDEX8_EXT
;
1135 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1136 rb
->DataType
= GL_UNSIGNED_BYTE
;
1137 rb
->GetPointer
= get_pointer_ubyte
;
1138 rb
->GetRow
= get_row_ubyte
;
1139 rb
->GetValues
= get_values_ubyte
;
1140 rb
->PutRow
= put_row_ubyte
;
1141 rb
->PutRowRGB
= NULL
;
1142 rb
->PutMonoRow
= put_mono_row_ubyte
;
1143 rb
->PutValues
= put_values_ubyte
;
1144 rb
->PutMonoValues
= put_mono_values_ubyte
;
1145 rb
->IndexBits
= 8 * sizeof(GLubyte
);
1146 pixelSize
= sizeof(GLubyte
);
1148 case GL_COLOR_INDEX16_EXT
:
1149 rb
->_ActualFormat
= GL_COLOR_INDEX16_EXT
;
1150 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1151 rb
->DataType
= GL_UNSIGNED_SHORT
;
1152 rb
->GetPointer
= get_pointer_ushort
;
1153 rb
->GetRow
= get_row_ushort
;
1154 rb
->GetValues
= get_values_ushort
;
1155 rb
->PutRow
= put_row_ushort
;
1156 rb
->PutRowRGB
= NULL
;
1157 rb
->PutMonoRow
= put_mono_row_ushort
;
1158 rb
->PutValues
= put_values_ushort
;
1159 rb
->PutMonoValues
= put_mono_values_ushort
;
1160 rb
->IndexBits
= 8 * sizeof(GLushort
);
1161 pixelSize
= sizeof(GLushort
);
1164 rb
->_ActualFormat
= COLOR_INDEX32
;
1165 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1166 rb
->DataType
= GL_UNSIGNED_INT
;
1167 rb
->GetPointer
= get_pointer_uint
;
1168 rb
->GetRow
= get_row_uint
;
1169 rb
->GetValues
= get_values_uint
;
1170 rb
->PutRow
= put_row_uint
;
1171 rb
->PutRowRGB
= NULL
;
1172 rb
->PutMonoRow
= put_mono_row_uint
;
1173 rb
->PutValues
= put_values_uint
;
1174 rb
->PutMonoValues
= put_mono_values_uint
;
1175 rb
->IndexBits
= 8 * sizeof(GLuint
);
1176 pixelSize
= sizeof(GLuint
);
1179 _mesa_problem(ctx
, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
1183 ASSERT(rb
->DataType
);
1184 ASSERT(rb
->GetPointer
);
1186 ASSERT(rb
->GetValues
);
1188 ASSERT(rb
->PutMonoRow
);
1189 ASSERT(rb
->PutValues
);
1190 ASSERT(rb
->PutMonoValues
);
1192 /* free old buffer storage */
1194 _mesa_free(rb
->Data
);
1196 /* allocate new buffer storage */
1197 rb
->Data
= _mesa_malloc(width
* height
* pixelSize
);
1198 if (rb
->Data
== NULL
) {
1201 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1202 "software renderbuffer allocation (%d x %d x %d)",
1203 width
, height
, pixelSize
);
1208 rb
->Height
= height
;
1215 /**********************************************************************/
1216 /**********************************************************************/
1217 /**********************************************************************/
1221 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1222 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1224 * When PutRow is called (for example), we store the alpha values in
1225 * this buffer, then pass on the PutRow call to the wrapped RGB
1231 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1232 GLenum internalFormat
, GLuint width
, GLuint height
)
1234 ASSERT(arb
!= arb
->Wrapped
);
1235 ASSERT(arb
->_ActualFormat
== GL_ALPHA8
);
1237 /* first, pass the call to the wrapped RGB buffer */
1238 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1243 /* next, resize my alpha buffer */
1245 _mesa_free(arb
->Data
);
1248 arb
->Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1249 if (arb
->Data
== NULL
) {
1252 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1257 arb
->Height
= height
;
1264 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1267 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1270 _mesa_free(arb
->Data
);
1272 ASSERT(arb
->Wrapped
);
1273 ASSERT(arb
!= arb
->Wrapped
);
1274 arb
->Wrapped
->Delete(arb
->Wrapped
);
1275 arb
->Wrapped
= NULL
;
1281 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1284 return NULL
; /* don't allow direct access! */
1289 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1290 GLint x
, GLint y
, void *values
)
1292 /* NOTE: 'values' is RGBA format! */
1293 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1294 GLubyte
*dst
= (GLubyte
*) values
;
1296 ASSERT(arb
!= arb
->Wrapped
);
1297 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1298 /* first, pass the call to the wrapped RGB buffer */
1299 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1300 /* second, fill in alpha values from this buffer! */
1301 for (i
= 0; i
< count
; i
++) {
1302 dst
[i
* 4 + 3] = src
[i
];
1308 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1309 const GLint x
[], const GLint y
[], void *values
)
1311 GLubyte
*dst
= (GLubyte
*) values
;
1313 ASSERT(arb
!= arb
->Wrapped
);
1314 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1315 /* first, pass the call to the wrapped RGB buffer */
1316 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1317 /* second, fill in alpha values from this buffer! */
1318 for (i
= 0; i
< count
; i
++) {
1319 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1320 dst
[i
* 4 + 3] = *src
;
1326 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1327 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1329 const GLubyte
*src
= (const GLubyte
*) values
;
1330 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1332 ASSERT(arb
!= arb
->Wrapped
);
1333 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1334 /* first, pass the call to the wrapped RGB buffer */
1335 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1336 /* second, store alpha in our buffer */
1337 for (i
= 0; i
< count
; i
++) {
1338 if (!mask
|| mask
[i
]) {
1339 dst
[i
] = src
[i
* 4 + 3];
1346 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1347 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1349 const GLubyte
*src
= (const GLubyte
*) values
;
1350 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1352 ASSERT(arb
!= arb
->Wrapped
);
1353 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1354 /* first, pass the call to the wrapped RGB buffer */
1355 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1356 /* second, store alpha in our buffer */
1357 for (i
= 0; i
< count
; i
++) {
1358 if (!mask
|| mask
[i
]) {
1359 dst
[i
] = src
[i
* 4 + 3];
1366 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1367 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1369 const GLubyte val
= ((const GLubyte
*) value
)[3];
1370 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1371 ASSERT(arb
!= arb
->Wrapped
);
1372 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1373 /* first, pass the call to the wrapped RGB buffer */
1374 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1375 /* second, store alpha in our buffer */
1378 for (i
= 0; i
< count
; i
++) {
1385 _mesa_memset(dst
, val
, count
);
1391 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1392 const GLint x
[], const GLint y
[],
1393 const void *values
, const GLubyte
*mask
)
1395 const GLubyte
*src
= (const GLubyte
*) values
;
1397 ASSERT(arb
!= arb
->Wrapped
);
1398 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1399 /* first, pass the call to the wrapped RGB buffer */
1400 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1401 /* second, store alpha in our buffer */
1402 for (i
= 0; i
< count
; i
++) {
1403 if (!mask
|| mask
[i
]) {
1404 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1405 *dst
= src
[i
* 4 + 3];
1412 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1413 GLuint count
, const GLint x
[], const GLint y
[],
1414 const void *value
, const GLubyte
*mask
)
1416 const GLubyte val
= ((const GLubyte
*) value
)[3];
1418 ASSERT(arb
!= arb
->Wrapped
);
1419 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1420 /* first, pass the call to the wrapped RGB buffer */
1421 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1422 /* second, store alpha in our buffer */
1423 for (i
= 0; i
< count
; i
++) {
1424 if (!mask
|| mask
[i
]) {
1425 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1433 /**********************************************************************/
1434 /**********************************************************************/
1435 /**********************************************************************/
1439 * Default GetPointer routine. Always return NULL to indicate that
1440 * direct buffer access is not supported.
1443 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1450 * Initialize the fields of a gl_renderbuffer to default values.
1453 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1455 _glthread_INIT_MUTEX(rb
->Mutex
);
1460 rb
->Delete
= _mesa_delete_renderbuffer
;
1462 /* The rest of these should be set later by the caller of this function or
1463 * the AllocStorage method:
1465 rb
->AllocStorage
= NULL
;
1469 rb
->InternalFormat
= GL_NONE
;
1470 rb
->_ActualFormat
= GL_NONE
;
1471 rb
->_BaseFormat
= GL_NONE
;
1472 rb
->DataType
= GL_NONE
;
1473 rb
->RedBits
= rb
->GreenBits
= rb
->BlueBits
= rb
->AlphaBits
= 0;
1476 rb
->StencilBits
= 0;
1479 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1480 * all over the drivers.
1484 rb
->GetPointer
= nop_get_pointer
;
1486 rb
->GetValues
= NULL
;
1488 rb
->PutRowRGB
= NULL
;
1489 rb
->PutMonoRow
= NULL
;
1490 rb
->PutValues
= NULL
;
1491 rb
->PutMonoValues
= NULL
;
1496 * Allocate a new gl_renderbuffer object. This can be used for user-created
1497 * renderbuffers or window-system renderbuffers.
1499 struct gl_renderbuffer
*
1500 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1502 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1504 _mesa_init_renderbuffer(rb
, name
);
1511 * Delete a gl_framebuffer.
1512 * This is the default function for framebuffer->Delete().
1515 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1518 _mesa_free(rb
->Data
);
1520 _glthread_INIT_MUTEX(rb
->Mutex
);
1526 * Allocate a software-based renderbuffer. This is called via the
1527 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1529 * This would not be used for hardware-based renderbuffers.
1531 struct gl_renderbuffer
*
1532 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1534 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1536 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1537 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1538 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1547 * Add software-based color renderbuffers to the given framebuffer.
1548 * This is a helper routine for device drivers when creating a
1549 * window system framebuffer (not a user-created render/framebuffer).
1550 * Once this function is called, you can basically forget about this
1551 * renderbuffer; core Mesa will handle all the buffer management and
1555 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1556 GLuint rgbBits
, GLuint alphaBits
,
1557 GLboolean frontLeft
, GLboolean backLeft
,
1558 GLboolean frontRight
, GLboolean backRight
)
1562 if (rgbBits
> 16 || alphaBits
> 16) {
1564 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1568 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1570 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1571 struct gl_renderbuffer
*rb
;
1573 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1575 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1577 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1579 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1582 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1584 rb
= _mesa_new_renderbuffer(ctx
, 0);
1586 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1592 rb
->_ActualFormat
= GL_RGBA8
;
1594 rb
->_ActualFormat
= GL_RGB8
;
1597 assert(rgbBits
<= 16);
1599 rb
->_ActualFormat
= GL_RGBA16
;
1601 rb
->_ActualFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1603 rb
->InternalFormat
= rb
->_ActualFormat
;
1605 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1606 _mesa_add_renderbuffer(fb
, b
, rb
);
1614 * Add software-based color index renderbuffers to the given framebuffer.
1615 * This is a helper routine for device drivers when creating a
1616 * window system framebuffer (not a user-created render/framebuffer).
1617 * Once this function is called, you can basically forget about this
1618 * renderbuffer; core Mesa will handle all the buffer management and
1622 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1624 GLboolean frontLeft
, GLboolean backLeft
,
1625 GLboolean frontRight
, GLboolean backRight
)
1629 if (indexBits
> 8) {
1631 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1635 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1637 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1638 struct gl_renderbuffer
*rb
;
1640 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1642 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1644 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1646 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1649 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1651 rb
= _mesa_new_renderbuffer(ctx
, 0);
1653 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1657 if (indexBits
<= 8) {
1658 /* only support GLuint for now */
1659 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1660 rb
->_ActualFormat
= COLOR_INDEX32
;
1663 rb
->_ActualFormat
= COLOR_INDEX32
;
1665 rb
->InternalFormat
= rb
->_ActualFormat
;
1667 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1668 _mesa_add_renderbuffer(fb
, b
, rb
);
1676 * Add software-based alpha renderbuffers to the given framebuffer.
1677 * This is a helper routine for device drivers when creating a
1678 * window system framebuffer (not a user-created render/framebuffer).
1679 * Once this function is called, you can basically forget about this
1680 * renderbuffer; core Mesa will handle all the buffer management and
1684 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1686 GLboolean frontLeft
, GLboolean backLeft
,
1687 GLboolean frontRight
, GLboolean backRight
)
1691 /* for window system framebuffers only! */
1692 assert(fb
->Name
== 0);
1694 if (alphaBits
> 8) {
1696 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1700 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1702 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1704 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1705 struct gl_renderbuffer
*arb
;
1707 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1709 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1711 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1713 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1716 /* the RGB buffer to wrap must already exist!! */
1717 assert(fb
->Attachment
[b
].Renderbuffer
);
1719 /* only GLubyte supported for now */
1720 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1722 /* allocate alpha renderbuffer */
1723 arb
= _mesa_new_renderbuffer(ctx
, 0);
1725 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1729 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1730 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1732 /* Set up my alphabuffer fields and plug in my functions.
1733 * The functions will put/get the alpha values from/to RGBA arrays
1734 * and then call the wrapped buffer's functions to handle the RGB
1737 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1738 arb
->_ActualFormat
= GL_ALPHA8
;
1739 arb
->_BaseFormat
= arb
->Wrapped
->_BaseFormat
;
1740 arb
->DataType
= arb
->Wrapped
->DataType
;
1741 arb
->AllocStorage
= alloc_storage_alpha8
;
1742 arb
->Delete
= delete_renderbuffer_alpha8
;
1743 arb
->GetPointer
= get_pointer_alpha8
;
1744 arb
->GetRow
= get_row_alpha8
;
1745 arb
->GetValues
= get_values_alpha8
;
1746 arb
->PutRow
= put_row_alpha8
;
1747 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1748 arb
->PutMonoRow
= put_mono_row_alpha8
;
1749 arb
->PutValues
= put_values_alpha8
;
1750 arb
->PutMonoValues
= put_mono_values_alpha8
;
1752 /* clear the pointer to avoid assertion/sanity check failure later */
1753 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1755 /* plug the alpha renderbuffer into the colorbuffer attachment */
1756 _mesa_add_renderbuffer(fb
, b
, arb
);
1764 * Add a software-based depth renderbuffer to the given framebuffer.
1765 * This is a helper routine for device drivers when creating a
1766 * window system framebuffer (not a user-created render/framebuffer).
1767 * Once this function is called, you can basically forget about this
1768 * renderbuffer; core Mesa will handle all the buffer management and
1772 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1775 struct gl_renderbuffer
*rb
;
1777 if (depthBits
> 32) {
1779 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1783 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1785 rb
= _mesa_new_renderbuffer(ctx
, 0);
1787 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1791 if (depthBits
<= 16) {
1792 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1794 else if (depthBits
<= 24) {
1795 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1798 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1800 rb
->InternalFormat
= rb
->_ActualFormat
;
1802 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1803 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1810 * Add a software-based stencil renderbuffer to the given framebuffer.
1811 * This is a helper routine for device drivers when creating a
1812 * window system framebuffer (not a user-created render/framebuffer).
1813 * Once this function is called, you can basically forget about this
1814 * renderbuffer; core Mesa will handle all the buffer management and
1818 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1821 struct gl_renderbuffer
*rb
;
1823 if (stencilBits
> 16) {
1825 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1829 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1831 rb
= _mesa_new_renderbuffer(ctx
, 0);
1833 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1837 if (stencilBits
<= 8) {
1838 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1841 /* not really supported (see s_stencil.c code) */
1842 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1844 rb
->InternalFormat
= rb
->_ActualFormat
;
1846 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1847 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1854 * Add a software-based accumulation renderbuffer to the given framebuffer.
1855 * This is a helper routine for device drivers when creating a
1856 * window system framebuffer (not a user-created render/framebuffer).
1857 * Once this function is called, you can basically forget about this
1858 * renderbuffer; core Mesa will handle all the buffer management and
1862 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1863 GLuint redBits
, GLuint greenBits
,
1864 GLuint blueBits
, GLuint alphaBits
)
1866 struct gl_renderbuffer
*rb
;
1868 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1870 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1874 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1876 rb
= _mesa_new_renderbuffer(ctx
, 0);
1878 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1882 rb
->_ActualFormat
= GL_RGBA16
;
1883 rb
->InternalFormat
= GL_RGBA16
;
1884 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1885 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1893 * Add a software-based accumulation renderbuffer to the given framebuffer.
1894 * This is a helper routine for device drivers when creating a
1895 * window system framebuffer (not a user-created render/framebuffer).
1896 * Once this function is called, you can basically forget about this
1897 * renderbuffer; core Mesa will handle all the buffer management and
1900 * NOTE: color-index aux buffers not supported.
1903 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1904 GLuint colorBits
, GLuint numBuffers
)
1908 if (colorBits
> 16) {
1910 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1914 assert(numBuffers
< MAX_AUX_BUFFERS
);
1916 for (i
= 0; i
< numBuffers
; i
++) {
1917 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1919 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1922 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1926 if (colorBits
<= 8) {
1927 rb
->_ActualFormat
= GL_RGBA8
;
1930 rb
->_ActualFormat
= GL_RGBA16
;
1932 rb
->InternalFormat
= rb
->_ActualFormat
;
1934 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1935 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1942 * Create/attach software-based renderbuffers to the given framebuffer.
1943 * This is a helper routine for device drivers. Drivers can just as well
1944 * call the individual _mesa_add_*_renderbuffer() routines directly.
1947 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1955 GLboolean frontLeft
= GL_TRUE
;
1956 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1957 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1958 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1961 if (fb
->Visual
.rgbMode
) {
1962 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1963 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1964 _mesa_add_color_renderbuffers(NULL
, fb
,
1966 fb
->Visual
.alphaBits
,
1967 frontLeft
, backLeft
,
1968 frontRight
, backRight
);
1971 _mesa_add_color_index_renderbuffers(NULL
, fb
,
1972 fb
->Visual
.indexBits
,
1973 frontLeft
, backLeft
,
1974 frontRight
, backRight
);
1979 assert(fb
->Visual
.depthBits
> 0);
1980 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1984 assert(fb
->Visual
.stencilBits
> 0);
1985 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1989 assert(fb
->Visual
.rgbMode
);
1990 assert(fb
->Visual
.accumRedBits
> 0);
1991 assert(fb
->Visual
.accumGreenBits
> 0);
1992 assert(fb
->Visual
.accumBlueBits
> 0);
1993 _mesa_add_accum_renderbuffer(NULL
, fb
,
1994 fb
->Visual
.accumRedBits
,
1995 fb
->Visual
.accumGreenBits
,
1996 fb
->Visual
.accumBlueBits
,
1997 fb
->Visual
.accumAlphaBits
);
2001 assert(fb
->Visual
.rgbMode
);
2002 assert(fb
->Visual
.numAuxBuffers
> 0);
2003 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
2004 fb
->Visual
.numAuxBuffers
);
2008 assert(fb
->Visual
.rgbMode
);
2009 assert(fb
->Visual
.alphaBits
> 0);
2010 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
2011 frontLeft
, backLeft
,
2012 frontRight
, backRight
);
2024 * Attach a renderbuffer to a framebuffer.
2027 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
2028 GLuint bufferName
, struct gl_renderbuffer
*rb
)
2033 /* there should be no previous renderbuffer on this attachment point! */
2034 assert(fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
2036 assert(bufferName
< BUFFER_COUNT
);
2038 /* winsys vs. user-created buffer cross check */
2046 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
2047 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
2048 fb
->Attachment
[bufferName
].Renderbuffer
= rb
;
2053 * Create a new combined depth/stencil renderbuffer for implementing
2054 * the GL_EXT_packed_depth_stencil extension.
2055 * \return new depth/stencil renderbuffer
2057 struct gl_renderbuffer
*
2058 _mesa_new_depthstencil_renderbuffer(GLcontext
*ctx
, GLuint name
)
2060 struct gl_renderbuffer
*dsrb
;
2062 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
2066 /* init fields not covered by _mesa_new_renderbuffer() */
2067 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
2068 dsrb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
2069 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;