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"
52 #include "state_tracker/st_context.h"
55 /* 32-bit color index format. Not a public format. */
56 #define COLOR_INDEX32 0x424243
60 * Routines for get/put values in common buffer formats follow.
61 * Someday add support for arbitrary row stride to make them more
65 /**********************************************************************
66 * Functions for buffers of 1 X GLubyte values.
71 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
76 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
77 /* Can't assert _ActualFormat since these funcs may be used for serveral
78 * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
80 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
85 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
86 GLint x
, GLint y
, void *values
)
88 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
89 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
90 _mesa_memcpy(values
, src
, count
* sizeof(GLubyte
));
95 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
96 const GLint x
[], const GLint y
[], void *values
)
98 GLubyte
*dst
= (GLubyte
*) values
;
100 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
101 for (i
= 0; i
< count
; i
++) {
102 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
109 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
110 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
112 const GLubyte
*src
= (const GLubyte
*) values
;
113 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
114 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
117 for (i
= 0; i
< count
; i
++) {
124 _mesa_memcpy(dst
, values
, count
* sizeof(GLubyte
));
130 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
131 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
133 const GLubyte val
= *((const GLubyte
*) value
);
134 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
135 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
138 for (i
= 0; i
< count
; i
++) {
146 for (i
= 0; i
< count
; i
++) {
154 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
155 const GLint x
[], const GLint y
[],
156 const void *values
, const GLubyte
*mask
)
158 const GLubyte
*src
= (const GLubyte
*) values
;
160 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
161 for (i
= 0; i
< count
; i
++) {
162 if (!mask
|| mask
[i
]) {
163 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
171 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
172 const GLint x
[], const GLint y
[],
173 const void *value
, const GLubyte
*mask
)
175 const GLubyte val
= *((const GLubyte
*) value
);
177 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
178 for (i
= 0; i
< count
; i
++) {
179 if (!mask
|| mask
[i
]) {
180 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
187 /**********************************************************************
188 * Functions for buffers of 1 X GLushort values.
193 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
198 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
199 ASSERT(rb
->Width
> 0);
200 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
205 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
206 GLint x
, GLint y
, void *values
)
208 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
209 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
210 _mesa_memcpy(values
, src
, count
* sizeof(GLushort
));
215 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
216 const GLint x
[], const GLint y
[], void *values
)
218 GLushort
*dst
= (GLushort
*) values
;
220 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
221 for (i
= 0; i
< count
; i
++) {
222 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
229 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
230 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
232 const GLushort
*src
= (const GLushort
*) values
;
233 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
234 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
237 for (i
= 0; i
< count
; i
++) {
244 _mesa_memcpy(dst
, src
, count
* sizeof(GLushort
));
250 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
251 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
253 const GLushort val
= *((const GLushort
*) value
);
254 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
255 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
258 for (i
= 0; i
< count
; i
++) {
266 for (i
= 0; i
< count
; i
++) {
274 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
275 const GLint x
[], const GLint y
[], const void *values
,
278 const GLushort
*src
= (const GLushort
*) values
;
280 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
281 for (i
= 0; i
< count
; i
++) {
282 if (!mask
|| mask
[i
]) {
283 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
291 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
292 GLuint count
, const GLint x
[], const GLint y
[],
293 const void *value
, const GLubyte
*mask
)
295 const GLushort val
= *((const GLushort
*) value
);
296 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
299 for (i
= 0; i
< count
; i
++) {
301 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
308 for (i
= 0; i
< count
; i
++) {
309 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
316 /**********************************************************************
317 * Functions for buffers of 1 X GLuint values.
318 * Typically depth/Z or color index.
322 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
327 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
328 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
329 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
334 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
335 GLint x
, GLint y
, void *values
)
337 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
338 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
339 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
340 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
345 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
346 const GLint x
[], const GLint y
[], void *values
)
348 GLuint
*dst
= (GLuint
*) values
;
350 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
351 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
352 for (i
= 0; i
< count
; i
++) {
353 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
360 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
361 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
363 const GLuint
*src
= (const GLuint
*) values
;
364 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
365 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
366 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
369 for (i
= 0; i
< count
; i
++) {
376 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
382 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
383 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
385 const GLuint val
= *((const GLuint
*) value
);
386 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
387 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
388 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
391 for (i
= 0; i
< count
; i
++) {
399 for (i
= 0; i
< count
; i
++) {
407 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
408 const GLint x
[], const GLint y
[], const void *values
,
411 const GLuint
*src
= (const GLuint
*) values
;
413 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
414 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
415 for (i
= 0; i
< count
; i
++) {
416 if (!mask
|| mask
[i
]) {
417 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
425 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
426 const GLint x
[], const GLint y
[], const void *value
,
429 const GLuint val
= *((const GLuint
*) value
);
431 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
432 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
433 for (i
= 0; i
< count
; i
++) {
434 if (!mask
|| mask
[i
]) {
435 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
442 /**********************************************************************
443 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
444 * Typically color buffers.
445 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
446 * alpha values and return 255 for outgoing alpha values.
450 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
453 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
454 /* No direct access since this buffer is RGB but caller will be
455 * treating it as if it were RGBA.
462 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
463 GLint x
, GLint y
, void *values
)
465 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
466 GLubyte
*dst
= (GLubyte
*) values
;
468 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
469 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
470 for (i
= 0; i
< count
; i
++) {
471 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
472 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
473 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
474 dst
[i
* 4 + 3] = 255;
480 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
481 const GLint x
[], const GLint y
[], void *values
)
483 GLubyte
*dst
= (GLubyte
*) values
;
485 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
486 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
487 for (i
= 0; i
< count
; i
++) {
489 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
490 dst
[i
* 4 + 0] = src
[0];
491 dst
[i
* 4 + 1] = src
[1];
492 dst
[i
* 4 + 2] = src
[2];
493 dst
[i
* 4 + 3] = 255;
499 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
500 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
502 /* note: incoming values are RGB+A! */
503 const GLubyte
*src
= (const GLubyte
*) values
;
504 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
506 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
507 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
508 for (i
= 0; i
< count
; i
++) {
509 if (!mask
|| mask
[i
]) {
510 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
511 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
512 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
519 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
520 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
522 /* note: incoming values are RGB+A! */
523 const GLubyte
*src
= (const GLubyte
*) values
;
524 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
526 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
527 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
528 for (i
= 0; i
< count
; i
++) {
529 if (!mask
|| mask
[i
]) {
530 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
531 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
532 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
539 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
540 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
542 /* note: incoming value is RGB+A! */
543 const GLubyte val0
= ((const GLubyte
*) value
)[0];
544 const GLubyte val1
= ((const GLubyte
*) value
)[1];
545 const GLubyte val2
= ((const GLubyte
*) value
)[2];
546 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
547 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
548 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
549 if (!mask
&& val0
== val1
&& val1
== val2
) {
551 _mesa_memset(dst
, val0
, 3 * count
);
555 for (i
= 0; i
< count
; i
++) {
556 if (!mask
|| mask
[i
]) {
557 dst
[i
* 3 + 0] = val0
;
558 dst
[i
* 3 + 1] = val1
;
559 dst
[i
* 3 + 2] = val2
;
567 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
568 const GLint x
[], const GLint y
[], const void *values
,
571 /* note: incoming values are RGB+A! */
572 const GLubyte
*src
= (const GLubyte
*) values
;
574 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
575 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
576 for (i
= 0; i
< count
; i
++) {
577 if (!mask
|| mask
[i
]) {
578 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
579 dst
[0] = src
[i
* 4 + 0];
580 dst
[1] = src
[i
* 4 + 1];
581 dst
[2] = src
[i
* 4 + 2];
588 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
589 GLuint count
, const GLint x
[], const GLint y
[],
590 const void *value
, const GLubyte
*mask
)
592 /* note: incoming value is RGB+A! */
593 const GLubyte val0
= ((const GLubyte
*) value
)[0];
594 const GLubyte val1
= ((const GLubyte
*) value
)[1];
595 const GLubyte val2
= ((const GLubyte
*) value
)[2];
597 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
598 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
599 for (i
= 0; i
< count
; i
++) {
600 if (!mask
|| mask
[i
]) {
601 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
610 /**********************************************************************
611 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
612 * Typically color buffers.
616 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
621 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
622 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
623 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
628 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
629 GLint x
, GLint y
, void *values
)
631 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
632 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
633 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
634 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLubyte
));
639 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
640 const GLint x
[], const GLint y
[], void *values
)
642 /* treat 4*GLubyte as 1*GLuint */
643 GLuint
*dst
= (GLuint
*) values
;
645 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
646 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
647 for (i
= 0; i
< count
; i
++) {
648 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
655 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
656 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
658 /* treat 4*GLubyte as 1*GLuint */
659 const GLuint
*src
= (const GLuint
*) values
;
660 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
661 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
662 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
665 for (i
= 0; i
< count
; i
++) {
672 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
678 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
679 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
681 /* Store RGB values in RGBA buffer */
682 const GLubyte
*src
= (const GLubyte
*) values
;
683 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
685 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
686 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
687 for (i
= 0; i
< count
; i
++) {
688 if (!mask
|| mask
[i
]) {
689 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
690 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
691 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
692 dst
[i
* 4 + 3] = 0xff;
699 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
700 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
702 /* treat 4*GLubyte as 1*GLuint */
703 const GLuint val
= *((const GLuint
*) value
);
704 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
705 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
706 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
707 if (!mask
&& val
== 0) {
709 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
715 for (i
= 0; i
< count
; i
++) {
723 for (i
= 0; i
< count
; i
++) {
732 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
733 const GLint x
[], const GLint y
[], const void *values
,
736 /* treat 4*GLubyte as 1*GLuint */
737 const GLuint
*src
= (const GLuint
*) values
;
739 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
740 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
741 for (i
= 0; i
< count
; i
++) {
742 if (!mask
|| mask
[i
]) {
743 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
751 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
752 GLuint count
, const GLint x
[], const GLint y
[],
753 const void *value
, const GLubyte
*mask
)
755 /* treat 4*GLubyte as 1*GLuint */
756 const GLuint val
= *((const GLuint
*) value
);
758 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
759 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
760 for (i
= 0; i
< count
; i
++) {
761 if (!mask
|| mask
[i
]) {
762 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
769 /**********************************************************************
770 * Functions for buffers of 4 X GLushort (or GLshort) values.
771 * Typically accum buffer.
775 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
780 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
781 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
786 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
787 GLint x
, GLint y
, void *values
)
789 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
790 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
791 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
796 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
797 const GLint x
[], const GLint y
[], void *values
)
799 GLushort
*dst
= (GLushort
*) values
;
801 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
802 for (i
= 0; i
< count
; i
++) {
804 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
811 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
812 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
814 const GLushort
*src
= (const GLushort
*) values
;
815 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
816 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
819 for (i
= 0; i
< count
; i
++) {
821 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
822 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
823 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
824 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
829 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
835 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
836 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
838 /* Put RGB values in RGBA buffer */
839 const GLushort
*src
= (const GLushort
*) values
;
840 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
841 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
844 for (i
= 0; i
< count
; i
++) {
846 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
847 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
848 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
849 dst
[i
* 4 + 3] = 0xffff;
854 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
860 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
861 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
863 const GLushort val0
= ((const GLushort
*) value
)[0];
864 const GLushort val1
= ((const GLushort
*) value
)[1];
865 const GLushort val2
= ((const GLushort
*) value
)[2];
866 const GLushort val3
= ((const GLushort
*) value
)[3];
867 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
868 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
869 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
870 /* common case for clearing accum buffer */
871 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
875 for (i
= 0; i
< count
; i
++) {
876 if (!mask
|| mask
[i
]) {
877 dst
[i
* 4 + 0] = val0
;
878 dst
[i
* 4 + 1] = val1
;
879 dst
[i
* 4 + 2] = val2
;
880 dst
[i
* 4 + 3] = val3
;
888 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
889 const GLint x
[], const GLint y
[], const void *values
,
892 const GLushort
*src
= (const GLushort
*) values
;
894 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
895 for (i
= 0; i
< count
; i
++) {
896 if (!mask
|| mask
[i
]) {
897 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
898 dst
[0] = src
[i
* 4 + 0];
899 dst
[1] = src
[i
* 4 + 1];
900 dst
[2] = src
[i
* 4 + 2];
901 dst
[3] = src
[i
* 4 + 3];
908 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
909 GLuint count
, const GLint x
[], const GLint y
[],
910 const void *value
, const GLubyte
*mask
)
912 const GLushort val0
= ((const GLushort
*) value
)[0];
913 const GLushort val1
= ((const GLushort
*) value
)[1];
914 const GLushort val2
= ((const GLushort
*) value
)[2];
915 const GLushort val3
= ((const GLushort
*) value
)[3];
917 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
918 for (i
= 0; i
< count
; i
++) {
919 if (!mask
|| mask
[i
]) {
920 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
932 * This is a software fallback for the gl_renderbuffer->AllocStorage
934 * Device drivers will typically override this function for the buffers
935 * which it manages (typically color buffers, Z and stencil).
936 * Other buffers (like software accumulation and aux buffers) which the driver
937 * doesn't manage can be handled with this function.
939 * This one multi-purpose function can allocate stencil, depth, accum, color
940 * or color-index buffers!
942 * This function also plugs in the appropriate GetPointer, Get/PutRow and
943 * Get/PutValues functions.
946 _mesa_soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
947 GLenum internalFormat
,
948 GLuint width
, GLuint height
)
952 /* first clear these fields */
961 switch (internalFormat
) {
970 rb
->_ActualFormat
= GL_RGB8
;
971 rb
->_BaseFormat
= GL_RGB
;
972 rb
->DataType
= GL_UNSIGNED_BYTE
;
973 rb
->GetPointer
= get_pointer_ubyte3
;
974 rb
->GetRow
= get_row_ubyte3
;
975 rb
->GetValues
= get_values_ubyte3
;
976 rb
->PutRow
= put_row_ubyte3
;
977 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
978 rb
->PutMonoRow
= put_mono_row_ubyte3
;
979 rb
->PutValues
= put_values_ubyte3
;
980 rb
->PutMonoValues
= put_mono_values_ubyte3
;
981 rb
->RedBits
= 8 * sizeof(GLubyte
);
982 rb
->GreenBits
= 8 * sizeof(GLubyte
);
983 rb
->BlueBits
= 8 * sizeof(GLubyte
);
985 pixelSize
= 3 * sizeof(GLubyte
);
992 rb
->_ActualFormat
= GL_RGBA8
;
993 rb
->_BaseFormat
= GL_RGBA
;
994 rb
->DataType
= GL_UNSIGNED_BYTE
;
995 rb
->GetPointer
= get_pointer_ubyte4
;
996 rb
->GetRow
= get_row_ubyte4
;
997 rb
->GetValues
= get_values_ubyte4
;
998 rb
->PutRow
= put_row_ubyte4
;
999 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
1000 rb
->PutMonoRow
= put_mono_row_ubyte4
;
1001 rb
->PutValues
= put_values_ubyte4
;
1002 rb
->PutMonoValues
= put_mono_values_ubyte4
;
1003 rb
->RedBits
= 8 * sizeof(GLubyte
);
1004 rb
->GreenBits
= 8 * sizeof(GLubyte
);
1005 rb
->BlueBits
= 8 * sizeof(GLubyte
);
1006 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1007 pixelSize
= 4 * sizeof(GLubyte
);
1012 rb
->_ActualFormat
= GL_RGBA16
;
1013 rb
->_BaseFormat
= GL_RGBA
;
1014 rb
->DataType
= GL_UNSIGNED_SHORT
;
1015 rb
->GetPointer
= get_pointer_ushort4
;
1016 rb
->GetRow
= get_row_ushort4
;
1017 rb
->GetValues
= get_values_ushort4
;
1018 rb
->PutRow
= put_row_ushort4
;
1019 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1020 rb
->PutMonoRow
= put_mono_row_ushort4
;
1021 rb
->PutValues
= put_values_ushort4
;
1022 rb
->PutMonoValues
= put_mono_values_ushort4
;
1023 rb
->RedBits
= 8 * sizeof(GLushort
);
1024 rb
->GreenBits
= 8 * sizeof(GLushort
);
1025 rb
->BlueBits
= 8 * sizeof(GLushort
);
1026 rb
->AlphaBits
= 8 * sizeof(GLushort
);
1027 pixelSize
= 4 * sizeof(GLushort
);
1031 rb
->_ActualFormat
= GL_ALPHA8
;
1032 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
1033 rb
->DataType
= GL_UNSIGNED_BYTE
;
1034 rb
->GetPointer
= get_pointer_alpha8
;
1035 rb
->GetRow
= get_row_alpha8
;
1036 rb
->GetValues
= get_values_alpha8
;
1037 rb
->PutRow
= put_row_alpha8
;
1038 rb
->PutRowRGB
= NULL
;
1039 rb
->PutMonoRow
= put_mono_row_alpha8
;
1040 rb
->PutValues
= put_values_alpha8
;
1041 rb
->PutMonoValues
= put_mono_values_alpha8
;
1042 rb
->RedBits
= 0; /*red*/
1043 rb
->GreenBits
= 0; /*green*/
1044 rb
->BlueBits
= 0; /*blue*/
1045 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1046 pixelSize
= sizeof(GLubyte
);
1049 case GL_STENCIL_INDEX
:
1050 case GL_STENCIL_INDEX1_EXT
:
1051 case GL_STENCIL_INDEX4_EXT
:
1052 case GL_STENCIL_INDEX8_EXT
:
1053 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1054 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1055 rb
->DataType
= GL_UNSIGNED_BYTE
;
1056 rb
->GetPointer
= get_pointer_ubyte
;
1057 rb
->GetRow
= get_row_ubyte
;
1058 rb
->GetValues
= get_values_ubyte
;
1059 rb
->PutRow
= put_row_ubyte
;
1060 rb
->PutRowRGB
= NULL
;
1061 rb
->PutMonoRow
= put_mono_row_ubyte
;
1062 rb
->PutValues
= put_values_ubyte
;
1063 rb
->PutMonoValues
= put_mono_values_ubyte
;
1064 rb
->StencilBits
= 8 * sizeof(GLubyte
);
1065 pixelSize
= sizeof(GLubyte
);
1067 case GL_STENCIL_INDEX16_EXT
:
1068 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1069 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1070 rb
->DataType
= GL_UNSIGNED_SHORT
;
1071 rb
->GetPointer
= get_pointer_ushort
;
1072 rb
->GetRow
= get_row_ushort
;
1073 rb
->GetValues
= get_values_ushort
;
1074 rb
->PutRow
= put_row_ushort
;
1075 rb
->PutRowRGB
= NULL
;
1076 rb
->PutMonoRow
= put_mono_row_ushort
;
1077 rb
->PutValues
= put_values_ushort
;
1078 rb
->PutMonoValues
= put_mono_values_ushort
;
1079 rb
->StencilBits
= 8 * sizeof(GLushort
);
1080 pixelSize
= sizeof(GLushort
);
1082 case GL_DEPTH_COMPONENT
:
1083 case GL_DEPTH_COMPONENT16
:
1084 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1085 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1086 rb
->DataType
= GL_UNSIGNED_SHORT
;
1087 rb
->GetPointer
= get_pointer_ushort
;
1088 rb
->GetRow
= get_row_ushort
;
1089 rb
->GetValues
= get_values_ushort
;
1090 rb
->PutRow
= put_row_ushort
;
1091 rb
->PutRowRGB
= NULL
;
1092 rb
->PutMonoRow
= put_mono_row_ushort
;
1093 rb
->PutValues
= put_values_ushort
;
1094 rb
->PutMonoValues
= put_mono_values_ushort
;
1095 rb
->DepthBits
= 8 * sizeof(GLushort
);
1096 pixelSize
= sizeof(GLushort
);
1098 case GL_DEPTH_COMPONENT24
:
1099 case GL_DEPTH_COMPONENT32
:
1100 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1101 rb
->DataType
= GL_UNSIGNED_INT
;
1102 rb
->GetPointer
= get_pointer_uint
;
1103 rb
->GetRow
= get_row_uint
;
1104 rb
->GetValues
= get_values_uint
;
1105 rb
->PutRow
= put_row_uint
;
1106 rb
->PutRowRGB
= NULL
;
1107 rb
->PutMonoRow
= put_mono_row_uint
;
1108 rb
->PutValues
= put_values_uint
;
1109 rb
->PutMonoValues
= put_mono_values_uint
;
1110 if (internalFormat
== GL_DEPTH_COMPONENT24
) {
1111 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1115 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1118 pixelSize
= sizeof(GLuint
);
1120 case GL_DEPTH_STENCIL_EXT
:
1121 case GL_DEPTH24_STENCIL8_EXT
:
1122 rb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
1123 rb
->_BaseFormat
= GL_DEPTH_STENCIL_EXT
;
1124 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1125 rb
->GetPointer
= get_pointer_uint
;
1126 rb
->GetRow
= get_row_uint
;
1127 rb
->GetValues
= get_values_uint
;
1128 rb
->PutRow
= put_row_uint
;
1129 rb
->PutRowRGB
= NULL
;
1130 rb
->PutMonoRow
= put_mono_row_uint
;
1131 rb
->PutValues
= put_values_uint
;
1132 rb
->PutMonoValues
= put_mono_values_uint
;
1134 rb
->StencilBits
= 8;
1135 pixelSize
= sizeof(GLuint
);
1137 case GL_COLOR_INDEX8_EXT
:
1138 rb
->_ActualFormat
= GL_COLOR_INDEX8_EXT
;
1139 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1140 rb
->DataType
= GL_UNSIGNED_BYTE
;
1141 rb
->GetPointer
= get_pointer_ubyte
;
1142 rb
->GetRow
= get_row_ubyte
;
1143 rb
->GetValues
= get_values_ubyte
;
1144 rb
->PutRow
= put_row_ubyte
;
1145 rb
->PutRowRGB
= NULL
;
1146 rb
->PutMonoRow
= put_mono_row_ubyte
;
1147 rb
->PutValues
= put_values_ubyte
;
1148 rb
->PutMonoValues
= put_mono_values_ubyte
;
1149 rb
->IndexBits
= 8 * sizeof(GLubyte
);
1150 pixelSize
= sizeof(GLubyte
);
1152 case GL_COLOR_INDEX16_EXT
:
1153 rb
->_ActualFormat
= GL_COLOR_INDEX16_EXT
;
1154 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1155 rb
->DataType
= GL_UNSIGNED_SHORT
;
1156 rb
->GetPointer
= get_pointer_ushort
;
1157 rb
->GetRow
= get_row_ushort
;
1158 rb
->GetValues
= get_values_ushort
;
1159 rb
->PutRow
= put_row_ushort
;
1160 rb
->PutRowRGB
= NULL
;
1161 rb
->PutMonoRow
= put_mono_row_ushort
;
1162 rb
->PutValues
= put_values_ushort
;
1163 rb
->PutMonoValues
= put_mono_values_ushort
;
1164 rb
->IndexBits
= 8 * sizeof(GLushort
);
1165 pixelSize
= sizeof(GLushort
);
1168 rb
->_ActualFormat
= COLOR_INDEX32
;
1169 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1170 rb
->DataType
= GL_UNSIGNED_INT
;
1171 rb
->GetPointer
= get_pointer_uint
;
1172 rb
->GetRow
= get_row_uint
;
1173 rb
->GetValues
= get_values_uint
;
1174 rb
->PutRow
= put_row_uint
;
1175 rb
->PutRowRGB
= NULL
;
1176 rb
->PutMonoRow
= put_mono_row_uint
;
1177 rb
->PutValues
= put_values_uint
;
1178 rb
->PutMonoValues
= put_mono_values_uint
;
1179 rb
->IndexBits
= 8 * sizeof(GLuint
);
1180 pixelSize
= sizeof(GLuint
);
1183 _mesa_problem(ctx
, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
1187 ASSERT(rb
->DataType
);
1188 ASSERT(rb
->GetPointer
);
1190 ASSERT(rb
->GetValues
);
1192 ASSERT(rb
->PutMonoRow
);
1193 ASSERT(rb
->PutValues
);
1194 ASSERT(rb
->PutMonoValues
);
1196 /* free old buffer storage */
1198 _mesa_free(rb
->Data
);
1202 if (width
> 0 && height
> 0) {
1203 /* allocate new buffer storage */
1204 rb
->Data
= malloc(width
* height
* pixelSize
);
1206 if (rb
->Data
== NULL
) {
1209 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1210 "software renderbuffer allocation (%d x %d x %d)",
1211 width
, height
, pixelSize
);
1217 rb
->Height
= height
;
1224 /**********************************************************************/
1225 /**********************************************************************/
1226 /**********************************************************************/
1230 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1231 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1233 * When PutRow is called (for example), we store the alpha values in
1234 * this buffer, then pass on the PutRow call to the wrapped RGB
1240 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1241 GLenum internalFormat
, GLuint width
, GLuint height
)
1243 ASSERT(arb
!= arb
->Wrapped
);
1244 ASSERT(arb
->_ActualFormat
== GL_ALPHA8
);
1246 /* first, pass the call to the wrapped RGB buffer */
1247 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1252 /* next, resize my alpha buffer */
1254 _mesa_free(arb
->Data
);
1257 arb
->Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1258 if (arb
->Data
== NULL
) {
1261 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1266 arb
->Height
= height
;
1273 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1276 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1279 _mesa_free(arb
->Data
);
1281 ASSERT(arb
->Wrapped
);
1282 ASSERT(arb
!= arb
->Wrapped
);
1283 arb
->Wrapped
->Delete(arb
->Wrapped
);
1284 arb
->Wrapped
= NULL
;
1290 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1293 return NULL
; /* don't allow direct access! */
1298 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1299 GLint x
, GLint y
, void *values
)
1301 /* NOTE: 'values' is RGBA format! */
1302 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1303 GLubyte
*dst
= (GLubyte
*) values
;
1305 ASSERT(arb
!= arb
->Wrapped
);
1306 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1307 /* first, pass the call to the wrapped RGB buffer */
1308 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1309 /* second, fill in alpha values from this buffer! */
1310 for (i
= 0; i
< count
; i
++) {
1311 dst
[i
* 4 + 3] = src
[i
];
1317 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1318 const GLint x
[], const GLint y
[], void *values
)
1320 GLubyte
*dst
= (GLubyte
*) values
;
1322 ASSERT(arb
!= arb
->Wrapped
);
1323 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1324 /* first, pass the call to the wrapped RGB buffer */
1325 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1326 /* second, fill in alpha values from this buffer! */
1327 for (i
= 0; i
< count
; i
++) {
1328 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1329 dst
[i
* 4 + 3] = *src
;
1335 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1336 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1338 const GLubyte
*src
= (const GLubyte
*) values
;
1339 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1341 ASSERT(arb
!= arb
->Wrapped
);
1342 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1343 /* first, pass the call to the wrapped RGB buffer */
1344 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1345 /* second, store alpha in our buffer */
1346 for (i
= 0; i
< count
; i
++) {
1347 if (!mask
|| mask
[i
]) {
1348 dst
[i
] = src
[i
* 4 + 3];
1355 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1356 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1358 const GLubyte
*src
= (const GLubyte
*) values
;
1359 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1361 ASSERT(arb
!= arb
->Wrapped
);
1362 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1363 /* first, pass the call to the wrapped RGB buffer */
1364 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1365 /* second, store alpha in our buffer */
1366 for (i
= 0; i
< count
; i
++) {
1367 if (!mask
|| mask
[i
]) {
1368 dst
[i
] = src
[i
* 4 + 3];
1375 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1376 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1378 const GLubyte val
= ((const GLubyte
*) value
)[3];
1379 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1380 ASSERT(arb
!= arb
->Wrapped
);
1381 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1382 /* first, pass the call to the wrapped RGB buffer */
1383 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1384 /* second, store alpha in our buffer */
1387 for (i
= 0; i
< count
; i
++) {
1394 _mesa_memset(dst
, val
, count
);
1400 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1401 const GLint x
[], const GLint y
[],
1402 const void *values
, const GLubyte
*mask
)
1404 const GLubyte
*src
= (const GLubyte
*) values
;
1406 ASSERT(arb
!= arb
->Wrapped
);
1407 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1408 /* first, pass the call to the wrapped RGB buffer */
1409 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1410 /* second, store alpha in our buffer */
1411 for (i
= 0; i
< count
; i
++) {
1412 if (!mask
|| mask
[i
]) {
1413 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1414 *dst
= src
[i
* 4 + 3];
1421 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1422 GLuint count
, const GLint x
[], const GLint y
[],
1423 const void *value
, const GLubyte
*mask
)
1425 const GLubyte val
= ((const GLubyte
*) value
)[3];
1427 ASSERT(arb
!= arb
->Wrapped
);
1428 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1429 /* first, pass the call to the wrapped RGB buffer */
1430 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1431 /* second, store alpha in our buffer */
1432 for (i
= 0; i
< count
; i
++) {
1433 if (!mask
|| mask
[i
]) {
1434 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1442 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1444 ASSERT(dst
->_ActualFormat
== GL_ALPHA8
);
1445 ASSERT(src
->_ActualFormat
== GL_ALPHA8
);
1446 ASSERT(dst
->Width
== src
->Width
);
1447 ASSERT(dst
->Height
== src
->Height
);
1449 _mesa_memcpy(dst
->Data
, src
->Data
, dst
->Width
* dst
->Height
* sizeof(GLubyte
));
1453 /**********************************************************************/
1454 /**********************************************************************/
1455 /**********************************************************************/
1459 * Default GetPointer routine. Always return NULL to indicate that
1460 * direct buffer access is not supported.
1463 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1470 * Initialize the fields of a gl_renderbuffer to default values.
1473 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1475 _glthread_INIT_MUTEX(rb
->Mutex
);
1477 rb
->Magic
= RB_MAGIC
;
1481 rb
->Delete
= _mesa_delete_renderbuffer
;
1483 /* The rest of these should be set later by the caller of this function or
1484 * the AllocStorage method:
1486 rb
->AllocStorage
= NULL
;
1490 rb
->InternalFormat
= GL_NONE
;
1491 rb
->_ActualFormat
= GL_NONE
;
1492 rb
->_BaseFormat
= GL_NONE
;
1493 rb
->DataType
= GL_NONE
;
1494 rb
->RedBits
= rb
->GreenBits
= rb
->BlueBits
= rb
->AlphaBits
= 0;
1497 rb
->StencilBits
= 0;
1500 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1501 * all over the drivers.
1505 rb
->GetPointer
= nop_get_pointer
;
1507 rb
->GetValues
= NULL
;
1509 rb
->PutRowRGB
= NULL
;
1510 rb
->PutMonoRow
= NULL
;
1511 rb
->PutValues
= NULL
;
1512 rb
->PutMonoValues
= NULL
;
1517 * Allocate a new gl_renderbuffer object. This can be used for user-created
1518 * renderbuffers or window-system renderbuffers.
1520 struct gl_renderbuffer
*
1521 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1523 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1525 _mesa_init_renderbuffer(rb
, name
);
1532 * Delete a gl_framebuffer.
1533 * This is the default function for renderbuffer->Delete().
1536 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1539 _mesa_free(rb
->Data
);
1546 * Allocate a software-based renderbuffer. This is called via the
1547 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1549 * This would not be used for hardware-based renderbuffers.
1551 struct gl_renderbuffer
*
1552 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1554 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1556 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1557 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1558 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1567 * Add software-based color renderbuffers to the given framebuffer.
1568 * This is a helper routine for device drivers when creating a
1569 * window system framebuffer (not a user-created render/framebuffer).
1570 * Once this function is called, you can basically forget about this
1571 * renderbuffer; core Mesa will handle all the buffer management and
1575 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1576 GLuint rgbBits
, GLuint alphaBits
,
1577 GLboolean frontLeft
, GLboolean backLeft
,
1578 GLboolean frontRight
, GLboolean backRight
)
1582 if (rgbBits
> 16 || alphaBits
> 16) {
1584 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1588 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1590 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1591 struct gl_renderbuffer
*rb
;
1593 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1595 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1597 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1599 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1602 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1604 rb
= _mesa_new_renderbuffer(ctx
, 0);
1606 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1612 rb
->_ActualFormat
= GL_RGBA8
;
1614 rb
->_ActualFormat
= GL_RGB8
;
1617 assert(rgbBits
<= 16);
1619 rb
->_ActualFormat
= GL_RGBA16
;
1621 rb
->_ActualFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1623 rb
->InternalFormat
= rb
->_ActualFormat
;
1625 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1626 _mesa_add_renderbuffer(fb
, b
, rb
);
1634 * Add software-based color index renderbuffers to the given framebuffer.
1635 * This is a helper routine for device drivers when creating a
1636 * window system framebuffer (not a user-created render/framebuffer).
1637 * Once this function is called, you can basically forget about this
1638 * renderbuffer; core Mesa will handle all the buffer management and
1642 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1644 GLboolean frontLeft
, GLboolean backLeft
,
1645 GLboolean frontRight
, GLboolean backRight
)
1649 if (indexBits
> 8) {
1651 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1655 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1657 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1658 struct gl_renderbuffer
*rb
;
1660 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1662 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1664 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1666 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1669 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1671 rb
= _mesa_new_renderbuffer(ctx
, 0);
1673 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1677 if (indexBits
<= 8) {
1678 /* only support GLuint for now */
1679 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1680 rb
->_ActualFormat
= COLOR_INDEX32
;
1683 rb
->_ActualFormat
= COLOR_INDEX32
;
1685 rb
->InternalFormat
= rb
->_ActualFormat
;
1687 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1688 _mesa_add_renderbuffer(fb
, b
, rb
);
1696 * Add software-based alpha renderbuffers to the given framebuffer.
1697 * This is a helper routine for device drivers when creating a
1698 * window system framebuffer (not a user-created render/framebuffer).
1699 * Once this function is called, you can basically forget about this
1700 * renderbuffer; core Mesa will handle all the buffer management and
1704 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1706 GLboolean frontLeft
, GLboolean backLeft
,
1707 GLboolean frontRight
, GLboolean backRight
)
1711 /* for window system framebuffers only! */
1712 assert(fb
->Name
== 0);
1714 if (alphaBits
> 8) {
1716 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1720 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1722 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1724 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1725 struct gl_renderbuffer
*arb
;
1727 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1729 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1731 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1733 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1736 /* the RGB buffer to wrap must already exist!! */
1737 assert(fb
->Attachment
[b
].Renderbuffer
);
1739 /* only GLubyte supported for now */
1740 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1742 /* allocate alpha renderbuffer */
1743 arb
= _mesa_new_renderbuffer(ctx
, 0);
1745 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1749 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1750 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1752 /* Set up my alphabuffer fields and plug in my functions.
1753 * The functions will put/get the alpha values from/to RGBA arrays
1754 * and then call the wrapped buffer's functions to handle the RGB
1757 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1758 arb
->_ActualFormat
= GL_ALPHA8
;
1759 arb
->_BaseFormat
= arb
->Wrapped
->_BaseFormat
;
1760 arb
->DataType
= arb
->Wrapped
->DataType
;
1761 arb
->AllocStorage
= alloc_storage_alpha8
;
1762 arb
->Delete
= delete_renderbuffer_alpha8
;
1763 arb
->GetPointer
= get_pointer_alpha8
;
1764 arb
->GetRow
= get_row_alpha8
;
1765 arb
->GetValues
= get_values_alpha8
;
1766 arb
->PutRow
= put_row_alpha8
;
1767 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1768 arb
->PutMonoRow
= put_mono_row_alpha8
;
1769 arb
->PutValues
= put_values_alpha8
;
1770 arb
->PutMonoValues
= put_mono_values_alpha8
;
1772 /* clear the pointer to avoid assertion/sanity check failure later */
1773 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1775 /* plug the alpha renderbuffer into the colorbuffer attachment */
1776 _mesa_add_renderbuffer(fb
, b
, arb
);
1784 * For framebuffers that use a software alpha channel wrapper
1785 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
1786 * copy the back buffer alpha channel into the front buffer alpha channel.
1789 _mesa_copy_soft_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
)
1791 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
1792 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
1793 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
1794 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
1797 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
1798 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
1799 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
1800 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
1805 * Add a software-based depth renderbuffer to the given framebuffer.
1806 * This is a helper routine for device drivers when creating a
1807 * window system framebuffer (not a user-created render/framebuffer).
1808 * Once this function is called, you can basically forget about this
1809 * renderbuffer; core Mesa will handle all the buffer management and
1813 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1816 struct gl_renderbuffer
*rb
;
1818 if (depthBits
> 32) {
1820 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1824 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1826 rb
= _mesa_new_renderbuffer(ctx
, 0);
1828 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1832 if (depthBits
<= 16) {
1833 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1835 else if (depthBits
<= 24) {
1836 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1839 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1841 rb
->InternalFormat
= rb
->_ActualFormat
;
1843 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1844 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1851 * Add a software-based stencil renderbuffer to the given framebuffer.
1852 * This is a helper routine for device drivers when creating a
1853 * window system framebuffer (not a user-created render/framebuffer).
1854 * Once this function is called, you can basically forget about this
1855 * renderbuffer; core Mesa will handle all the buffer management and
1859 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1862 struct gl_renderbuffer
*rb
;
1864 if (stencilBits
> 16) {
1866 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1870 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1872 rb
= _mesa_new_renderbuffer(ctx
, 0);
1874 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1878 if (stencilBits
<= 8) {
1879 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1882 /* not really supported (see s_stencil.c code) */
1883 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1885 rb
->InternalFormat
= rb
->_ActualFormat
;
1887 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1888 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1895 * Add a software-based accumulation renderbuffer to the given framebuffer.
1896 * This is a helper routine for device drivers when creating a
1897 * window system framebuffer (not a user-created render/framebuffer).
1898 * Once this function is called, you can basically forget about this
1899 * renderbuffer; core Mesa will handle all the buffer management and
1903 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1904 GLuint redBits
, GLuint greenBits
,
1905 GLuint blueBits
, GLuint alphaBits
)
1907 struct gl_renderbuffer
*rb
;
1909 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1911 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1915 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1917 rb
= _mesa_new_renderbuffer(ctx
, 0);
1919 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1923 rb
->_ActualFormat
= GL_RGBA16
;
1924 rb
->InternalFormat
= GL_RGBA16
;
1925 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1926 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1934 * Add a software-based accumulation renderbuffer to the given framebuffer.
1935 * This is a helper routine for device drivers when creating a
1936 * window system framebuffer (not a user-created render/framebuffer).
1937 * Once this function is called, you can basically forget about this
1938 * renderbuffer; core Mesa will handle all the buffer management and
1941 * NOTE: color-index aux buffers not supported.
1944 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1945 GLuint colorBits
, GLuint numBuffers
)
1949 if (colorBits
> 16) {
1951 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1955 assert(numBuffers
< MAX_AUX_BUFFERS
);
1957 for (i
= 0; i
< numBuffers
; i
++) {
1958 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1960 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1963 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1967 if (colorBits
<= 8) {
1968 rb
->_ActualFormat
= GL_RGBA8
;
1971 rb
->_ActualFormat
= GL_RGBA16
;
1973 rb
->InternalFormat
= rb
->_ActualFormat
;
1975 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1976 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1983 * Create/attach software-based renderbuffers to the given framebuffer.
1984 * This is a helper routine for device drivers. Drivers can just as well
1985 * call the individual _mesa_add_*_renderbuffer() routines directly.
1988 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1996 GLboolean frontLeft
= GL_TRUE
;
1997 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1998 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1999 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
2002 if (fb
->Visual
.rgbMode
) {
2003 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
2004 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
2005 _mesa_add_color_renderbuffers(NULL
, fb
,
2007 fb
->Visual
.alphaBits
,
2008 frontLeft
, backLeft
,
2009 frontRight
, backRight
);
2012 _mesa_add_color_index_renderbuffers(NULL
, fb
,
2013 fb
->Visual
.indexBits
,
2014 frontLeft
, backLeft
,
2015 frontRight
, backRight
);
2020 assert(fb
->Visual
.depthBits
> 0);
2021 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
2025 assert(fb
->Visual
.stencilBits
> 0);
2026 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
2030 assert(fb
->Visual
.rgbMode
);
2031 assert(fb
->Visual
.accumRedBits
> 0);
2032 assert(fb
->Visual
.accumGreenBits
> 0);
2033 assert(fb
->Visual
.accumBlueBits
> 0);
2034 _mesa_add_accum_renderbuffer(NULL
, fb
,
2035 fb
->Visual
.accumRedBits
,
2036 fb
->Visual
.accumGreenBits
,
2037 fb
->Visual
.accumBlueBits
,
2038 fb
->Visual
.accumAlphaBits
);
2042 assert(fb
->Visual
.rgbMode
);
2043 assert(fb
->Visual
.numAuxBuffers
> 0);
2044 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
2045 fb
->Visual
.numAuxBuffers
);
2049 assert(fb
->Visual
.rgbMode
);
2050 assert(fb
->Visual
.alphaBits
> 0);
2051 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
2052 frontLeft
, backLeft
,
2053 frontRight
, backRight
);
2065 * Attach a renderbuffer to a framebuffer.
2068 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
2069 GLuint bufferName
, struct gl_renderbuffer
*rb
)
2073 assert(bufferName
< BUFFER_COUNT
);
2075 /* There should be no previous renderbuffer on this attachment point,
2076 * with the exception of depth/stencil since the same renderbuffer may
2079 assert(bufferName
== BUFFER_DEPTH
||
2080 bufferName
== BUFFER_STENCIL
||
2081 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
2083 /* winsys vs. user-created buffer cross check */
2091 /* If Mesa's compiled with deep color channels (16 or 32 bits / channel)
2092 * and the device driver is expecting 8-bit values (GLubyte), we can
2093 * use a "renderbuffer adaptor/wrapper" to do the necessary conversions.
2095 if (rb
->_BaseFormat
== GL_RGBA
) {
2096 if (CHAN_BITS
== 16 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2097 GET_CURRENT_CONTEXT(ctx
);
2098 rb
= _mesa_new_renderbuffer_16wrap8(ctx
, rb
);
2100 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2101 GET_CURRENT_CONTEXT(ctx
);
2102 rb
= _mesa_new_renderbuffer_32wrap8(ctx
, rb
);
2104 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_SHORT
) {
2105 GET_CURRENT_CONTEXT(ctx
);
2106 rb
= _mesa_new_renderbuffer_32wrap16(ctx
, rb
);
2110 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
2111 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
2112 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
2117 * Remove the named renderbuffer from the given framebuffer.
2120 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
, GLuint bufferName
)
2122 struct gl_renderbuffer
*rb
;
2124 assert(bufferName
< BUFFER_COUNT
);
2126 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
2130 _mesa_reference_renderbuffer(&rb
, NULL
);
2132 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
2137 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
2138 * dereference that buffer first. The new renderbuffer's refcount will
2139 * be incremented. The old renderbuffer's refcount will be decremented.
2142 _mesa_reference_renderbuffer(struct gl_renderbuffer
**ptr
,
2143 struct gl_renderbuffer
*rb
)
2152 /* Unreference the old renderbuffer */
2153 GLboolean deleteFlag
= GL_FALSE
;
2154 struct gl_renderbuffer
*oldRb
= *ptr
;
2156 assert(oldRb
->Magic
== RB_MAGIC
);
2157 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
2158 assert(oldRb
->Magic
== RB_MAGIC
);
2159 ASSERT(oldRb
->RefCount
> 0);
2161 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
2162 deleteFlag
= (oldRb
->RefCount
== 0);
2163 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
2166 oldRb
->Magic
= 0; /* now invalid memory! */
2167 oldRb
->Delete(oldRb
);
2175 assert(rb
->Magic
== RB_MAGIC
);
2176 /* reference new renderbuffer */
2177 _glthread_LOCK_MUTEX(rb
->Mutex
);
2179 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
2180 _glthread_UNLOCK_MUTEX(rb
->Mutex
);
2187 * Create a new combined depth/stencil renderbuffer for implementing
2188 * the GL_EXT_packed_depth_stencil extension.
2189 * \return new depth/stencil renderbuffer
2191 struct gl_renderbuffer
*
2192 _mesa_new_depthstencil_renderbuffer(GLcontext
*ctx
, GLuint name
)
2194 struct gl_renderbuffer
*dsrb
;
2196 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
2200 /* init fields not covered by _mesa_new_renderbuffer() */
2201 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
2202 dsrb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
2203 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;