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"
50 #include "rbadaptors.h"
53 /* 32-bit color index format. Not a public format. */
54 #define COLOR_INDEX32 0x424243
58 * Routines for get/put values in common buffer formats follow.
59 * Someday add support for arbitrary row stride to make them more
63 /**********************************************************************
64 * Functions for buffers of 1 X GLubyte values.
69 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
74 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
75 /* Can't assert _ActualFormat since these funcs may be used for serveral
76 * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
78 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
83 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
84 GLint x
, GLint y
, void *values
)
86 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
87 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
88 _mesa_memcpy(values
, src
, count
* sizeof(GLubyte
));
93 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
94 const GLint x
[], const GLint y
[], void *values
)
96 GLubyte
*dst
= (GLubyte
*) values
;
98 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
99 for (i
= 0; i
< count
; i
++) {
100 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
107 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
108 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
110 const GLubyte
*src
= (const GLubyte
*) values
;
111 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
112 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
115 for (i
= 0; i
< count
; i
++) {
122 _mesa_memcpy(dst
, values
, count
* sizeof(GLubyte
));
128 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
129 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
131 const GLubyte val
= *((const GLubyte
*) value
);
132 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
133 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
136 for (i
= 0; i
< count
; i
++) {
144 for (i
= 0; i
< count
; i
++) {
152 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
153 const GLint x
[], const GLint y
[],
154 const void *values
, const GLubyte
*mask
)
156 const GLubyte
*src
= (const GLubyte
*) values
;
158 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
159 for (i
= 0; i
< count
; i
++) {
160 if (!mask
|| mask
[i
]) {
161 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
169 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
170 const GLint x
[], const GLint y
[],
171 const void *value
, const GLubyte
*mask
)
173 const GLubyte val
= *((const GLubyte
*) value
);
175 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
176 for (i
= 0; i
< count
; i
++) {
177 if (!mask
|| mask
[i
]) {
178 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
185 /**********************************************************************
186 * Functions for buffers of 1 X GLushort values.
191 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
196 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
197 ASSERT(rb
->Width
> 0);
198 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
203 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
204 GLint x
, GLint y
, void *values
)
206 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
207 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
208 _mesa_memcpy(values
, src
, count
* sizeof(GLushort
));
213 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
214 const GLint x
[], const GLint y
[], void *values
)
216 GLushort
*dst
= (GLushort
*) values
;
218 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
219 for (i
= 0; i
< count
; i
++) {
220 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
227 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
228 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
230 const GLushort
*src
= (const GLushort
*) values
;
231 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
232 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
235 for (i
= 0; i
< count
; i
++) {
242 _mesa_memcpy(dst
, src
, count
* sizeof(GLushort
));
248 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
249 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
251 const GLushort val
= *((const GLushort
*) value
);
252 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
253 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
256 for (i
= 0; i
< count
; i
++) {
264 for (i
= 0; i
< count
; i
++) {
272 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
273 const GLint x
[], const GLint y
[], const void *values
,
276 const GLushort
*src
= (const GLushort
*) values
;
278 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
279 for (i
= 0; i
< count
; i
++) {
280 if (!mask
|| mask
[i
]) {
281 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
289 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
290 GLuint count
, const GLint x
[], const GLint y
[],
291 const void *value
, const GLubyte
*mask
)
293 const GLushort val
= *((const GLushort
*) value
);
294 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
297 for (i
= 0; i
< count
; i
++) {
299 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
306 for (i
= 0; i
< count
; i
++) {
307 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
314 /**********************************************************************
315 * Functions for buffers of 1 X GLuint values.
316 * Typically depth/Z or color index.
320 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
325 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
326 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
327 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
332 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
333 GLint x
, GLint y
, void *values
)
335 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
336 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
337 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
338 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
343 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
344 const GLint x
[], const GLint y
[], void *values
)
346 GLuint
*dst
= (GLuint
*) values
;
348 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
349 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
350 for (i
= 0; i
< count
; i
++) {
351 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
358 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
359 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
361 const GLuint
*src
= (const GLuint
*) values
;
362 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
363 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
364 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
367 for (i
= 0; i
< count
; i
++) {
374 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
380 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
381 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
383 const GLuint val
= *((const GLuint
*) value
);
384 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
385 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
386 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
389 for (i
= 0; i
< count
; i
++) {
397 for (i
= 0; i
< count
; i
++) {
405 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
406 const GLint x
[], const GLint y
[], const void *values
,
409 const GLuint
*src
= (const GLuint
*) values
;
411 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
412 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
413 for (i
= 0; i
< count
; i
++) {
414 if (!mask
|| mask
[i
]) {
415 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
423 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
424 const GLint x
[], const GLint y
[], const void *value
,
427 const GLuint val
= *((const GLuint
*) value
);
429 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
430 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
431 for (i
= 0; i
< count
; i
++) {
432 if (!mask
|| mask
[i
]) {
433 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
440 /**********************************************************************
441 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
442 * Typically color buffers.
443 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
444 * alpha values and return 255 for outgoing alpha values.
448 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
451 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
452 /* No direct access since this buffer is RGB but caller will be
453 * treating it as if it were RGBA.
460 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
461 GLint x
, GLint y
, void *values
)
463 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
464 GLubyte
*dst
= (GLubyte
*) values
;
466 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
467 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
468 for (i
= 0; i
< count
; i
++) {
469 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
470 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
471 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
472 dst
[i
* 4 + 3] = 255;
478 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
479 const GLint x
[], const GLint y
[], void *values
)
481 GLubyte
*dst
= (GLubyte
*) values
;
483 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
484 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
485 for (i
= 0; i
< count
; i
++) {
487 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
488 dst
[i
* 4 + 0] = src
[0];
489 dst
[i
* 4 + 1] = src
[1];
490 dst
[i
* 4 + 2] = src
[2];
491 dst
[i
* 4 + 3] = 255;
497 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
498 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
500 /* note: incoming values are RGB+A! */
501 const GLubyte
*src
= (const GLubyte
*) values
;
502 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
504 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
505 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
506 for (i
= 0; i
< count
; i
++) {
507 if (!mask
|| mask
[i
]) {
508 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
509 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
510 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
517 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
518 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
520 /* note: incoming values are RGB+A! */
521 const GLubyte
*src
= (const GLubyte
*) values
;
522 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
524 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
525 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
526 for (i
= 0; i
< count
; i
++) {
527 if (!mask
|| mask
[i
]) {
528 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
529 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
530 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
537 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
538 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
540 /* note: incoming value is RGB+A! */
541 const GLubyte val0
= ((const GLubyte
*) value
)[0];
542 const GLubyte val1
= ((const GLubyte
*) value
)[1];
543 const GLubyte val2
= ((const GLubyte
*) value
)[2];
544 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
545 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
546 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
547 if (!mask
&& val0
== val1
&& val1
== val2
) {
549 _mesa_memset(dst
, val0
, 3 * count
);
553 for (i
= 0; i
< count
; i
++) {
554 if (!mask
|| mask
[i
]) {
555 dst
[i
* 3 + 0] = val0
;
556 dst
[i
* 3 + 1] = val1
;
557 dst
[i
* 3 + 2] = val2
;
565 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
566 const GLint x
[], const GLint y
[], const void *values
,
569 /* note: incoming values are RGB+A! */
570 const GLubyte
*src
= (const GLubyte
*) values
;
572 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
573 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
574 for (i
= 0; i
< count
; i
++) {
575 if (!mask
|| mask
[i
]) {
576 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
577 dst
[0] = src
[i
* 4 + 0];
578 dst
[1] = src
[i
* 4 + 1];
579 dst
[2] = src
[i
* 4 + 2];
586 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
587 GLuint count
, const GLint x
[], const GLint y
[],
588 const void *value
, const GLubyte
*mask
)
590 /* note: incoming value is RGB+A! */
591 const GLubyte val0
= ((const GLubyte
*) value
)[0];
592 const GLubyte val1
= ((const GLubyte
*) value
)[1];
593 const GLubyte val2
= ((const GLubyte
*) value
)[2];
595 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
596 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
597 for (i
= 0; i
< count
; i
++) {
598 if (!mask
|| mask
[i
]) {
599 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
608 /**********************************************************************
609 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
610 * Typically color buffers.
614 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
619 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
620 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
621 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
626 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
627 GLint x
, GLint y
, void *values
)
629 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
630 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
631 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
632 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLubyte
));
637 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
638 const GLint x
[], const GLint y
[], void *values
)
640 /* treat 4*GLubyte as 1*GLuint */
641 GLuint
*dst
= (GLuint
*) values
;
643 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
644 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
645 for (i
= 0; i
< count
; i
++) {
646 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
653 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
654 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
656 /* treat 4*GLubyte as 1*GLuint */
657 const GLuint
*src
= (const GLuint
*) values
;
658 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
659 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
660 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
663 for (i
= 0; i
< count
; i
++) {
670 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
676 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
677 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
679 /* Store RGB values in RGBA buffer */
680 const GLubyte
*src
= (const GLubyte
*) values
;
681 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
683 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
684 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
685 for (i
= 0; i
< count
; i
++) {
686 if (!mask
|| mask
[i
]) {
687 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
688 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
689 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
690 dst
[i
* 4 + 3] = 0xff;
697 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
698 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
700 /* treat 4*GLubyte as 1*GLuint */
701 const GLuint val
= *((const GLuint
*) value
);
702 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
703 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
704 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
705 if (!mask
&& val
== 0) {
707 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
713 for (i
= 0; i
< count
; i
++) {
721 for (i
= 0; i
< count
; i
++) {
730 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
731 const GLint x
[], const GLint y
[], const void *values
,
734 /* treat 4*GLubyte as 1*GLuint */
735 const GLuint
*src
= (const GLuint
*) values
;
737 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
738 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
739 for (i
= 0; i
< count
; i
++) {
740 if (!mask
|| mask
[i
]) {
741 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
749 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
750 GLuint count
, const GLint x
[], const GLint y
[],
751 const void *value
, const GLubyte
*mask
)
753 /* treat 4*GLubyte as 1*GLuint */
754 const GLuint val
= *((const GLuint
*) value
);
756 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
757 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
758 for (i
= 0; i
< count
; i
++) {
759 if (!mask
|| mask
[i
]) {
760 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
767 /**********************************************************************
768 * Functions for buffers of 4 X GLushort (or GLshort) values.
769 * Typically accum buffer.
773 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
778 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
779 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
784 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
785 GLint x
, GLint y
, void *values
)
787 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
788 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
789 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
794 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
795 const GLint x
[], const GLint y
[], void *values
)
797 GLushort
*dst
= (GLushort
*) values
;
799 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
800 for (i
= 0; i
< count
; i
++) {
802 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
809 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
810 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
812 const GLushort
*src
= (const GLushort
*) values
;
813 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
814 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
817 for (i
= 0; i
< count
; i
++) {
819 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
820 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
821 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
822 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
827 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
833 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
834 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
836 /* Put RGB values in RGBA buffer */
837 const GLushort
*src
= (const GLushort
*) values
;
838 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
839 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
842 for (i
= 0; i
< count
; i
++) {
844 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
845 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
846 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
847 dst
[i
* 4 + 3] = 0xffff;
852 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
858 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
859 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
861 const GLushort val0
= ((const GLushort
*) value
)[0];
862 const GLushort val1
= ((const GLushort
*) value
)[1];
863 const GLushort val2
= ((const GLushort
*) value
)[2];
864 const GLushort val3
= ((const GLushort
*) value
)[3];
865 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
866 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
867 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
868 /* common case for clearing accum buffer */
869 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
873 for (i
= 0; i
< count
; i
++) {
874 if (!mask
|| mask
[i
]) {
875 dst
[i
* 4 + 0] = val0
;
876 dst
[i
* 4 + 1] = val1
;
877 dst
[i
* 4 + 2] = val2
;
878 dst
[i
* 4 + 3] = val3
;
886 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
887 const GLint x
[], const GLint y
[], const void *values
,
890 const GLushort
*src
= (const GLushort
*) values
;
892 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
893 for (i
= 0; i
< count
; i
++) {
894 if (!mask
|| mask
[i
]) {
895 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
896 dst
[0] = src
[i
* 4 + 0];
897 dst
[1] = src
[i
* 4 + 1];
898 dst
[2] = src
[i
* 4 + 2];
899 dst
[3] = src
[i
* 4 + 3];
906 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
907 GLuint count
, const GLint x
[], const GLint y
[],
908 const void *value
, const GLubyte
*mask
)
910 const GLushort val0
= ((const GLushort
*) value
)[0];
911 const GLushort val1
= ((const GLushort
*) value
)[1];
912 const GLushort val2
= ((const GLushort
*) value
)[2];
913 const GLushort val3
= ((const GLushort
*) value
)[3];
915 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
916 for (i
= 0; i
< count
; i
++) {
917 if (!mask
|| mask
[i
]) {
918 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
930 * This is a software fallback for the gl_renderbuffer->AllocStorage
932 * Device drivers will typically override this function for the buffers
933 * which it manages (typically color buffers, Z and stencil).
934 * Other buffers (like software accumulation and aux buffers) which the driver
935 * doesn't manage can be handled with this function.
937 * This one multi-purpose function can allocate stencil, depth, accum, color
938 * or color-index buffers!
940 * This function also plugs in the appropriate GetPointer, Get/PutRow and
941 * Get/PutValues functions.
944 _mesa_soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
945 GLenum internalFormat
,
946 GLuint width
, GLuint height
)
950 /* first clear these fields */
959 switch (internalFormat
) {
968 rb
->_ActualFormat
= GL_RGB8
;
969 rb
->_BaseFormat
= GL_RGB
;
970 rb
->DataType
= GL_UNSIGNED_BYTE
;
971 rb
->GetPointer
= get_pointer_ubyte3
;
972 rb
->GetRow
= get_row_ubyte3
;
973 rb
->GetValues
= get_values_ubyte3
;
974 rb
->PutRow
= put_row_ubyte3
;
975 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
976 rb
->PutMonoRow
= put_mono_row_ubyte3
;
977 rb
->PutValues
= put_values_ubyte3
;
978 rb
->PutMonoValues
= put_mono_values_ubyte3
;
979 rb
->RedBits
= 8 * sizeof(GLubyte
);
980 rb
->GreenBits
= 8 * sizeof(GLubyte
);
981 rb
->BlueBits
= 8 * sizeof(GLubyte
);
983 pixelSize
= 3 * sizeof(GLubyte
);
990 rb
->_ActualFormat
= GL_RGBA8
;
991 rb
->_BaseFormat
= GL_RGBA
;
992 rb
->DataType
= GL_UNSIGNED_BYTE
;
993 rb
->GetPointer
= get_pointer_ubyte4
;
994 rb
->GetRow
= get_row_ubyte4
;
995 rb
->GetValues
= get_values_ubyte4
;
996 rb
->PutRow
= put_row_ubyte4
;
997 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
998 rb
->PutMonoRow
= put_mono_row_ubyte4
;
999 rb
->PutValues
= put_values_ubyte4
;
1000 rb
->PutMonoValues
= put_mono_values_ubyte4
;
1001 rb
->RedBits
= 8 * sizeof(GLubyte
);
1002 rb
->GreenBits
= 8 * sizeof(GLubyte
);
1003 rb
->BlueBits
= 8 * sizeof(GLubyte
);
1004 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1005 pixelSize
= 4 * sizeof(GLubyte
);
1010 rb
->_ActualFormat
= GL_RGBA16
;
1011 rb
->_BaseFormat
= GL_RGBA
;
1012 rb
->DataType
= GL_UNSIGNED_SHORT
;
1013 rb
->GetPointer
= get_pointer_ushort4
;
1014 rb
->GetRow
= get_row_ushort4
;
1015 rb
->GetValues
= get_values_ushort4
;
1016 rb
->PutRow
= put_row_ushort4
;
1017 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1018 rb
->PutMonoRow
= put_mono_row_ushort4
;
1019 rb
->PutValues
= put_values_ushort4
;
1020 rb
->PutMonoValues
= put_mono_values_ushort4
;
1021 rb
->RedBits
= 8 * sizeof(GLushort
);
1022 rb
->GreenBits
= 8 * sizeof(GLushort
);
1023 rb
->BlueBits
= 8 * sizeof(GLushort
);
1024 rb
->AlphaBits
= 8 * sizeof(GLushort
);
1025 pixelSize
= 4 * sizeof(GLushort
);
1029 rb
->_ActualFormat
= GL_ALPHA8
;
1030 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
1031 rb
->DataType
= GL_UNSIGNED_BYTE
;
1032 rb
->GetPointer
= get_pointer_alpha8
;
1033 rb
->GetRow
= get_row_alpha8
;
1034 rb
->GetValues
= get_values_alpha8
;
1035 rb
->PutRow
= put_row_alpha8
;
1036 rb
->PutRowRGB
= NULL
;
1037 rb
->PutMonoRow
= put_mono_row_alpha8
;
1038 rb
->PutValues
= put_values_alpha8
;
1039 rb
->PutMonoValues
= put_mono_values_alpha8
;
1040 rb
->RedBits
= 0; /*red*/
1041 rb
->GreenBits
= 0; /*green*/
1042 rb
->BlueBits
= 0; /*blue*/
1043 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1044 pixelSize
= sizeof(GLubyte
);
1047 case GL_STENCIL_INDEX
:
1048 case GL_STENCIL_INDEX1_EXT
:
1049 case GL_STENCIL_INDEX4_EXT
:
1050 case GL_STENCIL_INDEX8_EXT
:
1051 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1052 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1053 rb
->DataType
= GL_UNSIGNED_BYTE
;
1054 rb
->GetPointer
= get_pointer_ubyte
;
1055 rb
->GetRow
= get_row_ubyte
;
1056 rb
->GetValues
= get_values_ubyte
;
1057 rb
->PutRow
= put_row_ubyte
;
1058 rb
->PutRowRGB
= NULL
;
1059 rb
->PutMonoRow
= put_mono_row_ubyte
;
1060 rb
->PutValues
= put_values_ubyte
;
1061 rb
->PutMonoValues
= put_mono_values_ubyte
;
1062 rb
->StencilBits
= 8 * sizeof(GLubyte
);
1063 pixelSize
= sizeof(GLubyte
);
1065 case GL_STENCIL_INDEX16_EXT
:
1066 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1067 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1068 rb
->DataType
= GL_UNSIGNED_SHORT
;
1069 rb
->GetPointer
= get_pointer_ushort
;
1070 rb
->GetRow
= get_row_ushort
;
1071 rb
->GetValues
= get_values_ushort
;
1072 rb
->PutRow
= put_row_ushort
;
1073 rb
->PutRowRGB
= NULL
;
1074 rb
->PutMonoRow
= put_mono_row_ushort
;
1075 rb
->PutValues
= put_values_ushort
;
1076 rb
->PutMonoValues
= put_mono_values_ushort
;
1077 rb
->StencilBits
= 8 * sizeof(GLushort
);
1078 pixelSize
= sizeof(GLushort
);
1080 case GL_DEPTH_COMPONENT
:
1081 case GL_DEPTH_COMPONENT16
:
1082 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1083 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1084 rb
->DataType
= GL_UNSIGNED_SHORT
;
1085 rb
->GetPointer
= get_pointer_ushort
;
1086 rb
->GetRow
= get_row_ushort
;
1087 rb
->GetValues
= get_values_ushort
;
1088 rb
->PutRow
= put_row_ushort
;
1089 rb
->PutRowRGB
= NULL
;
1090 rb
->PutMonoRow
= put_mono_row_ushort
;
1091 rb
->PutValues
= put_values_ushort
;
1092 rb
->PutMonoValues
= put_mono_values_ushort
;
1093 rb
->DepthBits
= 8 * sizeof(GLushort
);
1094 pixelSize
= sizeof(GLushort
);
1096 case GL_DEPTH_COMPONENT24
:
1097 case GL_DEPTH_COMPONENT32
:
1098 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1099 rb
->DataType
= GL_UNSIGNED_INT
;
1100 rb
->GetPointer
= get_pointer_uint
;
1101 rb
->GetRow
= get_row_uint
;
1102 rb
->GetValues
= get_values_uint
;
1103 rb
->PutRow
= put_row_uint
;
1104 rb
->PutRowRGB
= NULL
;
1105 rb
->PutMonoRow
= put_mono_row_uint
;
1106 rb
->PutValues
= put_values_uint
;
1107 rb
->PutMonoValues
= put_mono_values_uint
;
1108 if (internalFormat
== GL_DEPTH_COMPONENT24
) {
1109 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1113 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1116 pixelSize
= sizeof(GLuint
);
1118 case GL_DEPTH_STENCIL_EXT
:
1119 case GL_DEPTH24_STENCIL8_EXT
:
1120 rb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
1121 rb
->_BaseFormat
= GL_DEPTH_STENCIL_EXT
;
1122 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1123 rb
->GetPointer
= get_pointer_uint
;
1124 rb
->GetRow
= get_row_uint
;
1125 rb
->GetValues
= get_values_uint
;
1126 rb
->PutRow
= put_row_uint
;
1127 rb
->PutRowRGB
= NULL
;
1128 rb
->PutMonoRow
= put_mono_row_uint
;
1129 rb
->PutValues
= put_values_uint
;
1130 rb
->PutMonoValues
= put_mono_values_uint
;
1132 rb
->StencilBits
= 8;
1133 pixelSize
= sizeof(GLuint
);
1135 case GL_COLOR_INDEX8_EXT
:
1136 rb
->_ActualFormat
= GL_COLOR_INDEX8_EXT
;
1137 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1138 rb
->DataType
= GL_UNSIGNED_BYTE
;
1139 rb
->GetPointer
= get_pointer_ubyte
;
1140 rb
->GetRow
= get_row_ubyte
;
1141 rb
->GetValues
= get_values_ubyte
;
1142 rb
->PutRow
= put_row_ubyte
;
1143 rb
->PutRowRGB
= NULL
;
1144 rb
->PutMonoRow
= put_mono_row_ubyte
;
1145 rb
->PutValues
= put_values_ubyte
;
1146 rb
->PutMonoValues
= put_mono_values_ubyte
;
1147 rb
->IndexBits
= 8 * sizeof(GLubyte
);
1148 pixelSize
= sizeof(GLubyte
);
1150 case GL_COLOR_INDEX16_EXT
:
1151 rb
->_ActualFormat
= GL_COLOR_INDEX16_EXT
;
1152 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1153 rb
->DataType
= GL_UNSIGNED_SHORT
;
1154 rb
->GetPointer
= get_pointer_ushort
;
1155 rb
->GetRow
= get_row_ushort
;
1156 rb
->GetValues
= get_values_ushort
;
1157 rb
->PutRow
= put_row_ushort
;
1158 rb
->PutRowRGB
= NULL
;
1159 rb
->PutMonoRow
= put_mono_row_ushort
;
1160 rb
->PutValues
= put_values_ushort
;
1161 rb
->PutMonoValues
= put_mono_values_ushort
;
1162 rb
->IndexBits
= 8 * sizeof(GLushort
);
1163 pixelSize
= sizeof(GLushort
);
1166 rb
->_ActualFormat
= COLOR_INDEX32
;
1167 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1168 rb
->DataType
= GL_UNSIGNED_INT
;
1169 rb
->GetPointer
= get_pointer_uint
;
1170 rb
->GetRow
= get_row_uint
;
1171 rb
->GetValues
= get_values_uint
;
1172 rb
->PutRow
= put_row_uint
;
1173 rb
->PutRowRGB
= NULL
;
1174 rb
->PutMonoRow
= put_mono_row_uint
;
1175 rb
->PutValues
= put_values_uint
;
1176 rb
->PutMonoValues
= put_mono_values_uint
;
1177 rb
->IndexBits
= 8 * sizeof(GLuint
);
1178 pixelSize
= sizeof(GLuint
);
1181 _mesa_problem(ctx
, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
1185 ASSERT(rb
->DataType
);
1186 ASSERT(rb
->GetPointer
);
1188 ASSERT(rb
->GetValues
);
1190 ASSERT(rb
->PutMonoRow
);
1191 ASSERT(rb
->PutValues
);
1192 ASSERT(rb
->PutMonoValues
);
1194 /* free old buffer storage */
1196 _mesa_free(rb
->Data
);
1200 if (width
> 0 && height
> 0) {
1201 /* allocate new buffer storage */
1202 rb
->Data
= _mesa_malloc(width
* height
* pixelSize
);
1203 if (rb
->Data
== NULL
) {
1206 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1207 "software renderbuffer allocation (%d x %d x %d)",
1208 width
, height
, pixelSize
);
1214 rb
->Height
= height
;
1221 /**********************************************************************/
1222 /**********************************************************************/
1223 /**********************************************************************/
1227 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1228 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1230 * When PutRow is called (for example), we store the alpha values in
1231 * this buffer, then pass on the PutRow call to the wrapped RGB
1237 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1238 GLenum internalFormat
, GLuint width
, GLuint height
)
1240 ASSERT(arb
!= arb
->Wrapped
);
1241 ASSERT(arb
->_ActualFormat
== GL_ALPHA8
);
1243 /* first, pass the call to the wrapped RGB buffer */
1244 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1249 /* next, resize my alpha buffer */
1251 _mesa_free(arb
->Data
);
1254 arb
->Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1255 if (arb
->Data
== NULL
) {
1258 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1263 arb
->Height
= height
;
1270 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1273 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1276 _mesa_free(arb
->Data
);
1278 ASSERT(arb
->Wrapped
);
1279 ASSERT(arb
!= arb
->Wrapped
);
1280 arb
->Wrapped
->Delete(arb
->Wrapped
);
1281 arb
->Wrapped
= NULL
;
1287 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1290 return NULL
; /* don't allow direct access! */
1295 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1296 GLint x
, GLint y
, void *values
)
1298 /* NOTE: 'values' is RGBA format! */
1299 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1300 GLubyte
*dst
= (GLubyte
*) values
;
1302 ASSERT(arb
!= arb
->Wrapped
);
1303 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1304 /* first, pass the call to the wrapped RGB buffer */
1305 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1306 /* second, fill in alpha values from this buffer! */
1307 for (i
= 0; i
< count
; i
++) {
1308 dst
[i
* 4 + 3] = src
[i
];
1314 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1315 const GLint x
[], const GLint y
[], void *values
)
1317 GLubyte
*dst
= (GLubyte
*) values
;
1319 ASSERT(arb
!= arb
->Wrapped
);
1320 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1321 /* first, pass the call to the wrapped RGB buffer */
1322 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1323 /* second, fill in alpha values from this buffer! */
1324 for (i
= 0; i
< count
; i
++) {
1325 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1326 dst
[i
* 4 + 3] = *src
;
1332 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1333 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1335 const GLubyte
*src
= (const GLubyte
*) values
;
1336 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1338 ASSERT(arb
!= arb
->Wrapped
);
1339 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1340 /* first, pass the call to the wrapped RGB buffer */
1341 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1342 /* second, store alpha in our buffer */
1343 for (i
= 0; i
< count
; i
++) {
1344 if (!mask
|| mask
[i
]) {
1345 dst
[i
] = src
[i
* 4 + 3];
1352 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1353 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1355 const GLubyte
*src
= (const GLubyte
*) values
;
1356 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1358 ASSERT(arb
!= arb
->Wrapped
);
1359 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1360 /* first, pass the call to the wrapped RGB buffer */
1361 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1362 /* second, store alpha in our buffer */
1363 for (i
= 0; i
< count
; i
++) {
1364 if (!mask
|| mask
[i
]) {
1365 dst
[i
] = src
[i
* 4 + 3];
1372 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1373 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1375 const GLubyte val
= ((const GLubyte
*) value
)[3];
1376 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1377 ASSERT(arb
!= arb
->Wrapped
);
1378 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1379 /* first, pass the call to the wrapped RGB buffer */
1380 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1381 /* second, store alpha in our buffer */
1384 for (i
= 0; i
< count
; i
++) {
1391 _mesa_memset(dst
, val
, count
);
1397 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1398 const GLint x
[], const GLint y
[],
1399 const void *values
, const GLubyte
*mask
)
1401 const GLubyte
*src
= (const GLubyte
*) values
;
1403 ASSERT(arb
!= arb
->Wrapped
);
1404 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1405 /* first, pass the call to the wrapped RGB buffer */
1406 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1407 /* second, store alpha in our buffer */
1408 for (i
= 0; i
< count
; i
++) {
1409 if (!mask
|| mask
[i
]) {
1410 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1411 *dst
= src
[i
* 4 + 3];
1418 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1419 GLuint count
, const GLint x
[], const GLint y
[],
1420 const void *value
, const GLubyte
*mask
)
1422 const GLubyte val
= ((const GLubyte
*) value
)[3];
1424 ASSERT(arb
!= arb
->Wrapped
);
1425 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1426 /* first, pass the call to the wrapped RGB buffer */
1427 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1428 /* second, store alpha in our buffer */
1429 for (i
= 0; i
< count
; i
++) {
1430 if (!mask
|| mask
[i
]) {
1431 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1439 /**********************************************************************/
1440 /**********************************************************************/
1441 /**********************************************************************/
1445 * Default GetPointer routine. Always return NULL to indicate that
1446 * direct buffer access is not supported.
1449 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1456 * Initialize the fields of a gl_renderbuffer to default values.
1459 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1461 _glthread_INIT_MUTEX(rb
->Mutex
);
1466 rb
->Delete
= _mesa_delete_renderbuffer
;
1468 /* The rest of these should be set later by the caller of this function or
1469 * the AllocStorage method:
1471 rb
->AllocStorage
= NULL
;
1475 rb
->InternalFormat
= GL_NONE
;
1476 rb
->_ActualFormat
= GL_NONE
;
1477 rb
->_BaseFormat
= GL_NONE
;
1478 rb
->DataType
= GL_NONE
;
1479 rb
->RedBits
= rb
->GreenBits
= rb
->BlueBits
= rb
->AlphaBits
= 0;
1482 rb
->StencilBits
= 0;
1485 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1486 * all over the drivers.
1490 rb
->GetPointer
= nop_get_pointer
;
1492 rb
->GetValues
= NULL
;
1494 rb
->PutRowRGB
= NULL
;
1495 rb
->PutMonoRow
= NULL
;
1496 rb
->PutValues
= NULL
;
1497 rb
->PutMonoValues
= NULL
;
1502 * Allocate a new gl_renderbuffer object. This can be used for user-created
1503 * renderbuffers or window-system renderbuffers.
1505 struct gl_renderbuffer
*
1506 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1508 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1510 _mesa_init_renderbuffer(rb
, name
);
1517 * Delete a gl_framebuffer.
1518 * This is the default function for renderbuffer->Delete().
1521 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1524 _mesa_free(rb
->Data
);
1531 * Allocate a software-based renderbuffer. This is called via the
1532 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1534 * This would not be used for hardware-based renderbuffers.
1536 struct gl_renderbuffer
*
1537 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1539 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1541 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1542 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1543 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1552 * Add software-based color renderbuffers to the given framebuffer.
1553 * This is a helper routine for device drivers when creating a
1554 * window system framebuffer (not a user-created render/framebuffer).
1555 * Once this function is called, you can basically forget about this
1556 * renderbuffer; core Mesa will handle all the buffer management and
1560 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1561 GLuint rgbBits
, GLuint alphaBits
,
1562 GLboolean frontLeft
, GLboolean backLeft
,
1563 GLboolean frontRight
, GLboolean backRight
)
1567 if (rgbBits
> 16 || alphaBits
> 16) {
1569 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1573 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1575 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1576 struct gl_renderbuffer
*rb
;
1578 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1580 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1582 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1584 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1587 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1589 rb
= _mesa_new_renderbuffer(ctx
, 0);
1591 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1597 rb
->_ActualFormat
= GL_RGBA8
;
1599 rb
->_ActualFormat
= GL_RGB8
;
1602 assert(rgbBits
<= 16);
1604 rb
->_ActualFormat
= GL_RGBA16
;
1606 rb
->_ActualFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1608 rb
->InternalFormat
= rb
->_ActualFormat
;
1610 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1611 _mesa_add_renderbuffer(fb
, b
, rb
);
1619 * Add software-based color index renderbuffers to the given framebuffer.
1620 * This is a helper routine for device drivers when creating a
1621 * window system framebuffer (not a user-created render/framebuffer).
1622 * Once this function is called, you can basically forget about this
1623 * renderbuffer; core Mesa will handle all the buffer management and
1627 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1629 GLboolean frontLeft
, GLboolean backLeft
,
1630 GLboolean frontRight
, GLboolean backRight
)
1634 if (indexBits
> 8) {
1636 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1640 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1642 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1643 struct gl_renderbuffer
*rb
;
1645 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1647 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1649 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1651 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1654 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1656 rb
= _mesa_new_renderbuffer(ctx
, 0);
1658 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1662 if (indexBits
<= 8) {
1663 /* only support GLuint for now */
1664 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1665 rb
->_ActualFormat
= COLOR_INDEX32
;
1668 rb
->_ActualFormat
= COLOR_INDEX32
;
1670 rb
->InternalFormat
= rb
->_ActualFormat
;
1672 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1673 _mesa_add_renderbuffer(fb
, b
, rb
);
1681 * Add software-based alpha renderbuffers to the given framebuffer.
1682 * This is a helper routine for device drivers when creating a
1683 * window system framebuffer (not a user-created render/framebuffer).
1684 * Once this function is called, you can basically forget about this
1685 * renderbuffer; core Mesa will handle all the buffer management and
1689 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1691 GLboolean frontLeft
, GLboolean backLeft
,
1692 GLboolean frontRight
, GLboolean backRight
)
1696 /* for window system framebuffers only! */
1697 assert(fb
->Name
== 0);
1699 if (alphaBits
> 8) {
1701 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1705 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1707 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1709 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1710 struct gl_renderbuffer
*arb
;
1712 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1714 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1716 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1718 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1721 /* the RGB buffer to wrap must already exist!! */
1722 assert(fb
->Attachment
[b
].Renderbuffer
);
1724 /* only GLubyte supported for now */
1725 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1727 /* allocate alpha renderbuffer */
1728 arb
= _mesa_new_renderbuffer(ctx
, 0);
1730 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1734 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1735 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1737 /* Set up my alphabuffer fields and plug in my functions.
1738 * The functions will put/get the alpha values from/to RGBA arrays
1739 * and then call the wrapped buffer's functions to handle the RGB
1742 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1743 arb
->_ActualFormat
= GL_ALPHA8
;
1744 arb
->_BaseFormat
= arb
->Wrapped
->_BaseFormat
;
1745 arb
->DataType
= arb
->Wrapped
->DataType
;
1746 arb
->AllocStorage
= alloc_storage_alpha8
;
1747 arb
->Delete
= delete_renderbuffer_alpha8
;
1748 arb
->GetPointer
= get_pointer_alpha8
;
1749 arb
->GetRow
= get_row_alpha8
;
1750 arb
->GetValues
= get_values_alpha8
;
1751 arb
->PutRow
= put_row_alpha8
;
1752 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1753 arb
->PutMonoRow
= put_mono_row_alpha8
;
1754 arb
->PutValues
= put_values_alpha8
;
1755 arb
->PutMonoValues
= put_mono_values_alpha8
;
1757 /* clear the pointer to avoid assertion/sanity check failure later */
1758 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1760 /* plug the alpha renderbuffer into the colorbuffer attachment */
1761 _mesa_add_renderbuffer(fb
, b
, arb
);
1769 * Add a software-based depth renderbuffer to the given framebuffer.
1770 * This is a helper routine for device drivers when creating a
1771 * window system framebuffer (not a user-created render/framebuffer).
1772 * Once this function is called, you can basically forget about this
1773 * renderbuffer; core Mesa will handle all the buffer management and
1777 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1780 struct gl_renderbuffer
*rb
;
1782 if (depthBits
> 32) {
1784 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1788 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1790 rb
= _mesa_new_renderbuffer(ctx
, 0);
1792 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1796 if (depthBits
<= 16) {
1797 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1799 else if (depthBits
<= 24) {
1800 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1803 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1805 rb
->InternalFormat
= rb
->_ActualFormat
;
1807 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1808 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1815 * Add a software-based stencil renderbuffer to the given framebuffer.
1816 * This is a helper routine for device drivers when creating a
1817 * window system framebuffer (not a user-created render/framebuffer).
1818 * Once this function is called, you can basically forget about this
1819 * renderbuffer; core Mesa will handle all the buffer management and
1823 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1826 struct gl_renderbuffer
*rb
;
1828 if (stencilBits
> 16) {
1830 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1834 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1836 rb
= _mesa_new_renderbuffer(ctx
, 0);
1838 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1842 if (stencilBits
<= 8) {
1843 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1846 /* not really supported (see s_stencil.c code) */
1847 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1849 rb
->InternalFormat
= rb
->_ActualFormat
;
1851 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1852 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1859 * Add a software-based accumulation renderbuffer to the given framebuffer.
1860 * This is a helper routine for device drivers when creating a
1861 * window system framebuffer (not a user-created render/framebuffer).
1862 * Once this function is called, you can basically forget about this
1863 * renderbuffer; core Mesa will handle all the buffer management and
1867 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1868 GLuint redBits
, GLuint greenBits
,
1869 GLuint blueBits
, GLuint alphaBits
)
1871 struct gl_renderbuffer
*rb
;
1873 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1875 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1879 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1881 rb
= _mesa_new_renderbuffer(ctx
, 0);
1883 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1887 rb
->_ActualFormat
= GL_RGBA16
;
1888 rb
->InternalFormat
= GL_RGBA16
;
1889 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1890 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1898 * Add a software-based accumulation renderbuffer to the given framebuffer.
1899 * This is a helper routine for device drivers when creating a
1900 * window system framebuffer (not a user-created render/framebuffer).
1901 * Once this function is called, you can basically forget about this
1902 * renderbuffer; core Mesa will handle all the buffer management and
1905 * NOTE: color-index aux buffers not supported.
1908 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1909 GLuint colorBits
, GLuint numBuffers
)
1913 if (colorBits
> 16) {
1915 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1919 assert(numBuffers
< MAX_AUX_BUFFERS
);
1921 for (i
= 0; i
< numBuffers
; i
++) {
1922 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1924 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1927 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1931 if (colorBits
<= 8) {
1932 rb
->_ActualFormat
= GL_RGBA8
;
1935 rb
->_ActualFormat
= GL_RGBA16
;
1937 rb
->InternalFormat
= rb
->_ActualFormat
;
1939 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1940 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1947 * Create/attach software-based renderbuffers to the given framebuffer.
1948 * This is a helper routine for device drivers. Drivers can just as well
1949 * call the individual _mesa_add_*_renderbuffer() routines directly.
1952 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1960 GLboolean frontLeft
= GL_TRUE
;
1961 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1962 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1963 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1966 if (fb
->Visual
.rgbMode
) {
1967 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1968 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1969 _mesa_add_color_renderbuffers(NULL
, fb
,
1971 fb
->Visual
.alphaBits
,
1972 frontLeft
, backLeft
,
1973 frontRight
, backRight
);
1976 _mesa_add_color_index_renderbuffers(NULL
, fb
,
1977 fb
->Visual
.indexBits
,
1978 frontLeft
, backLeft
,
1979 frontRight
, backRight
);
1984 assert(fb
->Visual
.depthBits
> 0);
1985 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1989 assert(fb
->Visual
.stencilBits
> 0);
1990 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1994 assert(fb
->Visual
.rgbMode
);
1995 assert(fb
->Visual
.accumRedBits
> 0);
1996 assert(fb
->Visual
.accumGreenBits
> 0);
1997 assert(fb
->Visual
.accumBlueBits
> 0);
1998 _mesa_add_accum_renderbuffer(NULL
, fb
,
1999 fb
->Visual
.accumRedBits
,
2000 fb
->Visual
.accumGreenBits
,
2001 fb
->Visual
.accumBlueBits
,
2002 fb
->Visual
.accumAlphaBits
);
2006 assert(fb
->Visual
.rgbMode
);
2007 assert(fb
->Visual
.numAuxBuffers
> 0);
2008 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
2009 fb
->Visual
.numAuxBuffers
);
2013 assert(fb
->Visual
.rgbMode
);
2014 assert(fb
->Visual
.alphaBits
> 0);
2015 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
2016 frontLeft
, backLeft
,
2017 frontRight
, backRight
);
2029 * Attach a renderbuffer to a framebuffer.
2032 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
2033 GLuint bufferName
, struct gl_renderbuffer
*rb
)
2037 assert(bufferName
< BUFFER_COUNT
);
2039 /* There should be no previous renderbuffer on this attachment point,
2040 * with the exception of depth/stencil since the same renderbuffer may
2043 assert(bufferName
== BUFFER_DEPTH
||
2044 bufferName
== BUFFER_STENCIL
||
2045 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
2047 /* winsys vs. user-created buffer cross check */
2055 /* If Mesa's compiled with deep color channels (16 or 32 bits / channel)
2056 * and the device driver is expecting 8-bit values (GLubyte), we can
2057 * use a "renderbuffer adaptor/wrapper" to do the necessary conversions.
2059 if (rb
->_BaseFormat
== GL_RGBA
) {
2060 if (CHAN_BITS
== 16 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2061 GET_CURRENT_CONTEXT(ctx
);
2062 rb
= _mesa_new_renderbuffer_16wrap8(ctx
, rb
);
2064 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2065 GET_CURRENT_CONTEXT(ctx
);
2066 rb
= _mesa_new_renderbuffer_32wrap8(ctx
, rb
);
2068 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_SHORT
) {
2069 GET_CURRENT_CONTEXT(ctx
);
2070 rb
= _mesa_new_renderbuffer_32wrap16(ctx
, rb
);
2074 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
2075 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
2076 fb
->Attachment
[bufferName
].Renderbuffer
= rb
;
2083 * Remove the named renderbuffer from the given framebuffer.
2086 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
, GLuint bufferName
)
2088 struct gl_renderbuffer
*rb
;
2090 assert(bufferName
< BUFFER_COUNT
);
2092 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
2096 _mesa_unreference_renderbuffer(&rb
);
2098 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
2103 * Decrement a renderbuffer object's reference count and delete it when
2104 * the refcount hits zero.
2105 * Note: we pass the address of a pointer.
2108 _mesa_unreference_renderbuffer(struct gl_renderbuffer
**rb
)
2112 GLboolean deleteFlag
= GL_FALSE
;
2114 _glthread_LOCK_MUTEX((*rb
)->Mutex
);
2115 ASSERT((*rb
)->RefCount
> 0);
2117 deleteFlag
= ((*rb
)->RefCount
== 0);
2118 _glthread_UNLOCK_MUTEX((*rb
)->Mutex
);
2131 * Create a new combined depth/stencil renderbuffer for implementing
2132 * the GL_EXT_packed_depth_stencil extension.
2133 * \return new depth/stencil renderbuffer
2135 struct gl_renderbuffer
*
2136 _mesa_new_depthstencil_renderbuffer(GLcontext
*ctx
, GLuint name
)
2138 struct gl_renderbuffer
*dsrb
;
2140 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
2144 /* init fields not covered by _mesa_new_renderbuffer() */
2145 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
2146 dsrb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
2147 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;