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 "pipe/softpipe/sp_z_surface.h"
53 #include "pipe/p_state.h"
54 #include "pipe/p_defines.h"
57 /* 32-bit color index format. Not a public format. */
58 #define COLOR_INDEX32 0x424243
62 * Routines for get/put values in common buffer formats follow.
63 * Someday add support for arbitrary row stride to make them more
67 /**********************************************************************
68 * Functions for buffers of 1 X GLubyte values.
73 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
78 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
79 /* Can't assert _ActualFormat since these funcs may be used for serveral
80 * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
82 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
87 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
88 GLint x
, GLint y
, void *values
)
90 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
91 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
92 _mesa_memcpy(values
, src
, count
* sizeof(GLubyte
));
97 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
98 const GLint x
[], const GLint y
[], void *values
)
100 GLubyte
*dst
= (GLubyte
*) values
;
102 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
103 for (i
= 0; i
< count
; i
++) {
104 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
111 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
112 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
114 const GLubyte
*src
= (const GLubyte
*) values
;
115 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
116 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
119 for (i
= 0; i
< count
; i
++) {
126 _mesa_memcpy(dst
, values
, count
* sizeof(GLubyte
));
132 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
133 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
135 const GLubyte val
= *((const GLubyte
*) value
);
136 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
137 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
140 for (i
= 0; i
< count
; i
++) {
148 for (i
= 0; i
< count
; i
++) {
156 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
157 const GLint x
[], const GLint y
[],
158 const void *values
, const GLubyte
*mask
)
160 const GLubyte
*src
= (const GLubyte
*) values
;
162 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
163 for (i
= 0; i
< count
; i
++) {
164 if (!mask
|| mask
[i
]) {
165 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
173 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
174 const GLint x
[], const GLint y
[],
175 const void *value
, const GLubyte
*mask
)
177 const GLubyte val
= *((const GLubyte
*) value
);
179 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
180 for (i
= 0; i
< count
; i
++) {
181 if (!mask
|| mask
[i
]) {
182 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
189 /**********************************************************************
190 * Functions for buffers of 1 X GLushort values.
195 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
200 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
201 ASSERT(rb
->Width
> 0);
202 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
207 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
208 GLint x
, GLint y
, void *values
)
210 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
211 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
212 _mesa_memcpy(values
, src
, count
* sizeof(GLushort
));
217 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
218 const GLint x
[], const GLint y
[], void *values
)
220 GLushort
*dst
= (GLushort
*) values
;
222 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
223 for (i
= 0; i
< count
; i
++) {
224 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
231 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
232 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
234 const GLushort
*src
= (const GLushort
*) values
;
235 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
236 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
239 for (i
= 0; i
< count
; i
++) {
246 _mesa_memcpy(dst
, src
, count
* sizeof(GLushort
));
252 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
253 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
255 const GLushort val
= *((const GLushort
*) value
);
256 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
257 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
260 for (i
= 0; i
< count
; i
++) {
268 for (i
= 0; i
< count
; i
++) {
276 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
277 const GLint x
[], const GLint y
[], const void *values
,
280 const GLushort
*src
= (const GLushort
*) values
;
282 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
283 for (i
= 0; i
< count
; i
++) {
284 if (!mask
|| mask
[i
]) {
285 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
293 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
294 GLuint count
, const GLint x
[], const GLint y
[],
295 const void *value
, const GLubyte
*mask
)
297 const GLushort val
= *((const GLushort
*) value
);
298 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
301 for (i
= 0; i
< count
; i
++) {
303 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
310 for (i
= 0; i
< count
; i
++) {
311 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
318 /**********************************************************************
319 * Functions for buffers of 1 X GLuint values.
320 * Typically depth/Z or color index.
324 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
329 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
330 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
331 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
336 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
337 GLint x
, GLint y
, void *values
)
339 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
340 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
341 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
342 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
347 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
348 const GLint x
[], const GLint y
[], void *values
)
350 GLuint
*dst
= (GLuint
*) values
;
352 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
353 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
354 for (i
= 0; i
< count
; i
++) {
355 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
362 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
363 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
365 const GLuint
*src
= (const GLuint
*) values
;
366 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
367 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
368 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
371 for (i
= 0; i
< count
; i
++) {
378 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
384 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
385 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
387 const GLuint val
= *((const GLuint
*) value
);
388 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
389 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
390 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
393 for (i
= 0; i
< count
; i
++) {
401 for (i
= 0; i
< count
; i
++) {
409 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
410 const GLint x
[], const GLint y
[], const void *values
,
413 const GLuint
*src
= (const GLuint
*) values
;
415 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
416 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
417 for (i
= 0; i
< count
; i
++) {
418 if (!mask
|| mask
[i
]) {
419 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
427 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
428 const GLint x
[], const GLint y
[], const void *value
,
431 const GLuint val
= *((const GLuint
*) value
);
433 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
434 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
435 for (i
= 0; i
< count
; i
++) {
436 if (!mask
|| mask
[i
]) {
437 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
444 /**********************************************************************
445 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
446 * Typically color buffers.
447 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
448 * alpha values and return 255 for outgoing alpha values.
452 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
455 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
456 /* No direct access since this buffer is RGB but caller will be
457 * treating it as if it were RGBA.
464 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
465 GLint x
, GLint y
, void *values
)
467 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
468 GLubyte
*dst
= (GLubyte
*) values
;
470 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
471 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
472 for (i
= 0; i
< count
; i
++) {
473 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
474 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
475 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
476 dst
[i
* 4 + 3] = 255;
482 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
483 const GLint x
[], const GLint y
[], void *values
)
485 GLubyte
*dst
= (GLubyte
*) values
;
487 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
488 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
489 for (i
= 0; i
< count
; i
++) {
491 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
492 dst
[i
* 4 + 0] = src
[0];
493 dst
[i
* 4 + 1] = src
[1];
494 dst
[i
* 4 + 2] = src
[2];
495 dst
[i
* 4 + 3] = 255;
501 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
502 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
504 /* note: incoming values are RGB+A! */
505 const GLubyte
*src
= (const GLubyte
*) values
;
506 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
508 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
509 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
510 for (i
= 0; i
< count
; i
++) {
511 if (!mask
|| mask
[i
]) {
512 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
513 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
514 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
521 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
522 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
524 /* note: incoming values are RGB+A! */
525 const GLubyte
*src
= (const GLubyte
*) values
;
526 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
528 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
529 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
530 for (i
= 0; i
< count
; i
++) {
531 if (!mask
|| mask
[i
]) {
532 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
533 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
534 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
541 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
542 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
544 /* note: incoming value is RGB+A! */
545 const GLubyte val0
= ((const GLubyte
*) value
)[0];
546 const GLubyte val1
= ((const GLubyte
*) value
)[1];
547 const GLubyte val2
= ((const GLubyte
*) value
)[2];
548 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
549 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
550 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
551 if (!mask
&& val0
== val1
&& val1
== val2
) {
553 _mesa_memset(dst
, val0
, 3 * count
);
557 for (i
= 0; i
< count
; i
++) {
558 if (!mask
|| mask
[i
]) {
559 dst
[i
* 3 + 0] = val0
;
560 dst
[i
* 3 + 1] = val1
;
561 dst
[i
* 3 + 2] = val2
;
569 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
570 const GLint x
[], const GLint y
[], const void *values
,
573 /* note: incoming values are RGB+A! */
574 const GLubyte
*src
= (const GLubyte
*) values
;
576 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
577 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
578 for (i
= 0; i
< count
; i
++) {
579 if (!mask
|| mask
[i
]) {
580 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
581 dst
[0] = src
[i
* 4 + 0];
582 dst
[1] = src
[i
* 4 + 1];
583 dst
[2] = src
[i
* 4 + 2];
590 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
591 GLuint count
, const GLint x
[], const GLint y
[],
592 const void *value
, const GLubyte
*mask
)
594 /* note: incoming value is RGB+A! */
595 const GLubyte val0
= ((const GLubyte
*) value
)[0];
596 const GLubyte val1
= ((const GLubyte
*) value
)[1];
597 const GLubyte val2
= ((const GLubyte
*) value
)[2];
599 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
600 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
601 for (i
= 0; i
< count
; i
++) {
602 if (!mask
|| mask
[i
]) {
603 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
612 /**********************************************************************
613 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
614 * Typically color buffers.
618 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
623 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
624 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
625 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
630 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
631 GLint x
, GLint y
, void *values
)
633 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
634 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
635 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
636 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLubyte
));
641 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
642 const GLint x
[], const GLint y
[], void *values
)
644 /* treat 4*GLubyte as 1*GLuint */
645 GLuint
*dst
= (GLuint
*) values
;
647 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
648 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
649 for (i
= 0; i
< count
; i
++) {
650 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
657 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
658 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
660 /* treat 4*GLubyte as 1*GLuint */
661 const GLuint
*src
= (const GLuint
*) values
;
662 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
663 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
664 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
667 for (i
= 0; i
< count
; i
++) {
674 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
680 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
681 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
683 /* Store RGB values in RGBA buffer */
684 const GLubyte
*src
= (const GLubyte
*) values
;
685 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
687 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
688 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
689 for (i
= 0; i
< count
; i
++) {
690 if (!mask
|| mask
[i
]) {
691 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
692 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
693 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
694 dst
[i
* 4 + 3] = 0xff;
701 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
702 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
704 /* treat 4*GLubyte as 1*GLuint */
705 const GLuint val
= *((const GLuint
*) value
);
706 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
707 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
708 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
709 if (!mask
&& val
== 0) {
711 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
717 for (i
= 0; i
< count
; i
++) {
725 for (i
= 0; i
< count
; i
++) {
734 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
735 const GLint x
[], const GLint y
[], const void *values
,
738 /* treat 4*GLubyte as 1*GLuint */
739 const GLuint
*src
= (const GLuint
*) values
;
741 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
742 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
743 for (i
= 0; i
< count
; i
++) {
744 if (!mask
|| mask
[i
]) {
745 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
753 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
754 GLuint count
, const GLint x
[], const GLint y
[],
755 const void *value
, const GLubyte
*mask
)
757 /* treat 4*GLubyte as 1*GLuint */
758 const GLuint val
= *((const GLuint
*) value
);
760 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
761 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
762 for (i
= 0; i
< count
; i
++) {
763 if (!mask
|| mask
[i
]) {
764 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
771 /**********************************************************************
772 * Functions for buffers of 4 X GLushort (or GLshort) values.
773 * Typically accum buffer.
777 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
782 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
783 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
788 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
789 GLint x
, GLint y
, void *values
)
791 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
792 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
793 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
798 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
799 const GLint x
[], const GLint y
[], void *values
)
801 GLushort
*dst
= (GLushort
*) values
;
803 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
804 for (i
= 0; i
< count
; i
++) {
806 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
813 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
814 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
816 const GLushort
*src
= (const GLushort
*) values
;
817 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
818 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
821 for (i
= 0; i
< count
; i
++) {
823 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
824 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
825 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
826 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
831 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
837 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
838 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
840 /* Put RGB values in RGBA buffer */
841 const GLushort
*src
= (const GLushort
*) values
;
842 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
843 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
846 for (i
= 0; i
< count
; i
++) {
848 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
849 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
850 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
851 dst
[i
* 4 + 3] = 0xffff;
856 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
862 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
863 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
865 const GLushort val0
= ((const GLushort
*) value
)[0];
866 const GLushort val1
= ((const GLushort
*) value
)[1];
867 const GLushort val2
= ((const GLushort
*) value
)[2];
868 const GLushort val3
= ((const GLushort
*) value
)[3];
869 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
870 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
871 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
872 /* common case for clearing accum buffer */
873 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
877 for (i
= 0; i
< count
; i
++) {
878 if (!mask
|| mask
[i
]) {
879 dst
[i
* 4 + 0] = val0
;
880 dst
[i
* 4 + 1] = val1
;
881 dst
[i
* 4 + 2] = val2
;
882 dst
[i
* 4 + 3] = val3
;
890 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
891 const GLint x
[], const GLint y
[], const void *values
,
894 const GLushort
*src
= (const GLushort
*) values
;
896 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
897 for (i
= 0; i
< count
; i
++) {
898 if (!mask
|| mask
[i
]) {
899 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
900 dst
[0] = src
[i
* 4 + 0];
901 dst
[1] = src
[i
* 4 + 1];
902 dst
[2] = src
[i
* 4 + 2];
903 dst
[3] = src
[i
* 4 + 3];
910 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
911 GLuint count
, const GLint x
[], const GLint y
[],
912 const void *value
, const GLubyte
*mask
)
914 const GLushort val0
= ((const GLushort
*) value
)[0];
915 const GLushort val1
= ((const GLushort
*) value
)[1];
916 const GLushort val2
= ((const GLushort
*) value
)[2];
917 const GLushort val3
= ((const GLushort
*) value
)[3];
919 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
920 for (i
= 0; i
< count
; i
++) {
921 if (!mask
|| mask
[i
]) {
922 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
934 * This is a software fallback for the gl_renderbuffer->AllocStorage
936 * Device drivers will typically override this function for the buffers
937 * which it manages (typically color buffers, Z and stencil).
938 * Other buffers (like software accumulation and aux buffers) which the driver
939 * doesn't manage can be handled with this function.
941 * This one multi-purpose function can allocate stencil, depth, accum, color
942 * or color-index buffers!
944 * This function also plugs in the appropriate GetPointer, Get/PutRow and
945 * Get/PutValues functions.
948 _mesa_soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
949 GLenum internalFormat
,
950 GLuint width
, GLuint height
)
954 /* first clear these fields */
963 switch (internalFormat
) {
972 rb
->_ActualFormat
= GL_RGB8
;
973 rb
->_BaseFormat
= GL_RGB
;
974 rb
->DataType
= GL_UNSIGNED_BYTE
;
975 rb
->GetPointer
= get_pointer_ubyte3
;
976 rb
->GetRow
= get_row_ubyte3
;
977 rb
->GetValues
= get_values_ubyte3
;
978 rb
->PutRow
= put_row_ubyte3
;
979 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
980 rb
->PutMonoRow
= put_mono_row_ubyte3
;
981 rb
->PutValues
= put_values_ubyte3
;
982 rb
->PutMonoValues
= put_mono_values_ubyte3
;
983 rb
->RedBits
= 8 * sizeof(GLubyte
);
984 rb
->GreenBits
= 8 * sizeof(GLubyte
);
985 rb
->BlueBits
= 8 * sizeof(GLubyte
);
987 pixelSize
= 3 * sizeof(GLubyte
);
994 rb
->_ActualFormat
= GL_RGBA8
;
995 rb
->_BaseFormat
= GL_RGBA
;
996 rb
->DataType
= GL_UNSIGNED_BYTE
;
997 rb
->GetPointer
= get_pointer_ubyte4
;
998 rb
->GetRow
= get_row_ubyte4
;
999 rb
->GetValues
= get_values_ubyte4
;
1000 rb
->PutRow
= put_row_ubyte4
;
1001 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
1002 rb
->PutMonoRow
= put_mono_row_ubyte4
;
1003 rb
->PutValues
= put_values_ubyte4
;
1004 rb
->PutMonoValues
= put_mono_values_ubyte4
;
1005 rb
->RedBits
= 8 * sizeof(GLubyte
);
1006 rb
->GreenBits
= 8 * sizeof(GLubyte
);
1007 rb
->BlueBits
= 8 * sizeof(GLubyte
);
1008 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1009 pixelSize
= 4 * sizeof(GLubyte
);
1014 rb
->_ActualFormat
= GL_RGBA16
;
1015 rb
->_BaseFormat
= GL_RGBA
;
1016 rb
->DataType
= GL_UNSIGNED_SHORT
;
1017 rb
->GetPointer
= get_pointer_ushort4
;
1018 rb
->GetRow
= get_row_ushort4
;
1019 rb
->GetValues
= get_values_ushort4
;
1020 rb
->PutRow
= put_row_ushort4
;
1021 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1022 rb
->PutMonoRow
= put_mono_row_ushort4
;
1023 rb
->PutValues
= put_values_ushort4
;
1024 rb
->PutMonoValues
= put_mono_values_ushort4
;
1025 rb
->RedBits
= 8 * sizeof(GLushort
);
1026 rb
->GreenBits
= 8 * sizeof(GLushort
);
1027 rb
->BlueBits
= 8 * sizeof(GLushort
);
1028 rb
->AlphaBits
= 8 * sizeof(GLushort
);
1029 pixelSize
= 4 * sizeof(GLushort
);
1033 rb
->_ActualFormat
= GL_ALPHA8
;
1034 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
1035 rb
->DataType
= GL_UNSIGNED_BYTE
;
1036 rb
->GetPointer
= get_pointer_alpha8
;
1037 rb
->GetRow
= get_row_alpha8
;
1038 rb
->GetValues
= get_values_alpha8
;
1039 rb
->PutRow
= put_row_alpha8
;
1040 rb
->PutRowRGB
= NULL
;
1041 rb
->PutMonoRow
= put_mono_row_alpha8
;
1042 rb
->PutValues
= put_values_alpha8
;
1043 rb
->PutMonoValues
= put_mono_values_alpha8
;
1044 rb
->RedBits
= 0; /*red*/
1045 rb
->GreenBits
= 0; /*green*/
1046 rb
->BlueBits
= 0; /*blue*/
1047 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1048 pixelSize
= sizeof(GLubyte
);
1051 case GL_STENCIL_INDEX
:
1052 case GL_STENCIL_INDEX1_EXT
:
1053 case GL_STENCIL_INDEX4_EXT
:
1054 case GL_STENCIL_INDEX8_EXT
:
1055 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1056 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1057 rb
->DataType
= GL_UNSIGNED_BYTE
;
1058 rb
->GetPointer
= get_pointer_ubyte
;
1059 rb
->GetRow
= get_row_ubyte
;
1060 rb
->GetValues
= get_values_ubyte
;
1061 rb
->PutRow
= put_row_ubyte
;
1062 rb
->PutRowRGB
= NULL
;
1063 rb
->PutMonoRow
= put_mono_row_ubyte
;
1064 rb
->PutValues
= put_values_ubyte
;
1065 rb
->PutMonoValues
= put_mono_values_ubyte
;
1066 rb
->StencilBits
= 8 * sizeof(GLubyte
);
1067 pixelSize
= sizeof(GLubyte
);
1069 case GL_STENCIL_INDEX16_EXT
:
1070 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1071 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1072 rb
->DataType
= GL_UNSIGNED_SHORT
;
1073 rb
->GetPointer
= get_pointer_ushort
;
1074 rb
->GetRow
= get_row_ushort
;
1075 rb
->GetValues
= get_values_ushort
;
1076 rb
->PutRow
= put_row_ushort
;
1077 rb
->PutRowRGB
= NULL
;
1078 rb
->PutMonoRow
= put_mono_row_ushort
;
1079 rb
->PutValues
= put_values_ushort
;
1080 rb
->PutMonoValues
= put_mono_values_ushort
;
1081 rb
->StencilBits
= 8 * sizeof(GLushort
);
1082 pixelSize
= sizeof(GLushort
);
1084 case GL_DEPTH_COMPONENT
:
1085 case GL_DEPTH_COMPONENT16
:
1086 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1087 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1088 rb
->DataType
= GL_UNSIGNED_SHORT
;
1089 rb
->GetPointer
= get_pointer_ushort
;
1090 rb
->GetRow
= get_row_ushort
;
1091 rb
->GetValues
= get_values_ushort
;
1092 rb
->PutRow
= put_row_ushort
;
1093 rb
->PutRowRGB
= NULL
;
1094 rb
->PutMonoRow
= put_mono_row_ushort
;
1095 rb
->PutValues
= put_values_ushort
;
1096 rb
->PutMonoValues
= put_mono_values_ushort
;
1097 rb
->DepthBits
= 8 * sizeof(GLushort
);
1099 = (struct pipe_surface
*) softpipe_new_z_surface(PIPE_FORMAT_U_Z16
);
1100 pixelSize
= sizeof(GLushort
);
1102 case GL_DEPTH_COMPONENT24
:
1103 case GL_DEPTH_COMPONENT32
:
1104 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1105 rb
->DataType
= GL_UNSIGNED_INT
;
1106 rb
->GetPointer
= get_pointer_uint
;
1107 rb
->GetRow
= get_row_uint
;
1108 rb
->GetValues
= get_values_uint
;
1109 rb
->PutRow
= put_row_uint
;
1110 rb
->PutRowRGB
= NULL
;
1111 rb
->PutMonoRow
= put_mono_row_uint
;
1112 rb
->PutValues
= put_values_uint
;
1113 rb
->PutMonoValues
= put_mono_values_uint
;
1114 if (internalFormat
== GL_DEPTH_COMPONENT24
) {
1115 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1119 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1123 = (struct pipe_surface
*) softpipe_new_z_surface(PIPE_FORMAT_U_Z32
);
1124 pixelSize
= sizeof(GLuint
);
1126 case GL_DEPTH_STENCIL_EXT
:
1127 case GL_DEPTH24_STENCIL8_EXT
:
1128 rb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
1129 rb
->_BaseFormat
= GL_DEPTH_STENCIL_EXT
;
1130 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1131 rb
->GetPointer
= get_pointer_uint
;
1132 rb
->GetRow
= get_row_uint
;
1133 rb
->GetValues
= get_values_uint
;
1134 rb
->PutRow
= put_row_uint
;
1135 rb
->PutRowRGB
= NULL
;
1136 rb
->PutMonoRow
= put_mono_row_uint
;
1137 rb
->PutValues
= put_values_uint
;
1138 rb
->PutMonoValues
= put_mono_values_uint
;
1140 rb
->StencilBits
= 8;
1142 = (struct pipe_surface
*) softpipe_new_z_surface(PIPE_FORMAT_Z24_S8
);
1143 pixelSize
= sizeof(GLuint
);
1145 case GL_COLOR_INDEX8_EXT
:
1146 rb
->_ActualFormat
= GL_COLOR_INDEX8_EXT
;
1147 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1148 rb
->DataType
= GL_UNSIGNED_BYTE
;
1149 rb
->GetPointer
= get_pointer_ubyte
;
1150 rb
->GetRow
= get_row_ubyte
;
1151 rb
->GetValues
= get_values_ubyte
;
1152 rb
->PutRow
= put_row_ubyte
;
1153 rb
->PutRowRGB
= NULL
;
1154 rb
->PutMonoRow
= put_mono_row_ubyte
;
1155 rb
->PutValues
= put_values_ubyte
;
1156 rb
->PutMonoValues
= put_mono_values_ubyte
;
1157 rb
->IndexBits
= 8 * sizeof(GLubyte
);
1158 pixelSize
= sizeof(GLubyte
);
1160 case GL_COLOR_INDEX16_EXT
:
1161 rb
->_ActualFormat
= GL_COLOR_INDEX16_EXT
;
1162 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1163 rb
->DataType
= GL_UNSIGNED_SHORT
;
1164 rb
->GetPointer
= get_pointer_ushort
;
1165 rb
->GetRow
= get_row_ushort
;
1166 rb
->GetValues
= get_values_ushort
;
1167 rb
->PutRow
= put_row_ushort
;
1168 rb
->PutRowRGB
= NULL
;
1169 rb
->PutMonoRow
= put_mono_row_ushort
;
1170 rb
->PutValues
= put_values_ushort
;
1171 rb
->PutMonoValues
= put_mono_values_ushort
;
1172 rb
->IndexBits
= 8 * sizeof(GLushort
);
1173 pixelSize
= sizeof(GLushort
);
1176 rb
->_ActualFormat
= COLOR_INDEX32
;
1177 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1178 rb
->DataType
= GL_UNSIGNED_INT
;
1179 rb
->GetPointer
= get_pointer_uint
;
1180 rb
->GetRow
= get_row_uint
;
1181 rb
->GetValues
= get_values_uint
;
1182 rb
->PutRow
= put_row_uint
;
1183 rb
->PutRowRGB
= NULL
;
1184 rb
->PutMonoRow
= put_mono_row_uint
;
1185 rb
->PutValues
= put_values_uint
;
1186 rb
->PutMonoValues
= put_mono_values_uint
;
1187 rb
->IndexBits
= 8 * sizeof(GLuint
);
1188 pixelSize
= sizeof(GLuint
);
1191 _mesa_problem(ctx
, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
1195 ASSERT(rb
->DataType
);
1196 ASSERT(rb
->GetPointer
);
1198 ASSERT(rb
->GetValues
);
1200 ASSERT(rb
->PutMonoRow
);
1201 ASSERT(rb
->PutValues
);
1202 ASSERT(rb
->PutMonoValues
);
1204 /* free old buffer storage */
1210 /* legacy renderbuffer */
1211 _mesa_free(rb
->Data
);
1216 if (width
> 0 && height
> 0) {
1217 /* allocate new buffer storage */
1220 rb
->surface
->resize(rb
->surface
, width
, height
);
1221 rb
->Data
= rb
->surface
->buffer
.ptr
;
1224 /* legacy renderbuffer */
1225 rb
->Data
= _mesa_malloc(width
* height
* pixelSize
);
1227 if (rb
->Data
== NULL
) {
1230 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1231 "software renderbuffer allocation (%d x %d x %d)",
1232 width
, height
, pixelSize
);
1238 rb
->Height
= height
;
1245 /**********************************************************************/
1246 /**********************************************************************/
1247 /**********************************************************************/
1251 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1252 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1254 * When PutRow is called (for example), we store the alpha values in
1255 * this buffer, then pass on the PutRow call to the wrapped RGB
1261 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1262 GLenum internalFormat
, GLuint width
, GLuint height
)
1264 ASSERT(arb
!= arb
->Wrapped
);
1265 ASSERT(arb
->_ActualFormat
== GL_ALPHA8
);
1267 /* first, pass the call to the wrapped RGB buffer */
1268 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1273 /* next, resize my alpha buffer */
1275 _mesa_free(arb
->Data
);
1278 arb
->Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1279 if (arb
->Data
== NULL
) {
1282 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1287 arb
->Height
= height
;
1294 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1297 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1300 _mesa_free(arb
->Data
);
1302 ASSERT(arb
->Wrapped
);
1303 ASSERT(arb
!= arb
->Wrapped
);
1304 arb
->Wrapped
->Delete(arb
->Wrapped
);
1305 arb
->Wrapped
= NULL
;
1311 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1314 return NULL
; /* don't allow direct access! */
1319 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1320 GLint x
, GLint y
, void *values
)
1322 /* NOTE: 'values' is RGBA format! */
1323 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1324 GLubyte
*dst
= (GLubyte
*) values
;
1326 ASSERT(arb
!= arb
->Wrapped
);
1327 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1328 /* first, pass the call to the wrapped RGB buffer */
1329 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1330 /* second, fill in alpha values from this buffer! */
1331 for (i
= 0; i
< count
; i
++) {
1332 dst
[i
* 4 + 3] = src
[i
];
1338 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1339 const GLint x
[], const GLint y
[], void *values
)
1341 GLubyte
*dst
= (GLubyte
*) values
;
1343 ASSERT(arb
!= arb
->Wrapped
);
1344 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1345 /* first, pass the call to the wrapped RGB buffer */
1346 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1347 /* second, fill in alpha values from this buffer! */
1348 for (i
= 0; i
< count
; i
++) {
1349 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1350 dst
[i
* 4 + 3] = *src
;
1356 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1357 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1359 const GLubyte
*src
= (const GLubyte
*) values
;
1360 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1362 ASSERT(arb
!= arb
->Wrapped
);
1363 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1364 /* first, pass the call to the wrapped RGB buffer */
1365 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1366 /* second, store alpha in our buffer */
1367 for (i
= 0; i
< count
; i
++) {
1368 if (!mask
|| mask
[i
]) {
1369 dst
[i
] = src
[i
* 4 + 3];
1376 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1377 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1379 const GLubyte
*src
= (const GLubyte
*) values
;
1380 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1382 ASSERT(arb
!= arb
->Wrapped
);
1383 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1384 /* first, pass the call to the wrapped RGB buffer */
1385 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1386 /* second, store alpha in our buffer */
1387 for (i
= 0; i
< count
; i
++) {
1388 if (!mask
|| mask
[i
]) {
1389 dst
[i
] = src
[i
* 4 + 3];
1396 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1397 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1399 const GLubyte val
= ((const GLubyte
*) value
)[3];
1400 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1401 ASSERT(arb
!= arb
->Wrapped
);
1402 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1403 /* first, pass the call to the wrapped RGB buffer */
1404 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1405 /* second, store alpha in our buffer */
1408 for (i
= 0; i
< count
; i
++) {
1415 _mesa_memset(dst
, val
, count
);
1421 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1422 const GLint x
[], const GLint y
[],
1423 const void *values
, const GLubyte
*mask
)
1425 const GLubyte
*src
= (const GLubyte
*) values
;
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
, values
, 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
];
1435 *dst
= src
[i
* 4 + 3];
1442 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1443 GLuint count
, const GLint x
[], const GLint y
[],
1444 const void *value
, const GLubyte
*mask
)
1446 const GLubyte val
= ((const GLubyte
*) value
)[3];
1448 ASSERT(arb
!= arb
->Wrapped
);
1449 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1450 /* first, pass the call to the wrapped RGB buffer */
1451 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1452 /* second, store alpha in our buffer */
1453 for (i
= 0; i
< count
; i
++) {
1454 if (!mask
|| mask
[i
]) {
1455 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1463 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1465 ASSERT(dst
->_ActualFormat
== GL_ALPHA8
);
1466 ASSERT(src
->_ActualFormat
== GL_ALPHA8
);
1467 ASSERT(dst
->Width
== src
->Width
);
1468 ASSERT(dst
->Height
== src
->Height
);
1470 _mesa_memcpy(dst
->Data
, src
->Data
, dst
->Width
* dst
->Height
* sizeof(GLubyte
));
1474 /**********************************************************************/
1475 /**********************************************************************/
1476 /**********************************************************************/
1480 * Default GetPointer routine. Always return NULL to indicate that
1481 * direct buffer access is not supported.
1484 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1491 * Initialize the fields of a gl_renderbuffer to default values.
1494 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1496 _glthread_INIT_MUTEX(rb
->Mutex
);
1498 rb
->Magic
= RB_MAGIC
;
1502 rb
->Delete
= _mesa_delete_renderbuffer
;
1504 /* The rest of these should be set later by the caller of this function or
1505 * the AllocStorage method:
1507 rb
->AllocStorage
= NULL
;
1511 rb
->InternalFormat
= GL_NONE
;
1512 rb
->_ActualFormat
= GL_NONE
;
1513 rb
->_BaseFormat
= GL_NONE
;
1514 rb
->DataType
= GL_NONE
;
1515 rb
->RedBits
= rb
->GreenBits
= rb
->BlueBits
= rb
->AlphaBits
= 0;
1518 rb
->StencilBits
= 0;
1521 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1522 * all over the drivers.
1526 rb
->GetPointer
= nop_get_pointer
;
1528 rb
->GetValues
= NULL
;
1530 rb
->PutRowRGB
= NULL
;
1531 rb
->PutMonoRow
= NULL
;
1532 rb
->PutValues
= NULL
;
1533 rb
->PutMonoValues
= NULL
;
1538 * Allocate a new gl_renderbuffer object. This can be used for user-created
1539 * renderbuffers or window-system renderbuffers.
1541 struct gl_renderbuffer
*
1542 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1544 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1546 _mesa_init_renderbuffer(rb
, name
);
1553 * Delete a gl_framebuffer.
1554 * This is the default function for renderbuffer->Delete().
1557 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1560 _mesa_free(rb
->Data
);
1567 * Allocate a software-based renderbuffer. This is called via the
1568 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1570 * This would not be used for hardware-based renderbuffers.
1572 struct gl_renderbuffer
*
1573 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1575 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1577 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1578 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1579 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1588 * Add software-based color renderbuffers to the given framebuffer.
1589 * This is a helper routine for device drivers when creating a
1590 * window system framebuffer (not a user-created render/framebuffer).
1591 * Once this function is called, you can basically forget about this
1592 * renderbuffer; core Mesa will handle all the buffer management and
1596 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1597 GLuint rgbBits
, GLuint alphaBits
,
1598 GLboolean frontLeft
, GLboolean backLeft
,
1599 GLboolean frontRight
, GLboolean backRight
)
1603 if (rgbBits
> 16 || alphaBits
> 16) {
1605 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1609 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1611 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1612 struct gl_renderbuffer
*rb
;
1614 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1616 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1618 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1620 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1623 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1625 rb
= _mesa_new_renderbuffer(ctx
, 0);
1627 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1633 rb
->_ActualFormat
= GL_RGBA8
;
1635 rb
->_ActualFormat
= GL_RGB8
;
1638 assert(rgbBits
<= 16);
1640 rb
->_ActualFormat
= GL_RGBA16
;
1642 rb
->_ActualFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1644 rb
->InternalFormat
= rb
->_ActualFormat
;
1646 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1647 _mesa_add_renderbuffer(fb
, b
, rb
);
1655 * Add software-based color index renderbuffers to the given framebuffer.
1656 * This is a helper routine for device drivers when creating a
1657 * window system framebuffer (not a user-created render/framebuffer).
1658 * Once this function is called, you can basically forget about this
1659 * renderbuffer; core Mesa will handle all the buffer management and
1663 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1665 GLboolean frontLeft
, GLboolean backLeft
,
1666 GLboolean frontRight
, GLboolean backRight
)
1670 if (indexBits
> 8) {
1672 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1676 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1678 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1679 struct gl_renderbuffer
*rb
;
1681 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1683 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1685 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1687 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1690 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1692 rb
= _mesa_new_renderbuffer(ctx
, 0);
1694 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1698 if (indexBits
<= 8) {
1699 /* only support GLuint for now */
1700 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1701 rb
->_ActualFormat
= COLOR_INDEX32
;
1704 rb
->_ActualFormat
= COLOR_INDEX32
;
1706 rb
->InternalFormat
= rb
->_ActualFormat
;
1708 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1709 _mesa_add_renderbuffer(fb
, b
, rb
);
1717 * Add software-based alpha renderbuffers to the given framebuffer.
1718 * This is a helper routine for device drivers when creating a
1719 * window system framebuffer (not a user-created render/framebuffer).
1720 * Once this function is called, you can basically forget about this
1721 * renderbuffer; core Mesa will handle all the buffer management and
1725 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1727 GLboolean frontLeft
, GLboolean backLeft
,
1728 GLboolean frontRight
, GLboolean backRight
)
1732 /* for window system framebuffers only! */
1733 assert(fb
->Name
== 0);
1735 if (alphaBits
> 8) {
1737 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1741 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1743 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1745 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1746 struct gl_renderbuffer
*arb
;
1748 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1750 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1752 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1754 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1757 /* the RGB buffer to wrap must already exist!! */
1758 assert(fb
->Attachment
[b
].Renderbuffer
);
1760 /* only GLubyte supported for now */
1761 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1763 /* allocate alpha renderbuffer */
1764 arb
= _mesa_new_renderbuffer(ctx
, 0);
1766 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1770 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1771 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1773 /* Set up my alphabuffer fields and plug in my functions.
1774 * The functions will put/get the alpha values from/to RGBA arrays
1775 * and then call the wrapped buffer's functions to handle the RGB
1778 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1779 arb
->_ActualFormat
= GL_ALPHA8
;
1780 arb
->_BaseFormat
= arb
->Wrapped
->_BaseFormat
;
1781 arb
->DataType
= arb
->Wrapped
->DataType
;
1782 arb
->AllocStorage
= alloc_storage_alpha8
;
1783 arb
->Delete
= delete_renderbuffer_alpha8
;
1784 arb
->GetPointer
= get_pointer_alpha8
;
1785 arb
->GetRow
= get_row_alpha8
;
1786 arb
->GetValues
= get_values_alpha8
;
1787 arb
->PutRow
= put_row_alpha8
;
1788 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1789 arb
->PutMonoRow
= put_mono_row_alpha8
;
1790 arb
->PutValues
= put_values_alpha8
;
1791 arb
->PutMonoValues
= put_mono_values_alpha8
;
1793 /* clear the pointer to avoid assertion/sanity check failure later */
1794 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1796 /* plug the alpha renderbuffer into the colorbuffer attachment */
1797 _mesa_add_renderbuffer(fb
, b
, arb
);
1805 * For framebuffers that use a software alpha channel wrapper
1806 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
1807 * copy the back buffer alpha channel into the front buffer alpha channel.
1810 _mesa_copy_soft_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
)
1812 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
1813 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
1814 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
1815 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
1818 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
1819 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
1820 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
1821 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
1826 * Add a software-based depth renderbuffer to the given framebuffer.
1827 * This is a helper routine for device drivers when creating a
1828 * window system framebuffer (not a user-created render/framebuffer).
1829 * Once this function is called, you can basically forget about this
1830 * renderbuffer; core Mesa will handle all the buffer management and
1834 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1837 struct gl_renderbuffer
*rb
;
1839 if (depthBits
> 32) {
1841 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1845 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1847 rb
= _mesa_new_renderbuffer(ctx
, 0);
1849 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1853 if (depthBits
<= 16) {
1854 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1856 else if (depthBits
<= 24) {
1857 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1860 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1862 rb
->InternalFormat
= rb
->_ActualFormat
;
1864 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1865 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1872 * Add a software-based stencil renderbuffer to the given framebuffer.
1873 * This is a helper routine for device drivers when creating a
1874 * window system framebuffer (not a user-created render/framebuffer).
1875 * Once this function is called, you can basically forget about this
1876 * renderbuffer; core Mesa will handle all the buffer management and
1880 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1883 struct gl_renderbuffer
*rb
;
1885 if (stencilBits
> 16) {
1887 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1891 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1893 rb
= _mesa_new_renderbuffer(ctx
, 0);
1895 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1899 if (stencilBits
<= 8) {
1900 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1903 /* not really supported (see s_stencil.c code) */
1904 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1906 rb
->InternalFormat
= rb
->_ActualFormat
;
1908 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1909 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1916 * Add a software-based accumulation renderbuffer to the given framebuffer.
1917 * This is a helper routine for device drivers when creating a
1918 * window system framebuffer (not a user-created render/framebuffer).
1919 * Once this function is called, you can basically forget about this
1920 * renderbuffer; core Mesa will handle all the buffer management and
1924 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1925 GLuint redBits
, GLuint greenBits
,
1926 GLuint blueBits
, GLuint alphaBits
)
1928 struct gl_renderbuffer
*rb
;
1930 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1932 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1936 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1938 rb
= _mesa_new_renderbuffer(ctx
, 0);
1940 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1944 rb
->_ActualFormat
= GL_RGBA16
;
1945 rb
->InternalFormat
= GL_RGBA16
;
1946 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1947 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1955 * Add a software-based accumulation renderbuffer to the given framebuffer.
1956 * This is a helper routine for device drivers when creating a
1957 * window system framebuffer (not a user-created render/framebuffer).
1958 * Once this function is called, you can basically forget about this
1959 * renderbuffer; core Mesa will handle all the buffer management and
1962 * NOTE: color-index aux buffers not supported.
1965 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1966 GLuint colorBits
, GLuint numBuffers
)
1970 if (colorBits
> 16) {
1972 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1976 assert(numBuffers
< MAX_AUX_BUFFERS
);
1978 for (i
= 0; i
< numBuffers
; i
++) {
1979 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1981 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1984 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1988 if (colorBits
<= 8) {
1989 rb
->_ActualFormat
= GL_RGBA8
;
1992 rb
->_ActualFormat
= GL_RGBA16
;
1994 rb
->InternalFormat
= rb
->_ActualFormat
;
1996 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1997 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
2004 * Create/attach software-based renderbuffers to the given framebuffer.
2005 * This is a helper routine for device drivers. Drivers can just as well
2006 * call the individual _mesa_add_*_renderbuffer() routines directly.
2009 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
2017 GLboolean frontLeft
= GL_TRUE
;
2018 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
2019 GLboolean frontRight
= fb
->Visual
.stereoMode
;
2020 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
2023 if (fb
->Visual
.rgbMode
) {
2024 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
2025 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
2026 _mesa_add_color_renderbuffers(NULL
, fb
,
2028 fb
->Visual
.alphaBits
,
2029 frontLeft
, backLeft
,
2030 frontRight
, backRight
);
2033 _mesa_add_color_index_renderbuffers(NULL
, fb
,
2034 fb
->Visual
.indexBits
,
2035 frontLeft
, backLeft
,
2036 frontRight
, backRight
);
2041 assert(fb
->Visual
.depthBits
> 0);
2042 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
2046 assert(fb
->Visual
.stencilBits
> 0);
2047 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
2051 assert(fb
->Visual
.rgbMode
);
2052 assert(fb
->Visual
.accumRedBits
> 0);
2053 assert(fb
->Visual
.accumGreenBits
> 0);
2054 assert(fb
->Visual
.accumBlueBits
> 0);
2055 _mesa_add_accum_renderbuffer(NULL
, fb
,
2056 fb
->Visual
.accumRedBits
,
2057 fb
->Visual
.accumGreenBits
,
2058 fb
->Visual
.accumBlueBits
,
2059 fb
->Visual
.accumAlphaBits
);
2063 assert(fb
->Visual
.rgbMode
);
2064 assert(fb
->Visual
.numAuxBuffers
> 0);
2065 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
2066 fb
->Visual
.numAuxBuffers
);
2070 assert(fb
->Visual
.rgbMode
);
2071 assert(fb
->Visual
.alphaBits
> 0);
2072 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
2073 frontLeft
, backLeft
,
2074 frontRight
, backRight
);
2086 * Attach a renderbuffer to a framebuffer.
2089 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
2090 GLuint bufferName
, struct gl_renderbuffer
*rb
)
2094 assert(bufferName
< BUFFER_COUNT
);
2096 /* There should be no previous renderbuffer on this attachment point,
2097 * with the exception of depth/stencil since the same renderbuffer may
2100 assert(bufferName
== BUFFER_DEPTH
||
2101 bufferName
== BUFFER_STENCIL
||
2102 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
2104 /* winsys vs. user-created buffer cross check */
2112 /* If Mesa's compiled with deep color channels (16 or 32 bits / channel)
2113 * and the device driver is expecting 8-bit values (GLubyte), we can
2114 * use a "renderbuffer adaptor/wrapper" to do the necessary conversions.
2116 if (rb
->_BaseFormat
== GL_RGBA
) {
2117 if (CHAN_BITS
== 16 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2118 GET_CURRENT_CONTEXT(ctx
);
2119 rb
= _mesa_new_renderbuffer_16wrap8(ctx
, rb
);
2121 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2122 GET_CURRENT_CONTEXT(ctx
);
2123 rb
= _mesa_new_renderbuffer_32wrap8(ctx
, rb
);
2125 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_SHORT
) {
2126 GET_CURRENT_CONTEXT(ctx
);
2127 rb
= _mesa_new_renderbuffer_32wrap16(ctx
, rb
);
2131 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
2132 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
2133 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
2138 * Remove the named renderbuffer from the given framebuffer.
2141 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
, GLuint bufferName
)
2143 struct gl_renderbuffer
*rb
;
2145 assert(bufferName
< BUFFER_COUNT
);
2147 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
2151 _mesa_reference_renderbuffer(&rb
, NULL
);
2153 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
2158 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
2159 * dereference that buffer first. The new renderbuffer's refcount will
2160 * be incremented. The old renderbuffer's refcount will be decremented.
2163 _mesa_reference_renderbuffer(struct gl_renderbuffer
**ptr
,
2164 struct gl_renderbuffer
*rb
)
2173 /* Unreference the old renderbuffer */
2174 GLboolean deleteFlag
= GL_FALSE
;
2175 struct gl_renderbuffer
*oldRb
= *ptr
;
2177 assert(oldRb
->Magic
== RB_MAGIC
);
2178 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
2179 assert(oldRb
->Magic
== RB_MAGIC
);
2180 ASSERT(oldRb
->RefCount
> 0);
2182 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
2183 deleteFlag
= (oldRb
->RefCount
== 0);
2184 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
2187 oldRb
->Magic
= 0; /* now invalid memory! */
2188 oldRb
->Delete(oldRb
);
2196 assert(rb
->Magic
== RB_MAGIC
);
2197 /* reference new renderbuffer */
2198 _glthread_LOCK_MUTEX(rb
->Mutex
);
2200 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
2201 _glthread_UNLOCK_MUTEX(rb
->Mutex
);
2208 * Create a new combined depth/stencil renderbuffer for implementing
2209 * the GL_EXT_packed_depth_stencil extension.
2210 * \return new depth/stencil renderbuffer
2212 struct gl_renderbuffer
*
2213 _mesa_new_depthstencil_renderbuffer(GLcontext
*ctx
, GLuint name
)
2215 struct gl_renderbuffer
*dsrb
;
2217 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
2221 /* init fields not covered by _mesa_new_renderbuffer() */
2222 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
2223 dsrb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
2224 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;