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 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
326 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
327 GLint x
, GLint y
, void *values
)
329 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
330 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
331 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
336 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
337 const GLint x
[], const GLint y
[], void *values
)
339 GLuint
*dst
= (GLuint
*) values
;
341 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
342 for (i
= 0; i
< count
; i
++) {
343 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
350 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
351 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
353 const GLuint
*src
= (const GLuint
*) values
;
354 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
355 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
358 for (i
= 0; i
< count
; i
++) {
365 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
371 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
372 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
374 const GLuint val
= *((const GLuint
*) value
);
375 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
377 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
378 for (i
= 0; i
< count
; i
++) {
379 if (!mask
|| mask
[i
]) {
387 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
388 const GLint x
[], const GLint y
[], const void *values
,
391 const GLuint
*src
= (const GLuint
*) values
;
393 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
394 for (i
= 0; i
< count
; i
++) {
395 if (!mask
|| mask
[i
]) {
396 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
404 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
405 const GLint x
[], const GLint y
[], const void *value
,
408 const GLuint val
= *((const GLuint
*) value
);
410 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
411 for (i
= 0; i
< count
; i
++) {
412 if (!mask
|| mask
[i
]) {
413 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
420 /**********************************************************************
421 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
422 * Typically color buffers.
423 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
424 * alpha values and return 255 for outgoing alpha values.
428 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
431 /* No direct access since this buffer is RGB but caller will be
432 * treating it as if it were RGBA.
439 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
440 GLint x
, GLint y
, void *values
)
442 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
443 GLubyte
*dst
= (GLubyte
*) values
;
445 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
446 for (i
= 0; i
< count
; i
++) {
447 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
448 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
449 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
450 dst
[i
* 4 + 3] = 255;
456 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
457 const GLint x
[], const GLint y
[], void *values
)
459 GLubyte
*dst
= (GLubyte
*) values
;
461 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
462 for (i
= 0; i
< count
; i
++) {
464 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
465 dst
[i
* 4 + 0] = src
[0];
466 dst
[i
* 4 + 1] = src
[1];
467 dst
[i
* 4 + 2] = src
[2];
468 dst
[i
* 4 + 3] = 255;
474 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
475 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
477 /* note: incoming values are RGB+A! */
478 const GLubyte
*src
= (const GLubyte
*) values
;
479 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
481 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
482 for (i
= 0; i
< count
; i
++) {
483 if (!mask
|| mask
[i
]) {
484 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
485 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
486 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
493 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
494 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
496 /* note: incoming values are RGB+A! */
497 const GLubyte
*src
= (const GLubyte
*) values
;
498 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
500 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
501 for (i
= 0; i
< count
; i
++) {
502 if (!mask
|| mask
[i
]) {
503 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
504 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
505 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
512 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
513 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
515 /* note: incoming value is RGB+A! */
516 const GLubyte val0
= ((const GLubyte
*) value
)[0];
517 const GLubyte val1
= ((const GLubyte
*) value
)[1];
518 const GLubyte val2
= ((const GLubyte
*) value
)[2];
519 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
520 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
521 if (!mask
&& val0
== val1
&& val1
== val2
) {
523 _mesa_memset(dst
, val0
, 3 * count
);
527 for (i
= 0; i
< count
; i
++) {
528 if (!mask
|| mask
[i
]) {
529 dst
[i
* 3 + 0] = val0
;
530 dst
[i
* 3 + 1] = val1
;
531 dst
[i
* 3 + 2] = val2
;
539 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
540 const GLint x
[], const GLint y
[], const void *values
,
543 /* note: incoming values are RGB+A! */
544 const GLubyte
*src
= (const GLubyte
*) values
;
546 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
547 for (i
= 0; i
< count
; i
++) {
548 if (!mask
|| mask
[i
]) {
549 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
550 dst
[0] = src
[i
* 4 + 0];
551 dst
[1] = src
[i
* 4 + 1];
552 dst
[2] = src
[i
* 4 + 2];
559 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
560 GLuint count
, const GLint x
[], const GLint y
[],
561 const void *value
, const GLubyte
*mask
)
563 /* note: incoming value is RGB+A! */
564 const GLubyte val0
= ((const GLubyte
*) value
)[0];
565 const GLubyte val1
= ((const GLubyte
*) value
)[1];
566 const GLubyte val2
= ((const GLubyte
*) value
)[2];
568 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
569 for (i
= 0; i
< count
; i
++) {
570 if (!mask
|| mask
[i
]) {
571 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
580 /**********************************************************************
581 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
582 * Typically color buffers.
586 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
591 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
592 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
597 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
598 GLint x
, GLint y
, void *values
)
600 const GLbyte
*src
= (const GLbyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
601 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
602 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLbyte
));
607 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
608 const GLint x
[], const GLint y
[], void *values
)
610 /* treat 4*GLubyte as 1*GLuint */
611 GLuint
*dst
= (GLuint
*) values
;
613 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
614 for (i
= 0; i
< count
; i
++) {
615 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
622 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
623 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
625 /* treat 4*GLubyte as 1*GLuint */
626 const GLuint
*src
= (const GLuint
*) values
;
627 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
628 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
631 for (i
= 0; i
< count
; i
++) {
638 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
644 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
645 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
647 /* Store RGB values in RGBA buffer */
648 const GLubyte
*src
= (const GLubyte
*) values
;
649 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
651 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
652 for (i
= 0; i
< count
; i
++) {
653 if (!mask
|| mask
[i
]) {
654 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
655 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
656 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
657 dst
[i
* 4 + 3] = 0xff;
664 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
665 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
667 /* treat 4*GLubyte as 1*GLuint */
668 const GLuint val
= *((const GLuint
*) value
);
669 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
670 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
671 if (!mask
&& val
== 0) {
673 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
679 for (i
= 0; i
< count
; i
++) {
687 for (i
= 0; i
< count
; i
++) {
696 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
697 const GLint x
[], const GLint y
[], const void *values
,
700 /* treat 4*GLubyte as 1*GLuint */
701 const GLuint
*src
= (const GLuint
*) values
;
703 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
704 for (i
= 0; i
< count
; i
++) {
705 if (!mask
|| mask
[i
]) {
706 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
714 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
715 GLuint count
, const GLint x
[], const GLint y
[],
716 const void *value
, const GLubyte
*mask
)
718 /* treat 4*GLubyte as 1*GLuint */
719 const GLuint val
= *((const GLuint
*) value
);
721 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
722 for (i
= 0; i
< count
; i
++) {
723 if (!mask
|| mask
[i
]) {
724 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
731 /**********************************************************************
732 * Functions for buffers of 4 X GLushort (or GLshort) values.
733 * Typically accum buffer.
737 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
742 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
743 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
748 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
749 GLint x
, GLint y
, void *values
)
751 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
752 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
753 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
758 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
759 const GLint x
[], const GLint y
[], void *values
)
761 GLushort
*dst
= (GLushort
*) values
;
763 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
764 for (i
= 0; i
< count
; i
++) {
766 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
773 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
774 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
776 const GLushort
*src
= (const GLushort
*) values
;
777 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
778 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
781 for (i
= 0; i
< count
; i
++) {
783 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
784 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
785 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
786 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
791 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
797 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
798 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
800 /* Put RGB values in RGBA buffer */
801 const GLushort
*src
= (const GLushort
*) values
;
802 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
803 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
806 for (i
= 0; i
< count
; i
++) {
808 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
809 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
810 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
811 dst
[i
* 4 + 3] = 0xffff;
816 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
822 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
823 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
825 const GLushort val0
= ((const GLushort
*) value
)[0];
826 const GLushort val1
= ((const GLushort
*) value
)[1];
827 const GLushort val2
= ((const GLushort
*) value
)[2];
828 const GLushort val3
= ((const GLushort
*) value
)[3];
829 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
830 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
831 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
832 /* common case for clearing accum buffer */
833 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
837 for (i
= 0; i
< count
; i
++) {
838 if (!mask
|| mask
[i
]) {
839 dst
[i
* 4 + 0] = val0
;
840 dst
[i
* 4 + 1] = val1
;
841 dst
[i
* 4 + 2] = val2
;
842 dst
[i
* 4 + 3] = val3
;
850 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
851 const GLint x
[], const GLint y
[], const void *values
,
854 const GLushort
*src
= (const GLushort
*) values
;
856 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
857 for (i
= 0; i
< count
; i
++) {
858 if (!mask
|| mask
[i
]) {
859 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
860 dst
[0] = src
[i
* 4 + 0];
861 dst
[1] = src
[i
* 4 + 1];
862 dst
[2] = src
[i
* 4 + 2];
863 dst
[3] = src
[i
* 4 + 3];
870 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
871 GLuint count
, const GLint x
[], const GLint y
[],
872 const void *value
, const GLubyte
*mask
)
874 const GLushort val0
= ((const GLushort
*) value
)[0];
875 const GLushort val1
= ((const GLushort
*) value
)[1];
876 const GLushort val2
= ((const GLushort
*) value
)[2];
877 const GLushort val3
= ((const GLushort
*) value
)[3];
879 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
880 for (i
= 0; i
< count
; i
++) {
881 if (!mask
|| mask
[i
]) {
882 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
894 * This is a software fallback for the gl_renderbuffer->AllocStorage
896 * Device drivers will typically override this function for the buffers
897 * which it manages (typically color buffers, Z and stencil).
898 * Other buffers (like software accumulation and aux buffers) which the driver
899 * doesn't manage can be handled with this function.
901 * This one multi-purpose function can allocate stencil, depth, accum, color
902 * or color-index buffers!
904 * This function also plugs in the appropriate GetPointer, Get/PutRow and
905 * Get/PutValues functions.
908 soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
909 GLenum internalFormat
, GLuint width
, GLuint height
)
913 switch (internalFormat
) {
922 rb
->_BaseFormat
= GL_RGB
;
923 rb
->DataType
= GL_UNSIGNED_BYTE
;
924 rb
->GetPointer
= get_pointer_ubyte3
;
925 rb
->GetRow
= get_row_ubyte3
;
926 rb
->GetValues
= get_values_ubyte3
;
927 rb
->PutRow
= put_row_ubyte3
;
928 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
929 rb
->PutMonoRow
= put_mono_row_ubyte3
;
930 rb
->PutValues
= put_values_ubyte3
;
931 rb
->PutMonoValues
= put_mono_values_ubyte3
;
932 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
933 rb
->ComponentSizes
[1] = 8 * sizeof(GLubyte
);
934 rb
->ComponentSizes
[2] = 8 * sizeof(GLubyte
);
935 rb
->ComponentSizes
[3] = 0;
936 pixelSize
= 3 * sizeof(GLubyte
);
943 rb
->_BaseFormat
= GL_RGBA
;
944 rb
->DataType
= GL_UNSIGNED_BYTE
;
945 rb
->GetPointer
= get_pointer_ubyte4
;
946 rb
->GetRow
= get_row_ubyte4
;
947 rb
->GetValues
= get_values_ubyte4
;
948 rb
->PutRow
= put_row_ubyte4
;
949 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
950 rb
->PutMonoRow
= put_mono_row_ubyte4
;
951 rb
->PutValues
= put_values_ubyte4
;
952 rb
->PutMonoValues
= put_mono_values_ubyte4
;
953 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
954 rb
->ComponentSizes
[1] = 8 * sizeof(GLubyte
);
955 rb
->ComponentSizes
[2] = 8 * sizeof(GLubyte
);
956 rb
->ComponentSizes
[3] = 8 * sizeof(GLubyte
);
957 pixelSize
= 4 * sizeof(GLubyte
);
962 rb
->_BaseFormat
= GL_RGBA
;
963 rb
->DataType
= GL_UNSIGNED_SHORT
;
964 rb
->GetPointer
= get_pointer_ushort4
;
965 rb
->GetRow
= get_row_ushort4
;
966 rb
->GetValues
= get_values_ushort4
;
967 rb
->PutRow
= put_row_ushort4
;
968 rb
->PutRowRGB
= put_row_rgb_ushort4
;
969 rb
->PutMonoRow
= put_mono_row_ushort4
;
970 rb
->PutValues
= put_values_ushort4
;
971 rb
->PutMonoValues
= put_mono_values_ushort4
;
972 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
973 rb
->ComponentSizes
[1] = 8 * sizeof(GLushort
);
974 rb
->ComponentSizes
[2] = 8 * sizeof(GLushort
);
975 rb
->ComponentSizes
[3] = 8 * sizeof(GLushort
);
976 pixelSize
= 4 * sizeof(GLushort
);
980 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
981 rb
->DataType
= GL_UNSIGNED_BYTE
;
982 rb
->GetPointer
= get_pointer_alpha8
;
983 rb
->GetRow
= get_row_alpha8
;
984 rb
->GetValues
= get_values_alpha8
;
985 rb
->PutRow
= put_row_alpha8
;
986 rb
->PutRowRGB
= NULL
;
987 rb
->PutMonoRow
= put_mono_row_alpha8
;
988 rb
->PutValues
= put_values_alpha8
;
989 rb
->PutMonoValues
= put_mono_values_alpha8
;
990 rb
->ComponentSizes
[0] = 0; /*red*/
991 rb
->ComponentSizes
[1] = 0; /*green*/
992 rb
->ComponentSizes
[2] = 0; /*blue*/
993 rb
->ComponentSizes
[3] = 8 * sizeof(GLubyte
);
994 pixelSize
= sizeof(GLubyte
);
997 case GL_STENCIL_INDEX
:
998 case GL_STENCIL_INDEX1_EXT
:
999 case GL_STENCIL_INDEX4_EXT
:
1000 case GL_STENCIL_INDEX8_EXT
:
1001 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1002 rb
->DataType
= GL_UNSIGNED_BYTE
;
1003 rb
->GetPointer
= get_pointer_ubyte
;
1004 rb
->GetRow
= get_row_ubyte
;
1005 rb
->GetValues
= get_values_ubyte
;
1006 rb
->PutRow
= put_row_ubyte
;
1007 rb
->PutRowRGB
= NULL
;
1008 rb
->PutMonoRow
= put_mono_row_ubyte
;
1009 rb
->PutValues
= put_values_ubyte
;
1010 rb
->PutMonoValues
= put_mono_values_ubyte
;
1011 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
1012 pixelSize
= sizeof(GLubyte
);
1014 case GL_STENCIL_INDEX16_EXT
:
1015 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1016 rb
->DataType
= GL_UNSIGNED_SHORT
;
1017 rb
->GetPointer
= get_pointer_ushort
;
1018 rb
->GetRow
= get_row_ushort
;
1019 rb
->GetValues
= get_values_ushort
;
1020 rb
->PutRow
= put_row_ushort
;
1021 rb
->PutRowRGB
= NULL
;
1022 rb
->PutMonoRow
= put_mono_row_ushort
;
1023 rb
->PutValues
= put_values_ushort
;
1024 rb
->PutMonoValues
= put_mono_values_ushort
;
1025 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
1026 pixelSize
= sizeof(GLushort
);
1028 case GL_DEPTH_COMPONENT
:
1029 case GL_DEPTH_COMPONENT16
:
1030 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
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
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
1041 pixelSize
= sizeof(GLushort
);
1043 case GL_DEPTH_COMPONENT24
:
1044 case GL_DEPTH_COMPONENT32
:
1045 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1046 rb
->DataType
= GL_UNSIGNED_INT
;
1047 rb
->GetPointer
= get_pointer_uint
;
1048 rb
->GetRow
= get_row_uint
;
1049 rb
->GetValues
= get_values_uint
;
1050 rb
->PutRow
= put_row_uint
;
1051 rb
->PutRowRGB
= NULL
;
1052 rb
->PutMonoRow
= put_mono_row_uint
;
1053 rb
->PutValues
= put_values_uint
;
1054 rb
->PutMonoValues
= put_mono_values_uint
;
1055 rb
->ComponentSizes
[0] = 8 * sizeof(GLuint
);
1056 pixelSize
= sizeof(GLuint
);
1058 case GL_COLOR_INDEX8_EXT
:
1059 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1060 rb
->DataType
= GL_UNSIGNED_BYTE
;
1061 rb
->GetPointer
= get_pointer_ubyte
;
1062 rb
->GetRow
= get_row_ubyte
;
1063 rb
->GetValues
= get_values_ubyte
;
1064 rb
->PutRow
= put_row_ubyte
;
1065 rb
->PutRowRGB
= NULL
;
1066 rb
->PutMonoRow
= put_mono_row_ubyte
;
1067 rb
->PutValues
= put_values_ubyte
;
1068 rb
->PutMonoValues
= put_mono_values_ubyte
;
1069 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
1070 pixelSize
= sizeof(GLubyte
);
1072 case GL_COLOR_INDEX16_EXT
:
1073 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1074 rb
->DataType
= GL_UNSIGNED_SHORT
;
1075 rb
->GetPointer
= get_pointer_ushort
;
1076 rb
->GetRow
= get_row_ushort
;
1077 rb
->GetValues
= get_values_ushort
;
1078 rb
->PutRow
= put_row_ushort
;
1079 rb
->PutRowRGB
= NULL
;
1080 rb
->PutMonoRow
= put_mono_row_ushort
;
1081 rb
->PutValues
= put_values_ushort
;
1082 rb
->PutMonoValues
= put_mono_values_ushort
;
1083 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
1084 pixelSize
= sizeof(GLushort
);
1087 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1088 rb
->DataType
= GL_UNSIGNED_INT
;
1089 rb
->GetPointer
= get_pointer_uint
;
1090 rb
->GetRow
= get_row_uint
;
1091 rb
->GetValues
= get_values_uint
;
1092 rb
->PutRow
= put_row_uint
;
1093 rb
->PutRowRGB
= NULL
;
1094 rb
->PutMonoRow
= put_mono_row_uint
;
1095 rb
->PutValues
= put_values_uint
;
1096 rb
->PutMonoValues
= put_mono_values_uint
;
1097 rb
->ComponentSizes
[0] = 8 * sizeof(GLuint
);
1098 pixelSize
= sizeof(GLuint
);
1101 _mesa_problem(ctx
, "Bad internalFormat in soft_renderbuffer_storage");
1105 ASSERT(rb
->DataType
);
1106 ASSERT(rb
->GetPointer
);
1108 ASSERT(rb
->GetValues
);
1110 ASSERT(rb
->PutMonoRow
);
1111 ASSERT(rb
->PutValues
);
1112 ASSERT(rb
->PutMonoValues
);
1113 ASSERT(rb
->ComponentSizes
[0] > 0);
1115 /* free old buffer storage */
1117 _mesa_free(rb
->Data
);
1119 /* allocate new buffer storage */
1120 rb
->Data
= _mesa_malloc(width
* height
* pixelSize
);
1121 if (rb
->Data
== NULL
) {
1124 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software renderbuffer allocation");
1129 rb
->Height
= height
;
1130 rb
->InternalFormat
= internalFormat
;
1136 /**********************************************************************/
1137 /**********************************************************************/
1138 /**********************************************************************/
1142 * The alpha_renderbuffer class is used to augment an RGB renderbuffer with
1143 * an alpha channel. The RGB buffer can be hardware-based.
1144 * We basically wrap the RGB buffer. When PutRow is called (for example),
1145 * we store the alpha values in this buffer, then pass on the PutRow call
1146 * to the wrapped RGB buffer.
1148 struct alpha_renderbuffer
1150 struct gl_renderbuffer Base
; /* the alpha buffer */
1151 struct gl_renderbuffer
*RGBbuffer
; /* the wrapped RGB buffer */
1156 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1157 GLenum internalFormat
, GLuint width
, GLuint height
)
1159 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1161 /* first, pass the call to the wrapped RGB buffer */
1162 if (!arb
->RGBbuffer
->AllocStorage(ctx
, arb
->RGBbuffer
, internalFormat
,
1167 /* next, resize my alpha buffer */
1168 if (arb
->Base
.Data
) {
1169 _mesa_free(arb
->Base
.Data
);
1172 arb
->Base
.Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1173 if (arb
->Base
.Data
== NULL
) {
1174 arb
->Base
.Width
= 0;
1175 arb
->Base
.Height
= 0;
1176 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1180 arb
->Base
.Width
= width
;
1181 arb
->Base
.Height
= height
;
1182 arb
->Base
.InternalFormat
= internalFormat
;
1189 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1192 delete_renderbuffer_alpha8(struct gl_renderbuffer
*rb
)
1194 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1195 if (arb
->Base
.Data
) {
1196 _mesa_free(arb
->Base
.Data
);
1198 assert(arb
->RGBbuffer
);
1199 arb
->RGBbuffer
->Delete(arb
->RGBbuffer
);
1200 arb
->RGBbuffer
= NULL
;
1206 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1209 return NULL
; /* don't allow direct access! */
1214 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1215 GLint x
, GLint y
, void *values
)
1217 /* NOTE: 'values' is RGBA format! */
1218 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1219 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1220 GLubyte
*dst
= (GLubyte
*) values
;
1222 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
1223 /* first, pass the call to the wrapped RGB buffer */
1224 arb
->RGBbuffer
->GetRow(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
);
1225 /* second, fill in alpha values from this buffer! */
1226 for (i
= 0; i
< count
; i
++) {
1227 dst
[i
* 4 + 3] = src
[i
];
1233 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1234 const GLint x
[], const GLint y
[], void *values
)
1236 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1237 GLubyte
*dst
= (GLubyte
*) values
;
1239 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1240 /* first, pass the call to the wrapped RGB buffer */
1241 arb
->RGBbuffer
->GetValues(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
);
1242 /* second, fill in alpha values from this buffer! */
1243 for (i
= 0; i
< count
; i
++) {
1244 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
1245 dst
[i
* 4 + 3] = *src
;
1251 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1252 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1254 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1255 const GLubyte
*src
= (const GLubyte
*) values
;
1256 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1258 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1259 /* first, pass the call to the wrapped RGB buffer */
1260 arb
->RGBbuffer
->PutRow(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
, mask
);
1261 /* second, store alpha in our buffer */
1262 for (i
= 0; i
< count
; i
++) {
1263 if (!mask
|| mask
[i
]) {
1264 dst
[i
] = src
[i
* 4 + 3];
1271 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1272 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1274 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1275 const GLubyte
*src
= (const GLubyte
*) values
;
1276 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1278 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1279 /* first, pass the call to the wrapped RGB buffer */
1280 arb
->RGBbuffer
->PutRowRGB(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
, mask
);
1281 /* second, store alpha in our buffer */
1282 for (i
= 0; i
< count
; i
++) {
1283 if (!mask
|| mask
[i
]) {
1284 dst
[i
] = src
[i
* 4 + 3];
1291 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1292 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1294 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1295 const GLubyte val
= ((const GLubyte
*) value
)[3];
1296 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1297 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1298 /* first, pass the call to the wrapped RGB buffer */
1299 arb
->RGBbuffer
->PutMonoRow(ctx
, arb
->RGBbuffer
, count
, x
, y
, value
, mask
);
1300 /* second, store alpha in our buffer */
1303 for (i
= 0; i
< count
; i
++) {
1310 _mesa_memset(dst
, val
, count
);
1316 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1317 const GLint x
[], const GLint y
[],
1318 const void *values
, const GLubyte
*mask
)
1320 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1321 const GLubyte
*src
= (const GLubyte
*) values
;
1323 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1324 /* first, pass the call to the wrapped RGB buffer */
1325 arb
->RGBbuffer
->PutValues(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
, mask
);
1326 /* second, store alpha in our buffer */
1327 for (i
= 0; i
< count
; i
++) {
1328 if (!mask
|| mask
[i
]) {
1329 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
1330 *dst
= src
[i
* 4 + 3];
1337 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1338 GLuint count
, const GLint x
[], const GLint y
[],
1339 const void *value
, const GLubyte
*mask
)
1341 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1342 const GLubyte val
= ((const GLubyte
*) value
)[3];
1344 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1345 /* first, pass the call to the wrapped RGB buffer */
1346 arb
->RGBbuffer
->PutValues(ctx
, arb
->RGBbuffer
, count
, x
, y
, value
, mask
);
1347 /* second, store alpha in our buffer */
1348 for (i
= 0; i
< count
; i
++) {
1349 if (!mask
|| mask
[i
]) {
1350 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
1358 /**********************************************************************/
1359 /**********************************************************************/
1360 /**********************************************************************/
1364 * Default GetPointer routine. Always return NULL to indicate that
1365 * direct buffer access is not supported.
1368 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1375 * Initialize the fields of a gl_renderbuffer to default values.
1378 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1382 rb
->Delete
= _mesa_delete_renderbuffer
;
1384 /* The rest of these should be set later by the caller of this function or
1385 * the AllocStorage method:
1387 rb
->AllocStorage
= NULL
;
1391 rb
->InternalFormat
= GL_NONE
;
1392 rb
->_BaseFormat
= GL_NONE
;
1393 rb
->DataType
= GL_NONE
;
1394 rb
->ComponentSizes
[0] = 0;
1395 rb
->ComponentSizes
[1] = 0;
1396 rb
->ComponentSizes
[2] = 0;
1397 rb
->ComponentSizes
[3] = 0;
1400 rb
->GetPointer
= nop_get_pointer
;
1402 rb
->GetValues
= NULL
;
1404 rb
->PutRowRGB
= NULL
;
1405 rb
->PutMonoRow
= NULL
;
1406 rb
->PutValues
= NULL
;
1407 rb
->PutMonoValues
= NULL
;
1412 * Allocate a new gl_renderbuffer object. This can be used for user-created
1413 * renderbuffers or window-system renderbuffers.
1415 struct gl_renderbuffer
*
1416 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1418 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1420 _mesa_init_renderbuffer(rb
, name
);
1427 * Delete a gl_framebuffer.
1428 * This is the default function for framebuffer->Delete().
1431 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1434 _mesa_free(rb
->Data
);
1441 * Allocate a software-based renderbuffer. This is called via the
1442 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1444 * This would not be used for hardware-based renderbuffers.
1446 struct gl_renderbuffer
*
1447 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1449 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1451 rb
->AllocStorage
= soft_renderbuffer_storage
;
1452 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1453 * But we're doing that in the soft_renderbuffer_storage() function
1462 * Add software-based color renderbuffers to the given framebuffer.
1463 * This is a helper routine for device drivers when creating a
1464 * window system framebuffer (not a user-created render/framebuffer).
1465 * Once this function is called, you can basically forget about this
1466 * renderbuffer; core Mesa will handle all the buffer management and
1470 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1471 GLuint rgbBits
, GLuint alphaBits
,
1472 GLboolean frontLeft
, GLboolean backLeft
,
1473 GLboolean frontRight
, GLboolean backRight
)
1477 if (rgbBits
> 16 || alphaBits
> 16) {
1479 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1483 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1485 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1486 struct gl_renderbuffer
*rb
;
1488 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1490 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1492 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1494 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1497 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1499 rb
= _mesa_new_renderbuffer(ctx
, 0);
1501 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1507 rb
->InternalFormat
= GL_RGBA8
;
1509 rb
->InternalFormat
= GL_RGB8
;
1512 assert(rgbBits
<= 16);
1514 rb
->InternalFormat
= GL_RGBA16
;
1516 rb
->InternalFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1519 rb
->AllocStorage
= soft_renderbuffer_storage
;
1520 _mesa_add_renderbuffer(fb
, b
, rb
);
1528 * Add software-based color index renderbuffers to the given framebuffer.
1529 * This is a helper routine for device drivers when creating a
1530 * window system framebuffer (not a user-created render/framebuffer).
1531 * Once this function is called, you can basically forget about this
1532 * renderbuffer; core Mesa will handle all the buffer management and
1536 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1538 GLboolean frontLeft
, GLboolean backLeft
,
1539 GLboolean frontRight
, GLboolean backRight
)
1543 if (indexBits
> 8) {
1545 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1549 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1551 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1552 struct gl_renderbuffer
*rb
;
1554 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1556 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1558 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1560 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1563 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1565 rb
= _mesa_new_renderbuffer(ctx
, 0);
1567 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1571 if (indexBits
<= 8) {
1572 /* only support GLuint for now */
1573 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1574 rb
->InternalFormat
= COLOR_INDEX32
;
1577 rb
->InternalFormat
= COLOR_INDEX32
;
1579 rb
->AllocStorage
= soft_renderbuffer_storage
;
1580 _mesa_add_renderbuffer(fb
, b
, rb
);
1588 * Add software-based alpha renderbuffers to the given framebuffer.
1589 * This is a helper routine for device drivers when creating a
1590 * window system framebuffer (not a user-created render/framebuffer).
1591 * Once this function is called, you can basically forget about this
1592 * renderbuffer; core Mesa will handle all the buffer management and
1596 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1598 GLboolean frontLeft
, GLboolean backLeft
,
1599 GLboolean frontRight
, GLboolean backRight
)
1603 /* for window system framebuffers only! */
1604 assert(fb
->Name
== 0);
1606 if (alphaBits
> 8) {
1608 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1612 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1614 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1615 struct alpha_renderbuffer
*arb
;
1617 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1619 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1621 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1623 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1626 /* the RGB buffer to wrap must already exist!! */
1627 assert(fb
->Attachment
[b
].Renderbuffer
);
1629 /* only GLubyte supported for now */
1630 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1632 arb
= CALLOC_STRUCT(alpha_renderbuffer
);
1634 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1638 _mesa_init_renderbuffer(&arb
->Base
, 0);
1640 /* wrap the RGB buffer */
1641 arb
->RGBbuffer
= fb
->Attachment
[b
].Renderbuffer
;
1643 /* plug in my functions */
1644 arb
->Base
.InternalFormat
= arb
->RGBbuffer
->InternalFormat
;
1645 arb
->Base
._BaseFormat
= arb
->RGBbuffer
->_BaseFormat
;
1646 arb
->Base
.DataType
= arb
->RGBbuffer
->DataType
;
1647 arb
->Base
.AllocStorage
= alloc_storage_alpha8
;
1648 arb
->Base
.Delete
= delete_renderbuffer_alpha8
;
1649 arb
->Base
.GetPointer
= get_pointer_alpha8
;
1650 arb
->Base
.GetRow
= get_row_alpha8
;
1651 arb
->Base
.GetValues
= get_values_alpha8
;
1652 arb
->Base
.PutRow
= put_row_alpha8
;
1653 arb
->Base
.PutRowRGB
= put_row_rgb_alpha8
;
1654 arb
->Base
.PutMonoRow
= put_mono_row_alpha8
;
1655 arb
->Base
.PutValues
= put_values_alpha8
;
1656 arb
->Base
.PutMonoValues
= put_mono_values_alpha8
;
1658 /* clear the pointer to avoid assertion/sanity check failure later */
1659 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1661 /* plug the alpha renderbuffer into the colorbuffer attachment */
1662 _mesa_add_renderbuffer(fb
, b
, &arb
->Base
);
1670 * Add a software-based depth renderbuffer to the given framebuffer.
1671 * This is a helper routine for device drivers when creating a
1672 * window system framebuffer (not a user-created render/framebuffer).
1673 * Once this function is called, you can basically forget about this
1674 * renderbuffer; core Mesa will handle all the buffer management and
1678 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1681 struct gl_renderbuffer
*rb
;
1683 if (depthBits
> 32) {
1685 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1689 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1691 rb
= _mesa_new_renderbuffer(ctx
, 0);
1693 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1697 if (depthBits
<= 16) {
1698 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1701 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1704 rb
->AllocStorage
= soft_renderbuffer_storage
;
1705 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1712 * Add a software-based stencil renderbuffer to the given framebuffer.
1713 * This is a helper routine for device drivers when creating a
1714 * window system framebuffer (not a user-created render/framebuffer).
1715 * Once this function is called, you can basically forget about this
1716 * renderbuffer; core Mesa will handle all the buffer management and
1720 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1723 struct gl_renderbuffer
*rb
;
1725 if (stencilBits
> 16) {
1727 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1731 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1733 rb
= _mesa_new_renderbuffer(ctx
, 0);
1735 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1739 if (stencilBits
<= 8) {
1740 rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
1743 /* not really supported (see s_stencil.c code) */
1744 rb
->InternalFormat
= GL_STENCIL_INDEX16_EXT
;
1747 rb
->AllocStorage
= soft_renderbuffer_storage
;
1748 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1755 * Add a software-based accumulation 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_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1764 GLuint redBits
, GLuint greenBits
,
1765 GLuint blueBits
, GLuint alphaBits
)
1767 struct gl_renderbuffer
*rb
;
1769 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1771 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1775 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1777 rb
= _mesa_new_renderbuffer(ctx
, 0);
1779 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1783 rb
->InternalFormat
= GL_RGBA16
;
1784 rb
->AllocStorage
= soft_renderbuffer_storage
;
1785 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1793 * Add a software-based accumulation renderbuffer to the given framebuffer.
1794 * This is a helper routine for device drivers when creating a
1795 * window system framebuffer (not a user-created render/framebuffer).
1796 * Once this function is called, you can basically forget about this
1797 * renderbuffer; core Mesa will handle all the buffer management and
1800 * NOTE: color-index aux buffers not supported.
1803 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1804 GLuint colorBits
, GLuint numBuffers
)
1808 if (colorBits
> 16) {
1810 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1814 assert(numBuffers
< MAX_AUX_BUFFERS
);
1816 for (i
= 0; i
< numBuffers
; i
++) {
1817 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1819 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1822 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1826 if (colorBits
<= 8) {
1827 rb
->InternalFormat
= GL_RGBA8
;
1830 rb
->InternalFormat
= GL_RGBA16
;
1833 rb
->AllocStorage
= soft_renderbuffer_storage
;
1834 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1841 * Create/attach software-based renderbuffers to the given framebuffer.
1842 * This is a helper routine for device drivers. Drivers can just as well
1843 * call the individual _mesa_add_*_renderbuffer() routines directly.
1846 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1854 GLboolean frontLeft
= GL_TRUE
;
1855 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1856 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1857 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1860 if (fb
->Visual
.rgbMode
) {
1861 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1862 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1863 _mesa_add_color_renderbuffers(NULL
, fb
,
1865 fb
->Visual
.alphaBits
,
1866 frontLeft
, backLeft
,
1867 frontRight
, backRight
);
1870 _mesa_add_color_index_renderbuffers(NULL
, fb
,
1871 fb
->Visual
.indexBits
,
1872 frontLeft
, backLeft
,
1873 frontRight
, backRight
);
1878 assert(fb
->Visual
.depthBits
> 0);
1879 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1883 assert(fb
->Visual
.stencilBits
> 0);
1884 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1888 assert(fb
->Visual
.rgbMode
);
1889 assert(fb
->Visual
.accumRedBits
> 0);
1890 assert(fb
->Visual
.accumGreenBits
> 0);
1891 assert(fb
->Visual
.accumBlueBits
> 0);
1892 _mesa_add_accum_renderbuffer(NULL
, fb
,
1893 fb
->Visual
.accumRedBits
,
1894 fb
->Visual
.accumGreenBits
,
1895 fb
->Visual
.accumBlueBits
,
1896 fb
->Visual
.accumAlphaBits
);
1900 assert(fb
->Visual
.rgbMode
);
1901 assert(fb
->Visual
.numAuxBuffers
> 0);
1902 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
1903 fb
->Visual
.numAuxBuffers
);
1907 assert(fb
->Visual
.rgbMode
);
1908 assert(fb
->Visual
.alphaBits
> 0);
1909 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
1910 frontLeft
, backLeft
,
1911 frontRight
, backRight
);
1923 * Attach a renderbuffer to a framebuffer.
1926 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
1927 GLuint bufferName
, struct gl_renderbuffer
*rb
)
1932 /* there should be no previous renderbuffer on this attachment point! */
1933 assert(fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
1935 assert(bufferName
< BUFFER_COUNT
);
1937 /* winsys vs. user-created buffer cross check */
1945 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
1946 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
1947 fb
->Attachment
[bufferName
].Renderbuffer
= rb
;