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"
56 /* 32-bit color index format. Not a public format. */
57 #define COLOR_INDEX32 0x424243
61 * Routines for get/put values in common buffer formats follow.
62 * Someday add support for arbitrary row stride to make them more
66 /**********************************************************************
67 * Functions for buffers of 1 X GLubyte values.
72 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
77 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
78 /* Can't assert _ActualFormat since these funcs may be used for serveral
79 * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
81 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
86 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
87 GLint x
, GLint y
, void *values
)
89 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
90 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
91 _mesa_memcpy(values
, src
, count
* sizeof(GLubyte
));
96 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
97 const GLint x
[], const GLint y
[], void *values
)
99 GLubyte
*dst
= (GLubyte
*) values
;
101 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
102 for (i
= 0; i
< count
; i
++) {
103 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
110 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
111 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
113 const GLubyte
*src
= (const GLubyte
*) values
;
114 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
115 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
118 for (i
= 0; i
< count
; i
++) {
125 _mesa_memcpy(dst
, values
, count
* sizeof(GLubyte
));
131 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
132 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
134 const GLubyte val
= *((const GLubyte
*) value
);
135 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
136 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
139 for (i
= 0; i
< count
; i
++) {
147 for (i
= 0; i
< count
; i
++) {
155 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
156 const GLint x
[], const GLint y
[],
157 const void *values
, const GLubyte
*mask
)
159 const GLubyte
*src
= (const GLubyte
*) values
;
161 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
162 for (i
= 0; i
< count
; i
++) {
163 if (!mask
|| mask
[i
]) {
164 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
172 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
173 const GLint x
[], const GLint y
[],
174 const void *value
, const GLubyte
*mask
)
176 const GLubyte val
= *((const GLubyte
*) value
);
178 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
179 for (i
= 0; i
< count
; i
++) {
180 if (!mask
|| mask
[i
]) {
181 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
188 /**********************************************************************
189 * Functions for buffers of 1 X GLushort values.
194 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
199 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
200 ASSERT(rb
->Width
> 0);
201 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
206 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
207 GLint x
, GLint y
, void *values
)
209 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
210 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
211 _mesa_memcpy(values
, src
, count
* sizeof(GLushort
));
216 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
217 const GLint x
[], const GLint y
[], void *values
)
219 GLushort
*dst
= (GLushort
*) values
;
221 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
222 for (i
= 0; i
< count
; i
++) {
223 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
230 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
231 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
233 const GLushort
*src
= (const GLushort
*) values
;
234 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
235 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
238 for (i
= 0; i
< count
; i
++) {
245 _mesa_memcpy(dst
, src
, count
* sizeof(GLushort
));
251 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
252 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
254 const GLushort val
= *((const GLushort
*) value
);
255 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
256 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
259 for (i
= 0; i
< count
; i
++) {
267 for (i
= 0; i
< count
; i
++) {
275 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
276 const GLint x
[], const GLint y
[], const void *values
,
279 const GLushort
*src
= (const GLushort
*) values
;
281 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
282 for (i
= 0; i
< count
; i
++) {
283 if (!mask
|| mask
[i
]) {
284 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
292 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
293 GLuint count
, const GLint x
[], const GLint y
[],
294 const void *value
, const GLubyte
*mask
)
296 const GLushort val
= *((const GLushort
*) value
);
297 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
300 for (i
= 0; i
< count
; i
++) {
302 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
309 for (i
= 0; i
< count
; i
++) {
310 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
317 /**********************************************************************
318 * Functions for buffers of 1 X GLuint values.
319 * Typically depth/Z or color index.
323 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
328 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
329 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
330 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
335 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
336 GLint x
, GLint y
, void *values
)
338 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
339 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
340 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
341 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
346 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
347 const GLint x
[], const GLint y
[], void *values
)
349 GLuint
*dst
= (GLuint
*) values
;
351 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
352 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
353 for (i
= 0; i
< count
; i
++) {
354 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
361 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
362 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
364 const GLuint
*src
= (const GLuint
*) values
;
365 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
366 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
367 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
370 for (i
= 0; i
< count
; i
++) {
377 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
383 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
384 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
386 const GLuint val
= *((const GLuint
*) value
);
387 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
388 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
389 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
392 for (i
= 0; i
< count
; i
++) {
400 for (i
= 0; i
< count
; i
++) {
408 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
409 const GLint x
[], const GLint y
[], const void *values
,
412 const GLuint
*src
= (const GLuint
*) values
;
414 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
415 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
416 for (i
= 0; i
< count
; i
++) {
417 if (!mask
|| mask
[i
]) {
418 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
426 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
427 const GLint x
[], const GLint y
[], const void *value
,
430 const GLuint val
= *((const GLuint
*) value
);
432 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
433 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
434 for (i
= 0; i
< count
; i
++) {
435 if (!mask
|| mask
[i
]) {
436 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
443 /**********************************************************************
444 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
445 * Typically color buffers.
446 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
447 * alpha values and return 255 for outgoing alpha values.
451 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
454 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
455 /* No direct access since this buffer is RGB but caller will be
456 * treating it as if it were RGBA.
463 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
464 GLint x
, GLint y
, void *values
)
466 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
467 GLubyte
*dst
= (GLubyte
*) values
;
469 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
470 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
471 for (i
= 0; i
< count
; i
++) {
472 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
473 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
474 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
475 dst
[i
* 4 + 3] = 255;
481 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
482 const GLint x
[], const GLint y
[], void *values
)
484 GLubyte
*dst
= (GLubyte
*) values
;
486 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
487 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
488 for (i
= 0; i
< count
; i
++) {
490 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
491 dst
[i
* 4 + 0] = src
[0];
492 dst
[i
* 4 + 1] = src
[1];
493 dst
[i
* 4 + 2] = src
[2];
494 dst
[i
* 4 + 3] = 255;
500 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
501 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
503 /* note: incoming values are RGB+A! */
504 const GLubyte
*src
= (const GLubyte
*) values
;
505 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
507 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
508 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
509 for (i
= 0; i
< count
; i
++) {
510 if (!mask
|| mask
[i
]) {
511 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
512 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
513 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
520 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
521 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
523 /* note: incoming values are RGB+A! */
524 const GLubyte
*src
= (const GLubyte
*) values
;
525 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
527 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
528 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
529 for (i
= 0; i
< count
; i
++) {
530 if (!mask
|| mask
[i
]) {
531 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
532 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
533 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
540 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
541 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
543 /* note: incoming value is RGB+A! */
544 const GLubyte val0
= ((const GLubyte
*) value
)[0];
545 const GLubyte val1
= ((const GLubyte
*) value
)[1];
546 const GLubyte val2
= ((const GLubyte
*) value
)[2];
547 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
548 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
549 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
550 if (!mask
&& val0
== val1
&& val1
== val2
) {
552 _mesa_memset(dst
, val0
, 3 * count
);
556 for (i
= 0; i
< count
; i
++) {
557 if (!mask
|| mask
[i
]) {
558 dst
[i
* 3 + 0] = val0
;
559 dst
[i
* 3 + 1] = val1
;
560 dst
[i
* 3 + 2] = val2
;
568 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
569 const GLint x
[], const GLint y
[], const void *values
,
572 /* note: incoming values are RGB+A! */
573 const GLubyte
*src
= (const GLubyte
*) values
;
575 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
576 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
577 for (i
= 0; i
< count
; i
++) {
578 if (!mask
|| mask
[i
]) {
579 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
580 dst
[0] = src
[i
* 4 + 0];
581 dst
[1] = src
[i
* 4 + 1];
582 dst
[2] = src
[i
* 4 + 2];
589 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
590 GLuint count
, const GLint x
[], const GLint y
[],
591 const void *value
, const GLubyte
*mask
)
593 /* note: incoming value is RGB+A! */
594 const GLubyte val0
= ((const GLubyte
*) value
)[0];
595 const GLubyte val1
= ((const GLubyte
*) value
)[1];
596 const GLubyte val2
= ((const GLubyte
*) value
)[2];
598 ASSERT(rb
->_ActualFormat
== GL_RGB8
);
599 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
600 for (i
= 0; i
< count
; i
++) {
601 if (!mask
|| mask
[i
]) {
602 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
611 /**********************************************************************
612 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
613 * Typically color buffers.
617 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
622 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
623 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
624 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
629 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
630 GLint x
, GLint y
, void *values
)
632 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
633 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
634 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
635 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLubyte
));
640 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
641 const GLint x
[], const GLint y
[], void *values
)
643 /* treat 4*GLubyte as 1*GLuint */
644 GLuint
*dst
= (GLuint
*) values
;
646 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
647 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
648 for (i
= 0; i
< count
; i
++) {
649 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
656 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
657 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
659 /* treat 4*GLubyte as 1*GLuint */
660 const GLuint
*src
= (const GLuint
*) values
;
661 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
662 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
663 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
666 for (i
= 0; i
< count
; i
++) {
673 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
679 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
680 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
682 /* Store RGB values in RGBA buffer */
683 const GLubyte
*src
= (const GLubyte
*) values
;
684 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
686 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
687 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
688 for (i
= 0; i
< count
; i
++) {
689 if (!mask
|| mask
[i
]) {
690 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
691 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
692 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
693 dst
[i
* 4 + 3] = 0xff;
700 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
701 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
703 /* treat 4*GLubyte as 1*GLuint */
704 const GLuint val
= *((const GLuint
*) value
);
705 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
706 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
707 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
708 if (!mask
&& val
== 0) {
710 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
716 for (i
= 0; i
< count
; i
++) {
724 for (i
= 0; i
< count
; i
++) {
733 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
734 const GLint x
[], const GLint y
[], const void *values
,
737 /* treat 4*GLubyte as 1*GLuint */
738 const GLuint
*src
= (const GLuint
*) values
;
740 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
741 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
742 for (i
= 0; i
< count
; i
++) {
743 if (!mask
|| mask
[i
]) {
744 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
752 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
753 GLuint count
, const GLint x
[], const GLint y
[],
754 const void *value
, const GLubyte
*mask
)
756 /* treat 4*GLubyte as 1*GLuint */
757 const GLuint val
= *((const GLuint
*) value
);
759 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
760 ASSERT(rb
->_ActualFormat
== GL_RGBA8
);
761 for (i
= 0; i
< count
; i
++) {
762 if (!mask
|| mask
[i
]) {
763 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
770 /**********************************************************************
771 * Functions for buffers of 4 X GLushort (or GLshort) values.
772 * Typically accum buffer.
776 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
781 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
782 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
787 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
788 GLint x
, GLint y
, void *values
)
790 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
791 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
792 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
797 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
798 const GLint x
[], const GLint y
[], void *values
)
800 GLushort
*dst
= (GLushort
*) values
;
802 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
803 for (i
= 0; i
< count
; i
++) {
805 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
812 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
813 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
815 const GLushort
*src
= (const GLushort
*) values
;
816 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
817 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
820 for (i
= 0; i
< count
; i
++) {
822 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
823 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
824 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
825 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
830 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
836 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
837 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
839 /* Put RGB values in RGBA buffer */
840 const GLushort
*src
= (const GLushort
*) values
;
841 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
842 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
845 for (i
= 0; i
< count
; i
++) {
847 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
848 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
849 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
850 dst
[i
* 4 + 3] = 0xffff;
855 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
861 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
862 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
864 const GLushort val0
= ((const GLushort
*) value
)[0];
865 const GLushort val1
= ((const GLushort
*) value
)[1];
866 const GLushort val2
= ((const GLushort
*) value
)[2];
867 const GLushort val3
= ((const GLushort
*) value
)[3];
868 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
869 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
870 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
871 /* common case for clearing accum buffer */
872 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
876 for (i
= 0; i
< count
; i
++) {
877 if (!mask
|| mask
[i
]) {
878 dst
[i
* 4 + 0] = val0
;
879 dst
[i
* 4 + 1] = val1
;
880 dst
[i
* 4 + 2] = val2
;
881 dst
[i
* 4 + 3] = val3
;
889 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
890 const GLint x
[], const GLint y
[], const void *values
,
893 const GLushort
*src
= (const GLushort
*) values
;
895 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
896 for (i
= 0; i
< count
; i
++) {
897 if (!mask
|| mask
[i
]) {
898 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
899 dst
[0] = src
[i
* 4 + 0];
900 dst
[1] = src
[i
* 4 + 1];
901 dst
[2] = src
[i
* 4 + 2];
902 dst
[3] = src
[i
* 4 + 3];
909 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
910 GLuint count
, const GLint x
[], const GLint y
[],
911 const void *value
, const GLubyte
*mask
)
913 const GLushort val0
= ((const GLushort
*) value
)[0];
914 const GLushort val1
= ((const GLushort
*) value
)[1];
915 const GLushort val2
= ((const GLushort
*) value
)[2];
916 const GLushort val3
= ((const GLushort
*) value
)[3];
918 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
919 for (i
= 0; i
< count
; i
++) {
920 if (!mask
|| mask
[i
]) {
921 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
933 * This is a software fallback for the gl_renderbuffer->AllocStorage
935 * Device drivers will typically override this function for the buffers
936 * which it manages (typically color buffers, Z and stencil).
937 * Other buffers (like software accumulation and aux buffers) which the driver
938 * doesn't manage can be handled with this function.
940 * This one multi-purpose function can allocate stencil, depth, accum, color
941 * or color-index buffers!
943 * This function also plugs in the appropriate GetPointer, Get/PutRow and
944 * Get/PutValues functions.
947 _mesa_soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
948 GLenum internalFormat
,
949 GLuint width
, GLuint height
)
953 /* first clear these fields */
962 switch (internalFormat
) {
971 rb
->_ActualFormat
= GL_RGB8
;
972 rb
->_BaseFormat
= GL_RGB
;
973 rb
->DataType
= GL_UNSIGNED_BYTE
;
974 rb
->GetPointer
= get_pointer_ubyte3
;
975 rb
->GetRow
= get_row_ubyte3
;
976 rb
->GetValues
= get_values_ubyte3
;
977 rb
->PutRow
= put_row_ubyte3
;
978 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
979 rb
->PutMonoRow
= put_mono_row_ubyte3
;
980 rb
->PutValues
= put_values_ubyte3
;
981 rb
->PutMonoValues
= put_mono_values_ubyte3
;
982 rb
->RedBits
= 8 * sizeof(GLubyte
);
983 rb
->GreenBits
= 8 * sizeof(GLubyte
);
984 rb
->BlueBits
= 8 * sizeof(GLubyte
);
986 pixelSize
= 3 * sizeof(GLubyte
);
993 rb
->_ActualFormat
= GL_RGBA8
;
994 rb
->_BaseFormat
= GL_RGBA
;
995 rb
->DataType
= GL_UNSIGNED_BYTE
;
996 rb
->GetPointer
= get_pointer_ubyte4
;
997 rb
->GetRow
= get_row_ubyte4
;
998 rb
->GetValues
= get_values_ubyte4
;
999 rb
->PutRow
= put_row_ubyte4
;
1000 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
1001 rb
->PutMonoRow
= put_mono_row_ubyte4
;
1002 rb
->PutValues
= put_values_ubyte4
;
1003 rb
->PutMonoValues
= put_mono_values_ubyte4
;
1004 rb
->RedBits
= 8 * sizeof(GLubyte
);
1005 rb
->GreenBits
= 8 * sizeof(GLubyte
);
1006 rb
->BlueBits
= 8 * sizeof(GLubyte
);
1007 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1008 pixelSize
= 4 * sizeof(GLubyte
);
1013 rb
->_ActualFormat
= GL_RGBA16
;
1014 rb
->_BaseFormat
= GL_RGBA
;
1015 rb
->DataType
= GL_UNSIGNED_SHORT
;
1016 rb
->GetPointer
= get_pointer_ushort4
;
1017 rb
->GetRow
= get_row_ushort4
;
1018 rb
->GetValues
= get_values_ushort4
;
1019 rb
->PutRow
= put_row_ushort4
;
1020 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1021 rb
->PutMonoRow
= put_mono_row_ushort4
;
1022 rb
->PutValues
= put_values_ushort4
;
1023 rb
->PutMonoValues
= put_mono_values_ushort4
;
1024 rb
->RedBits
= 8 * sizeof(GLushort
);
1025 rb
->GreenBits
= 8 * sizeof(GLushort
);
1026 rb
->BlueBits
= 8 * sizeof(GLushort
);
1027 rb
->AlphaBits
= 8 * sizeof(GLushort
);
1028 pixelSize
= 4 * sizeof(GLushort
);
1032 rb
->_ActualFormat
= GL_ALPHA8
;
1033 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
1034 rb
->DataType
= GL_UNSIGNED_BYTE
;
1035 rb
->GetPointer
= get_pointer_alpha8
;
1036 rb
->GetRow
= get_row_alpha8
;
1037 rb
->GetValues
= get_values_alpha8
;
1038 rb
->PutRow
= put_row_alpha8
;
1039 rb
->PutRowRGB
= NULL
;
1040 rb
->PutMonoRow
= put_mono_row_alpha8
;
1041 rb
->PutValues
= put_values_alpha8
;
1042 rb
->PutMonoValues
= put_mono_values_alpha8
;
1043 rb
->RedBits
= 0; /*red*/
1044 rb
->GreenBits
= 0; /*green*/
1045 rb
->BlueBits
= 0; /*blue*/
1046 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1047 pixelSize
= sizeof(GLubyte
);
1050 case GL_STENCIL_INDEX
:
1051 case GL_STENCIL_INDEX1_EXT
:
1052 case GL_STENCIL_INDEX4_EXT
:
1053 case GL_STENCIL_INDEX8_EXT
:
1054 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1055 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1056 rb
->DataType
= GL_UNSIGNED_BYTE
;
1057 rb
->GetPointer
= get_pointer_ubyte
;
1058 rb
->GetRow
= get_row_ubyte
;
1059 rb
->GetValues
= get_values_ubyte
;
1060 rb
->PutRow
= put_row_ubyte
;
1061 rb
->PutRowRGB
= NULL
;
1062 rb
->PutMonoRow
= put_mono_row_ubyte
;
1063 rb
->PutValues
= put_values_ubyte
;
1064 rb
->PutMonoValues
= put_mono_values_ubyte
;
1065 rb
->StencilBits
= 8 * sizeof(GLubyte
);
1066 pixelSize
= sizeof(GLubyte
);
1068 case GL_STENCIL_INDEX16_EXT
:
1069 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1070 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1071 rb
->DataType
= GL_UNSIGNED_SHORT
;
1072 rb
->GetPointer
= get_pointer_ushort
;
1073 rb
->GetRow
= get_row_ushort
;
1074 rb
->GetValues
= get_values_ushort
;
1075 rb
->PutRow
= put_row_ushort
;
1076 rb
->PutRowRGB
= NULL
;
1077 rb
->PutMonoRow
= put_mono_row_ushort
;
1078 rb
->PutValues
= put_values_ushort
;
1079 rb
->PutMonoValues
= put_mono_values_ushort
;
1080 rb
->StencilBits
= 8 * sizeof(GLushort
);
1081 pixelSize
= sizeof(GLushort
);
1083 case GL_DEPTH_COMPONENT
:
1084 case GL_DEPTH_COMPONENT16
:
1085 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1086 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1087 rb
->DataType
= GL_UNSIGNED_SHORT
;
1088 rb
->GetPointer
= get_pointer_ushort
;
1089 rb
->GetRow
= get_row_ushort
;
1090 rb
->GetValues
= get_values_ushort
;
1091 rb
->PutRow
= put_row_ushort
;
1092 rb
->PutRowRGB
= NULL
;
1093 rb
->PutMonoRow
= put_mono_row_ushort
;
1094 rb
->PutValues
= put_values_ushort
;
1095 rb
->PutMonoValues
= put_mono_values_ushort
;
1096 rb
->DepthBits
= 8 * sizeof(GLushort
);
1097 rb
->surface
= (struct pipe_surface
*) softpipe_new_z_surface(16);
1098 pixelSize
= sizeof(GLushort
);
1100 case GL_DEPTH_COMPONENT24
:
1101 case GL_DEPTH_COMPONENT32
:
1102 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1103 rb
->DataType
= GL_UNSIGNED_INT
;
1104 rb
->GetPointer
= get_pointer_uint
;
1105 rb
->GetRow
= get_row_uint
;
1106 rb
->GetValues
= get_values_uint
;
1107 rb
->PutRow
= put_row_uint
;
1108 rb
->PutRowRGB
= NULL
;
1109 rb
->PutMonoRow
= put_mono_row_uint
;
1110 rb
->PutValues
= put_values_uint
;
1111 rb
->PutMonoValues
= put_mono_values_uint
;
1112 if (internalFormat
== GL_DEPTH_COMPONENT24
) {
1113 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1117 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1120 pixelSize
= sizeof(GLuint
);
1122 case GL_DEPTH_STENCIL_EXT
:
1123 case GL_DEPTH24_STENCIL8_EXT
:
1124 rb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
1125 rb
->_BaseFormat
= GL_DEPTH_STENCIL_EXT
;
1126 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1127 rb
->GetPointer
= get_pointer_uint
;
1128 rb
->GetRow
= get_row_uint
;
1129 rb
->GetValues
= get_values_uint
;
1130 rb
->PutRow
= put_row_uint
;
1131 rb
->PutRowRGB
= NULL
;
1132 rb
->PutMonoRow
= put_mono_row_uint
;
1133 rb
->PutValues
= put_values_uint
;
1134 rb
->PutMonoValues
= put_mono_values_uint
;
1136 rb
->StencilBits
= 8;
1137 pixelSize
= sizeof(GLuint
);
1139 case GL_COLOR_INDEX8_EXT
:
1140 rb
->_ActualFormat
= GL_COLOR_INDEX8_EXT
;
1141 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1142 rb
->DataType
= GL_UNSIGNED_BYTE
;
1143 rb
->GetPointer
= get_pointer_ubyte
;
1144 rb
->GetRow
= get_row_ubyte
;
1145 rb
->GetValues
= get_values_ubyte
;
1146 rb
->PutRow
= put_row_ubyte
;
1147 rb
->PutRowRGB
= NULL
;
1148 rb
->PutMonoRow
= put_mono_row_ubyte
;
1149 rb
->PutValues
= put_values_ubyte
;
1150 rb
->PutMonoValues
= put_mono_values_ubyte
;
1151 rb
->IndexBits
= 8 * sizeof(GLubyte
);
1152 pixelSize
= sizeof(GLubyte
);
1154 case GL_COLOR_INDEX16_EXT
:
1155 rb
->_ActualFormat
= GL_COLOR_INDEX16_EXT
;
1156 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1157 rb
->DataType
= GL_UNSIGNED_SHORT
;
1158 rb
->GetPointer
= get_pointer_ushort
;
1159 rb
->GetRow
= get_row_ushort
;
1160 rb
->GetValues
= get_values_ushort
;
1161 rb
->PutRow
= put_row_ushort
;
1162 rb
->PutRowRGB
= NULL
;
1163 rb
->PutMonoRow
= put_mono_row_ushort
;
1164 rb
->PutValues
= put_values_ushort
;
1165 rb
->PutMonoValues
= put_mono_values_ushort
;
1166 rb
->IndexBits
= 8 * sizeof(GLushort
);
1167 pixelSize
= sizeof(GLushort
);
1170 rb
->_ActualFormat
= COLOR_INDEX32
;
1171 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1172 rb
->DataType
= GL_UNSIGNED_INT
;
1173 rb
->GetPointer
= get_pointer_uint
;
1174 rb
->GetRow
= get_row_uint
;
1175 rb
->GetValues
= get_values_uint
;
1176 rb
->PutRow
= put_row_uint
;
1177 rb
->PutRowRGB
= NULL
;
1178 rb
->PutMonoRow
= put_mono_row_uint
;
1179 rb
->PutValues
= put_values_uint
;
1180 rb
->PutMonoValues
= put_mono_values_uint
;
1181 rb
->IndexBits
= 8 * sizeof(GLuint
);
1182 pixelSize
= sizeof(GLuint
);
1185 _mesa_problem(ctx
, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
1189 ASSERT(rb
->DataType
);
1190 ASSERT(rb
->GetPointer
);
1192 ASSERT(rb
->GetValues
);
1194 ASSERT(rb
->PutMonoRow
);
1195 ASSERT(rb
->PutValues
);
1196 ASSERT(rb
->PutMonoValues
);
1198 /* free old buffer storage */
1204 /* legacy renderbuffer */
1205 _mesa_free(rb
->Data
);
1210 if (width
> 0 && height
> 0) {
1211 /* allocate new buffer storage */
1214 rb
->surface
->resize(rb
->surface
, width
, height
);
1215 rb
->Data
= rb
->surface
->buffer
.ptr
;
1218 /* legacy renderbuffer */
1219 rb
->Data
= _mesa_malloc(width
* height
* pixelSize
);
1221 if (rb
->Data
== NULL
) {
1224 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1225 "software renderbuffer allocation (%d x %d x %d)",
1226 width
, height
, pixelSize
);
1232 rb
->Height
= height
;
1239 /**********************************************************************/
1240 /**********************************************************************/
1241 /**********************************************************************/
1245 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1246 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1248 * When PutRow is called (for example), we store the alpha values in
1249 * this buffer, then pass on the PutRow call to the wrapped RGB
1255 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1256 GLenum internalFormat
, GLuint width
, GLuint height
)
1258 ASSERT(arb
!= arb
->Wrapped
);
1259 ASSERT(arb
->_ActualFormat
== GL_ALPHA8
);
1261 /* first, pass the call to the wrapped RGB buffer */
1262 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1267 /* next, resize my alpha buffer */
1269 _mesa_free(arb
->Data
);
1272 arb
->Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1273 if (arb
->Data
== NULL
) {
1276 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1281 arb
->Height
= height
;
1288 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1291 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1294 _mesa_free(arb
->Data
);
1296 ASSERT(arb
->Wrapped
);
1297 ASSERT(arb
!= arb
->Wrapped
);
1298 arb
->Wrapped
->Delete(arb
->Wrapped
);
1299 arb
->Wrapped
= NULL
;
1305 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1308 return NULL
; /* don't allow direct access! */
1313 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1314 GLint x
, GLint y
, void *values
)
1316 /* NOTE: 'values' is RGBA format! */
1317 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1318 GLubyte
*dst
= (GLubyte
*) values
;
1320 ASSERT(arb
!= arb
->Wrapped
);
1321 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1322 /* first, pass the call to the wrapped RGB buffer */
1323 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1324 /* second, fill in alpha values from this buffer! */
1325 for (i
= 0; i
< count
; i
++) {
1326 dst
[i
* 4 + 3] = src
[i
];
1332 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1333 const GLint x
[], const GLint y
[], void *values
)
1335 GLubyte
*dst
= (GLubyte
*) values
;
1337 ASSERT(arb
!= arb
->Wrapped
);
1338 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1339 /* first, pass the call to the wrapped RGB buffer */
1340 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1341 /* second, fill in alpha values from this buffer! */
1342 for (i
= 0; i
< count
; i
++) {
1343 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1344 dst
[i
* 4 + 3] = *src
;
1350 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1351 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1353 const GLubyte
*src
= (const GLubyte
*) values
;
1354 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1356 ASSERT(arb
!= arb
->Wrapped
);
1357 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1358 /* first, pass the call to the wrapped RGB buffer */
1359 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1360 /* second, store alpha in our buffer */
1361 for (i
= 0; i
< count
; i
++) {
1362 if (!mask
|| mask
[i
]) {
1363 dst
[i
] = src
[i
* 4 + 3];
1370 put_row_rgb_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
->PutRowRGB(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_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1391 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1393 const GLubyte val
= ((const GLubyte
*) value
)[3];
1394 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1395 ASSERT(arb
!= arb
->Wrapped
);
1396 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1397 /* first, pass the call to the wrapped RGB buffer */
1398 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1399 /* second, store alpha in our buffer */
1402 for (i
= 0; i
< count
; i
++) {
1409 _mesa_memset(dst
, val
, count
);
1415 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1416 const GLint x
[], const GLint y
[],
1417 const void *values
, const GLubyte
*mask
)
1419 const GLubyte
*src
= (const GLubyte
*) values
;
1421 ASSERT(arb
!= arb
->Wrapped
);
1422 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1423 /* first, pass the call to the wrapped RGB buffer */
1424 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1425 /* second, store alpha in our buffer */
1426 for (i
= 0; i
< count
; i
++) {
1427 if (!mask
|| mask
[i
]) {
1428 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1429 *dst
= src
[i
* 4 + 3];
1436 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1437 GLuint count
, const GLint x
[], const GLint y
[],
1438 const void *value
, const GLubyte
*mask
)
1440 const GLubyte val
= ((const GLubyte
*) value
)[3];
1442 ASSERT(arb
!= arb
->Wrapped
);
1443 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1444 /* first, pass the call to the wrapped RGB buffer */
1445 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1446 /* second, store alpha in our buffer */
1447 for (i
= 0; i
< count
; i
++) {
1448 if (!mask
|| mask
[i
]) {
1449 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1457 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1459 ASSERT(dst
->_ActualFormat
== GL_ALPHA8
);
1460 ASSERT(src
->_ActualFormat
== GL_ALPHA8
);
1461 ASSERT(dst
->Width
== src
->Width
);
1462 ASSERT(dst
->Height
== src
->Height
);
1464 _mesa_memcpy(dst
->Data
, src
->Data
, dst
->Width
* dst
->Height
* sizeof(GLubyte
));
1468 /**********************************************************************/
1469 /**********************************************************************/
1470 /**********************************************************************/
1474 * Default GetPointer routine. Always return NULL to indicate that
1475 * direct buffer access is not supported.
1478 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1485 * Initialize the fields of a gl_renderbuffer to default values.
1488 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1490 _glthread_INIT_MUTEX(rb
->Mutex
);
1492 rb
->Magic
= RB_MAGIC
;
1496 rb
->Delete
= _mesa_delete_renderbuffer
;
1498 /* The rest of these should be set later by the caller of this function or
1499 * the AllocStorage method:
1501 rb
->AllocStorage
= NULL
;
1505 rb
->InternalFormat
= GL_NONE
;
1506 rb
->_ActualFormat
= GL_NONE
;
1507 rb
->_BaseFormat
= GL_NONE
;
1508 rb
->DataType
= GL_NONE
;
1509 rb
->RedBits
= rb
->GreenBits
= rb
->BlueBits
= rb
->AlphaBits
= 0;
1512 rb
->StencilBits
= 0;
1515 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1516 * all over the drivers.
1520 rb
->GetPointer
= nop_get_pointer
;
1522 rb
->GetValues
= NULL
;
1524 rb
->PutRowRGB
= NULL
;
1525 rb
->PutMonoRow
= NULL
;
1526 rb
->PutValues
= NULL
;
1527 rb
->PutMonoValues
= NULL
;
1532 * Allocate a new gl_renderbuffer object. This can be used for user-created
1533 * renderbuffers or window-system renderbuffers.
1535 struct gl_renderbuffer
*
1536 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1538 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1540 _mesa_init_renderbuffer(rb
, name
);
1547 * Delete a gl_framebuffer.
1548 * This is the default function for renderbuffer->Delete().
1551 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1554 _mesa_free(rb
->Data
);
1561 * Allocate a software-based renderbuffer. This is called via the
1562 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1564 * This would not be used for hardware-based renderbuffers.
1566 struct gl_renderbuffer
*
1567 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1569 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1571 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1572 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1573 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1582 * Add software-based color renderbuffers to the given framebuffer.
1583 * This is a helper routine for device drivers when creating a
1584 * window system framebuffer (not a user-created render/framebuffer).
1585 * Once this function is called, you can basically forget about this
1586 * renderbuffer; core Mesa will handle all the buffer management and
1590 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1591 GLuint rgbBits
, GLuint alphaBits
,
1592 GLboolean frontLeft
, GLboolean backLeft
,
1593 GLboolean frontRight
, GLboolean backRight
)
1597 if (rgbBits
> 16 || alphaBits
> 16) {
1599 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1603 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1605 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1606 struct gl_renderbuffer
*rb
;
1608 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1610 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1612 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1614 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1617 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1619 rb
= _mesa_new_renderbuffer(ctx
, 0);
1621 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1627 rb
->_ActualFormat
= GL_RGBA8
;
1629 rb
->_ActualFormat
= GL_RGB8
;
1632 assert(rgbBits
<= 16);
1634 rb
->_ActualFormat
= GL_RGBA16
;
1636 rb
->_ActualFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1638 rb
->InternalFormat
= rb
->_ActualFormat
;
1640 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1641 _mesa_add_renderbuffer(fb
, b
, rb
);
1649 * Add software-based color index renderbuffers to the given framebuffer.
1650 * This is a helper routine for device drivers when creating a
1651 * window system framebuffer (not a user-created render/framebuffer).
1652 * Once this function is called, you can basically forget about this
1653 * renderbuffer; core Mesa will handle all the buffer management and
1657 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1659 GLboolean frontLeft
, GLboolean backLeft
,
1660 GLboolean frontRight
, GLboolean backRight
)
1664 if (indexBits
> 8) {
1666 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1670 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1672 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1673 struct gl_renderbuffer
*rb
;
1675 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1677 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1679 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1681 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1684 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1686 rb
= _mesa_new_renderbuffer(ctx
, 0);
1688 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1692 if (indexBits
<= 8) {
1693 /* only support GLuint for now */
1694 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1695 rb
->_ActualFormat
= COLOR_INDEX32
;
1698 rb
->_ActualFormat
= COLOR_INDEX32
;
1700 rb
->InternalFormat
= rb
->_ActualFormat
;
1702 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1703 _mesa_add_renderbuffer(fb
, b
, rb
);
1711 * Add software-based alpha renderbuffers to the given framebuffer.
1712 * This is a helper routine for device drivers when creating a
1713 * window system framebuffer (not a user-created render/framebuffer).
1714 * Once this function is called, you can basically forget about this
1715 * renderbuffer; core Mesa will handle all the buffer management and
1719 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1721 GLboolean frontLeft
, GLboolean backLeft
,
1722 GLboolean frontRight
, GLboolean backRight
)
1726 /* for window system framebuffers only! */
1727 assert(fb
->Name
== 0);
1729 if (alphaBits
> 8) {
1731 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1735 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1737 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1739 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1740 struct gl_renderbuffer
*arb
;
1742 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1744 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1746 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1748 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1751 /* the RGB buffer to wrap must already exist!! */
1752 assert(fb
->Attachment
[b
].Renderbuffer
);
1754 /* only GLubyte supported for now */
1755 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1757 /* allocate alpha renderbuffer */
1758 arb
= _mesa_new_renderbuffer(ctx
, 0);
1760 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1764 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1765 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1767 /* Set up my alphabuffer fields and plug in my functions.
1768 * The functions will put/get the alpha values from/to RGBA arrays
1769 * and then call the wrapped buffer's functions to handle the RGB
1772 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1773 arb
->_ActualFormat
= GL_ALPHA8
;
1774 arb
->_BaseFormat
= arb
->Wrapped
->_BaseFormat
;
1775 arb
->DataType
= arb
->Wrapped
->DataType
;
1776 arb
->AllocStorage
= alloc_storage_alpha8
;
1777 arb
->Delete
= delete_renderbuffer_alpha8
;
1778 arb
->GetPointer
= get_pointer_alpha8
;
1779 arb
->GetRow
= get_row_alpha8
;
1780 arb
->GetValues
= get_values_alpha8
;
1781 arb
->PutRow
= put_row_alpha8
;
1782 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1783 arb
->PutMonoRow
= put_mono_row_alpha8
;
1784 arb
->PutValues
= put_values_alpha8
;
1785 arb
->PutMonoValues
= put_mono_values_alpha8
;
1787 /* clear the pointer to avoid assertion/sanity check failure later */
1788 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1790 /* plug the alpha renderbuffer into the colorbuffer attachment */
1791 _mesa_add_renderbuffer(fb
, b
, arb
);
1799 * For framebuffers that use a software alpha channel wrapper
1800 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
1801 * copy the back buffer alpha channel into the front buffer alpha channel.
1804 _mesa_copy_soft_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
)
1806 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
1807 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
1808 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
1809 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
1812 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
1813 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
1814 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
1815 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
1820 * Add a software-based depth renderbuffer to the given framebuffer.
1821 * This is a helper routine for device drivers when creating a
1822 * window system framebuffer (not a user-created render/framebuffer).
1823 * Once this function is called, you can basically forget about this
1824 * renderbuffer; core Mesa will handle all the buffer management and
1828 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1831 struct gl_renderbuffer
*rb
;
1833 if (depthBits
> 32) {
1835 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1839 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1841 rb
= _mesa_new_renderbuffer(ctx
, 0);
1843 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1847 if (depthBits
<= 16) {
1848 rb
->_ActualFormat
= GL_DEPTH_COMPONENT16
;
1850 else if (depthBits
<= 24) {
1851 rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
1854 rb
->_ActualFormat
= GL_DEPTH_COMPONENT32
;
1856 rb
->InternalFormat
= rb
->_ActualFormat
;
1858 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1859 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1866 * Add a software-based stencil renderbuffer to the given framebuffer.
1867 * This is a helper routine for device drivers when creating a
1868 * window system framebuffer (not a user-created render/framebuffer).
1869 * Once this function is called, you can basically forget about this
1870 * renderbuffer; core Mesa will handle all the buffer management and
1874 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1877 struct gl_renderbuffer
*rb
;
1879 if (stencilBits
> 16) {
1881 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1885 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1887 rb
= _mesa_new_renderbuffer(ctx
, 0);
1889 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1893 if (stencilBits
<= 8) {
1894 rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
1897 /* not really supported (see s_stencil.c code) */
1898 rb
->_ActualFormat
= GL_STENCIL_INDEX16_EXT
;
1900 rb
->InternalFormat
= rb
->_ActualFormat
;
1902 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1903 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1910 * Add a software-based accumulation renderbuffer to the given framebuffer.
1911 * This is a helper routine for device drivers when creating a
1912 * window system framebuffer (not a user-created render/framebuffer).
1913 * Once this function is called, you can basically forget about this
1914 * renderbuffer; core Mesa will handle all the buffer management and
1918 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1919 GLuint redBits
, GLuint greenBits
,
1920 GLuint blueBits
, GLuint alphaBits
)
1922 struct gl_renderbuffer
*rb
;
1924 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1926 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1930 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1932 rb
= _mesa_new_renderbuffer(ctx
, 0);
1934 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1938 rb
->_ActualFormat
= GL_RGBA16
;
1939 rb
->InternalFormat
= GL_RGBA16
;
1940 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1941 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1949 * Add a software-based accumulation renderbuffer to the given framebuffer.
1950 * This is a helper routine for device drivers when creating a
1951 * window system framebuffer (not a user-created render/framebuffer).
1952 * Once this function is called, you can basically forget about this
1953 * renderbuffer; core Mesa will handle all the buffer management and
1956 * NOTE: color-index aux buffers not supported.
1959 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1960 GLuint colorBits
, GLuint numBuffers
)
1964 if (colorBits
> 16) {
1966 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1970 assert(numBuffers
< MAX_AUX_BUFFERS
);
1972 for (i
= 0; i
< numBuffers
; i
++) {
1973 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1975 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1978 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1982 if (colorBits
<= 8) {
1983 rb
->_ActualFormat
= GL_RGBA8
;
1986 rb
->_ActualFormat
= GL_RGBA16
;
1988 rb
->InternalFormat
= rb
->_ActualFormat
;
1990 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1991 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1998 * Create/attach software-based renderbuffers to the given framebuffer.
1999 * This is a helper routine for device drivers. Drivers can just as well
2000 * call the individual _mesa_add_*_renderbuffer() routines directly.
2003 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
2011 GLboolean frontLeft
= GL_TRUE
;
2012 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
2013 GLboolean frontRight
= fb
->Visual
.stereoMode
;
2014 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
2017 if (fb
->Visual
.rgbMode
) {
2018 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
2019 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
2020 _mesa_add_color_renderbuffers(NULL
, fb
,
2022 fb
->Visual
.alphaBits
,
2023 frontLeft
, backLeft
,
2024 frontRight
, backRight
);
2027 _mesa_add_color_index_renderbuffers(NULL
, fb
,
2028 fb
->Visual
.indexBits
,
2029 frontLeft
, backLeft
,
2030 frontRight
, backRight
);
2035 assert(fb
->Visual
.depthBits
> 0);
2036 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
2040 assert(fb
->Visual
.stencilBits
> 0);
2041 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
2045 assert(fb
->Visual
.rgbMode
);
2046 assert(fb
->Visual
.accumRedBits
> 0);
2047 assert(fb
->Visual
.accumGreenBits
> 0);
2048 assert(fb
->Visual
.accumBlueBits
> 0);
2049 _mesa_add_accum_renderbuffer(NULL
, fb
,
2050 fb
->Visual
.accumRedBits
,
2051 fb
->Visual
.accumGreenBits
,
2052 fb
->Visual
.accumBlueBits
,
2053 fb
->Visual
.accumAlphaBits
);
2057 assert(fb
->Visual
.rgbMode
);
2058 assert(fb
->Visual
.numAuxBuffers
> 0);
2059 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
2060 fb
->Visual
.numAuxBuffers
);
2064 assert(fb
->Visual
.rgbMode
);
2065 assert(fb
->Visual
.alphaBits
> 0);
2066 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
2067 frontLeft
, backLeft
,
2068 frontRight
, backRight
);
2080 * Attach a renderbuffer to a framebuffer.
2083 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
2084 GLuint bufferName
, struct gl_renderbuffer
*rb
)
2088 assert(bufferName
< BUFFER_COUNT
);
2090 /* There should be no previous renderbuffer on this attachment point,
2091 * with the exception of depth/stencil since the same renderbuffer may
2094 assert(bufferName
== BUFFER_DEPTH
||
2095 bufferName
== BUFFER_STENCIL
||
2096 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
2098 /* winsys vs. user-created buffer cross check */
2106 /* If Mesa's compiled with deep color channels (16 or 32 bits / channel)
2107 * and the device driver is expecting 8-bit values (GLubyte), we can
2108 * use a "renderbuffer adaptor/wrapper" to do the necessary conversions.
2110 if (rb
->_BaseFormat
== GL_RGBA
) {
2111 if (CHAN_BITS
== 16 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2112 GET_CURRENT_CONTEXT(ctx
);
2113 rb
= _mesa_new_renderbuffer_16wrap8(ctx
, rb
);
2115 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_BYTE
) {
2116 GET_CURRENT_CONTEXT(ctx
);
2117 rb
= _mesa_new_renderbuffer_32wrap8(ctx
, rb
);
2119 else if (CHAN_BITS
== 32 && rb
->DataType
== GL_UNSIGNED_SHORT
) {
2120 GET_CURRENT_CONTEXT(ctx
);
2121 rb
= _mesa_new_renderbuffer_32wrap16(ctx
, rb
);
2125 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
2126 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
2127 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
2132 * Remove the named renderbuffer from the given framebuffer.
2135 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
, GLuint bufferName
)
2137 struct gl_renderbuffer
*rb
;
2139 assert(bufferName
< BUFFER_COUNT
);
2141 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
2145 _mesa_reference_renderbuffer(&rb
, NULL
);
2147 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
2152 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
2153 * dereference that buffer first. The new renderbuffer's refcount will
2154 * be incremented. The old renderbuffer's refcount will be decremented.
2157 _mesa_reference_renderbuffer(struct gl_renderbuffer
**ptr
,
2158 struct gl_renderbuffer
*rb
)
2167 /* Unreference the old renderbuffer */
2168 GLboolean deleteFlag
= GL_FALSE
;
2169 struct gl_renderbuffer
*oldRb
= *ptr
;
2171 assert(oldRb
->Magic
== RB_MAGIC
);
2172 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
2173 assert(oldRb
->Magic
== RB_MAGIC
);
2174 ASSERT(oldRb
->RefCount
> 0);
2176 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
2177 deleteFlag
= (oldRb
->RefCount
== 0);
2178 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
2181 oldRb
->Magic
= 0; /* now invalid memory! */
2182 oldRb
->Delete(oldRb
);
2190 assert(rb
->Magic
== RB_MAGIC
);
2191 /* reference new renderbuffer */
2192 _glthread_LOCK_MUTEX(rb
->Mutex
);
2194 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
2195 _glthread_UNLOCK_MUTEX(rb
->Mutex
);
2202 * Create a new combined depth/stencil renderbuffer for implementing
2203 * the GL_EXT_packed_depth_stencil extension.
2204 * \return new depth/stencil renderbuffer
2206 struct gl_renderbuffer
*
2207 _mesa_new_depthstencil_renderbuffer(GLcontext
*ctx
, GLuint name
)
2209 struct gl_renderbuffer
*dsrb
;
2211 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
2215 /* init fields not covered by _mesa_new_renderbuffer() */
2216 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
2217 dsrb
->_ActualFormat
= GL_DEPTH24_STENCIL8_EXT
;
2218 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;