2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2005 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"
51 /* 32-bit color index format. Not a public format. */
52 #define COLOR_INDEX32 0x424243
56 * Routines for get/put values in common buffer formats follow.
57 * Someday add support for arbitrary row stride to make them more
61 /**********************************************************************
62 * Functions for buffers of 1 X GLubyte values.
67 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
72 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
73 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
78 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
79 GLint x
, GLint y
, void *values
)
81 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
82 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
83 _mesa_memcpy(values
, src
, count
* sizeof(GLubyte
));
88 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
89 const GLint x
[], const GLint y
[], void *values
)
91 GLubyte
*dst
= (GLubyte
*) values
;
93 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
94 for (i
= 0; i
< count
; i
++) {
95 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
102 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
103 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
105 const GLubyte
*src
= (const GLubyte
*) values
;
106 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
107 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
110 for (i
= 0; i
< count
; i
++) {
117 _mesa_memcpy(dst
, values
, count
* sizeof(GLubyte
));
123 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
124 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
126 const GLubyte val
= *((const GLubyte
*) value
);
127 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
128 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
131 for (i
= 0; i
< count
; i
++) {
139 for (i
= 0; i
< count
; i
++) {
147 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
148 const GLint x
[], const GLint y
[],
149 const void *values
, const GLubyte
*mask
)
151 const GLubyte
*src
= (const GLubyte
*) values
;
153 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
154 for (i
= 0; i
< count
; i
++) {
155 if (!mask
|| mask
[i
]) {
156 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
164 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
165 const GLint x
[], const GLint y
[],
166 const void *value
, const GLubyte
*mask
)
168 const GLubyte val
= *((const GLubyte
*) value
);
170 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
171 for (i
= 0; i
< count
; i
++) {
172 if (!mask
|| mask
[i
]) {
173 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
180 /**********************************************************************
181 * Functions for buffers of 1 X GLushort values.
186 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
191 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
192 ASSERT(rb
->Width
> 0);
193 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
198 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
199 GLint x
, GLint y
, void *values
)
201 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
202 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
203 _mesa_memcpy(values
, src
, count
* sizeof(GLushort
));
208 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
209 const GLint x
[], const GLint y
[], void *values
)
211 GLushort
*dst
= (GLushort
*) values
;
213 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
214 for (i
= 0; i
< count
; i
++) {
215 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
222 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
223 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
225 const GLushort
*src
= (const GLushort
*) values
;
226 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
227 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
230 for (i
= 0; i
< count
; i
++) {
237 _mesa_memcpy(dst
, src
, count
* sizeof(GLushort
));
243 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
244 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
246 const GLushort val
= *((const GLushort
*) value
);
247 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
248 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
251 for (i
= 0; i
< count
; i
++) {
259 for (i
= 0; i
< count
; i
++) {
267 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
268 const GLint x
[], const GLint y
[], const void *values
,
271 const GLushort
*src
= (const GLushort
*) values
;
273 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
274 for (i
= 0; i
< count
; i
++) {
275 if (!mask
|| mask
[i
]) {
276 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
284 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
285 GLuint count
, const GLint x
[], const GLint y
[],
286 const void *value
, const GLubyte
*mask
)
288 const GLushort val
= *((const GLushort
*) value
);
289 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
292 for (i
= 0; i
< count
; i
++) {
294 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
301 for (i
= 0; i
< count
; i
++) {
302 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
309 /**********************************************************************
310 * Functions for buffers of 1 X GLuint values.
311 * Typically depth/Z or color index.
315 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
320 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
321 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
322 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
327 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
328 GLint x
, GLint y
, void *values
)
330 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
331 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
332 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
333 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
338 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
339 const GLint x
[], const GLint y
[], void *values
)
341 GLuint
*dst
= (GLuint
*) values
;
343 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
344 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
345 for (i
= 0; i
< count
; i
++) {
346 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
353 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
354 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
356 const GLuint
*src
= (const GLuint
*) values
;
357 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
358 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
359 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
362 for (i
= 0; i
< count
; i
++) {
369 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
375 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
376 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
378 const GLuint val
= *((const GLuint
*) value
);
379 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
380 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
381 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
384 for (i
= 0; i
< count
; i
++) {
392 for (i
= 0; i
< count
; i
++) {
400 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
401 const GLint x
[], const GLint y
[], const void *values
,
404 const GLuint
*src
= (const GLuint
*) values
;
406 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
407 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
408 for (i
= 0; i
< count
; i
++) {
409 if (!mask
|| mask
[i
]) {
410 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
418 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
419 const GLint x
[], const GLint y
[], const void *value
,
422 const GLuint val
= *((const GLuint
*) value
);
424 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
425 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
426 for (i
= 0; i
< count
; i
++) {
427 if (!mask
|| mask
[i
]) {
428 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
435 /**********************************************************************
436 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
437 * Typically color buffers.
438 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
439 * alpha values and return 255 for outgoing alpha values.
443 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
446 /* No direct access since this buffer is RGB but caller will be
447 * treating it as if it were RGBA.
454 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
455 GLint x
, GLint y
, void *values
)
457 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
458 GLubyte
*dst
= (GLubyte
*) values
;
460 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
461 for (i
= 0; i
< count
; i
++) {
462 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
463 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
464 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
465 dst
[i
* 4 + 3] = 255;
471 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
472 const GLint x
[], const GLint y
[], void *values
)
474 GLubyte
*dst
= (GLubyte
*) values
;
476 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
477 for (i
= 0; i
< count
; i
++) {
479 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
480 dst
[i
* 4 + 0] = src
[0];
481 dst
[i
* 4 + 1] = src
[1];
482 dst
[i
* 4 + 2] = src
[2];
483 dst
[i
* 4 + 3] = 255;
489 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
490 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
492 /* note: incoming values are RGB+A! */
493 const GLubyte
*src
= (const GLubyte
*) values
;
494 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
496 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
497 for (i
= 0; i
< count
; i
++) {
498 if (!mask
|| mask
[i
]) {
499 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
500 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
501 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
508 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
509 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
511 /* note: incoming values are RGB+A! */
512 const GLubyte
*src
= (const GLubyte
*) values
;
513 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
515 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
516 for (i
= 0; i
< count
; i
++) {
517 if (!mask
|| mask
[i
]) {
518 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
519 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
520 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
527 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
528 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
530 /* note: incoming value is RGB+A! */
531 const GLubyte val0
= ((const GLubyte
*) value
)[0];
532 const GLubyte val1
= ((const GLubyte
*) value
)[1];
533 const GLubyte val2
= ((const GLubyte
*) value
)[2];
534 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
535 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
536 if (!mask
&& val0
== val1
&& val1
== val2
) {
538 _mesa_memset(dst
, val0
, 3 * count
);
542 for (i
= 0; i
< count
; i
++) {
543 if (!mask
|| mask
[i
]) {
544 dst
[i
* 3 + 0] = val0
;
545 dst
[i
* 3 + 1] = val1
;
546 dst
[i
* 3 + 2] = val2
;
554 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
555 const GLint x
[], const GLint y
[], const void *values
,
558 /* note: incoming values are RGB+A! */
559 const GLubyte
*src
= (const GLubyte
*) values
;
561 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
562 for (i
= 0; i
< count
; i
++) {
563 if (!mask
|| mask
[i
]) {
564 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
565 dst
[0] = src
[i
* 4 + 0];
566 dst
[1] = src
[i
* 4 + 1];
567 dst
[2] = src
[i
* 4 + 2];
574 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
575 GLuint count
, const GLint x
[], const GLint y
[],
576 const void *value
, const GLubyte
*mask
)
578 /* note: incoming value is RGB+A! */
579 const GLubyte val0
= ((const GLubyte
*) value
)[0];
580 const GLubyte val1
= ((const GLubyte
*) value
)[1];
581 const GLubyte val2
= ((const GLubyte
*) value
)[2];
583 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
584 for (i
= 0; i
< count
; i
++) {
585 if (!mask
|| mask
[i
]) {
586 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
595 /**********************************************************************
596 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
597 * Typically color buffers.
601 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
606 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
607 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
612 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
613 GLint x
, GLint y
, void *values
)
615 const GLbyte
*src
= (const GLbyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
616 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
617 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLbyte
));
622 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
623 const GLint x
[], const GLint y
[], void *values
)
625 /* treat 4*GLubyte as 1*GLuint */
626 GLuint
*dst
= (GLuint
*) values
;
628 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
629 for (i
= 0; i
< count
; i
++) {
630 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
637 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
638 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
640 /* treat 4*GLubyte as 1*GLuint */
641 const GLuint
*src
= (const GLuint
*) values
;
642 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
643 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
646 for (i
= 0; i
< count
; i
++) {
653 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
659 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
660 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
662 /* Store RGB values in RGBA buffer */
663 const GLubyte
*src
= (const GLubyte
*) values
;
664 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
666 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
667 for (i
= 0; i
< count
; i
++) {
668 if (!mask
|| mask
[i
]) {
669 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
670 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
671 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
672 dst
[i
* 4 + 3] = 0xff;
679 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
680 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
682 /* treat 4*GLubyte as 1*GLuint */
683 const GLuint val
= *((const GLuint
*) value
);
684 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
685 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
686 if (!mask
&& val
== 0) {
688 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
694 for (i
= 0; i
< count
; i
++) {
702 for (i
= 0; i
< count
; i
++) {
711 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
712 const GLint x
[], const GLint y
[], const void *values
,
715 /* treat 4*GLubyte as 1*GLuint */
716 const GLuint
*src
= (const GLuint
*) values
;
718 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
719 for (i
= 0; i
< count
; i
++) {
720 if (!mask
|| mask
[i
]) {
721 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
729 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
730 GLuint count
, const GLint x
[], const GLint y
[],
731 const void *value
, const GLubyte
*mask
)
733 /* treat 4*GLubyte as 1*GLuint */
734 const GLuint val
= *((const GLuint
*) value
);
736 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
737 for (i
= 0; i
< count
; i
++) {
738 if (!mask
|| mask
[i
]) {
739 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
746 /**********************************************************************
747 * Functions for buffers of 4 X GLushort (or GLshort) values.
748 * Typically accum buffer.
752 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
757 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
758 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
763 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
764 GLint x
, GLint y
, void *values
)
766 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
767 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
768 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
773 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
774 const GLint x
[], const GLint y
[], void *values
)
776 GLushort
*dst
= (GLushort
*) values
;
778 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
779 for (i
= 0; i
< count
; i
++) {
781 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
788 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
789 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
791 const GLushort
*src
= (const GLushort
*) values
;
792 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
793 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
796 for (i
= 0; i
< count
; i
++) {
798 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
799 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
800 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
801 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
806 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
812 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
813 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
815 /* Put RGB values in RGBA buffer */
816 const GLushort
*src
= (const GLushort
*) values
;
817 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
818 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
821 for (i
= 0; i
< count
; i
++) {
823 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
824 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
825 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
826 dst
[i
* 4 + 3] = 0xffff;
831 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
837 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
838 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
840 const GLushort val0
= ((const GLushort
*) value
)[0];
841 const GLushort val1
= ((const GLushort
*) value
)[1];
842 const GLushort val2
= ((const GLushort
*) value
)[2];
843 const GLushort val3
= ((const GLushort
*) value
)[3];
844 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
845 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
846 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
847 /* common case for clearing accum buffer */
848 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
852 for (i
= 0; i
< count
; i
++) {
853 if (!mask
|| mask
[i
]) {
854 dst
[i
* 4 + 0] = val0
;
855 dst
[i
* 4 + 1] = val1
;
856 dst
[i
* 4 + 2] = val2
;
857 dst
[i
* 4 + 3] = val3
;
865 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
866 const GLint x
[], const GLint y
[], const void *values
,
869 const GLushort
*src
= (const GLushort
*) values
;
871 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
872 for (i
= 0; i
< count
; i
++) {
873 if (!mask
|| mask
[i
]) {
874 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
875 dst
[0] = src
[i
* 4 + 0];
876 dst
[1] = src
[i
* 4 + 1];
877 dst
[2] = src
[i
* 4 + 2];
878 dst
[3] = src
[i
* 4 + 3];
885 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
886 GLuint count
, const GLint x
[], const GLint y
[],
887 const void *value
, const GLubyte
*mask
)
889 const GLushort val0
= ((const GLushort
*) value
)[0];
890 const GLushort val1
= ((const GLushort
*) value
)[1];
891 const GLushort val2
= ((const GLushort
*) value
)[2];
892 const GLushort val3
= ((const GLushort
*) value
)[3];
894 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
895 for (i
= 0; i
< count
; i
++) {
896 if (!mask
|| mask
[i
]) {
897 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
909 * This is a software fallback for the gl_renderbuffer->AllocStorage
911 * Device drivers will typically override this function for the buffers
912 * which it manages (typically color buffers, Z and stencil).
913 * Other buffers (like software accumulation and aux buffers) which the driver
914 * doesn't manage can be handled with this function.
916 * This one multi-purpose function can allocate stencil, depth, accum, color
917 * or color-index buffers!
919 * This function also plugs in the appropriate GetPointer, Get/PutRow and
920 * Get/PutValues functions.
923 soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
924 GLenum internalFormat
, GLuint width
, GLuint height
)
928 switch (internalFormat
) {
937 rb
->_BaseFormat
= GL_RGB
;
938 rb
->DataType
= GL_UNSIGNED_BYTE
;
939 rb
->GetPointer
= get_pointer_ubyte3
;
940 rb
->GetRow
= get_row_ubyte3
;
941 rb
->GetValues
= get_values_ubyte3
;
942 rb
->PutRow
= put_row_ubyte3
;
943 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
944 rb
->PutMonoRow
= put_mono_row_ubyte3
;
945 rb
->PutValues
= put_values_ubyte3
;
946 rb
->PutMonoValues
= put_mono_values_ubyte3
;
947 rb
->RedBits
= 8 * sizeof(GLubyte
);
948 rb
->GreenBits
= 8 * sizeof(GLubyte
);
949 rb
->BlueBits
= 8 * sizeof(GLubyte
);
951 pixelSize
= 3 * sizeof(GLubyte
);
958 rb
->_BaseFormat
= GL_RGBA
;
959 rb
->DataType
= GL_UNSIGNED_BYTE
;
960 rb
->GetPointer
= get_pointer_ubyte4
;
961 rb
->GetRow
= get_row_ubyte4
;
962 rb
->GetValues
= get_values_ubyte4
;
963 rb
->PutRow
= put_row_ubyte4
;
964 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
965 rb
->PutMonoRow
= put_mono_row_ubyte4
;
966 rb
->PutValues
= put_values_ubyte4
;
967 rb
->PutMonoValues
= put_mono_values_ubyte4
;
968 rb
->RedBits
= 8 * sizeof(GLubyte
);
969 rb
->GreenBits
= 8 * sizeof(GLubyte
);
970 rb
->BlueBits
= 8 * sizeof(GLubyte
);
971 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
972 pixelSize
= 4 * sizeof(GLubyte
);
977 rb
->_BaseFormat
= GL_RGBA
;
978 rb
->DataType
= GL_UNSIGNED_SHORT
;
979 rb
->GetPointer
= get_pointer_ushort4
;
980 rb
->GetRow
= get_row_ushort4
;
981 rb
->GetValues
= get_values_ushort4
;
982 rb
->PutRow
= put_row_ushort4
;
983 rb
->PutRowRGB
= put_row_rgb_ushort4
;
984 rb
->PutMonoRow
= put_mono_row_ushort4
;
985 rb
->PutValues
= put_values_ushort4
;
986 rb
->PutMonoValues
= put_mono_values_ushort4
;
987 rb
->RedBits
= 8 * sizeof(GLushort
);
988 rb
->GreenBits
= 8 * sizeof(GLushort
);
989 rb
->BlueBits
= 8 * sizeof(GLushort
);
990 rb
->AlphaBits
= 8 * sizeof(GLushort
);
991 pixelSize
= 4 * sizeof(GLushort
);
995 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
996 rb
->DataType
= GL_UNSIGNED_BYTE
;
997 rb
->GetPointer
= get_pointer_alpha8
;
998 rb
->GetRow
= get_row_alpha8
;
999 rb
->GetValues
= get_values_alpha8
;
1000 rb
->PutRow
= put_row_alpha8
;
1001 rb
->PutRowRGB
= NULL
;
1002 rb
->PutMonoRow
= put_mono_row_alpha8
;
1003 rb
->PutValues
= put_values_alpha8
;
1004 rb
->PutMonoValues
= put_mono_values_alpha8
;
1005 rb
->RedBits
= 0; /*red*/
1006 rb
->GreenBits
= 0; /*green*/
1007 rb
->BlueBits
= 0; /*blue*/
1008 rb
->AlphaBits
= 8 * sizeof(GLubyte
);
1009 pixelSize
= sizeof(GLubyte
);
1012 case GL_STENCIL_INDEX
:
1013 case GL_STENCIL_INDEX1_EXT
:
1014 case GL_STENCIL_INDEX4_EXT
:
1015 case GL_STENCIL_INDEX8_EXT
:
1016 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1017 rb
->DataType
= GL_UNSIGNED_BYTE
;
1018 rb
->GetPointer
= get_pointer_ubyte
;
1019 rb
->GetRow
= get_row_ubyte
;
1020 rb
->GetValues
= get_values_ubyte
;
1021 rb
->PutRow
= put_row_ubyte
;
1022 rb
->PutRowRGB
= NULL
;
1023 rb
->PutMonoRow
= put_mono_row_ubyte
;
1024 rb
->PutValues
= put_values_ubyte
;
1025 rb
->PutMonoValues
= put_mono_values_ubyte
;
1026 rb
->StencilBits
= 8 * sizeof(GLubyte
);
1027 pixelSize
= sizeof(GLubyte
);
1029 case GL_STENCIL_INDEX16_EXT
:
1030 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1031 rb
->DataType
= GL_UNSIGNED_SHORT
;
1032 rb
->GetPointer
= get_pointer_ushort
;
1033 rb
->GetRow
= get_row_ushort
;
1034 rb
->GetValues
= get_values_ushort
;
1035 rb
->PutRow
= put_row_ushort
;
1036 rb
->PutRowRGB
= NULL
;
1037 rb
->PutMonoRow
= put_mono_row_ushort
;
1038 rb
->PutValues
= put_values_ushort
;
1039 rb
->PutMonoValues
= put_mono_values_ushort
;
1040 rb
->StencilBits
= 8 * sizeof(GLushort
);
1041 pixelSize
= sizeof(GLushort
);
1043 case GL_DEPTH_COMPONENT
:
1044 case GL_DEPTH_COMPONENT16
:
1045 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1046 rb
->DataType
= GL_UNSIGNED_SHORT
;
1047 rb
->GetPointer
= get_pointer_ushort
;
1048 rb
->GetRow
= get_row_ushort
;
1049 rb
->GetValues
= get_values_ushort
;
1050 rb
->PutRow
= put_row_ushort
;
1051 rb
->PutRowRGB
= NULL
;
1052 rb
->PutMonoRow
= put_mono_row_ushort
;
1053 rb
->PutValues
= put_values_ushort
;
1054 rb
->PutMonoValues
= put_mono_values_ushort
;
1055 rb
->DepthBits
= 8 * sizeof(GLushort
);
1056 pixelSize
= sizeof(GLushort
);
1058 case GL_DEPTH_COMPONENT24
:
1059 case GL_DEPTH_COMPONENT32
:
1060 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1061 rb
->DataType
= GL_UNSIGNED_INT
;
1062 rb
->GetPointer
= get_pointer_uint
;
1063 rb
->GetRow
= get_row_uint
;
1064 rb
->GetValues
= get_values_uint
;
1065 rb
->PutRow
= put_row_uint
;
1066 rb
->PutRowRGB
= NULL
;
1067 rb
->PutMonoRow
= put_mono_row_uint
;
1068 rb
->PutValues
= put_values_uint
;
1069 rb
->PutMonoValues
= put_mono_values_uint
;
1070 if (internalFormat
== GL_DEPTH_COMPONENT24
)
1074 pixelSize
= sizeof(GLuint
);
1076 case GL_DEPTH_STENCIL_EXT
:
1077 case GL_DEPTH24_STENCIL8_EXT
:
1078 rb
->_BaseFormat
= GL_DEPTH_STENCIL_EXT
;
1079 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1080 rb
->GetPointer
= get_pointer_uint
;
1081 rb
->GetRow
= get_row_uint
;
1082 rb
->GetValues
= get_values_uint
;
1083 rb
->PutRow
= put_row_uint
;
1084 rb
->PutRowRGB
= NULL
;
1085 rb
->PutMonoRow
= put_mono_row_uint
;
1086 rb
->PutValues
= put_values_uint
;
1087 rb
->PutMonoValues
= put_mono_values_uint
;
1089 rb
->StencilBits
= 8;
1090 pixelSize
= sizeof(GLuint
);
1092 case GL_COLOR_INDEX8_EXT
:
1093 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1094 rb
->DataType
= GL_UNSIGNED_BYTE
;
1095 rb
->GetPointer
= get_pointer_ubyte
;
1096 rb
->GetRow
= get_row_ubyte
;
1097 rb
->GetValues
= get_values_ubyte
;
1098 rb
->PutRow
= put_row_ubyte
;
1099 rb
->PutRowRGB
= NULL
;
1100 rb
->PutMonoRow
= put_mono_row_ubyte
;
1101 rb
->PutValues
= put_values_ubyte
;
1102 rb
->PutMonoValues
= put_mono_values_ubyte
;
1103 rb
->IndexBits
= 8 * sizeof(GLubyte
);
1104 pixelSize
= sizeof(GLubyte
);
1106 case GL_COLOR_INDEX16_EXT
:
1107 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1108 rb
->DataType
= GL_UNSIGNED_SHORT
;
1109 rb
->GetPointer
= get_pointer_ushort
;
1110 rb
->GetRow
= get_row_ushort
;
1111 rb
->GetValues
= get_values_ushort
;
1112 rb
->PutRow
= put_row_ushort
;
1113 rb
->PutRowRGB
= NULL
;
1114 rb
->PutMonoRow
= put_mono_row_ushort
;
1115 rb
->PutValues
= put_values_ushort
;
1116 rb
->PutMonoValues
= put_mono_values_ushort
;
1117 rb
->IndexBits
= 8 * sizeof(GLushort
);
1118 pixelSize
= sizeof(GLushort
);
1121 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1122 rb
->DataType
= GL_UNSIGNED_INT
;
1123 rb
->GetPointer
= get_pointer_uint
;
1124 rb
->GetRow
= get_row_uint
;
1125 rb
->GetValues
= get_values_uint
;
1126 rb
->PutRow
= put_row_uint
;
1127 rb
->PutRowRGB
= NULL
;
1128 rb
->PutMonoRow
= put_mono_row_uint
;
1129 rb
->PutValues
= put_values_uint
;
1130 rb
->PutMonoValues
= put_mono_values_uint
;
1131 rb
->IndexBits
= 8 * sizeof(GLuint
);
1132 pixelSize
= sizeof(GLuint
);
1135 _mesa_problem(ctx
, "Bad internalFormat in soft_renderbuffer_storage");
1139 ASSERT(rb
->DataType
);
1140 ASSERT(rb
->GetPointer
);
1142 ASSERT(rb
->GetValues
);
1144 ASSERT(rb
->PutMonoRow
);
1145 ASSERT(rb
->PutValues
);
1146 ASSERT(rb
->PutMonoValues
);
1148 /* free old buffer storage */
1150 _mesa_free(rb
->Data
);
1152 /* allocate new buffer storage */
1153 rb
->Data
= _mesa_malloc(width
* height
* pixelSize
);
1154 if (rb
->Data
== NULL
) {
1157 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software renderbuffer allocation");
1162 rb
->Height
= height
;
1163 rb
->InternalFormat
= internalFormat
;
1170 /**********************************************************************/
1171 /**********************************************************************/
1172 /**********************************************************************/
1176 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1177 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1179 * When PutRow is called (for example), we store the alpha values in
1180 * this buffer, then pass on the PutRow call to the wrapped RGB
1186 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1187 GLenum internalFormat
, GLuint width
, GLuint height
)
1189 ASSERT(arb
!= arb
->Wrapped
);
1191 /* first, pass the call to the wrapped RGB buffer */
1192 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1197 /* next, resize my alpha buffer */
1199 _mesa_free(arb
->Data
);
1202 arb
->Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1203 if (arb
->Data
== NULL
) {
1206 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1211 arb
->Height
= height
;
1212 arb
->InternalFormat
= internalFormat
;
1219 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1222 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1225 _mesa_free(arb
->Data
);
1227 ASSERT(arb
->Wrapped
);
1228 ASSERT(arb
!= arb
->Wrapped
);
1229 arb
->Wrapped
->Delete(arb
->Wrapped
);
1230 arb
->Wrapped
= NULL
;
1236 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1239 return NULL
; /* don't allow direct access! */
1244 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1245 GLint x
, GLint y
, void *values
)
1247 /* NOTE: 'values' is RGBA format! */
1248 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1249 GLubyte
*dst
= (GLubyte
*) values
;
1251 ASSERT(arb
!= arb
->Wrapped
);
1252 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1253 /* first, pass the call to the wrapped RGB buffer */
1254 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1255 /* second, fill in alpha values from this buffer! */
1256 for (i
= 0; i
< count
; i
++) {
1257 dst
[i
* 4 + 3] = src
[i
];
1263 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1264 const GLint x
[], const GLint y
[], void *values
)
1266 GLubyte
*dst
= (GLubyte
*) values
;
1268 ASSERT(arb
!= arb
->Wrapped
);
1269 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1270 /* first, pass the call to the wrapped RGB buffer */
1271 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1272 /* second, fill in alpha values from this buffer! */
1273 for (i
= 0; i
< count
; i
++) {
1274 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1275 dst
[i
* 4 + 3] = *src
;
1281 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1282 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1284 const GLubyte
*src
= (const GLubyte
*) values
;
1285 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1287 ASSERT(arb
!= arb
->Wrapped
);
1288 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1289 /* first, pass the call to the wrapped RGB buffer */
1290 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1291 /* second, store alpha in our buffer */
1292 for (i
= 0; i
< count
; i
++) {
1293 if (!mask
|| mask
[i
]) {
1294 dst
[i
] = src
[i
* 4 + 3];
1301 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1302 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1304 const GLubyte
*src
= (const GLubyte
*) values
;
1305 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1307 ASSERT(arb
!= arb
->Wrapped
);
1308 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1309 /* first, pass the call to the wrapped RGB buffer */
1310 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1311 /* second, store alpha in our buffer */
1312 for (i
= 0; i
< count
; i
++) {
1313 if (!mask
|| mask
[i
]) {
1314 dst
[i
] = src
[i
* 4 + 3];
1321 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1322 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1324 const GLubyte val
= ((const GLubyte
*) value
)[3];
1325 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1326 ASSERT(arb
!= arb
->Wrapped
);
1327 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1328 /* first, pass the call to the wrapped RGB buffer */
1329 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1330 /* second, store alpha in our buffer */
1333 for (i
= 0; i
< count
; i
++) {
1340 _mesa_memset(dst
, val
, count
);
1346 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1347 const GLint x
[], const GLint y
[],
1348 const void *values
, const GLubyte
*mask
)
1350 const GLubyte
*src
= (const GLubyte
*) values
;
1352 ASSERT(arb
!= arb
->Wrapped
);
1353 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1354 /* first, pass the call to the wrapped RGB buffer */
1355 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1356 /* second, store alpha in our buffer */
1357 for (i
= 0; i
< count
; i
++) {
1358 if (!mask
|| mask
[i
]) {
1359 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1360 *dst
= src
[i
* 4 + 3];
1367 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1368 GLuint count
, const GLint x
[], const GLint y
[],
1369 const void *value
, const GLubyte
*mask
)
1371 const GLubyte val
= ((const GLubyte
*) value
)[3];
1373 ASSERT(arb
!= arb
->Wrapped
);
1374 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1375 /* first, pass the call to the wrapped RGB buffer */
1376 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1377 /* second, store alpha in our buffer */
1378 for (i
= 0; i
< count
; i
++) {
1379 if (!mask
|| mask
[i
]) {
1380 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1388 /**********************************************************************/
1389 /**********************************************************************/
1390 /**********************************************************************/
1394 * Default GetPointer routine. Always return NULL to indicate that
1395 * direct buffer access is not supported.
1398 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1405 * Initialize the fields of a gl_renderbuffer to default values.
1408 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1412 rb
->Delete
= _mesa_delete_renderbuffer
;
1414 /* The rest of these should be set later by the caller of this function or
1415 * the AllocStorage method:
1417 rb
->AllocStorage
= NULL
;
1421 rb
->InternalFormat
= GL_NONE
;
1422 rb
->_BaseFormat
= GL_NONE
;
1423 rb
->DataType
= GL_NONE
;
1424 rb
->RedBits
= rb
->GreenBits
= rb
->BlueBits
= rb
->AlphaBits
= 0;
1427 rb
->StencilBits
= 0;
1430 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1431 * all over the drivers.
1435 rb
->GetPointer
= nop_get_pointer
;
1437 rb
->GetValues
= NULL
;
1439 rb
->PutRowRGB
= NULL
;
1440 rb
->PutMonoRow
= NULL
;
1441 rb
->PutValues
= NULL
;
1442 rb
->PutMonoValues
= NULL
;
1447 * Allocate a new gl_renderbuffer object. This can be used for user-created
1448 * renderbuffers or window-system renderbuffers.
1450 struct gl_renderbuffer
*
1451 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1453 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1455 _mesa_init_renderbuffer(rb
, name
);
1462 * Delete a gl_framebuffer.
1463 * This is the default function for framebuffer->Delete().
1466 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1469 _mesa_free(rb
->Data
);
1476 * Allocate a software-based renderbuffer. This is called via the
1477 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1479 * This would not be used for hardware-based renderbuffers.
1481 struct gl_renderbuffer
*
1482 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1484 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1486 rb
->AllocStorage
= soft_renderbuffer_storage
;
1487 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1488 * But we're doing that in the soft_renderbuffer_storage() function
1497 * Add software-based color renderbuffers to the given framebuffer.
1498 * This is a helper routine for device drivers when creating a
1499 * window system framebuffer (not a user-created render/framebuffer).
1500 * Once this function is called, you can basically forget about this
1501 * renderbuffer; core Mesa will handle all the buffer management and
1505 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1506 GLuint rgbBits
, GLuint alphaBits
,
1507 GLboolean frontLeft
, GLboolean backLeft
,
1508 GLboolean frontRight
, GLboolean backRight
)
1512 if (rgbBits
> 16 || alphaBits
> 16) {
1514 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1518 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1520 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1521 struct gl_renderbuffer
*rb
;
1523 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1525 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1527 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1529 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1532 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1534 rb
= _mesa_new_renderbuffer(ctx
, 0);
1536 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1542 rb
->InternalFormat
= GL_RGBA8
;
1544 rb
->InternalFormat
= GL_RGB8
;
1547 assert(rgbBits
<= 16);
1549 rb
->InternalFormat
= GL_RGBA16
;
1551 rb
->InternalFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1554 rb
->AllocStorage
= soft_renderbuffer_storage
;
1555 _mesa_add_renderbuffer(fb
, b
, rb
);
1563 * Add software-based color index renderbuffers to the given framebuffer.
1564 * This is a helper routine for device drivers when creating a
1565 * window system framebuffer (not a user-created render/framebuffer).
1566 * Once this function is called, you can basically forget about this
1567 * renderbuffer; core Mesa will handle all the buffer management and
1571 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1573 GLboolean frontLeft
, GLboolean backLeft
,
1574 GLboolean frontRight
, GLboolean backRight
)
1578 if (indexBits
> 8) {
1580 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1584 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1586 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1587 struct gl_renderbuffer
*rb
;
1589 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1591 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1593 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1595 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1598 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1600 rb
= _mesa_new_renderbuffer(ctx
, 0);
1602 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1606 if (indexBits
<= 8) {
1607 /* only support GLuint for now */
1608 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1609 rb
->InternalFormat
= COLOR_INDEX32
;
1612 rb
->InternalFormat
= COLOR_INDEX32
;
1614 rb
->AllocStorage
= soft_renderbuffer_storage
;
1615 _mesa_add_renderbuffer(fb
, b
, rb
);
1623 * Add software-based alpha renderbuffers to the given framebuffer.
1624 * This is a helper routine for device drivers when creating a
1625 * window system framebuffer (not a user-created render/framebuffer).
1626 * Once this function is called, you can basically forget about this
1627 * renderbuffer; core Mesa will handle all the buffer management and
1631 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1633 GLboolean frontLeft
, GLboolean backLeft
,
1634 GLboolean frontRight
, GLboolean backRight
)
1638 /* for window system framebuffers only! */
1639 assert(fb
->Name
== 0);
1641 if (alphaBits
> 8) {
1643 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1647 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1649 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1651 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1652 struct gl_renderbuffer
*arb
;
1654 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1656 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1658 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1660 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1663 /* the RGB buffer to wrap must already exist!! */
1664 assert(fb
->Attachment
[b
].Renderbuffer
);
1666 /* only GLubyte supported for now */
1667 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1669 /* allocate alpha renderbuffer */
1670 arb
= _mesa_new_renderbuffer(ctx
, 0);
1672 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1676 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1677 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1679 /* Set up my alphabuffer fields and plug in my functions.
1680 * The functions will put/get the alpha values from/to RGBA arrays
1681 * and then call the wrapped buffer's functions to handle the RGB
1684 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1685 arb
->_BaseFormat
= arb
->Wrapped
->_BaseFormat
;
1686 arb
->DataType
= arb
->Wrapped
->DataType
;
1687 arb
->AllocStorage
= alloc_storage_alpha8
;
1688 arb
->Delete
= delete_renderbuffer_alpha8
;
1689 arb
->GetPointer
= get_pointer_alpha8
;
1690 arb
->GetRow
= get_row_alpha8
;
1691 arb
->GetValues
= get_values_alpha8
;
1692 arb
->PutRow
= put_row_alpha8
;
1693 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1694 arb
->PutMonoRow
= put_mono_row_alpha8
;
1695 arb
->PutValues
= put_values_alpha8
;
1696 arb
->PutMonoValues
= put_mono_values_alpha8
;
1698 /* clear the pointer to avoid assertion/sanity check failure later */
1699 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1701 /* plug the alpha renderbuffer into the colorbuffer attachment */
1702 _mesa_add_renderbuffer(fb
, b
, arb
);
1710 * Add a software-based depth renderbuffer to the given framebuffer.
1711 * This is a helper routine for device drivers when creating a
1712 * window system framebuffer (not a user-created render/framebuffer).
1713 * Once this function is called, you can basically forget about this
1714 * renderbuffer; core Mesa will handle all the buffer management and
1718 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1721 struct gl_renderbuffer
*rb
;
1723 if (depthBits
> 32) {
1725 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1729 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1731 rb
= _mesa_new_renderbuffer(ctx
, 0);
1733 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1737 if (depthBits
<= 16) {
1738 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1740 else if (depthBits
<= 24) {
1741 rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
1744 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1747 rb
->AllocStorage
= soft_renderbuffer_storage
;
1748 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1755 * Add a software-based stencil renderbuffer to the given framebuffer.
1756 * This is a helper routine for device drivers when creating a
1757 * window system framebuffer (not a user-created render/framebuffer).
1758 * Once this function is called, you can basically forget about this
1759 * renderbuffer; core Mesa will handle all the buffer management and
1763 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1766 struct gl_renderbuffer
*rb
;
1768 if (stencilBits
> 16) {
1770 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1774 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1776 rb
= _mesa_new_renderbuffer(ctx
, 0);
1778 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1782 if (stencilBits
<= 8) {
1783 rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
1786 /* not really supported (see s_stencil.c code) */
1787 rb
->InternalFormat
= GL_STENCIL_INDEX16_EXT
;
1790 rb
->AllocStorage
= soft_renderbuffer_storage
;
1791 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1798 * Add a software-based accumulation renderbuffer to the given framebuffer.
1799 * This is a helper routine for device drivers when creating a
1800 * window system framebuffer (not a user-created render/framebuffer).
1801 * Once this function is called, you can basically forget about this
1802 * renderbuffer; core Mesa will handle all the buffer management and
1806 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1807 GLuint redBits
, GLuint greenBits
,
1808 GLuint blueBits
, GLuint alphaBits
)
1810 struct gl_renderbuffer
*rb
;
1812 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1814 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1818 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1820 rb
= _mesa_new_renderbuffer(ctx
, 0);
1822 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1826 rb
->InternalFormat
= GL_RGBA16
;
1827 rb
->AllocStorage
= soft_renderbuffer_storage
;
1828 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1836 * Add a software-based accumulation renderbuffer to the given framebuffer.
1837 * This is a helper routine for device drivers when creating a
1838 * window system framebuffer (not a user-created render/framebuffer).
1839 * Once this function is called, you can basically forget about this
1840 * renderbuffer; core Mesa will handle all the buffer management and
1843 * NOTE: color-index aux buffers not supported.
1846 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1847 GLuint colorBits
, GLuint numBuffers
)
1851 if (colorBits
> 16) {
1853 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1857 assert(numBuffers
< MAX_AUX_BUFFERS
);
1859 for (i
= 0; i
< numBuffers
; i
++) {
1860 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1862 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1865 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1869 if (colorBits
<= 8) {
1870 rb
->InternalFormat
= GL_RGBA8
;
1873 rb
->InternalFormat
= GL_RGBA16
;
1876 rb
->AllocStorage
= soft_renderbuffer_storage
;
1877 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1884 * Create/attach software-based renderbuffers to the given framebuffer.
1885 * This is a helper routine for device drivers. Drivers can just as well
1886 * call the individual _mesa_add_*_renderbuffer() routines directly.
1889 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1897 GLboolean frontLeft
= GL_TRUE
;
1898 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1899 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1900 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1903 if (fb
->Visual
.rgbMode
) {
1904 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1905 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1906 _mesa_add_color_renderbuffers(NULL
, fb
,
1908 fb
->Visual
.alphaBits
,
1909 frontLeft
, backLeft
,
1910 frontRight
, backRight
);
1913 _mesa_add_color_index_renderbuffers(NULL
, fb
,
1914 fb
->Visual
.indexBits
,
1915 frontLeft
, backLeft
,
1916 frontRight
, backRight
);
1921 assert(fb
->Visual
.depthBits
> 0);
1922 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1926 assert(fb
->Visual
.stencilBits
> 0);
1927 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1931 assert(fb
->Visual
.rgbMode
);
1932 assert(fb
->Visual
.accumRedBits
> 0);
1933 assert(fb
->Visual
.accumGreenBits
> 0);
1934 assert(fb
->Visual
.accumBlueBits
> 0);
1935 _mesa_add_accum_renderbuffer(NULL
, fb
,
1936 fb
->Visual
.accumRedBits
,
1937 fb
->Visual
.accumGreenBits
,
1938 fb
->Visual
.accumBlueBits
,
1939 fb
->Visual
.accumAlphaBits
);
1943 assert(fb
->Visual
.rgbMode
);
1944 assert(fb
->Visual
.numAuxBuffers
> 0);
1945 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
1946 fb
->Visual
.numAuxBuffers
);
1950 assert(fb
->Visual
.rgbMode
);
1951 assert(fb
->Visual
.alphaBits
> 0);
1952 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
1953 frontLeft
, backLeft
,
1954 frontRight
, backRight
);
1966 * Attach a renderbuffer to a framebuffer.
1969 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
1970 GLuint bufferName
, struct gl_renderbuffer
*rb
)
1975 /* there should be no previous renderbuffer on this attachment point! */
1976 assert(fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
1978 assert(bufferName
< BUFFER_COUNT
);
1980 /* winsys vs. user-created buffer cross check */
1988 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
1989 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
1990 fb
->Attachment
[bufferName
].Renderbuffer
= rb
;
1995 * Create a new combined depth/stencil renderbuffer for implementing
1996 * the GL_EXT_packed_depth_stencil extension.
1997 * \return new depth/stencil renderbuffer
1999 struct gl_renderbuffer
*
2000 _mesa_new_depthstencil_renderbuffer(GLcontext
*ctx
, GLuint name
)
2002 struct gl_renderbuffer
*dsrb
;
2004 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
2008 /* init fields not covered by _mesa_new_renderbuffer() */
2009 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
2010 dsrb
->AllocStorage
= soft_renderbuffer_storage
;