2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Functions for allocating/managing renderbuffers.
28 * Also, routines for reading/writing software-based renderbuffer data as
29 * ubytes, ushorts, uints, etc.
31 * The 'alpha8' renderbuffer is interesting. It's used to add a software-based
32 * alpha channel to RGB renderbuffers. This is done by wrapping the RGB
33 * renderbuffer with the alpha renderbuffer. We can do this because of the
34 * OO-nature of renderbuffers.
36 * Down the road we'll use this for run-time support of 8, 16 and 32-bit
37 * color channels. For example, Mesa may use 32-bit/float color channels
38 * internally (swrast) and use wrapper renderbuffers to convert 32-bit
39 * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
49 #include "renderbuffer.h"
53 * Routines for get/put values in common buffer formats follow.
54 * Someday add support for arbitrary row stride to make them more
58 /**********************************************************************
59 * Functions for buffers of 1 X GLubyte values.
64 get_pointer_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
69 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
70 /* Can't assert rb->Format since these funcs may be used for serveral
71 * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
73 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
78 get_row_ubyte(struct gl_context
*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 memcpy(values
, src
, count
* sizeof(GLubyte
));
88 get_values_ubyte(struct gl_context
*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(struct gl_context
*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 memcpy(dst
, values
, count
* sizeof(GLubyte
));
123 put_mono_row_ubyte(struct gl_context
*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(struct gl_context
*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(struct gl_context
*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(struct gl_context
*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(struct gl_context
*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 memcpy(values
, src
, count
* sizeof(GLushort
));
208 get_values_ushort(struct gl_context
*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(struct gl_context
*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 memcpy(dst
, src
, count
* sizeof(GLushort
));
243 put_mono_row_ushort(struct gl_context
*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(struct gl_context
*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(struct gl_context
*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(struct gl_context
*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(struct gl_context
*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 memcpy(values
, src
, count
* sizeof(GLuint
));
338 get_values_uint(struct gl_context
*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(struct gl_context
*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 memcpy(dst
, src
, count
* sizeof(GLuint
));
375 put_mono_row_uint(struct gl_context
*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(struct gl_context
*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(struct gl_context
*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(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
446 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
447 /* No direct access since this buffer is RGB but caller will be
448 * treating it as if it were RGBA.
455 get_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
456 GLint x
, GLint y
, void *values
)
458 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
459 GLubyte
*dst
= (GLubyte
*) values
;
461 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
462 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
463 for (i
= 0; i
< count
; i
++) {
464 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
465 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
466 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
467 dst
[i
* 4 + 3] = 255;
473 get_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
474 const GLint x
[], const GLint y
[], void *values
)
476 GLubyte
*dst
= (GLubyte
*) values
;
478 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
479 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
480 for (i
= 0; i
< count
; i
++) {
482 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
483 dst
[i
* 4 + 0] = src
[0];
484 dst
[i
* 4 + 1] = src
[1];
485 dst
[i
* 4 + 2] = src
[2];
486 dst
[i
* 4 + 3] = 255;
492 put_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
493 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
495 /* note: incoming values are RGB+A! */
496 const GLubyte
*src
= (const GLubyte
*) values
;
497 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
499 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
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
* 4 + 0];
504 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
505 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
512 put_row_rgb_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
513 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
515 /* note: incoming values are RGB+A! */
516 const GLubyte
*src
= (const GLubyte
*) values
;
517 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
519 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
520 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
521 for (i
= 0; i
< count
; i
++) {
522 if (!mask
|| mask
[i
]) {
523 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
524 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
525 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
532 put_mono_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
533 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
535 /* note: incoming value is RGB+A! */
536 const GLubyte val0
= ((const GLubyte
*) value
)[0];
537 const GLubyte val1
= ((const GLubyte
*) value
)[1];
538 const GLubyte val2
= ((const GLubyte
*) value
)[2];
539 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
540 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
541 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
542 if (!mask
&& val0
== val1
&& val1
== val2
) {
544 memset(dst
, val0
, 3 * count
);
548 for (i
= 0; i
< count
; i
++) {
549 if (!mask
|| mask
[i
]) {
550 dst
[i
* 3 + 0] = val0
;
551 dst
[i
* 3 + 1] = val1
;
552 dst
[i
* 3 + 2] = val2
;
560 put_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
561 const GLint x
[], const GLint y
[], const void *values
,
564 /* note: incoming values are RGB+A! */
565 const GLubyte
*src
= (const GLubyte
*) values
;
567 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
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
]);
572 dst
[0] = src
[i
* 4 + 0];
573 dst
[1] = src
[i
* 4 + 1];
574 dst
[2] = src
[i
* 4 + 2];
581 put_mono_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
582 GLuint count
, const GLint x
[], const GLint y
[],
583 const void *value
, const GLubyte
*mask
)
585 /* note: incoming value is RGB+A! */
586 const GLubyte val0
= ((const GLubyte
*) value
)[0];
587 const GLubyte val1
= ((const GLubyte
*) value
)[1];
588 const GLubyte val2
= ((const GLubyte
*) value
)[2];
590 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
591 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
592 for (i
= 0; i
< count
; i
++) {
593 if (!mask
|| mask
[i
]) {
594 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
603 /**********************************************************************
604 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
605 * Typically color buffers.
609 get_pointer_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
614 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
615 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
616 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
621 get_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
622 GLint x
, GLint y
, void *values
)
624 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
625 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
626 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
627 memcpy(values
, src
, 4 * count
* sizeof(GLubyte
));
632 get_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
633 const GLint x
[], const GLint y
[], void *values
)
635 /* treat 4*GLubyte as 1*GLuint */
636 GLuint
*dst
= (GLuint
*) values
;
638 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
639 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
640 for (i
= 0; i
< count
; i
++) {
641 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
648 put_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
649 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
651 /* treat 4*GLubyte as 1*GLuint */
652 const GLuint
*src
= (const GLuint
*) values
;
653 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
654 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
655 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
658 for (i
= 0; i
< count
; i
++) {
665 memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
671 put_row_rgb_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
672 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
674 /* Store RGB values in RGBA buffer */
675 const GLubyte
*src
= (const GLubyte
*) values
;
676 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
678 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
679 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
680 for (i
= 0; i
< count
; i
++) {
681 if (!mask
|| mask
[i
]) {
682 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
683 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
684 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
685 dst
[i
* 4 + 3] = 0xff;
692 put_mono_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
693 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
695 /* treat 4*GLubyte as 1*GLuint */
696 const GLuint val
= *((const GLuint
*) value
);
697 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
698 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
699 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
700 if (!mask
&& val
== 0) {
702 memset(dst
, 0, count
* 4 * sizeof(GLubyte
));
708 for (i
= 0; i
< count
; i
++) {
716 for (i
= 0; i
< count
; i
++) {
725 put_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
726 const GLint x
[], const GLint y
[], const void *values
,
729 /* treat 4*GLubyte as 1*GLuint */
730 const GLuint
*src
= (const GLuint
*) values
;
732 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
733 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
734 for (i
= 0; i
< count
; i
++) {
735 if (!mask
|| mask
[i
]) {
736 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
744 put_mono_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
745 GLuint count
, const GLint x
[], const GLint y
[],
746 const void *value
, const GLubyte
*mask
)
748 /* treat 4*GLubyte as 1*GLuint */
749 const GLuint val
= *((const GLuint
*) value
);
751 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
752 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
753 for (i
= 0; i
< count
; i
++) {
754 if (!mask
|| mask
[i
]) {
755 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
762 /**********************************************************************
763 * Functions for buffers of 4 X GLushort (or GLshort) values.
764 * Typically accum buffer.
768 get_pointer_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
773 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
774 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
779 get_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
780 GLint x
, GLint y
, void *values
)
782 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
783 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
784 memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
789 get_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
790 const GLint x
[], const GLint y
[], void *values
)
792 GLushort
*dst
= (GLushort
*) values
;
794 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
795 for (i
= 0; i
< count
; i
++) {
797 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
804 put_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
805 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
807 const GLushort
*src
= (const GLushort
*) values
;
808 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
809 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
812 for (i
= 0; i
< count
; i
++) {
814 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
815 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
816 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
817 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
822 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
828 put_row_rgb_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
829 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
831 /* Put RGB values in RGBA buffer */
832 const GLushort
*src
= (const GLushort
*) values
;
833 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
834 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
837 for (i
= 0; i
< count
; i
++) {
839 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
840 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
841 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
842 dst
[i
* 4 + 3] = 0xffff;
847 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
853 put_mono_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
854 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
856 const GLushort val0
= ((const GLushort
*) value
)[0];
857 const GLushort val1
= ((const GLushort
*) value
)[1];
858 const GLushort val2
= ((const GLushort
*) value
)[2];
859 const GLushort val3
= ((const GLushort
*) value
)[3];
860 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
861 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
862 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
863 /* common case for clearing accum buffer */
864 memset(dst
, 0, count
* 4 * sizeof(GLushort
));
868 for (i
= 0; i
< count
; i
++) {
869 if (!mask
|| mask
[i
]) {
870 dst
[i
* 4 + 0] = val0
;
871 dst
[i
* 4 + 1] = val1
;
872 dst
[i
* 4 + 2] = val2
;
873 dst
[i
* 4 + 3] = val3
;
881 put_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
882 const GLint x
[], const GLint y
[], const void *values
,
885 const GLushort
*src
= (const GLushort
*) values
;
887 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
888 for (i
= 0; i
< count
; i
++) {
889 if (!mask
|| mask
[i
]) {
890 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
891 dst
[0] = src
[i
* 4 + 0];
892 dst
[1] = src
[i
* 4 + 1];
893 dst
[2] = src
[i
* 4 + 2];
894 dst
[3] = src
[i
* 4 + 3];
901 put_mono_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
902 GLuint count
, const GLint x
[], const GLint y
[],
903 const void *value
, const GLubyte
*mask
)
905 const GLushort val0
= ((const GLushort
*) value
)[0];
906 const GLushort val1
= ((const GLushort
*) value
)[1];
907 const GLushort val2
= ((const GLushort
*) value
)[2];
908 const GLushort val3
= ((const GLushort
*) value
)[3];
910 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
911 for (i
= 0; i
< count
; i
++) {
912 if (!mask
|| mask
[i
]) {
913 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
925 * This is a software fallback for the gl_renderbuffer->AllocStorage
927 * Device drivers will typically override this function for the buffers
928 * which it manages (typically color buffers, Z and stencil).
929 * Other buffers (like software accumulation and aux buffers) which the driver
930 * doesn't manage can be handled with this function.
932 * This one multi-purpose function can allocate stencil, depth, accum, color
933 * or color-index buffers!
935 * This function also plugs in the appropriate GetPointer, Get/PutRow and
936 * Get/PutValues functions.
939 _mesa_soft_renderbuffer_storage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
940 GLenum internalFormat
,
941 GLuint width
, GLuint height
)
945 switch (internalFormat
) {
954 rb
->Format
= MESA_FORMAT_RGB888
;
955 rb
->DataType
= GL_UNSIGNED_BYTE
;
956 rb
->GetPointer
= get_pointer_ubyte3
;
957 rb
->GetRow
= get_row_ubyte3
;
958 rb
->GetValues
= get_values_ubyte3
;
959 rb
->PutRow
= put_row_ubyte3
;
960 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
961 rb
->PutMonoRow
= put_mono_row_ubyte3
;
962 rb
->PutValues
= put_values_ubyte3
;
963 rb
->PutMonoValues
= put_mono_values_ubyte3
;
964 pixelSize
= 3 * sizeof(GLubyte
);
975 rb
->Format
= MESA_FORMAT_RGBA8888
;
976 rb
->DataType
= GL_UNSIGNED_BYTE
;
977 rb
->GetPointer
= get_pointer_ubyte4
;
978 rb
->GetRow
= get_row_ubyte4
;
979 rb
->GetValues
= get_values_ubyte4
;
980 rb
->PutRow
= put_row_ubyte4
;
981 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
982 rb
->PutMonoRow
= put_mono_row_ubyte4
;
983 rb
->PutValues
= put_values_ubyte4
;
984 rb
->PutMonoValues
= put_mono_values_ubyte4
;
985 pixelSize
= 4 * sizeof(GLubyte
);
988 case GL_RGBA16_SNORM
:
989 /* for accum buffer */
990 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
991 rb
->DataType
= GL_SHORT
;
992 rb
->GetPointer
= get_pointer_ushort4
;
993 rb
->GetRow
= get_row_ushort4
;
994 rb
->GetValues
= get_values_ushort4
;
995 rb
->PutRow
= put_row_ushort4
;
996 rb
->PutRowRGB
= put_row_rgb_ushort4
;
997 rb
->PutMonoRow
= put_mono_row_ushort4
;
998 rb
->PutValues
= put_values_ushort4
;
999 rb
->PutMonoValues
= put_mono_values_ushort4
;
1000 pixelSize
= 4 * sizeof(GLushort
);
1004 rb
->Format
= MESA_FORMAT_A8
;
1005 rb
->DataType
= GL_UNSIGNED_BYTE
;
1006 rb
->GetPointer
= get_pointer_alpha8
;
1007 rb
->GetRow
= get_row_alpha8
;
1008 rb
->GetValues
= get_values_alpha8
;
1009 rb
->PutRow
= put_row_alpha8
;
1010 rb
->PutRowRGB
= NULL
;
1011 rb
->PutMonoRow
= put_mono_row_alpha8
;
1012 rb
->PutValues
= put_values_alpha8
;
1013 rb
->PutMonoValues
= put_mono_values_alpha8
;
1014 pixelSize
= sizeof(GLubyte
);
1017 case GL_STENCIL_INDEX
:
1018 case GL_STENCIL_INDEX1_EXT
:
1019 case GL_STENCIL_INDEX4_EXT
:
1020 case GL_STENCIL_INDEX8_EXT
:
1021 case GL_STENCIL_INDEX16_EXT
:
1022 rb
->Format
= MESA_FORMAT_S8
;
1023 rb
->DataType
= GL_UNSIGNED_BYTE
;
1024 rb
->GetPointer
= get_pointer_ubyte
;
1025 rb
->GetRow
= get_row_ubyte
;
1026 rb
->GetValues
= get_values_ubyte
;
1027 rb
->PutRow
= put_row_ubyte
;
1028 rb
->PutRowRGB
= NULL
;
1029 rb
->PutMonoRow
= put_mono_row_ubyte
;
1030 rb
->PutValues
= put_values_ubyte
;
1031 rb
->PutMonoValues
= put_mono_values_ubyte
;
1032 pixelSize
= sizeof(GLubyte
);
1034 case GL_DEPTH_COMPONENT
:
1035 case GL_DEPTH_COMPONENT16
:
1036 rb
->Format
= MESA_FORMAT_Z16
;
1037 rb
->DataType
= GL_UNSIGNED_SHORT
;
1038 rb
->GetPointer
= get_pointer_ushort
;
1039 rb
->GetRow
= get_row_ushort
;
1040 rb
->GetValues
= get_values_ushort
;
1041 rb
->PutRow
= put_row_ushort
;
1042 rb
->PutRowRGB
= NULL
;
1043 rb
->PutMonoRow
= put_mono_row_ushort
;
1044 rb
->PutValues
= put_values_ushort
;
1045 rb
->PutMonoValues
= put_mono_values_ushort
;
1046 pixelSize
= sizeof(GLushort
);
1048 case GL_DEPTH_COMPONENT24
:
1049 rb
->DataType
= GL_UNSIGNED_INT
;
1050 rb
->GetPointer
= get_pointer_uint
;
1051 rb
->GetRow
= get_row_uint
;
1052 rb
->GetValues
= get_values_uint
;
1053 rb
->PutRow
= put_row_uint
;
1054 rb
->PutRowRGB
= NULL
;
1055 rb
->PutMonoRow
= put_mono_row_uint
;
1056 rb
->PutValues
= put_values_uint
;
1057 rb
->PutMonoValues
= put_mono_values_uint
;
1058 rb
->Format
= MESA_FORMAT_X8_Z24
;
1059 pixelSize
= sizeof(GLuint
);
1061 case GL_DEPTH_COMPONENT32
:
1062 rb
->DataType
= GL_UNSIGNED_INT
;
1063 rb
->GetPointer
= get_pointer_uint
;
1064 rb
->GetRow
= get_row_uint
;
1065 rb
->GetValues
= get_values_uint
;
1066 rb
->PutRow
= put_row_uint
;
1067 rb
->PutRowRGB
= NULL
;
1068 rb
->PutMonoRow
= put_mono_row_uint
;
1069 rb
->PutValues
= put_values_uint
;
1070 rb
->PutMonoValues
= put_mono_values_uint
;
1071 rb
->Format
= MESA_FORMAT_Z32
;
1072 pixelSize
= sizeof(GLuint
);
1074 case GL_DEPTH_STENCIL_EXT
:
1075 case GL_DEPTH24_STENCIL8_EXT
:
1076 rb
->Format
= MESA_FORMAT_Z24_S8
;
1077 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1078 rb
->GetPointer
= get_pointer_uint
;
1079 rb
->GetRow
= get_row_uint
;
1080 rb
->GetValues
= get_values_uint
;
1081 rb
->PutRow
= put_row_uint
;
1082 rb
->PutRowRGB
= NULL
;
1083 rb
->PutMonoRow
= put_mono_row_uint
;
1084 rb
->PutValues
= put_values_uint
;
1085 rb
->PutMonoValues
= put_mono_values_uint
;
1086 pixelSize
= sizeof(GLuint
);
1089 _mesa_problem(ctx
, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
1093 ASSERT(rb
->DataType
);
1094 ASSERT(rb
->GetPointer
);
1096 ASSERT(rb
->GetValues
);
1098 ASSERT(rb
->PutMonoRow
);
1099 ASSERT(rb
->PutValues
);
1100 ASSERT(rb
->PutMonoValues
);
1102 /* free old buffer storage */
1108 if (width
> 0 && height
> 0) {
1109 /* allocate new buffer storage */
1110 rb
->Data
= malloc(width
* height
* pixelSize
);
1112 if (rb
->Data
== NULL
) {
1115 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1116 "software renderbuffer allocation (%d x %d x %d)",
1117 width
, height
, pixelSize
);
1123 rb
->Height
= height
;
1124 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
1125 ASSERT(rb
->_BaseFormat
);
1132 /**********************************************************************/
1133 /**********************************************************************/
1134 /**********************************************************************/
1138 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1139 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1141 * When PutRow is called (for example), we store the alpha values in
1142 * this buffer, then pass on the PutRow call to the wrapped RGB
1148 alloc_storage_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1149 GLenum internalFormat
, GLuint width
, GLuint height
)
1151 ASSERT(arb
!= arb
->Wrapped
);
1152 ASSERT(arb
->Format
== MESA_FORMAT_A8
);
1154 /* first, pass the call to the wrapped RGB buffer */
1155 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1160 /* next, resize my alpha buffer */
1165 arb
->Data
= malloc(width
* height
* sizeof(GLubyte
));
1166 if (arb
->Data
== NULL
) {
1169 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1174 arb
->Height
= height
;
1181 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1184 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1189 ASSERT(arb
->Wrapped
);
1190 ASSERT(arb
!= arb
->Wrapped
);
1191 arb
->Wrapped
->Delete(arb
->Wrapped
);
1192 arb
->Wrapped
= NULL
;
1198 get_pointer_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1201 return NULL
; /* don't allow direct access! */
1206 get_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1207 GLint x
, GLint y
, void *values
)
1209 /* NOTE: 'values' is RGBA format! */
1210 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1211 GLubyte
*dst
= (GLubyte
*) values
;
1213 ASSERT(arb
!= arb
->Wrapped
);
1214 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1215 /* first, pass the call to the wrapped RGB buffer */
1216 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1217 /* second, fill in alpha values from this buffer! */
1218 for (i
= 0; i
< count
; i
++) {
1219 dst
[i
* 4 + 3] = src
[i
];
1225 get_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1226 const GLint x
[], const GLint y
[], void *values
)
1228 GLubyte
*dst
= (GLubyte
*) values
;
1230 ASSERT(arb
!= arb
->Wrapped
);
1231 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1232 /* first, pass the call to the wrapped RGB buffer */
1233 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1234 /* second, fill in alpha values from this buffer! */
1235 for (i
= 0; i
< count
; i
++) {
1236 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1237 dst
[i
* 4 + 3] = *src
;
1243 put_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1244 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1246 const GLubyte
*src
= (const GLubyte
*) values
;
1247 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1249 ASSERT(arb
!= arb
->Wrapped
);
1250 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1251 /* first, pass the call to the wrapped RGB buffer */
1252 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1253 /* second, store alpha in our buffer */
1254 for (i
= 0; i
< count
; i
++) {
1255 if (!mask
|| mask
[i
]) {
1256 dst
[i
] = src
[i
* 4 + 3];
1263 put_row_rgb_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1264 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1266 const GLubyte
*src
= (const GLubyte
*) values
;
1267 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1269 ASSERT(arb
!= arb
->Wrapped
);
1270 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1271 /* first, pass the call to the wrapped RGB buffer */
1272 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1273 /* second, store alpha in our buffer */
1274 for (i
= 0; i
< count
; i
++) {
1275 if (!mask
|| mask
[i
]) {
1276 dst
[i
] = src
[i
* 4 + 3];
1283 put_mono_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1284 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1286 const GLubyte val
= ((const GLubyte
*) value
)[3];
1287 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1288 ASSERT(arb
!= arb
->Wrapped
);
1289 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1290 /* first, pass the call to the wrapped RGB buffer */
1291 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1292 /* second, store alpha in our buffer */
1295 for (i
= 0; i
< count
; i
++) {
1302 memset(dst
, val
, count
);
1308 put_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1309 const GLint x
[], const GLint y
[],
1310 const void *values
, const GLubyte
*mask
)
1312 const GLubyte
*src
= (const GLubyte
*) values
;
1314 ASSERT(arb
!= arb
->Wrapped
);
1315 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1316 /* first, pass the call to the wrapped RGB buffer */
1317 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1318 /* second, store alpha in our buffer */
1319 for (i
= 0; i
< count
; i
++) {
1320 if (!mask
|| mask
[i
]) {
1321 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1322 *dst
= src
[i
* 4 + 3];
1329 put_mono_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1330 GLuint count
, const GLint x
[], const GLint y
[],
1331 const void *value
, const GLubyte
*mask
)
1333 const GLubyte val
= ((const GLubyte
*) value
)[3];
1335 ASSERT(arb
!= arb
->Wrapped
);
1336 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1337 /* first, pass the call to the wrapped RGB buffer */
1338 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1339 /* second, store alpha in our buffer */
1340 for (i
= 0; i
< count
; i
++) {
1341 if (!mask
|| mask
[i
]) {
1342 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1350 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1352 ASSERT(dst
->Format
== MESA_FORMAT_A8
);
1353 ASSERT(src
->Format
== MESA_FORMAT_A8
);
1354 ASSERT(dst
->Width
== src
->Width
);
1355 ASSERT(dst
->Height
== src
->Height
);
1357 memcpy(dst
->Data
, src
->Data
, dst
->Width
* dst
->Height
* sizeof(GLubyte
));
1361 /**********************************************************************/
1362 /**********************************************************************/
1363 /**********************************************************************/
1367 * Default GetPointer routine. Always return NULL to indicate that
1368 * direct buffer access is not supported.
1371 nop_get_pointer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1378 * Initialize the fields of a gl_renderbuffer to default values.
1381 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1383 _glthread_INIT_MUTEX(rb
->Mutex
);
1385 rb
->Magic
= RB_MAGIC
;
1389 rb
->Delete
= _mesa_delete_renderbuffer
;
1391 /* The rest of these should be set later by the caller of this function or
1392 * the AllocStorage method:
1394 rb
->AllocStorage
= NULL
;
1398 rb
->InternalFormat
= GL_NONE
;
1399 rb
->Format
= MESA_FORMAT_NONE
;
1401 rb
->DataType
= GL_NONE
;
1404 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1405 * all over the drivers.
1409 rb
->GetPointer
= nop_get_pointer
;
1411 rb
->GetValues
= NULL
;
1413 rb
->PutRowRGB
= NULL
;
1414 rb
->PutMonoRow
= NULL
;
1415 rb
->PutValues
= NULL
;
1416 rb
->PutMonoValues
= NULL
;
1421 * Allocate a new gl_renderbuffer object. This can be used for user-created
1422 * renderbuffers or window-system renderbuffers.
1424 struct gl_renderbuffer
*
1425 _mesa_new_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1427 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1429 _mesa_init_renderbuffer(rb
, name
);
1436 * Delete a gl_framebuffer.
1437 * This is the default function for renderbuffer->Delete().
1440 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1450 * Allocate a software-based renderbuffer. This is called via the
1451 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1453 * This would not be used for hardware-based renderbuffers.
1455 struct gl_renderbuffer
*
1456 _mesa_new_soft_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1458 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1460 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1461 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1462 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1471 * Add software-based color renderbuffers to the given framebuffer.
1472 * This is a helper routine for device drivers when creating a
1473 * window system framebuffer (not a user-created render/framebuffer).
1474 * Once this function is called, you can basically forget about this
1475 * renderbuffer; core Mesa will handle all the buffer management and
1479 _mesa_add_color_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1480 GLuint rgbBits
, GLuint alphaBits
,
1481 GLboolean frontLeft
, GLboolean backLeft
,
1482 GLboolean frontRight
, GLboolean backRight
)
1486 if (rgbBits
> 16 || alphaBits
> 16) {
1488 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1492 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1494 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1495 struct gl_renderbuffer
*rb
;
1497 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1499 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1501 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1503 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1506 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1508 rb
= _mesa_new_renderbuffer(ctx
, 0);
1510 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1516 rb
->Format
= MESA_FORMAT_RGBA8888
;
1518 rb
->Format
= MESA_FORMAT_RGB888
;
1521 assert(rgbBits
<= 16);
1522 rb
->Format
= MESA_FORMAT_NONE
; /*XXX RGBA16;*/
1524 rb
->InternalFormat
= GL_RGBA
;
1526 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1527 _mesa_add_renderbuffer(fb
, b
, rb
);
1535 * Add software-based alpha renderbuffers to the given framebuffer.
1536 * This is a helper routine for device drivers when creating a
1537 * window system framebuffer (not a user-created render/framebuffer).
1538 * Once this function is called, you can basically forget about this
1539 * renderbuffer; core Mesa will handle all the buffer management and
1543 _mesa_add_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1545 GLboolean frontLeft
, GLboolean backLeft
,
1546 GLboolean frontRight
, GLboolean backRight
)
1550 /* for window system framebuffers only! */
1551 assert(fb
->Name
== 0);
1553 if (alphaBits
> 8) {
1555 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1559 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1561 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1563 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1564 struct gl_renderbuffer
*arb
;
1566 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1568 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1570 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1572 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1575 /* the RGB buffer to wrap must already exist!! */
1576 assert(fb
->Attachment
[b
].Renderbuffer
);
1578 /* only GLubyte supported for now */
1579 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1581 /* allocate alpha renderbuffer */
1582 arb
= _mesa_new_renderbuffer(ctx
, 0);
1584 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1588 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1589 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1591 /* Set up my alphabuffer fields and plug in my functions.
1592 * The functions will put/get the alpha values from/to RGBA arrays
1593 * and then call the wrapped buffer's functions to handle the RGB
1596 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1597 arb
->Format
= MESA_FORMAT_A8
;
1598 arb
->DataType
= arb
->Wrapped
->DataType
;
1599 arb
->AllocStorage
= alloc_storage_alpha8
;
1600 arb
->Delete
= delete_renderbuffer_alpha8
;
1601 arb
->GetPointer
= get_pointer_alpha8
;
1602 arb
->GetRow
= get_row_alpha8
;
1603 arb
->GetValues
= get_values_alpha8
;
1604 arb
->PutRow
= put_row_alpha8
;
1605 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1606 arb
->PutMonoRow
= put_mono_row_alpha8
;
1607 arb
->PutValues
= put_values_alpha8
;
1608 arb
->PutMonoValues
= put_mono_values_alpha8
;
1610 /* clear the pointer to avoid assertion/sanity check failure later */
1611 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1613 /* plug the alpha renderbuffer into the colorbuffer attachment */
1614 _mesa_add_renderbuffer(fb
, b
, arb
);
1622 * For framebuffers that use a software alpha channel wrapper
1623 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
1624 * copy the back buffer alpha channel into the front buffer alpha channel.
1627 _mesa_copy_soft_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
1629 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
1630 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
1631 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
1632 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
1635 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
1636 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
1637 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
1638 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
1643 * Add a software-based depth renderbuffer to the given framebuffer.
1644 * This is a helper routine for device drivers when creating a
1645 * window system framebuffer (not a user-created render/framebuffer).
1646 * Once this function is called, you can basically forget about this
1647 * renderbuffer; core Mesa will handle all the buffer management and
1651 _mesa_add_depth_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1654 struct gl_renderbuffer
*rb
;
1656 if (depthBits
> 32) {
1658 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1662 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1664 rb
= _mesa_new_renderbuffer(ctx
, 0);
1666 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1670 if (depthBits
<= 16) {
1671 rb
->Format
= MESA_FORMAT_Z16
;
1672 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1674 else if (depthBits
<= 24) {
1675 rb
->Format
= MESA_FORMAT_X8_Z24
;
1676 rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
1679 rb
->Format
= MESA_FORMAT_Z32
;
1680 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1683 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1684 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1691 * Add a software-based stencil renderbuffer to the given framebuffer.
1692 * This is a helper routine for device drivers when creating a
1693 * window system framebuffer (not a user-created render/framebuffer).
1694 * Once this function is called, you can basically forget about this
1695 * renderbuffer; core Mesa will handle all the buffer management and
1699 _mesa_add_stencil_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1702 struct gl_renderbuffer
*rb
;
1704 if (stencilBits
> 16) {
1706 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1710 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1712 rb
= _mesa_new_renderbuffer(ctx
, 0);
1714 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1718 assert(stencilBits
<= 8);
1719 rb
->Format
= MESA_FORMAT_S8
;
1720 rb
->InternalFormat
= GL_STENCIL_INDEX8
;
1722 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1723 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1730 * Add a software-based accumulation renderbuffer to the given framebuffer.
1731 * This is a helper routine for device drivers when creating a
1732 * window system framebuffer (not a user-created render/framebuffer).
1733 * Once this function is called, you can basically forget about this
1734 * renderbuffer; core Mesa will handle all the buffer management and
1738 _mesa_add_accum_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1739 GLuint redBits
, GLuint greenBits
,
1740 GLuint blueBits
, GLuint alphaBits
)
1742 struct gl_renderbuffer
*rb
;
1744 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1746 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1750 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1752 rb
= _mesa_new_renderbuffer(ctx
, 0);
1754 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1758 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
1759 rb
->InternalFormat
= GL_RGBA16_SNORM
;
1760 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1761 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1769 * Add a software-based aux renderbuffer to the given framebuffer.
1770 * This is a helper routine for device drivers when creating a
1771 * window system framebuffer (not a user-created render/framebuffer).
1772 * Once this function is called, you can basically forget about this
1773 * renderbuffer; core Mesa will handle all the buffer management and
1776 * NOTE: color-index aux buffers not supported.
1779 _mesa_add_aux_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1780 GLuint colorBits
, GLuint numBuffers
)
1784 if (colorBits
> 16) {
1786 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1790 assert(numBuffers
<= MAX_AUX_BUFFERS
);
1792 for (i
= 0; i
< numBuffers
; i
++) {
1793 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1795 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1798 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating aux buffer");
1802 assert (colorBits
<= 8);
1803 rb
->Format
= MESA_FORMAT_RGBA8888
;
1804 rb
->InternalFormat
= GL_RGBA
;
1806 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1807 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1814 * Create/attach software-based renderbuffers to the given framebuffer.
1815 * This is a helper routine for device drivers. Drivers can just as well
1816 * call the individual _mesa_add_*_renderbuffer() routines directly.
1819 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1827 GLboolean frontLeft
= GL_TRUE
;
1828 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1829 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1830 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1833 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1834 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1835 _mesa_add_color_renderbuffers(NULL
, fb
,
1837 fb
->Visual
.alphaBits
,
1838 frontLeft
, backLeft
,
1839 frontRight
, backRight
);
1843 assert(fb
->Visual
.depthBits
> 0);
1844 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1848 assert(fb
->Visual
.stencilBits
> 0);
1849 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1853 assert(fb
->Visual
.accumRedBits
> 0);
1854 assert(fb
->Visual
.accumGreenBits
> 0);
1855 assert(fb
->Visual
.accumBlueBits
> 0);
1856 _mesa_add_accum_renderbuffer(NULL
, fb
,
1857 fb
->Visual
.accumRedBits
,
1858 fb
->Visual
.accumGreenBits
,
1859 fb
->Visual
.accumBlueBits
,
1860 fb
->Visual
.accumAlphaBits
);
1864 assert(fb
->Visual
.numAuxBuffers
> 0);
1865 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
1866 fb
->Visual
.numAuxBuffers
);
1870 assert(fb
->Visual
.alphaBits
> 0);
1871 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
1872 frontLeft
, backLeft
,
1873 frontRight
, backRight
);
1885 * Attach a renderbuffer to a framebuffer.
1886 * \param bufferName one of the BUFFER_x tokens
1889 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
1890 gl_buffer_index bufferName
, struct gl_renderbuffer
*rb
)
1894 assert(bufferName
< BUFFER_COUNT
);
1896 /* There should be no previous renderbuffer on this attachment point,
1897 * with the exception of depth/stencil since the same renderbuffer may
1900 assert(bufferName
== BUFFER_DEPTH
||
1901 bufferName
== BUFFER_STENCIL
||
1902 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
1904 /* winsys vs. user-created buffer cross check */
1912 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
1913 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
1914 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
1919 * Remove the named renderbuffer from the given framebuffer.
1920 * \param bufferName one of the BUFFER_x tokens
1923 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
,
1924 gl_buffer_index bufferName
)
1926 struct gl_renderbuffer
*rb
;
1928 assert(bufferName
< BUFFER_COUNT
);
1930 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
1934 _mesa_reference_renderbuffer(&rb
, NULL
);
1936 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
1941 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
1942 * dereference that buffer first. The new renderbuffer's refcount will
1943 * be incremented. The old renderbuffer's refcount will be decremented.
1946 _mesa_reference_renderbuffer(struct gl_renderbuffer
**ptr
,
1947 struct gl_renderbuffer
*rb
)
1956 /* Unreference the old renderbuffer */
1957 GLboolean deleteFlag
= GL_FALSE
;
1958 struct gl_renderbuffer
*oldRb
= *ptr
;
1960 assert(oldRb
->Magic
== RB_MAGIC
);
1961 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
1962 assert(oldRb
->Magic
== RB_MAGIC
);
1963 ASSERT(oldRb
->RefCount
> 0);
1965 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
1966 deleteFlag
= (oldRb
->RefCount
== 0);
1967 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
1970 oldRb
->Magic
= 0; /* now invalid memory! */
1971 oldRb
->Delete(oldRb
);
1979 assert(rb
->Magic
== RB_MAGIC
);
1980 /* reference new renderbuffer */
1981 _glthread_LOCK_MUTEX(rb
->Mutex
);
1983 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
1984 _glthread_UNLOCK_MUTEX(rb
->Mutex
);
1991 * Create a new combined depth/stencil renderbuffer for implementing
1992 * the GL_EXT_packed_depth_stencil extension.
1993 * \return new depth/stencil renderbuffer
1995 struct gl_renderbuffer
*
1996 _mesa_new_depthstencil_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1998 struct gl_renderbuffer
*dsrb
;
2000 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
2004 /* init fields not covered by _mesa_new_renderbuffer() */
2005 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
2006 dsrb
->Format
= MESA_FORMAT_Z24_S8
;
2007 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;