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.
57 get_pointer_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
64 (y
* rb
->RowStride
+ x
) * _mesa_get_format_bytes(rb
->Format
));
67 /* GetRow() implementation for formats where DataType matches the rb->Format.
70 get_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
71 GLuint count
, GLint x
, GLint y
, void *values
)
73 void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
74 memcpy(values
, src
, count
* _mesa_get_format_bytes(rb
->Format
));
77 /**********************************************************************
78 * Functions for buffers of 1 X GLubyte values.
83 get_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
84 const GLint x
[], const GLint y
[], void *values
)
86 GLubyte
*dst
= (GLubyte
*) values
;
88 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
89 for (i
= 0; i
< count
; i
++) {
90 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
97 put_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
98 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
100 const GLubyte
*src
= (const GLubyte
*) values
;
101 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
102 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
105 for (i
= 0; i
< count
; i
++) {
112 memcpy(dst
, values
, count
* sizeof(GLubyte
));
118 put_mono_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
119 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
121 const GLubyte val
= *((const GLubyte
*) value
);
122 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
123 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
126 for (i
= 0; i
< count
; i
++) {
134 for (i
= 0; i
< count
; i
++) {
142 put_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
143 const GLint x
[], const GLint y
[],
144 const void *values
, const GLubyte
*mask
)
146 const GLubyte
*src
= (const GLubyte
*) values
;
148 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
149 for (i
= 0; i
< count
; i
++) {
150 if (!mask
|| mask
[i
]) {
151 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
159 put_mono_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
160 const GLint x
[], const GLint y
[],
161 const void *value
, const GLubyte
*mask
)
163 const GLubyte val
= *((const GLubyte
*) value
);
165 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
166 for (i
= 0; i
< count
; i
++) {
167 if (!mask
|| mask
[i
]) {
168 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
175 /**********************************************************************
176 * Functions for buffers of 1 X GLushort values.
181 get_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
182 const GLint x
[], const GLint y
[], void *values
)
184 GLushort
*dst
= (GLushort
*) values
;
186 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
187 for (i
= 0; i
< count
; i
++) {
188 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
195 put_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
196 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
198 const GLushort
*src
= (const GLushort
*) values
;
199 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
200 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
203 for (i
= 0; i
< count
; i
++) {
210 memcpy(dst
, src
, count
* sizeof(GLushort
));
216 put_mono_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
217 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
219 const GLushort val
= *((const GLushort
*) value
);
220 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
221 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
224 for (i
= 0; i
< count
; i
++) {
232 for (i
= 0; i
< count
; i
++) {
240 put_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
241 const GLint x
[], const GLint y
[], const void *values
,
244 const GLushort
*src
= (const GLushort
*) values
;
246 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
247 for (i
= 0; i
< count
; i
++) {
248 if (!mask
|| mask
[i
]) {
249 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
257 put_mono_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
258 GLuint count
, const GLint x
[], const GLint y
[],
259 const void *value
, const GLubyte
*mask
)
261 const GLushort val
= *((const GLushort
*) value
);
262 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
265 for (i
= 0; i
< count
; i
++) {
267 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
274 for (i
= 0; i
< count
; i
++) {
275 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
282 /**********************************************************************
283 * Functions for buffers of 1 X GLuint values.
284 * Typically depth/Z or color index.
288 get_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
289 const GLint x
[], const GLint y
[], void *values
)
291 GLuint
*dst
= (GLuint
*) values
;
293 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
294 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
295 for (i
= 0; i
< count
; i
++) {
296 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
303 put_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
304 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
306 const GLuint
*src
= (const GLuint
*) values
;
307 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
308 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
309 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
312 for (i
= 0; i
< count
; i
++) {
319 memcpy(dst
, src
, count
* sizeof(GLuint
));
325 put_mono_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
326 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
328 const GLuint val
= *((const GLuint
*) value
);
329 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
330 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
331 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
334 for (i
= 0; i
< count
; i
++) {
342 for (i
= 0; i
< count
; i
++) {
350 put_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
351 const GLint x
[], const GLint y
[], const void *values
,
354 const GLuint
*src
= (const GLuint
*) values
;
356 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
357 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
358 for (i
= 0; i
< count
; i
++) {
359 if (!mask
|| mask
[i
]) {
360 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
368 put_mono_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
369 const GLint x
[], const GLint y
[], const void *value
,
372 const GLuint val
= *((const GLuint
*) value
);
374 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
375 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
376 for (i
= 0; i
< count
; i
++) {
377 if (!mask
|| mask
[i
]) {
378 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
385 /**********************************************************************
386 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
387 * Typically color buffers.
388 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
389 * alpha values and return 255 for outgoing alpha values.
393 get_pointer_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
396 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
397 /* No direct access since this buffer is RGB but caller will be
398 * treating it as if it were RGBA.
405 get_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
406 GLint x
, GLint y
, void *values
)
408 const GLubyte
*src
= (const GLubyte
*) (rb
->Data
+
409 3 * (y
* rb
->RowStride
+ x
));
410 GLubyte
*dst
= (GLubyte
*) values
;
412 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
413 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
414 for (i
= 0; i
< count
; i
++) {
415 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
416 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
417 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
418 dst
[i
* 4 + 3] = 255;
424 get_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
425 const GLint x
[], const GLint y
[], void *values
)
427 GLubyte
*dst
= (GLubyte
*) values
;
429 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
430 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
431 for (i
= 0; i
< count
; i
++) {
433 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
434 dst
[i
* 4 + 0] = src
[0];
435 dst
[i
* 4 + 1] = src
[1];
436 dst
[i
* 4 + 2] = src
[2];
437 dst
[i
* 4 + 3] = 255;
443 put_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
444 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
446 /* note: incoming values are RGB+A! */
447 const GLubyte
*src
= (const GLubyte
*) values
;
448 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
450 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
451 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
452 for (i
= 0; i
< count
; i
++) {
453 if (!mask
|| mask
[i
]) {
454 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
455 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
456 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
463 put_row_rgb_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
464 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
466 /* note: incoming values are RGB+A! */
467 const GLubyte
*src
= (const GLubyte
*) values
;
468 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
470 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
471 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
472 for (i
= 0; i
< count
; i
++) {
473 if (!mask
|| mask
[i
]) {
474 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
475 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
476 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
483 put_mono_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
484 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
486 /* note: incoming value is RGB+A! */
487 const GLubyte val0
= ((const GLubyte
*) value
)[0];
488 const GLubyte val1
= ((const GLubyte
*) value
)[1];
489 const GLubyte val2
= ((const GLubyte
*) value
)[2];
490 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
491 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
492 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
493 if (!mask
&& val0
== val1
&& val1
== val2
) {
495 memset(dst
, val0
, 3 * count
);
499 for (i
= 0; i
< count
; i
++) {
500 if (!mask
|| mask
[i
]) {
501 dst
[i
* 3 + 0] = val0
;
502 dst
[i
* 3 + 1] = val1
;
503 dst
[i
* 3 + 2] = val2
;
511 put_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
512 const GLint x
[], const GLint y
[], const void *values
,
515 /* note: incoming values are RGB+A! */
516 const GLubyte
*src
= (const GLubyte
*) values
;
518 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
519 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
520 for (i
= 0; i
< count
; i
++) {
521 if (!mask
|| mask
[i
]) {
522 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
523 dst
[0] = src
[i
* 4 + 0];
524 dst
[1] = src
[i
* 4 + 1];
525 dst
[2] = src
[i
* 4 + 2];
532 put_mono_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
533 GLuint count
, const GLint x
[], const GLint y
[],
534 const void *value
, const GLubyte
*mask
)
536 /* note: incoming value is RGB+A! */
537 const GLubyte val0
= ((const GLubyte
*) value
)[0];
538 const GLubyte val1
= ((const GLubyte
*) value
)[1];
539 const GLubyte val2
= ((const GLubyte
*) value
)[2];
541 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
542 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
543 for (i
= 0; i
< count
; i
++) {
544 if (!mask
|| mask
[i
]) {
545 GLubyte
*dst
= (GLubyte
*) (rb
->Data
+
546 3 * (y
[i
] * rb
->RowStride
+ x
[i
]));
555 /**********************************************************************
556 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
557 * Typically color buffers.
561 get_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
562 const GLint x
[], const GLint y
[], void *values
)
564 /* treat 4*GLubyte as 1*GLuint */
565 GLuint
*dst
= (GLuint
*) values
;
567 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
568 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
569 for (i
= 0; i
< count
; i
++) {
570 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
577 put_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
578 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
580 /* treat 4*GLubyte as 1*GLuint */
581 const GLuint
*src
= (const GLuint
*) values
;
582 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
583 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
584 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
587 for (i
= 0; i
< count
; i
++) {
594 memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
600 put_row_rgb_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
601 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
603 /* Store RGB values in RGBA buffer */
604 const GLubyte
*src
= (const GLubyte
*) values
;
605 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
607 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
608 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
609 for (i
= 0; i
< count
; i
++) {
610 if (!mask
|| mask
[i
]) {
611 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
612 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
613 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
614 dst
[i
* 4 + 3] = 0xff;
621 put_mono_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
622 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
624 /* treat 4*GLubyte as 1*GLuint */
625 const GLuint val
= *((const GLuint
*) value
);
626 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
627 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
628 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
629 if (!mask
&& val
== 0) {
631 memset(dst
, 0, count
* 4 * sizeof(GLubyte
));
637 for (i
= 0; i
< count
; i
++) {
645 for (i
= 0; i
< count
; i
++) {
654 put_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
655 const GLint x
[], const GLint y
[], const void *values
,
658 /* treat 4*GLubyte as 1*GLuint */
659 const GLuint
*src
= (const GLuint
*) values
;
661 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
662 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
663 for (i
= 0; i
< count
; i
++) {
664 if (!mask
|| mask
[i
]) {
665 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
673 put_mono_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
674 GLuint count
, const GLint x
[], const GLint y
[],
675 const void *value
, const GLubyte
*mask
)
677 /* treat 4*GLubyte as 1*GLuint */
678 const GLuint val
= *((const GLuint
*) value
);
680 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
681 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
682 for (i
= 0; i
< count
; i
++) {
683 if (!mask
|| mask
[i
]) {
684 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
691 /**********************************************************************
692 * Functions for buffers of 4 X GLushort (or GLshort) values.
693 * Typically accum buffer.
697 get_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
698 const GLint x
[], const GLint y
[], void *values
)
700 GLushort
*dst
= (GLushort
*) values
;
702 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
703 for (i
= 0; i
< count
; i
++) {
705 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
712 put_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
713 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
715 const GLushort
*src
= (const GLushort
*) values
;
716 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
717 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
720 for (i
= 0; i
< count
; i
++) {
722 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
723 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
724 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
725 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
730 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
736 put_row_rgb_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
737 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
739 /* Put RGB values in RGBA buffer */
740 const GLushort
*src
= (const GLushort
*) values
;
741 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
742 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
745 for (i
= 0; i
< count
; i
++) {
747 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
748 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
749 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
750 dst
[i
* 4 + 3] = 0xffff;
755 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
761 put_mono_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
762 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
764 const GLushort val0
= ((const GLushort
*) value
)[0];
765 const GLushort val1
= ((const GLushort
*) value
)[1];
766 const GLushort val2
= ((const GLushort
*) value
)[2];
767 const GLushort val3
= ((const GLushort
*) value
)[3];
768 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
769 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
770 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
771 /* common case for clearing accum buffer */
772 memset(dst
, 0, count
* 4 * sizeof(GLushort
));
776 for (i
= 0; i
< count
; i
++) {
777 if (!mask
|| mask
[i
]) {
778 dst
[i
* 4 + 0] = val0
;
779 dst
[i
* 4 + 1] = val1
;
780 dst
[i
* 4 + 2] = val2
;
781 dst
[i
* 4 + 3] = val3
;
789 put_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
790 const GLint x
[], const GLint y
[], const void *values
,
793 const GLushort
*src
= (const GLushort
*) values
;
795 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
796 for (i
= 0; i
< count
; i
++) {
797 if (!mask
|| mask
[i
]) {
798 GLushort
*dst
= (GLushort
*) (rb
->Data
+ 4 *
799 (y
[i
] * rb
->RowStride
+ x
[i
]));
800 dst
[0] = src
[i
* 4 + 0];
801 dst
[1] = src
[i
* 4 + 1];
802 dst
[2] = src
[i
* 4 + 2];
803 dst
[3] = src
[i
* 4 + 3];
810 put_mono_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
811 GLuint count
, const GLint x
[], const GLint y
[],
812 const void *value
, const GLubyte
*mask
)
814 const GLushort val0
= ((const GLushort
*) value
)[0];
815 const GLushort val1
= ((const GLushort
*) value
)[1];
816 const GLushort val2
= ((const GLushort
*) value
)[2];
817 const GLushort val3
= ((const GLushort
*) value
)[3];
819 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
820 for (i
= 0; i
< count
; i
++) {
821 if (!mask
|| mask
[i
]) {
822 GLushort
*dst
= (GLushort
*) (rb
->Data
+
823 4 * (y
[i
] * rb
->RowStride
+ x
[i
]));
833 * This is the default software fallback for gl_renderbuffer's span
836 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
837 * are packed in the type of rb->Format, and that subsequent rows appear
838 * rb->RowStride pixels later.
841 _mesa_set_renderbuffer_accessors(struct gl_renderbuffer
*rb
)
843 rb
->GetPointer
= get_pointer_generic
;
844 rb
->GetRow
= get_row_generic
;
846 switch (rb
->Format
) {
847 case MESA_FORMAT_RGB888
:
848 rb
->DataType
= GL_UNSIGNED_BYTE
;
849 rb
->GetPointer
= get_pointer_ubyte3
;
850 rb
->GetRow
= get_row_ubyte3
;
851 rb
->GetValues
= get_values_ubyte3
;
852 rb
->PutRow
= put_row_ubyte3
;
853 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
854 rb
->PutMonoRow
= put_mono_row_ubyte3
;
855 rb
->PutValues
= put_values_ubyte3
;
856 rb
->PutMonoValues
= put_mono_values_ubyte3
;
859 case MESA_FORMAT_RGBA8888
:
860 rb
->DataType
= GL_UNSIGNED_BYTE
;
861 rb
->GetValues
= get_values_ubyte4
;
862 rb
->PutRow
= put_row_ubyte4
;
863 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
864 rb
->PutMonoRow
= put_mono_row_ubyte4
;
865 rb
->PutValues
= put_values_ubyte4
;
866 rb
->PutMonoValues
= put_mono_values_ubyte4
;
869 case MESA_FORMAT_SIGNED_RGBA_16
:
870 rb
->DataType
= GL_SHORT
;
871 rb
->GetValues
= get_values_ushort4
;
872 rb
->PutRow
= put_row_ushort4
;
873 rb
->PutRowRGB
= put_row_rgb_ushort4
;
874 rb
->PutMonoRow
= put_mono_row_ushort4
;
875 rb
->PutValues
= put_values_ushort4
;
876 rb
->PutMonoValues
= put_mono_values_ushort4
;
881 rb
->DataType
= GL_UNSIGNED_BYTE
;
882 rb
->GetValues
= get_values_alpha8
;
883 rb
->PutRow
= put_row_alpha8
;
884 rb
->PutRowRGB
= NULL
;
885 rb
->PutMonoRow
= put_mono_row_alpha8
;
886 rb
->PutValues
= put_values_alpha8
;
887 rb
->PutMonoValues
= put_mono_values_alpha8
;
892 rb
->DataType
= GL_UNSIGNED_BYTE
;
893 rb
->GetValues
= get_values_ubyte
;
894 rb
->PutRow
= put_row_ubyte
;
895 rb
->PutRowRGB
= NULL
;
896 rb
->PutMonoRow
= put_mono_row_ubyte
;
897 rb
->PutValues
= put_values_ubyte
;
898 rb
->PutMonoValues
= put_mono_values_ubyte
;
901 case MESA_FORMAT_Z16
:
902 rb
->DataType
= GL_UNSIGNED_SHORT
;
903 rb
->GetValues
= get_values_ushort
;
904 rb
->PutRow
= put_row_ushort
;
905 rb
->PutRowRGB
= NULL
;
906 rb
->PutMonoRow
= put_mono_row_ushort
;
907 rb
->PutValues
= put_values_ushort
;
908 rb
->PutMonoValues
= put_mono_values_ushort
;
911 case MESA_FORMAT_Z32
:
912 case MESA_FORMAT_X8_Z24
:
913 case MESA_FORMAT_Z24_X8
:
914 rb
->DataType
= GL_UNSIGNED_INT
;
915 rb
->GetValues
= get_values_uint
;
916 rb
->PutRow
= put_row_uint
;
917 rb
->PutRowRGB
= NULL
;
918 rb
->PutMonoRow
= put_mono_row_uint
;
919 rb
->PutValues
= put_values_uint
;
920 rb
->PutMonoValues
= put_mono_values_uint
;
923 case MESA_FORMAT_Z24_S8
:
924 case MESA_FORMAT_S8_Z24
:
925 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
926 rb
->GetValues
= get_values_uint
;
927 rb
->PutRow
= put_row_uint
;
928 rb
->PutRowRGB
= NULL
;
929 rb
->PutMonoRow
= put_mono_row_uint
;
930 rb
->PutValues
= put_values_uint
;
931 rb
->PutMonoValues
= put_mono_values_uint
;
940 * This is a software fallback for the gl_renderbuffer->AllocStorage
942 * Device drivers will typically override this function for the buffers
943 * which it manages (typically color buffers, Z and stencil).
944 * Other buffers (like software accumulation and aux buffers) which the driver
945 * doesn't manage can be handled with this function.
947 * This one multi-purpose function can allocate stencil, depth, accum, color
948 * or color-index buffers!
950 * This function also plugs in the appropriate GetPointer, Get/PutRow and
951 * Get/PutValues functions.
954 _mesa_soft_renderbuffer_storage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
955 GLenum internalFormat
,
956 GLuint width
, GLuint height
)
958 switch (internalFormat
) {
967 rb
->Format
= MESA_FORMAT_RGB888
;
978 rb
->Format
= MESA_FORMAT_RGBA8888
;
981 case GL_RGBA16_SNORM
:
982 /* for accum buffer */
983 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
987 rb
->Format
= MESA_FORMAT_A8
;
990 case GL_STENCIL_INDEX
:
991 case GL_STENCIL_INDEX1_EXT
:
992 case GL_STENCIL_INDEX4_EXT
:
993 case GL_STENCIL_INDEX8_EXT
:
994 case GL_STENCIL_INDEX16_EXT
:
995 rb
->Format
= MESA_FORMAT_S8
;
997 case GL_DEPTH_COMPONENT
:
998 case GL_DEPTH_COMPONENT16
:
999 rb
->Format
= MESA_FORMAT_Z16
;
1001 case GL_DEPTH_COMPONENT24
:
1002 rb
->Format
= MESA_FORMAT_X8_Z24
;
1004 case GL_DEPTH_COMPONENT32
:
1005 rb
->Format
= MESA_FORMAT_Z32
;
1007 case GL_DEPTH_STENCIL_EXT
:
1008 case GL_DEPTH24_STENCIL8_EXT
:
1009 rb
->Format
= MESA_FORMAT_Z24_S8
;
1012 /* unsupported format */
1016 _mesa_set_renderbuffer_accessors(rb
);
1018 ASSERT(rb
->DataType
);
1019 ASSERT(rb
->GetPointer
);
1021 ASSERT(rb
->GetValues
);
1023 ASSERT(rb
->PutMonoRow
);
1024 ASSERT(rb
->PutValues
);
1025 ASSERT(rb
->PutMonoValues
);
1027 /* free old buffer storage */
1033 rb
->RowStride
= width
;
1035 if (width
> 0 && height
> 0) {
1036 /* allocate new buffer storage */
1037 rb
->Data
= malloc(width
* height
* _mesa_get_format_bytes(rb
->Format
));
1039 if (rb
->Data
== NULL
) {
1043 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1044 "software renderbuffer allocation (%d x %d x %d)",
1045 width
, height
, _mesa_get_format_bytes(rb
->Format
));
1051 rb
->Height
= height
;
1052 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
1054 if (rb
->Name
== 0 &&
1055 internalFormat
== GL_RGBA16_SNORM
&&
1056 rb
->_BaseFormat
== 0) {
1057 /* NOTE: This is a special case just for accumulation buffers.
1058 * This is a very limited use case- there's no snorm texturing or
1059 * rendering going on.
1061 rb
->_BaseFormat
= GL_RGBA
;
1064 /* the internalFormat should have been error checked long ago */
1065 ASSERT(rb
->_BaseFormat
);
1073 /**********************************************************************/
1074 /**********************************************************************/
1075 /**********************************************************************/
1079 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1080 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1082 * When PutRow is called (for example), we store the alpha values in
1083 * this buffer, then pass on the PutRow call to the wrapped RGB
1089 alloc_storage_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1090 GLenum internalFormat
, GLuint width
, GLuint height
)
1092 ASSERT(arb
!= arb
->Wrapped
);
1093 ASSERT(arb
->Format
== MESA_FORMAT_A8
);
1095 /* first, pass the call to the wrapped RGB buffer */
1096 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1101 /* next, resize my alpha buffer */
1106 arb
->Data
= malloc(width
* height
* sizeof(GLubyte
));
1107 if (arb
->Data
== NULL
) {
1110 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1115 arb
->Height
= height
;
1116 arb
->RowStride
= width
;
1123 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1126 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1131 ASSERT(arb
->Wrapped
);
1132 ASSERT(arb
!= arb
->Wrapped
);
1133 arb
->Wrapped
->Delete(arb
->Wrapped
);
1134 arb
->Wrapped
= NULL
;
1140 get_pointer_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1143 return NULL
; /* don't allow direct access! */
1148 get_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1149 GLint x
, GLint y
, void *values
)
1151 /* NOTE: 'values' is RGBA format! */
1152 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1153 GLubyte
*dst
= (GLubyte
*) values
;
1155 ASSERT(arb
!= arb
->Wrapped
);
1156 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1157 /* first, pass the call to the wrapped RGB buffer */
1158 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1159 /* second, fill in alpha values from this buffer! */
1160 for (i
= 0; i
< count
; i
++) {
1161 dst
[i
* 4 + 3] = src
[i
];
1167 get_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1168 const GLint x
[], const GLint y
[], void *values
)
1170 GLubyte
*dst
= (GLubyte
*) values
;
1172 ASSERT(arb
!= arb
->Wrapped
);
1173 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1174 /* first, pass the call to the wrapped RGB buffer */
1175 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1176 /* second, fill in alpha values from this buffer! */
1177 for (i
= 0; i
< count
; i
++) {
1178 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1179 dst
[i
* 4 + 3] = *src
;
1185 put_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1186 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1188 const GLubyte
*src
= (const GLubyte
*) values
;
1189 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1191 ASSERT(arb
!= arb
->Wrapped
);
1192 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1193 /* first, pass the call to the wrapped RGB buffer */
1194 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1195 /* second, store alpha in our buffer */
1196 for (i
= 0; i
< count
; i
++) {
1197 if (!mask
|| mask
[i
]) {
1198 dst
[i
] = src
[i
* 4 + 3];
1205 put_row_rgb_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1206 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1208 const GLubyte
*src
= (const GLubyte
*) values
;
1209 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1211 ASSERT(arb
!= arb
->Wrapped
);
1212 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1213 /* first, pass the call to the wrapped RGB buffer */
1214 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1215 /* second, store alpha in our buffer */
1216 for (i
= 0; i
< count
; i
++) {
1217 if (!mask
|| mask
[i
]) {
1218 dst
[i
] = src
[i
* 4 + 3];
1225 put_mono_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1226 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1228 const GLubyte val
= ((const GLubyte
*) value
)[3];
1229 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
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
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1234 /* second, store alpha in our buffer */
1237 for (i
= 0; i
< count
; i
++) {
1244 memset(dst
, val
, count
);
1250 put_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1251 const GLint x
[], const GLint y
[],
1252 const void *values
, const GLubyte
*mask
)
1254 const GLubyte
*src
= (const GLubyte
*) values
;
1256 ASSERT(arb
!= arb
->Wrapped
);
1257 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1258 /* first, pass the call to the wrapped RGB buffer */
1259 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1260 /* second, store alpha in our buffer */
1261 for (i
= 0; i
< count
; i
++) {
1262 if (!mask
|| mask
[i
]) {
1263 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1264 *dst
= src
[i
* 4 + 3];
1271 put_mono_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1272 GLuint count
, const GLint x
[], const GLint y
[],
1273 const void *value
, const GLubyte
*mask
)
1275 const GLubyte val
= ((const GLubyte
*) value
)[3];
1277 ASSERT(arb
!= arb
->Wrapped
);
1278 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1279 /* first, pass the call to the wrapped RGB buffer */
1280 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1281 /* second, store alpha in our buffer */
1282 for (i
= 0; i
< count
; i
++) {
1283 if (!mask
|| mask
[i
]) {
1284 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1292 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1294 ASSERT(dst
->Format
== MESA_FORMAT_A8
);
1295 ASSERT(src
->Format
== MESA_FORMAT_A8
);
1296 ASSERT(dst
->Width
== src
->Width
);
1297 ASSERT(dst
->Height
== src
->Height
);
1298 ASSERT(dst
->RowStride
== src
->RowStride
);
1300 memcpy(dst
->Data
, src
->Data
, dst
->RowStride
* dst
->Height
* sizeof(GLubyte
));
1304 /**********************************************************************/
1305 /**********************************************************************/
1306 /**********************************************************************/
1310 * Default GetPointer routine. Always return NULL to indicate that
1311 * direct buffer access is not supported.
1314 nop_get_pointer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1321 * Initialize the fields of a gl_renderbuffer to default values.
1324 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1326 _glthread_INIT_MUTEX(rb
->Mutex
);
1331 rb
->Delete
= _mesa_delete_renderbuffer
;
1333 /* The rest of these should be set later by the caller of this function or
1334 * the AllocStorage method:
1336 rb
->AllocStorage
= NULL
;
1340 rb
->InternalFormat
= GL_NONE
;
1341 rb
->Format
= MESA_FORMAT_NONE
;
1343 rb
->DataType
= GL_NONE
;
1346 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1347 * all over the drivers.
1351 rb
->GetPointer
= nop_get_pointer
;
1353 rb
->GetValues
= NULL
;
1355 rb
->PutRowRGB
= NULL
;
1356 rb
->PutMonoRow
= NULL
;
1357 rb
->PutValues
= NULL
;
1358 rb
->PutMonoValues
= NULL
;
1363 * Allocate a new gl_renderbuffer object. This can be used for user-created
1364 * renderbuffers or window-system renderbuffers.
1366 struct gl_renderbuffer
*
1367 _mesa_new_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1369 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1371 _mesa_init_renderbuffer(rb
, name
);
1378 * Delete a gl_framebuffer.
1379 * This is the default function for renderbuffer->Delete().
1382 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1392 * Allocate a software-based renderbuffer. This is called via the
1393 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1395 * This would not be used for hardware-based renderbuffers.
1397 struct gl_renderbuffer
*
1398 _mesa_new_soft_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1400 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1402 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1403 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1404 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1413 * Add software-based color renderbuffers to the given framebuffer.
1414 * This is a helper routine for device drivers when creating a
1415 * window system framebuffer (not a user-created render/framebuffer).
1416 * Once this function is called, you can basically forget about this
1417 * renderbuffer; core Mesa will handle all the buffer management and
1421 _mesa_add_color_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1422 GLuint rgbBits
, GLuint alphaBits
,
1423 GLboolean frontLeft
, GLboolean backLeft
,
1424 GLboolean frontRight
, GLboolean backRight
)
1428 if (rgbBits
> 16 || alphaBits
> 16) {
1430 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1434 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1436 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1437 struct gl_renderbuffer
*rb
;
1439 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1441 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1443 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1445 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1448 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1450 rb
= _mesa_new_renderbuffer(ctx
, 0);
1452 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1458 rb
->Format
= MESA_FORMAT_RGBA8888
;
1460 rb
->Format
= MESA_FORMAT_RGB888
;
1463 assert(rgbBits
<= 16);
1464 rb
->Format
= MESA_FORMAT_NONE
; /*XXX RGBA16;*/
1466 rb
->InternalFormat
= GL_RGBA
;
1468 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1469 _mesa_add_renderbuffer(fb
, b
, rb
);
1477 * Add software-based alpha renderbuffers to the given framebuffer.
1478 * This is a helper routine for device drivers when creating a
1479 * window system framebuffer (not a user-created render/framebuffer).
1480 * Once this function is called, you can basically forget about this
1481 * renderbuffer; core Mesa will handle all the buffer management and
1485 _mesa_add_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1487 GLboolean frontLeft
, GLboolean backLeft
,
1488 GLboolean frontRight
, GLboolean backRight
)
1492 /* for window system framebuffers only! */
1493 assert(fb
->Name
== 0);
1495 if (alphaBits
> 8) {
1497 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1501 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1503 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1505 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1506 struct gl_renderbuffer
*arb
;
1508 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1510 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1512 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1514 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1517 /* the RGB buffer to wrap must already exist!! */
1518 assert(fb
->Attachment
[b
].Renderbuffer
);
1520 /* only GLubyte supported for now */
1521 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1523 /* allocate alpha renderbuffer */
1524 arb
= _mesa_new_renderbuffer(ctx
, 0);
1526 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1530 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1531 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1533 /* Set up my alphabuffer fields and plug in my functions.
1534 * The functions will put/get the alpha values from/to RGBA arrays
1535 * and then call the wrapped buffer's functions to handle the RGB
1538 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1539 arb
->Format
= MESA_FORMAT_A8
;
1540 arb
->DataType
= arb
->Wrapped
->DataType
;
1541 arb
->AllocStorage
= alloc_storage_alpha8
;
1542 arb
->Delete
= delete_renderbuffer_alpha8
;
1543 arb
->GetPointer
= get_pointer_alpha8
;
1544 arb
->GetRow
= get_row_alpha8
;
1545 arb
->GetValues
= get_values_alpha8
;
1546 arb
->PutRow
= put_row_alpha8
;
1547 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1548 arb
->PutMonoRow
= put_mono_row_alpha8
;
1549 arb
->PutValues
= put_values_alpha8
;
1550 arb
->PutMonoValues
= put_mono_values_alpha8
;
1552 /* clear the pointer to avoid assertion/sanity check failure later */
1553 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1555 /* plug the alpha renderbuffer into the colorbuffer attachment */
1556 _mesa_add_renderbuffer(fb
, b
, arb
);
1564 * For framebuffers that use a software alpha channel wrapper
1565 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
1566 * copy the back buffer alpha channel into the front buffer alpha channel.
1569 _mesa_copy_soft_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
1571 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
1572 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
1573 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
1574 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
1577 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
1578 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
1579 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
1580 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
1585 * Add a software-based depth renderbuffer to the given framebuffer.
1586 * This is a helper routine for device drivers when creating a
1587 * window system framebuffer (not a user-created render/framebuffer).
1588 * Once this function is called, you can basically forget about this
1589 * renderbuffer; core Mesa will handle all the buffer management and
1593 _mesa_add_depth_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1596 struct gl_renderbuffer
*rb
;
1598 if (depthBits
> 32) {
1600 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1604 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1606 rb
= _mesa_new_renderbuffer(ctx
, 0);
1608 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1612 if (depthBits
<= 16) {
1613 rb
->Format
= MESA_FORMAT_Z16
;
1614 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1616 else if (depthBits
<= 24) {
1617 rb
->Format
= MESA_FORMAT_X8_Z24
;
1618 rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
1621 rb
->Format
= MESA_FORMAT_Z32
;
1622 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1625 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1626 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1633 * Add a software-based stencil renderbuffer to the given framebuffer.
1634 * This is a helper routine for device drivers when creating a
1635 * window system framebuffer (not a user-created render/framebuffer).
1636 * Once this function is called, you can basically forget about this
1637 * renderbuffer; core Mesa will handle all the buffer management and
1641 _mesa_add_stencil_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1644 struct gl_renderbuffer
*rb
;
1646 if (stencilBits
> 16) {
1648 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1652 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1654 rb
= _mesa_new_renderbuffer(ctx
, 0);
1656 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1660 assert(stencilBits
<= 8);
1661 rb
->Format
= MESA_FORMAT_S8
;
1662 rb
->InternalFormat
= GL_STENCIL_INDEX8
;
1664 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1665 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1672 * Add a software-based accumulation renderbuffer to the given framebuffer.
1673 * This is a helper routine for device drivers when creating a
1674 * window system framebuffer (not a user-created render/framebuffer).
1675 * Once this function is called, you can basically forget about this
1676 * renderbuffer; core Mesa will handle all the buffer management and
1680 _mesa_add_accum_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1681 GLuint redBits
, GLuint greenBits
,
1682 GLuint blueBits
, GLuint alphaBits
)
1684 struct gl_renderbuffer
*rb
;
1686 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1688 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1692 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1694 rb
= _mesa_new_renderbuffer(ctx
, 0);
1696 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1700 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
1701 rb
->InternalFormat
= GL_RGBA16_SNORM
;
1702 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1703 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1711 * Add a software-based aux renderbuffer to the given framebuffer.
1712 * This is a helper routine for device drivers when creating a
1713 * window system framebuffer (not a user-created render/framebuffer).
1714 * Once this function is called, you can basically forget about this
1715 * renderbuffer; core Mesa will handle all the buffer management and
1718 * NOTE: color-index aux buffers not supported.
1721 _mesa_add_aux_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1722 GLuint colorBits
, GLuint numBuffers
)
1726 if (colorBits
> 16) {
1728 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1732 assert(numBuffers
<= MAX_AUX_BUFFERS
);
1734 for (i
= 0; i
< numBuffers
; i
++) {
1735 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1737 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1740 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating aux buffer");
1744 assert (colorBits
<= 8);
1745 rb
->Format
= MESA_FORMAT_RGBA8888
;
1746 rb
->InternalFormat
= GL_RGBA
;
1748 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1749 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1756 * Create/attach software-based renderbuffers to the given framebuffer.
1757 * This is a helper routine for device drivers. Drivers can just as well
1758 * call the individual _mesa_add_*_renderbuffer() routines directly.
1761 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1769 GLboolean frontLeft
= GL_TRUE
;
1770 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1771 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1772 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1775 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1776 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1777 _mesa_add_color_renderbuffers(NULL
, fb
,
1779 fb
->Visual
.alphaBits
,
1780 frontLeft
, backLeft
,
1781 frontRight
, backRight
);
1785 assert(fb
->Visual
.depthBits
> 0);
1786 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1790 assert(fb
->Visual
.stencilBits
> 0);
1791 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1795 assert(fb
->Visual
.accumRedBits
> 0);
1796 assert(fb
->Visual
.accumGreenBits
> 0);
1797 assert(fb
->Visual
.accumBlueBits
> 0);
1798 _mesa_add_accum_renderbuffer(NULL
, fb
,
1799 fb
->Visual
.accumRedBits
,
1800 fb
->Visual
.accumGreenBits
,
1801 fb
->Visual
.accumBlueBits
,
1802 fb
->Visual
.accumAlphaBits
);
1806 assert(fb
->Visual
.numAuxBuffers
> 0);
1807 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
1808 fb
->Visual
.numAuxBuffers
);
1812 assert(fb
->Visual
.alphaBits
> 0);
1813 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
1814 frontLeft
, backLeft
,
1815 frontRight
, backRight
);
1827 * Attach a renderbuffer to a framebuffer.
1828 * \param bufferName one of the BUFFER_x tokens
1831 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
1832 gl_buffer_index bufferName
, struct gl_renderbuffer
*rb
)
1836 assert(bufferName
< BUFFER_COUNT
);
1838 /* There should be no previous renderbuffer on this attachment point,
1839 * with the exception of depth/stencil since the same renderbuffer may
1842 assert(bufferName
== BUFFER_DEPTH
||
1843 bufferName
== BUFFER_STENCIL
||
1844 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
1846 /* winsys vs. user-created buffer cross check */
1854 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
1855 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
1856 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
1861 * Remove the named renderbuffer from the given framebuffer.
1862 * \param bufferName one of the BUFFER_x tokens
1865 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
,
1866 gl_buffer_index bufferName
)
1868 struct gl_renderbuffer
*rb
;
1870 assert(bufferName
< BUFFER_COUNT
);
1872 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
1876 _mesa_reference_renderbuffer(&rb
, NULL
);
1878 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
1883 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
1884 * dereference that buffer first. The new renderbuffer's refcount will
1885 * be incremented. The old renderbuffer's refcount will be decremented.
1888 _mesa_reference_renderbuffer(struct gl_renderbuffer
**ptr
,
1889 struct gl_renderbuffer
*rb
)
1898 /* Unreference the old renderbuffer */
1899 GLboolean deleteFlag
= GL_FALSE
;
1900 struct gl_renderbuffer
*oldRb
= *ptr
;
1902 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
1903 ASSERT(oldRb
->RefCount
> 0);
1905 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
1906 deleteFlag
= (oldRb
->RefCount
== 0);
1907 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
1910 oldRb
->Delete(oldRb
);
1918 /* reference new renderbuffer */
1919 _glthread_LOCK_MUTEX(rb
->Mutex
);
1921 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
1922 _glthread_UNLOCK_MUTEX(rb
->Mutex
);
1929 * Create a new combined depth/stencil renderbuffer for implementing
1930 * the GL_EXT_packed_depth_stencil extension.
1931 * \return new depth/stencil renderbuffer
1933 struct gl_renderbuffer
*
1934 _mesa_new_depthstencil_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1936 struct gl_renderbuffer
*dsrb
;
1938 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
1942 /* init fields not covered by _mesa_new_renderbuffer() */
1943 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
1944 dsrb
->Format
= MESA_FORMAT_Z24_S8
;
1945 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;