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_context.h"
55 #include "pipe/p_defines.h"
56 #include "state_tracker/st_context.h"
59 /* 32-bit color index format. Not a public format. */
60 #define COLOR_INDEX32 0x424243
64 * Routines for get/put values in common buffer formats follow.
65 * Someday add support for arbitrary row stride to make them more
69 /**********************************************************************
70 * Functions for buffers of 1 X GLubyte values.
75 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
80 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
81 /* Can't assert _ActualFormat since these funcs may be used for serveral
82 * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
84 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
89 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
90 GLint x
, GLint y
, void *values
)
92 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
93 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
94 _mesa_memcpy(values
, src
, count
* sizeof(GLubyte
));
99 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
100 const GLint x
[], const GLint y
[], void *values
)
102 GLubyte
*dst
= (GLubyte
*) values
;
104 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
105 for (i
= 0; i
< count
; i
++) {
106 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
113 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
114 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
116 const GLubyte
*src
= (const GLubyte
*) values
;
117 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
118 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
121 for (i
= 0; i
< count
; i
++) {
128 _mesa_memcpy(dst
, values
, count
* sizeof(GLubyte
));
134 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
135 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
137 const GLubyte val
= *((const GLubyte
*) value
);
138 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
139 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
142 for (i
= 0; i
< count
; i
++) {
150 for (i
= 0; i
< count
; i
++) {
158 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
159 const GLint x
[], const GLint y
[],
160 const void *values
, const GLubyte
*mask
)
162 const GLubyte
*src
= (const GLubyte
*) values
;
164 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
165 for (i
= 0; i
< count
; i
++) {
166 if (!mask
|| mask
[i
]) {
167 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
175 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
176 const GLint x
[], const GLint y
[],
177 const void *value
, const GLubyte
*mask
)
179 const GLubyte val
= *((const GLubyte
*) value
);
181 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
182 for (i
= 0; i
< count
; i
++) {
183 if (!mask
|| mask
[i
]) {
184 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
191 /**********************************************************************
192 * Functions for buffers of 1 X GLushort values.
197 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
202 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
203 ASSERT(rb
->Width
> 0);
204 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
209 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
210 GLint x
, GLint y
, void *values
)
212 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
213 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
214 _mesa_memcpy(values
, src
, count
* sizeof(GLushort
));
219 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
220 const GLint x
[], const GLint y
[], void *values
)
222 GLushort
*dst
= (GLushort
*) values
;
224 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
225 for (i
= 0; i
< count
; i
++) {
226 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
233 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
234 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
236 const GLushort
*src
= (const GLushort
*) values
;
237 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
238 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
241 for (i
= 0; i
< count
; i
++) {
248 _mesa_memcpy(dst
, src
, count
* sizeof(GLushort
));
254 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
255 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
257 const GLushort val
= *((const GLushort
*) value
);
258 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
259 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
262 for (i
= 0; i
< count
; i
++) {
270 for (i
= 0; i
< count
; i
++) {
278 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
279 const GLint x
[], const GLint y
[], const void *values
,
282 const GLushort
*src
= (const GLushort
*) values
;
284 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
285 for (i
= 0; i
< count
; i
++) {
286 if (!mask
|| mask
[i
]) {
287 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
295 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
296 GLuint count
, const GLint x
[], const GLint y
[],
297 const void *value
, const GLubyte
*mask
)
299 const GLushort val
= *((const GLushort
*) value
);
300 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
303 for (i
= 0; i
< count
; i
++) {
305 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
312 for (i
= 0; i
< count
; i
++) {
313 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
320 /**********************************************************************
321 * Functions for buffers of 1 X GLuint values.
322 * Typically depth/Z or color index.
326 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
331 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
332 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
333 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
338 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
339 GLint x
, GLint y
, void *values
)
341 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
342 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
343 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
344 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
349 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
350 const GLint x
[], const GLint y
[], void *values
)
352 GLuint
*dst
= (GLuint
*) values
;
354 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
355 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
356 for (i
= 0; i
< count
; i
++) {
357 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
364 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
365 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
367 const GLuint
*src
= (const GLuint
*) values
;
368 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
369 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
370 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
373 for (i
= 0; i
< count
; i
++) {
380 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
386 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
387 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
389 const GLuint val
= *((const GLuint
*) value
);
390 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
391 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
392 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
395 for (i
= 0; i
< count
; i
++) {
403 for (i
= 0; i
< count
; i
++) {
411 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
412 const GLint x
[], const GLint y
[], const void *values
,
415 const GLuint
*src
= (const GLuint
*) values
;
417 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
418 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
419 for (i
= 0; i
< count
; i
++) {
420 if (!mask
|| mask
[i
]) {
421 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
429 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
430 const GLint x
[], const GLint y
[], const void *value
,
433 const GLuint val
= *((const GLuint
*) value
);
435 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
436 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
437 for (i
= 0; i
< count
; i
++) {
438 if (!mask
|| mask
[i
]) {
439 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
446 /**********************************************************************
447 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
448 * Typically color buffers.
449 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
450 * alpha values and return 255 for outgoing alpha values.
454 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
457 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
458 /* No direct access since this buffer is RGB but caller will be
459 * treating it as if it were RGBA.
466 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
467 GLint x
, GLint y
, void *values
)
469 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
470 GLubyte
*dst
= (GLubyte
*) values
;
472 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
473 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
474 for (i
= 0; i
< count
; i
++) {
475 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
476 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
477 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
478 dst
[i
* 4 + 3] = 255;
484 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
485 const GLint x
[], const GLint y
[], void *values
)
487 GLubyte
*dst
= (GLubyte
*) values
;
489 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
490 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
491 for (i
= 0; i
< count
; i
++) {
493 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
494 dst
[i
* 4 + 0] = src
[0];
495 dst
[i
* 4 + 1] = src
[1];
496 dst
[i
* 4 + 2] = src
[2];
497 dst
[i
* 4 + 3] = 255;
503 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
504 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
506 /* note: incoming values are RGB+A! */
507 const GLubyte
*src
= (const GLubyte
*) values
;
508 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
510 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
511 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
512 for (i
= 0; i
< count
; i
++) {
513 if (!mask
|| mask
[i
]) {
514 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
515 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
516 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
523 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
524 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
526 /* note: incoming values are RGB+A! */
527 const GLubyte
*src
= (const GLubyte
*) values
;
528 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
530 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
531 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
532 for (i
= 0; i
< count
; i
++) {
533 if (!mask
|| mask
[i
]) {
534 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
535 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
536 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
543 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
544 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
546 /* note: incoming value is RGB+A! */
547 const GLubyte val0
= ((const GLubyte
*) value
)[0];
548 const GLubyte val1
= ((const GLubyte
*) value
)[1];
549 const GLubyte val2
= ((const GLubyte
*) value
)[2];
550 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
551 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
552 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
553 if (!mask
&& val0
== val1
&& val1
== val2
) {
555 _mesa_memset(dst
, val0
, 3 * count
);
559 for (i
= 0; i
< count
; i
++) {
560 if (!mask
|| mask
[i
]) {
561 dst
[i
* 3 + 0] = val0
;
562 dst
[i
* 3 + 1] = val1
;
563 dst
[i
* 3 + 2] = val2
;
571 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
572 const GLint x
[], const GLint y
[], const void *values
,
575 /* note: incoming values are RGB+A! */
576 const GLubyte
*src
= (const GLubyte
*) values
;
578 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
579 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
580 for (i
= 0; i
< count
; i
++) {
581 if (!mask
|| mask
[i
]) {
582 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
583 dst
[0] = src
[i
* 4 + 0];
584 dst
[1] = src
[i
* 4 + 1];
585 dst
[2] = src
[i
* 4 + 2];
592 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
593 GLuint count
, const GLint x
[], const GLint y
[],
594 const void *value
, const GLubyte
*mask
)
596 /* note: incoming value is RGB+A! */
597 const GLubyte val0
= ((const GLubyte
*) value
)[0];
598 const GLubyte val1
= ((const GLubyte
*) value
)[1];
599 const GLubyte val2
= ((const GLubyte
*) value
)[2];
601 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
602 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
603 for (i
= 0; i
< count
; i
++) {
604 if (!mask
|| mask
[i
]) {
605 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
614 /**********************************************************************
615 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
616 * Typically color buffers.
620 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
625 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
626 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
627 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
632 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
633 GLint x
, GLint y
, void *values
)
635 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
636 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
637 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
638 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLubyte
));
643 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
644 const GLint x
[], const GLint y
[], void *values
)
646 /* treat 4*GLubyte as 1*GLuint */
647 GLuint
*dst
= (GLuint
*) values
;
649 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
650 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
651 for (i
= 0; i
< count
; i
++) {
652 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
659 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
660 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
662 /* treat 4*GLubyte as 1*GLuint */
663 const GLuint
*src
= (const GLuint
*) values
;
664 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
665 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
666 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
669 for (i
= 0; i
< count
; i
++) {
676 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
682 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
683 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
685 /* Store RGB values in RGBA buffer */
686 const GLubyte
*src
= (const GLubyte
*) values
;
687 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
689 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
690 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
691 for (i
= 0; i
< count
; i
++) {
692 if (!mask
|| mask
[i
]) {
693 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
694 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
695 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
696 dst
[i
* 4 + 3] = 0xff;
703 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
704 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
706 /* treat 4*GLubyte as 1*GLuint */
707 const GLuint val
= *((const GLuint
*) value
);
708 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
709 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
710 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
711 if (!mask
&& val
== 0) {
713 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
719 for (i
= 0; i
< count
; i
++) {
727 for (i
= 0; i
< count
; i
++) {
736 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
737 const GLint x
[], const GLint y
[], const void *values
,
740 /* treat 4*GLubyte as 1*GLuint */
741 const GLuint
*src
= (const GLuint
*) values
;
743 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
744 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
745 for (i
= 0; i
< count
; i
++) {
746 if (!mask
|| mask
[i
]) {
747 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
755 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
756 GLuint count
, const GLint x
[], const GLint y
[],
757 const void *value
, const GLubyte
*mask
)
759 /* treat 4*GLubyte as 1*GLuint */
760 const GLuint val
= *((const GLuint
*) value
);
762 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
763 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
764 for (i
= 0; i
< count
; i
++) {
765 if (!mask
|| mask
[i
]) {
766 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
773 /**********************************************************************
774 * Functions for buffers of 4 X GLushort (or GLshort) values.
775 * Typically accum buffer.
779 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
784 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
785 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
790 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
791 GLint x
, GLint y
, void *values
)
793 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
794 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
795 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
800 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
801 const GLint x
[], const GLint y
[], void *values
)
803 GLushort
*dst
= (GLushort
*) values
;
805 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
806 for (i
= 0; i
< count
; i
++) {
808 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
815 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
816 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
818 const GLushort
*src
= (const GLushort
*) values
;
819 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
820 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
823 for (i
= 0; i
< count
; i
++) {
825 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
826 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
827 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
828 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
833 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
839 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
840 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
842 /* Put RGB values in RGBA buffer */
843 const GLushort
*src
= (const GLushort
*) values
;
844 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
845 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
848 for (i
= 0; i
< count
; i
++) {
850 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
851 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
852 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
853 dst
[i
* 4 + 3] = 0xffff;
858 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
864 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
865 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
867 const GLushort val0
= ((const GLushort
*) value
)[0];
868 const GLushort val1
= ((const GLushort
*) value
)[1];
869 const GLushort val2
= ((const GLushort
*) value
)[2];
870 const GLushort val3
= ((const GLushort
*) value
)[3];
871 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
872 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
873 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
874 /* common case for clearing accum buffer */
875 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
879 for (i
= 0; i
< count
; i
++) {
880 if (!mask
|| mask
[i
]) {
881 dst
[i
* 4 + 0] = val0
;
882 dst
[i
* 4 + 1] = val1
;
883 dst
[i
* 4 + 2] = val2
;
884 dst
[i
* 4 + 3] = val3
;
892 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
893 const GLint x
[], const GLint y
[], const void *values
,
896 const GLushort
*src
= (const GLushort
*) values
;
898 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
899 for (i
= 0; i
< count
; i
++) {
900 if (!mask
|| mask
[i
]) {
901 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
902 dst
[0] = src
[i
* 4 + 0];
903 dst
[1] = src
[i
* 4 + 1];
904 dst
[2] = src
[i
* 4 + 2];
905 dst
[3] = src
[i
* 4 + 3];
912 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
913 GLuint count
, const GLint x
[], const GLint y
[],
914 const void *value
, const GLubyte
*mask
)
916 const GLushort val0
= ((const GLushort
*) value
)[0];
917 const GLushort val1
= ((const GLushort
*) value
)[1];
918 const GLushort val2
= ((const GLushort
*) value
)[2];
919 const GLushort val3
= ((const GLushort
*) value
)[3];
921 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
922 for (i
= 0; i
< count
; i
++) {
923 if (!mask
|| mask
[i
]) {
924 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
936 * This is a software fallback for the gl_renderbuffer->AllocStorage
938 * Device drivers will typically override this function for the buffers
939 * which it manages (typically color buffers, Z and stencil).
940 * Other buffers (like software accumulation and aux buffers) which the driver
941 * doesn't manage can be handled with this function.
943 * This one multi-purpose function can allocate stencil, depth, accum, color
944 * or color-index buffers!
946 * This function also plugs in the appropriate GetPointer, Get/PutRow and
947 * Get/PutValues functions.
950 _mesa_soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
951 GLenum internalFormat
,
952 GLuint width
, GLuint height
)
954 struct pipe_context
*pipe
= ctx
->st
->pipe
;
957 /* first clear these fields */
966 switch (internalFormat
) {
975 rb
->_ActualFormat
= GL_RGB8
;
976 rb
->_BaseFormat
= GL_RGB
;
977 rb
->DataType
= GL_UNSIGNED_BYTE
;
978 rb
->GetPointer
= get_pointer_ubyte3
;
979 rb
->GetRow
= get_row_ubyte3
;
980 rb
->GetValues
= get_values_ubyte3
;
981 rb
->PutRow
= put_row_ubyte3
;
982 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
983 rb
->PutMonoRow
= put_mono_row_ubyte3
;
984 rb
->PutValues
= put_values_ubyte3
;
985 rb
->PutMonoValues
= put_mono_values_ubyte3
;
986 rb
->RedBits
= 8 * sizeof(GLubyte
);
987 rb
->GreenBits
= 8 * sizeof(GLubyte
);
988 rb
->BlueBits
= 8 * sizeof(GLubyte
);
990 pixelSize
= 3 * sizeof(GLubyte
);
997 rb
->_ActualFormat
= GL_RGBA8
;
998 rb
->_BaseFormat
= GL_RGBA
;
999 rb
->DataType
= GL_UNSIGNED_BYTE
;
1000 rb
->GetPointer
= get_pointer_ubyte4
;
1001 rb
->GetRow
= get_row_ubyte4
;
1002 rb
->GetValues
= get_values_ubyte4
;
1003 rb
->PutRow
= put_row_ubyte4
;
1004 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
1005 rb
->PutMonoRow
= put_mono_row_ubyte4
;
1006 rb
->PutValues
= put_values_ubyte4
;
1007 rb
->PutMonoValues
= put_mono_values_ubyte4
;
1008 rb
->RedBits
= 8 * sizeof(GLubyte
);
1009 rb
->GreenBits
= 8 * sizeof(GLubyte
);
1010 rb
->BlueBits
= 8 * sizeof(GLubyte
);
1011 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1012 pixelSize
= 4 * sizeof(GLubyte
);
1017 rb
->_ActualFormat
= GL_RGBA16
;
1018 rb
->_BaseFormat
= GL_RGBA
;
1019 rb
->DataType
= GL_UNSIGNED_SHORT
;
1020 rb
->GetPointer
= get_pointer_ushort4
;
1021 rb
->GetRow
= get_row_ushort4
;
1022 rb
->GetValues
= get_values_ushort4
;
1023 rb
->PutRow
= put_row_ushort4
;
1024 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1025 rb
->PutMonoRow
= put_mono_row_ushort4
;
1026 rb
->PutValues
= put_values_ushort4
;
1027 rb
->PutMonoValues
= put_mono_values_ushort4
;
1028 rb
->RedBits
= 8 * sizeof(GLushort
);
1029 rb
->GreenBits
= 8 * sizeof(GLushort
);
1030 rb
->BlueBits
= 8 * sizeof(GLushort
);
1031 rb
->AlphaBits
= 8 * sizeof(GLushort
);
1032 pixelSize
= 4 * sizeof(GLushort
);
1036 rb
->_ActualFormat
= GL_ALPHA8
;
1037 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
1038 rb
->DataType
= GL_UNSIGNED_BYTE
;
1039 rb
->GetPointer
= get_pointer_alpha8
;
1040 rb
->GetRow
= get_row_alpha8
;
1041 rb
->GetValues
= get_values_alpha8
;
1042 rb
->PutRow
= put_row_alpha8
;
1043 rb
->PutRowRGB
= NULL
;
1044 rb
->PutMonoRow
= put_mono_row_alpha8
;
1045 rb
->PutValues
= put_values_alpha8
;
1046 rb
->PutMonoValues
= put_mono_values_alpha8
;
1047 rb
->RedBits
= 0; /*red*/
1048 rb
->GreenBits
= 0; /*green*/
1049 rb
->BlueBits
= 0; /*blue*/
1050 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1051 pixelSize
= sizeof(GLubyte
);
1054 case GL_STENCIL_INDEX
:
1055 case GL_STENCIL_INDEX1_EXT
:
1056 case GL_STENCIL_INDEX4_EXT
:
1057 case GL_STENCIL_INDEX8_EXT
:
1058 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1059 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1060 rb
->DataType
= GL_UNSIGNED_BYTE
;
1061 rb
->GetPointer
= get_pointer_ubyte
;
1062 rb
->GetRow
= get_row_ubyte
;
1063 rb
->GetValues
= get_values_ubyte
;
1064 rb
->PutRow
= put_row_ubyte
;
1065 rb
->PutRowRGB
= NULL
;
1066 rb
->PutMonoRow
= put_mono_row_ubyte
;
1067 rb
->PutValues
= put_values_ubyte
;
1068 rb
->PutMonoValues
= put_mono_values_ubyte
;
1069 rb
->StencilBits
= 8 * sizeof(GLubyte
);
1070 pixelSize
= sizeof(GLubyte
);
1072 rb
->surface
= (struct pipe_surface
*)
1073 pipe
->surface_alloc(pipe
, PIPE_FORMAT_U_S8
);
1075 case GL_STENCIL_INDEX16_EXT
:
1076 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1077 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1078 rb
->DataType
= GL_UNSIGNED_SHORT
;
1079 rb
->GetPointer
= get_pointer_ushort
;
1080 rb
->GetRow
= get_row_ushort
;
1081 rb
->GetValues
= get_values_ushort
;
1082 rb
->PutRow
= put_row_ushort
;
1083 rb
->PutRowRGB
= NULL
;
1084 rb
->PutMonoRow
= put_mono_row_ushort
;
1085 rb
->PutValues
= put_values_ushort
;
1086 rb
->PutMonoValues
= put_mono_values_ushort
;
1087 rb
->StencilBits
= 8 * sizeof(GLushort
);
1088 pixelSize
= sizeof(GLushort
);
1090 case GL_DEPTH_COMPONENT
:
1091 case GL_DEPTH_COMPONENT16
:
1092 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1093 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1094 rb
->DataType
= GL_UNSIGNED_SHORT
;
1095 rb
->GetPointer
= get_pointer_ushort
;
1096 rb
->GetRow
= get_row_ushort
;
1097 rb
->GetValues
= get_values_ushort
;
1098 rb
->PutRow
= put_row_ushort
;
1099 rb
->PutRowRGB
= NULL
;
1100 rb
->PutMonoRow
= put_mono_row_ushort
;
1101 rb
->PutValues
= put_values_ushort
;
1102 rb
->PutMonoValues
= put_mono_values_ushort
;
1103 rb
->DepthBits
= 8 * sizeof(GLushort
);
1105 rb
->surface
= (struct pipe_surface
*)
1106 pipe
->surface_alloc(pipe
, PIPE_FORMAT_U_Z16
);
1107 pixelSize
= sizeof(GLushort
);
1109 case GL_DEPTH_COMPONENT24
:
1110 case GL_DEPTH_COMPONENT32
:
1111 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1112 rb
->DataType
= GL_UNSIGNED_INT
;
1113 rb
->GetPointer
= get_pointer_uint
;
1114 rb
->GetRow
= get_row_uint
;
1115 rb
->GetValues
= get_values_uint
;
1116 rb
->PutRow
= put_row_uint
;
1117 rb
->PutRowRGB
= NULL
;
1118 rb
->PutMonoRow
= put_mono_row_uint
;
1119 rb
->PutValues
= put_values_uint
;
1120 rb
->PutMonoValues
= put_mono_values_uint
;
1121 if (internalFormat
== GL_DEPTH_COMPONENT24
) {
1122 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1126 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1130 rb
->surface
= (struct pipe_surface
*)
1131 pipe
->surface_alloc(pipe
, PIPE_FORMAT_U_Z32
);
1132 pixelSize
= sizeof(GLuint
);
1134 case GL_DEPTH_STENCIL_EXT
:
1135 case GL_DEPTH24_STENCIL8_EXT
:
1136 rb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
1137 rb
->_BaseFormat
= GL_DEPTH_STENCIL_EXT
;
1138 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1139 rb
->GetPointer
= get_pointer_uint
;
1140 rb
->GetRow
= get_row_uint
;
1141 rb
->GetValues
= get_values_uint
;
1142 rb
->PutRow
= put_row_uint
;
1143 rb
->PutRowRGB
= NULL
;
1144 rb
->PutMonoRow
= put_mono_row_uint
;
1145 rb
->PutValues
= put_values_uint
;
1146 rb
->PutMonoValues
= put_mono_values_uint
;
1148 rb
->StencilBits
= 8;
1150 rb
->surface
= (struct pipe_surface
*)
1151 pipe
->surface_alloc(pipe
, PIPE_FORMAT_Z24_S8
);
1152 pixelSize
= sizeof(GLuint
);
1154 case GL_COLOR_INDEX8_EXT
:
1155 rb
->_ActualFormat
= GL_COLOR_INDEX8_EXT
;
1156 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1157 rb
->DataType
= GL_UNSIGNED_BYTE
;
1158 rb
->GetPointer
= get_pointer_ubyte
;
1159 rb
->GetRow
= get_row_ubyte
;
1160 rb
->GetValues
= get_values_ubyte
;
1161 rb
->PutRow
= put_row_ubyte
;
1162 rb
->PutRowRGB
= NULL
;
1163 rb
->PutMonoRow
= put_mono_row_ubyte
;
1164 rb
->PutValues
= put_values_ubyte
;
1165 rb
->PutMonoValues
= put_mono_values_ubyte
;
1166 rb
->IndexBits
= 8 * sizeof(GLubyte
);
1167 pixelSize
= sizeof(GLubyte
);
1169 case GL_COLOR_INDEX16_EXT
:
1170 rb
->_ActualFormat
= GL_COLOR_INDEX16_EXT
;
1171 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1172 rb
->DataType
= GL_UNSIGNED_SHORT
;
1173 rb
->GetPointer
= get_pointer_ushort
;
1174 rb
->GetRow
= get_row_ushort
;
1175 rb
->GetValues
= get_values_ushort
;
1176 rb
->PutRow
= put_row_ushort
;
1177 rb
->PutRowRGB
= NULL
;
1178 rb
->PutMonoRow
= put_mono_row_ushort
;
1179 rb
->PutValues
= put_values_ushort
;
1180 rb
->PutMonoValues
= put_mono_values_ushort
;
1181 rb
->IndexBits
= 8 * sizeof(GLushort
);
1182 pixelSize
= sizeof(GLushort
);
1185 rb
->_ActualFormat
= COLOR_INDEX32
;
1186 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1187 rb
->DataType
= GL_UNSIGNED_INT
;
1188 rb
->GetPointer
= get_pointer_uint
;
1189 rb
->GetRow
= get_row_uint
;
1190 rb
->GetValues
= get_values_uint
;
1191 rb
->PutRow
= put_row_uint
;
1192 rb
->PutRowRGB
= NULL
;
1193 rb
->PutMonoRow
= put_mono_row_uint
;
1194 rb
->PutValues
= put_values_uint
;
1195 rb
->PutMonoValues
= put_mono_values_uint
;
1196 rb
->IndexBits
= 8 * sizeof(GLuint
);
1197 pixelSize
= sizeof(GLuint
);
1200 _mesa_problem(ctx
, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
1204 ASSERT(rb
->DataType
);
1205 ASSERT(rb
->GetPointer
);
1207 ASSERT(rb
->GetValues
);
1209 ASSERT(rb
->PutMonoRow
);
1210 ASSERT(rb
->PutValues
);
1211 ASSERT(rb
->PutMonoValues
);
1213 /* free old buffer storage */
1215 /* pipe_surface/region */
1217 else if (rb
->Data
) {
1218 /* legacy renderbuffer (this will go away) */
1219 _mesa_free(rb
->Data
);
1223 if (width
> 0 && height
> 0) {
1224 /* allocate new buffer storage */
1226 /* pipe_surface/region */
1227 if (rb
->surface
->region
) {
1228 pipe
->region_unmap(pipe
, rb
->surface
->region
);
1229 pipe
->region_release(pipe
, &rb
->surface
->region
);
1231 rb
->surface
->region
= pipe
->region_alloc(pipe
, pixelSize
, width
, height
);
1232 /* XXX probably don't want to really map here */
1233 pipe
->region_map(pipe
, rb
->surface
->region
);
1234 rb
->Data
= rb
->surface
->region
->map
;
1237 /* legacy renderbuffer (this will go away) */
1238 rb
->Data
= malloc(width
* height
* pixelSize
);
1241 if (rb
->Data
== NULL
) {
1244 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1245 "software renderbuffer allocation (%d x %d x %d)",
1246 width
, height
, pixelSize
);
1252 rb
->Height
= height
;
1259 /**********************************************************************/
1260 /**********************************************************************/
1261 /**********************************************************************/
1265 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1266 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1268 * When PutRow is called (for example), we store the alpha values in
1269 * this buffer, then pass on the PutRow call to the wrapped RGB
1275 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1276 GLenum internalFormat
, GLuint width
, GLuint height
)
1278 ASSERT(arb
!= arb
->Wrapped
);
1279 ASSERT(arb
->_ActualFormat
== GL_ALPHA8
);
1281 /* first, pass the call to the wrapped RGB buffer */
1282 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1287 /* next, resize my alpha buffer */
1289 _mesa_free(arb
->Data
);
1292 arb
->Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1293 if (arb
->Data
== NULL
) {
1296 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1301 arb
->Height
= height
;
1308 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1311 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1314 _mesa_free(arb
->Data
);
1316 ASSERT(arb
->Wrapped
);
1317 ASSERT(arb
!= arb
->Wrapped
);
1318 arb
->Wrapped
->Delete(arb
->Wrapped
);
1319 arb
->Wrapped
= NULL
;
1325 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1328 return NULL
; /* don't allow direct access! */
1333 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1334 GLint x
, GLint y
, void *values
)
1336 /* NOTE: 'values' is RGBA format! */
1337 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1338 GLubyte
*dst
= (GLubyte
*) values
;
1340 ASSERT(arb
!= arb
->Wrapped
);
1341 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1342 /* first, pass the call to the wrapped RGB buffer */
1343 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1344 /* second, fill in alpha values from this buffer! */
1345 for (i
= 0; i
< count
; i
++) {
1346 dst
[i
* 4 + 3] = src
[i
];
1352 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1353 const GLint x
[], const GLint y
[], void *values
)
1355 GLubyte
*dst
= (GLubyte
*) values
;
1357 ASSERT(arb
!= arb
->Wrapped
);
1358 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1359 /* first, pass the call to the wrapped RGB buffer */
1360 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1361 /* second, fill in alpha values from this buffer! */
1362 for (i
= 0; i
< count
; i
++) {
1363 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1364 dst
[i
* 4 + 3] = *src
;
1370 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1371 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1373 const GLubyte
*src
= (const GLubyte
*) values
;
1374 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1376 ASSERT(arb
!= arb
->Wrapped
);
1377 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1378 /* first, pass the call to the wrapped RGB buffer */
1379 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1380 /* second, store alpha in our buffer */
1381 for (i
= 0; i
< count
; i
++) {
1382 if (!mask
|| mask
[i
]) {
1383 dst
[i
] = src
[i
* 4 + 3];
1390 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1391 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1393 const GLubyte
*src
= (const GLubyte
*) values
;
1394 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1396 ASSERT(arb
!= arb
->Wrapped
);
1397 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1398 /* first, pass the call to the wrapped RGB buffer */
1399 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1400 /* second, store alpha in our buffer */
1401 for (i
= 0; i
< count
; i
++) {
1402 if (!mask
|| mask
[i
]) {
1403 dst
[i
] = src
[i
* 4 + 3];
1410 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1411 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1413 const GLubyte val
= ((const GLubyte
*) value
)[3];
1414 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1415 ASSERT(arb
!= arb
->Wrapped
);
1416 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1417 /* first, pass the call to the wrapped RGB buffer */
1418 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1419 /* second, store alpha in our buffer */
1422 for (i
= 0; i
< count
; i
++) {
1429 _mesa_memset(dst
, val
, count
);
1435 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1436 const GLint x
[], const GLint y
[],
1437 const void *values
, const GLubyte
*mask
)
1439 const GLubyte
*src
= (const GLubyte
*) values
;
1441 ASSERT(arb
!= arb
->Wrapped
);
1442 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1443 /* first, pass the call to the wrapped RGB buffer */
1444 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1445 /* second, store alpha in our buffer */
1446 for (i
= 0; i
< count
; i
++) {
1447 if (!mask
|| mask
[i
]) {
1448 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1449 *dst
= src
[i
* 4 + 3];
1456 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1457 GLuint count
, const GLint x
[], const GLint y
[],
1458 const void *value
, const GLubyte
*mask
)
1460 const GLubyte val
= ((const GLubyte
*) value
)[3];
1462 ASSERT(arb
!= arb
->Wrapped
);
1463 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1464 /* first, pass the call to the wrapped RGB buffer */
1465 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1466 /* second, store alpha in our buffer */
1467 for (i
= 0; i
< count
; i
++) {
1468 if (!mask
|| mask
[i
]) {
1469 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1477 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1479 ASSERT(dst
->_ActualFormat
== GL_ALPHA8
);
1480 ASSERT(src
->_ActualFormat
== GL_ALPHA8
);
1481 ASSERT(dst
->Width
== src
->Width
);
1482 ASSERT(dst
->Height
== src
->Height
);
1484 _mesa_memcpy(dst
->Data
, src
->Data
, dst
->Width
* dst
->Height
* sizeof(GLubyte
));
1488 /**********************************************************************/
1489 /**********************************************************************/
1490 /**********************************************************************/
1494 * Default GetPointer routine. Always return NULL to indicate that
1495 * direct buffer access is not supported.
1498 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1505 * Initialize the fields of a gl_renderbuffer to default values.
1508 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1510 _glthread_INIT_MUTEX(rb
->Mutex
);
1512 rb
->Magic
= RB_MAGIC
;
1516 rb
->Delete
= _mesa_delete_renderbuffer
;
1518 /* The rest of these should be set later by the caller of this function or
1519 * the AllocStorage method:
1521 rb
->AllocStorage
= NULL
;
1525 rb
->InternalFormat
= GL_NONE
;
1526 rb
->_ActualFormat
= GL_NONE
;
1527 rb
->_BaseFormat
= GL_NONE
;
1528 rb
->DataType
= GL_NONE
;
1529 rb
->RedBits
= rb
->GreenBits
= rb
->BlueBits
= rb
->AlphaBits
= 0;
1532 rb
->StencilBits
= 0;
1535 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1536 * all over the drivers.
1540 rb
->GetPointer
= nop_get_pointer
;
1542 rb
->GetValues
= NULL
;
1544 rb
->PutRowRGB
= NULL
;
1545 rb
->PutMonoRow
= NULL
;
1546 rb
->PutValues
= NULL
;
1547 rb
->PutMonoValues
= NULL
;
1552 * Allocate a new gl_renderbuffer object. This can be used for user-created
1553 * renderbuffers or window-system renderbuffers.
1555 struct gl_renderbuffer
*
1556 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1558 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1560 _mesa_init_renderbuffer(rb
, name
);
1567 * Delete a gl_framebuffer.
1568 * This is the default function for renderbuffer->Delete().
1571 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1574 _mesa_free(rb
->Data
);
1581 * Allocate a software-based renderbuffer. This is called via the
1582 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1584 * This would not be used for hardware-based renderbuffers.
1586 struct gl_renderbuffer
*
1587 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1589 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1591 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1592 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1593 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1602 * Add software-based color renderbuffers to the given framebuffer.
1603 * This is a helper routine for device drivers when creating a
1604 * window system framebuffer (not a user-created render/framebuffer).
1605 * Once this function is called, you can basically forget about this
1606 * renderbuffer; core Mesa will handle all the buffer management and
1610 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1611 GLuint rgbBits
, GLuint alphaBits
,
1612 GLboolean frontLeft
, GLboolean backLeft
,
1613 GLboolean frontRight
, GLboolean backRight
)
1617 if (rgbBits
> 16 || alphaBits
> 16) {
1619 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1623 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1625 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1626 struct gl_renderbuffer
*rb
;
1628 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1630 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1632 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1634 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1637 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1639 rb
= _mesa_new_renderbuffer(ctx
, 0);
1641 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1647 rb
->_ActualFormat
= GL_RGBA8
;
1649 rb
->_ActualFormat
= GL_RGB8
;
1652 assert(rgbBits
<= 16);
1654 rb
->_ActualFormat
= GL_RGBA16
;
1656 rb
->_ActualFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1658 rb
->InternalFormat
= rb
->_ActualFormat
;
1660 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1661 _mesa_add_renderbuffer(fb
, b
, rb
);
1669 * Add software-based color index renderbuffers to the given framebuffer.
1670 * This is a helper routine for device drivers when creating a
1671 * window system framebuffer (not a user-created render/framebuffer).
1672 * Once this function is called, you can basically forget about this
1673 * renderbuffer; core Mesa will handle all the buffer management and
1677 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1679 GLboolean frontLeft
, GLboolean backLeft
,
1680 GLboolean frontRight
, GLboolean backRight
)
1684 if (indexBits
> 8) {
1686 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1690 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1692 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1693 struct gl_renderbuffer
*rb
;
1695 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1697 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1699 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1701 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1704 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1706 rb
= _mesa_new_renderbuffer(ctx
, 0);
1708 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1712 if (indexBits
<= 8) {
1713 /* only support GLuint for now */
1714 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1715 rb
->_ActualFormat
= COLOR_INDEX32
;
1718 rb
->_ActualFormat
= COLOR_INDEX32
;
1720 rb
->InternalFormat
= rb
->_ActualFormat
;
1722 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1723 _mesa_add_renderbuffer(fb
, b
, rb
);
1731 * Add software-based alpha renderbuffers to the given framebuffer.
1732 * This is a helper routine for device drivers when creating a
1733 * window system framebuffer (not a user-created render/framebuffer).
1734 * Once this function is called, you can basically forget about this
1735 * renderbuffer; core Mesa will handle all the buffer management and
1739 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1741 GLboolean frontLeft
, GLboolean backLeft
,
1742 GLboolean frontRight
, GLboolean backRight
)
1746 /* for window system framebuffers only! */
1747 assert(fb
->Name
== 0);
1749 if (alphaBits
> 8) {
1751 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1755 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1757 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1759 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1760 struct gl_renderbuffer
*arb
;
1762 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1764 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1766 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1768 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1771 /* the RGB buffer to wrap must already exist!! */
1772 assert(fb
->Attachment
[b
].Renderbuffer
);
1774 /* only GLubyte supported for now */
1775 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1777 /* allocate alpha renderbuffer */
1778 arb
= _mesa_new_renderbuffer(ctx
, 0);
1780 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1784 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1785 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1787 /* Set up my alphabuffer fields and plug in my functions.
1788 * The functions will put/get the alpha values from/to RGBA arrays
1789 * and then call the wrapped buffer's functions to handle the RGB
1792 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1793 arb
->_ActualFormat
= GL_ALPHA8
;
1794 arb
->_BaseFormat
= arb
->Wrapped
->_BaseFormat
;
1795 arb
->DataType
= arb
->Wrapped
->DataType
;
1796 arb
->AllocStorage
= alloc_storage_alpha8
;
1797 arb
->Delete
= delete_renderbuffer_alpha8
;
1798 arb
->GetPointer
= get_pointer_alpha8
;
1799 arb
->GetRow
= get_row_alpha8
;
1800 arb
->GetValues
= get_values_alpha8
;
1801 arb
->PutRow
= put_row_alpha8
;
1802 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1803 arb
->PutMonoRow
= put_mono_row_alpha8
;
1804 arb
->PutValues
= put_values_alpha8
;
1805 arb
->PutMonoValues
= put_mono_values_alpha8
;
1807 /* clear the pointer to avoid assertion/sanity check failure later */
1808 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1810 /* plug the alpha renderbuffer into the colorbuffer attachment */
1811 _mesa_add_renderbuffer(fb
, b
, arb
);
1819 * For framebuffers that use a software alpha channel wrapper
1820 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
1821 * copy the back buffer alpha channel into the front buffer alpha channel.
1824 _mesa_copy_soft_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
)
1826 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
1827 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
1828 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
1829 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
1832 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
1833 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
1834 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
1835 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
1840 * Add a software-based depth renderbuffer to the given framebuffer.
1841 * This is a helper routine for device drivers when creating a
1842 * window system framebuffer (not a user-created render/framebuffer).
1843 * Once this function is called, you can basically forget about this
1844 * renderbuffer; core Mesa will handle all the buffer management and
1848 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1851 struct gl_renderbuffer
*rb
;
1853 if (depthBits
> 32) {
1855 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1859 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1861 rb
= _mesa_new_renderbuffer(ctx
, 0);
1863 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1867 if (depthBits
<= 16) {
1868 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1870 else if (depthBits
<= 24) {
1871 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1874 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1876 rb
->InternalFormat
= rb
->_ActualFormat
;
1878 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1879 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1886 * Add a software-based stencil renderbuffer to the given framebuffer.
1887 * This is a helper routine for device drivers when creating a
1888 * window system framebuffer (not a user-created render/framebuffer).
1889 * Once this function is called, you can basically forget about this
1890 * renderbuffer; core Mesa will handle all the buffer management and
1894 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1897 struct gl_renderbuffer
*rb
;
1899 if (stencilBits
> 16) {
1901 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1905 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1907 rb
= _mesa_new_renderbuffer(ctx
, 0);
1909 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1913 if (stencilBits
<= 8) {
1914 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1917 /* not really supported (see s_stencil.c code) */
1918 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1920 rb
->InternalFormat
= rb
->_ActualFormat
;
1922 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1923 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1930 * Add a software-based accumulation renderbuffer to the given framebuffer.
1931 * This is a helper routine for device drivers when creating a
1932 * window system framebuffer (not a user-created render/framebuffer).
1933 * Once this function is called, you can basically forget about this
1934 * renderbuffer; core Mesa will handle all the buffer management and
1938 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1939 GLuint redBits
, GLuint greenBits
,
1940 GLuint blueBits
, GLuint alphaBits
)
1942 struct gl_renderbuffer
*rb
;
1944 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1946 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1950 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1952 rb
= _mesa_new_renderbuffer(ctx
, 0);
1954 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1958 rb
->_ActualFormat
= GL_RGBA16
;
1959 rb
->InternalFormat
= GL_RGBA16
;
1960 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1961 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1969 * Add a software-based accumulation renderbuffer to the given framebuffer.
1970 * This is a helper routine for device drivers when creating a
1971 * window system framebuffer (not a user-created render/framebuffer).
1972 * Once this function is called, you can basically forget about this
1973 * renderbuffer; core Mesa will handle all the buffer management and
1976 * NOTE: color-index aux buffers not supported.
1979 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1980 GLuint colorBits
, GLuint numBuffers
)
1984 if (colorBits
> 16) {
1986 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1990 assert(numBuffers
< MAX_AUX_BUFFERS
);
1992 for (i
= 0; i
< numBuffers
; i
++) {
1993 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1995 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1998 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
2002 if (colorBits
<= 8) {
2003 rb
->_ActualFormat
= GL_RGBA8
;
2006 rb
->_ActualFormat
= GL_RGBA16
;
2008 rb
->InternalFormat
= rb
->_ActualFormat
;
2010 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2011 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
2018 * Create/attach software-based renderbuffers to the given framebuffer.
2019 * This is a helper routine for device drivers. Drivers can just as well
2020 * call the individual _mesa_add_*_renderbuffer() routines directly.
2023 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
2031 GLboolean frontLeft
= GL_TRUE
;
2032 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
2033 GLboolean frontRight
= fb
->Visual
.stereoMode
;
2034 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
2037 if (fb
->Visual
.rgbMode
) {
2038 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
2039 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
2040 _mesa_add_color_renderbuffers(NULL
, fb
,
2042 fb
->Visual
.alphaBits
,
2043 frontLeft
, backLeft
,
2044 frontRight
, backRight
);
2047 _mesa_add_color_index_renderbuffers(NULL
, fb
,
2048 fb
->Visual
.indexBits
,
2049 frontLeft
, backLeft
,
2050 frontRight
, backRight
);
2055 assert(fb
->Visual
.depthBits
> 0);
2056 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
2060 assert(fb
->Visual
.stencilBits
> 0);
2061 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
2065 assert(fb
->Visual
.rgbMode
);
2066 assert(fb
->Visual
.accumRedBits
> 0);
2067 assert(fb
->Visual
.accumGreenBits
> 0);
2068 assert(fb
->Visual
.accumBlueBits
> 0);
2069 _mesa_add_accum_renderbuffer(NULL
, fb
,
2070 fb
->Visual
.accumRedBits
,
2071 fb
->Visual
.accumGreenBits
,
2072 fb
->Visual
.accumBlueBits
,
2073 fb
->Visual
.accumAlphaBits
);
2077 assert(fb
->Visual
.rgbMode
);
2078 assert(fb
->Visual
.numAuxBuffers
> 0);
2079 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
2080 fb
->Visual
.numAuxBuffers
);
2084 assert(fb
->Visual
.rgbMode
);
2085 assert(fb
->Visual
.alphaBits
> 0);
2086 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
2087 frontLeft
, backLeft
,
2088 frontRight
, backRight
);
2100 * Attach a renderbuffer to a framebuffer.
2103 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
2104 GLuint bufferName
, struct gl_renderbuffer
*rb
)
2108 assert(bufferName
< BUFFER_COUNT
);
2110 /* There should be no previous renderbuffer on this attachment point,
2111 * with the exception of depth/stencil since the same renderbuffer may
2114 assert(bufferName
== BUFFER_DEPTH
||
2115 bufferName
== BUFFER_STENCIL
||
2116 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
2118 /* winsys vs. user-created buffer cross check */
2126 /* If Mesa's compiled with deep color channels (16 or 32 bits / channel)
2127 * and the device driver is expecting 8-bit values (GLubyte), we can
2128 * use a "renderbuffer adaptor/wrapper" to do the necessary conversions.
2130 if (rb
->_BaseFormat
== GL_RGBA
) {
2131 if (CHAN_BITS
== 16 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2132 GET_CURRENT_CONTEXT(ctx
);
2133 rb
= _mesa_new_renderbuffer_16wrap8(ctx
, rb
);
2135 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2136 GET_CURRENT_CONTEXT(ctx
);
2137 rb
= _mesa_new_renderbuffer_32wrap8(ctx
, rb
);
2139 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_SHORT
) {
2140 GET_CURRENT_CONTEXT(ctx
);
2141 rb
= _mesa_new_renderbuffer_32wrap16(ctx
, rb
);
2145 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
2146 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
2147 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
2152 * Remove the named renderbuffer from the given framebuffer.
2155 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
, GLuint bufferName
)
2157 struct gl_renderbuffer
*rb
;
2159 assert(bufferName
< BUFFER_COUNT
);
2161 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
2165 _mesa_reference_renderbuffer(&rb
, NULL
);
2167 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
2172 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
2173 * dereference that buffer first. The new renderbuffer's refcount will
2174 * be incremented. The old renderbuffer's refcount will be decremented.
2177 _mesa_reference_renderbuffer(struct gl_renderbuffer
**ptr
,
2178 struct gl_renderbuffer
*rb
)
2187 /* Unreference the old renderbuffer */
2188 GLboolean deleteFlag
= GL_FALSE
;
2189 struct gl_renderbuffer
*oldRb
= *ptr
;
2191 assert(oldRb
->Magic
== RB_MAGIC
);
2192 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
2193 assert(oldRb
->Magic
== RB_MAGIC
);
2194 ASSERT(oldRb
->RefCount
> 0);
2196 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
2197 deleteFlag
= (oldRb
->RefCount
== 0);
2198 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
2201 oldRb
->Magic
= 0; /* now invalid memory! */
2202 oldRb
->Delete(oldRb
);
2210 assert(rb
->Magic
== RB_MAGIC
);
2211 /* reference new renderbuffer */
2212 _glthread_LOCK_MUTEX(rb
->Mutex
);
2214 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
2215 _glthread_UNLOCK_MUTEX(rb
->Mutex
);
2222 * Create a new combined depth/stencil renderbuffer for implementing
2223 * the GL_EXT_packed_depth_stencil extension.
2224 * \return new depth/stencil renderbuffer
2226 struct gl_renderbuffer
*
2227 _mesa_new_depthstencil_renderbuffer(GLcontext
*ctx
, GLuint name
)
2229 struct gl_renderbuffer
*dsrb
;
2231 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
2235 /* init fields not covered by _mesa_new_renderbuffer() */
2236 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
2237 dsrb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
2238 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;