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 /**********************************************************************
68 * Functions for buffers of 1 X GLubyte values.
73 get_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
74 GLint x
, GLint y
, void *values
)
76 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
77 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
78 memcpy(values
, src
, count
* sizeof(GLubyte
));
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_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
182 GLint x
, GLint y
, void *values
)
184 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
185 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
186 memcpy(values
, src
, count
* sizeof(GLushort
));
191 get_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
192 const GLint x
[], const GLint y
[], void *values
)
194 GLushort
*dst
= (GLushort
*) values
;
196 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
197 for (i
= 0; i
< count
; i
++) {
198 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
205 put_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
206 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
208 const GLushort
*src
= (const GLushort
*) values
;
209 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
210 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
213 for (i
= 0; i
< count
; i
++) {
220 memcpy(dst
, src
, count
* sizeof(GLushort
));
226 put_mono_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
227 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
229 const GLushort val
= *((const GLushort
*) value
);
230 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
231 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
234 for (i
= 0; i
< count
; i
++) {
242 for (i
= 0; i
< count
; i
++) {
250 put_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
251 const GLint x
[], const GLint y
[], const void *values
,
254 const GLushort
*src
= (const GLushort
*) values
;
256 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
257 for (i
= 0; i
< count
; i
++) {
258 if (!mask
|| mask
[i
]) {
259 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
267 put_mono_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
268 GLuint count
, const GLint x
[], const GLint y
[],
269 const void *value
, const GLubyte
*mask
)
271 const GLushort val
= *((const GLushort
*) value
);
272 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
275 for (i
= 0; i
< count
; i
++) {
277 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
284 for (i
= 0; i
< count
; i
++) {
285 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
292 /**********************************************************************
293 * Functions for buffers of 1 X GLuint values.
294 * Typically depth/Z or color index.
298 get_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
299 GLint x
, GLint y
, void *values
)
301 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
302 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
303 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
304 memcpy(values
, src
, count
* sizeof(GLuint
));
309 get_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
310 const GLint x
[], const GLint y
[], void *values
)
312 GLuint
*dst
= (GLuint
*) values
;
314 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
315 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
316 for (i
= 0; i
< count
; i
++) {
317 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
324 put_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
325 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
327 const GLuint
*src
= (const GLuint
*) values
;
328 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
329 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
330 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
333 for (i
= 0; i
< count
; i
++) {
340 memcpy(dst
, src
, count
* sizeof(GLuint
));
346 put_mono_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
347 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
349 const GLuint val
= *((const GLuint
*) value
);
350 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
351 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
352 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
355 for (i
= 0; i
< count
; i
++) {
363 for (i
= 0; i
< count
; i
++) {
371 put_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
372 const GLint x
[], const GLint y
[], const void *values
,
375 const GLuint
*src
= (const GLuint
*) values
;
377 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
378 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
379 for (i
= 0; i
< count
; i
++) {
380 if (!mask
|| mask
[i
]) {
381 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
389 put_mono_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
390 const GLint x
[], const GLint y
[], const void *value
,
393 const GLuint val
= *((const GLuint
*) value
);
395 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
396 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
397 for (i
= 0; i
< count
; i
++) {
398 if (!mask
|| mask
[i
]) {
399 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
406 /**********************************************************************
407 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
408 * Typically color buffers.
409 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
410 * alpha values and return 255 for outgoing alpha values.
414 get_pointer_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
417 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
418 /* No direct access since this buffer is RGB but caller will be
419 * treating it as if it were RGBA.
426 get_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
427 GLint x
, GLint y
, void *values
)
429 const GLubyte
*src
= (const GLubyte
*) (rb
->Data
+
430 3 * (y
* rb
->RowStride
+ x
));
431 GLubyte
*dst
= (GLubyte
*) values
;
433 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
434 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
435 for (i
= 0; i
< count
; i
++) {
436 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
437 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
438 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
439 dst
[i
* 4 + 3] = 255;
445 get_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
446 const GLint x
[], const GLint y
[], void *values
)
448 GLubyte
*dst
= (GLubyte
*) values
;
450 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
451 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
452 for (i
= 0; i
< count
; i
++) {
454 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
455 dst
[i
* 4 + 0] = src
[0];
456 dst
[i
* 4 + 1] = src
[1];
457 dst
[i
* 4 + 2] = src
[2];
458 dst
[i
* 4 + 3] = 255;
464 put_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
465 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
467 /* note: incoming values are RGB+A! */
468 const GLubyte
*src
= (const GLubyte
*) values
;
469 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
471 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
472 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
473 for (i
= 0; i
< count
; i
++) {
474 if (!mask
|| mask
[i
]) {
475 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
476 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
477 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
484 put_row_rgb_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
485 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
487 /* note: incoming values are RGB+A! */
488 const GLubyte
*src
= (const GLubyte
*) values
;
489 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 for (i
= 0; i
< count
; i
++) {
494 if (!mask
|| mask
[i
]) {
495 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
496 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
497 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
504 put_mono_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
505 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
507 /* note: incoming value is RGB+A! */
508 const GLubyte val0
= ((const GLubyte
*) value
)[0];
509 const GLubyte val1
= ((const GLubyte
*) value
)[1];
510 const GLubyte val2
= ((const GLubyte
*) value
)[2];
511 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
512 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
513 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
514 if (!mask
&& val0
== val1
&& val1
== val2
) {
516 memset(dst
, val0
, 3 * count
);
520 for (i
= 0; i
< count
; i
++) {
521 if (!mask
|| mask
[i
]) {
522 dst
[i
* 3 + 0] = val0
;
523 dst
[i
* 3 + 1] = val1
;
524 dst
[i
* 3 + 2] = val2
;
532 put_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
533 const GLint x
[], const GLint y
[], const void *values
,
536 /* note: incoming values are RGB+A! */
537 const GLubyte
*src
= (const GLubyte
*) values
;
539 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
540 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
541 for (i
= 0; i
< count
; i
++) {
542 if (!mask
|| mask
[i
]) {
543 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
544 dst
[0] = src
[i
* 4 + 0];
545 dst
[1] = src
[i
* 4 + 1];
546 dst
[2] = src
[i
* 4 + 2];
553 put_mono_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
554 GLuint count
, const GLint x
[], const GLint y
[],
555 const void *value
, const GLubyte
*mask
)
557 /* note: incoming value is RGB+A! */
558 const GLubyte val0
= ((const GLubyte
*) value
)[0];
559 const GLubyte val1
= ((const GLubyte
*) value
)[1];
560 const GLubyte val2
= ((const GLubyte
*) value
)[2];
562 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
563 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
564 for (i
= 0; i
< count
; i
++) {
565 if (!mask
|| mask
[i
]) {
566 GLubyte
*dst
= (GLubyte
*) (rb
->Data
+
567 3 * (y
[i
] * rb
->RowStride
+ x
[i
]));
576 /**********************************************************************
577 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
578 * Typically color buffers.
582 get_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
583 GLint x
, GLint y
, void *values
)
585 const GLubyte
*src
= (const GLubyte
*) (rb
->Data
+
586 4 * (y
* rb
->RowStride
+ x
));
587 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
588 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
589 memcpy(values
, src
, 4 * count
* sizeof(GLubyte
));
594 get_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
595 const GLint x
[], const GLint y
[], void *values
)
597 /* treat 4*GLubyte as 1*GLuint */
598 GLuint
*dst
= (GLuint
*) values
;
600 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
601 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
602 for (i
= 0; i
< count
; i
++) {
603 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
610 put_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
611 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
613 /* treat 4*GLubyte as 1*GLuint */
614 const GLuint
*src
= (const GLuint
*) values
;
615 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
616 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
617 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
620 for (i
= 0; i
< count
; i
++) {
627 memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
633 put_row_rgb_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
634 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
636 /* Store RGB values in RGBA buffer */
637 const GLubyte
*src
= (const GLubyte
*) values
;
638 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
640 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
641 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
642 for (i
= 0; i
< count
; i
++) {
643 if (!mask
|| mask
[i
]) {
644 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
645 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
646 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
647 dst
[i
* 4 + 3] = 0xff;
654 put_mono_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
655 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
657 /* treat 4*GLubyte as 1*GLuint */
658 const GLuint val
= *((const GLuint
*) value
);
659 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
660 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
661 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
662 if (!mask
&& val
== 0) {
664 memset(dst
, 0, count
* 4 * sizeof(GLubyte
));
670 for (i
= 0; i
< count
; i
++) {
678 for (i
= 0; i
< count
; i
++) {
687 put_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
688 const GLint x
[], const GLint y
[], const void *values
,
691 /* treat 4*GLubyte as 1*GLuint */
692 const GLuint
*src
= (const GLuint
*) values
;
694 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
695 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
696 for (i
= 0; i
< count
; i
++) {
697 if (!mask
|| mask
[i
]) {
698 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
706 put_mono_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
707 GLuint count
, const GLint x
[], const GLint y
[],
708 const void *value
, const GLubyte
*mask
)
710 /* treat 4*GLubyte as 1*GLuint */
711 const GLuint val
= *((const GLuint
*) value
);
713 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
714 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
715 for (i
= 0; i
< count
; i
++) {
716 if (!mask
|| mask
[i
]) {
717 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
724 /**********************************************************************
725 * Functions for buffers of 4 X GLushort (or GLshort) values.
726 * Typically accum buffer.
730 get_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
731 GLint x
, GLint y
, void *values
)
733 const GLshort
*src
= (const GLshort
*) (rb
->Data
+
734 4 * (y
* rb
->RowStride
+ x
));
735 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
736 memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
741 get_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
742 const GLint x
[], const GLint y
[], void *values
)
744 GLushort
*dst
= (GLushort
*) values
;
746 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
747 for (i
= 0; i
< count
; i
++) {
749 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
756 put_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
757 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
759 const GLushort
*src
= (const GLushort
*) values
;
760 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
761 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
764 for (i
= 0; i
< count
; i
++) {
766 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
767 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
768 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
769 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
774 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
780 put_row_rgb_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
781 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
783 /* Put RGB values in RGBA buffer */
784 const GLushort
*src
= (const GLushort
*) values
;
785 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
786 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
789 for (i
= 0; i
< count
; i
++) {
791 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
792 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
793 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
794 dst
[i
* 4 + 3] = 0xffff;
799 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
805 put_mono_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
806 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
808 const GLushort val0
= ((const GLushort
*) value
)[0];
809 const GLushort val1
= ((const GLushort
*) value
)[1];
810 const GLushort val2
= ((const GLushort
*) value
)[2];
811 const GLushort val3
= ((const GLushort
*) value
)[3];
812 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
813 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
814 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
815 /* common case for clearing accum buffer */
816 memset(dst
, 0, count
* 4 * sizeof(GLushort
));
820 for (i
= 0; i
< count
; i
++) {
821 if (!mask
|| mask
[i
]) {
822 dst
[i
* 4 + 0] = val0
;
823 dst
[i
* 4 + 1] = val1
;
824 dst
[i
* 4 + 2] = val2
;
825 dst
[i
* 4 + 3] = val3
;
833 put_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
834 const GLint x
[], const GLint y
[], const void *values
,
837 const GLushort
*src
= (const GLushort
*) values
;
839 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
840 for (i
= 0; i
< count
; i
++) {
841 if (!mask
|| mask
[i
]) {
842 GLushort
*dst
= (GLushort
*) (rb
->Data
+ 4 *
843 (y
[i
] * rb
->RowStride
+ x
[i
]));
844 dst
[0] = src
[i
* 4 + 0];
845 dst
[1] = src
[i
* 4 + 1];
846 dst
[2] = src
[i
* 4 + 2];
847 dst
[3] = src
[i
* 4 + 3];
854 put_mono_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
855 GLuint count
, const GLint x
[], const GLint y
[],
856 const void *value
, const GLubyte
*mask
)
858 const GLushort val0
= ((const GLushort
*) value
)[0];
859 const GLushort val1
= ((const GLushort
*) value
)[1];
860 const GLushort val2
= ((const GLushort
*) value
)[2];
861 const GLushort val3
= ((const GLushort
*) value
)[3];
863 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
864 for (i
= 0; i
< count
; i
++) {
865 if (!mask
|| mask
[i
]) {
866 GLushort
*dst
= (GLushort
*) (rb
->Data
+
867 4 * (y
[i
] * rb
->RowStride
+ x
[i
]));
877 * This is the default software fallback for gl_renderbuffer's span
880 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
881 * are packed in the type of rb->Format, and that subsequent rows appear
882 * rb->RowStride pixels later.
885 _mesa_set_renderbuffer_accessors(struct gl_renderbuffer
*rb
)
887 rb
->GetPointer
= get_pointer_generic
;
889 switch (rb
->Format
) {
890 case MESA_FORMAT_RGB888
:
891 rb
->DataType
= GL_UNSIGNED_BYTE
;
892 rb
->GetPointer
= get_pointer_ubyte3
;
893 rb
->GetRow
= get_row_ubyte3
;
894 rb
->GetValues
= get_values_ubyte3
;
895 rb
->PutRow
= put_row_ubyte3
;
896 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
897 rb
->PutMonoRow
= put_mono_row_ubyte3
;
898 rb
->PutValues
= put_values_ubyte3
;
899 rb
->PutMonoValues
= put_mono_values_ubyte3
;
902 case MESA_FORMAT_RGBA8888
:
903 rb
->DataType
= GL_UNSIGNED_BYTE
;
904 rb
->GetRow
= get_row_ubyte4
;
905 rb
->GetValues
= get_values_ubyte4
;
906 rb
->PutRow
= put_row_ubyte4
;
907 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
908 rb
->PutMonoRow
= put_mono_row_ubyte4
;
909 rb
->PutValues
= put_values_ubyte4
;
910 rb
->PutMonoValues
= put_mono_values_ubyte4
;
913 case MESA_FORMAT_SIGNED_RGBA_16
:
914 rb
->DataType
= GL_SHORT
;
915 rb
->GetRow
= get_row_ushort4
;
916 rb
->GetValues
= get_values_ushort4
;
917 rb
->PutRow
= put_row_ushort4
;
918 rb
->PutRowRGB
= put_row_rgb_ushort4
;
919 rb
->PutMonoRow
= put_mono_row_ushort4
;
920 rb
->PutValues
= put_values_ushort4
;
921 rb
->PutMonoValues
= put_mono_values_ushort4
;
926 rb
->DataType
= GL_UNSIGNED_BYTE
;
927 rb
->GetRow
= get_row_alpha8
;
928 rb
->GetValues
= get_values_alpha8
;
929 rb
->PutRow
= put_row_alpha8
;
930 rb
->PutRowRGB
= NULL
;
931 rb
->PutMonoRow
= put_mono_row_alpha8
;
932 rb
->PutValues
= put_values_alpha8
;
933 rb
->PutMonoValues
= put_mono_values_alpha8
;
938 rb
->DataType
= GL_UNSIGNED_BYTE
;
939 rb
->GetRow
= get_row_ubyte
;
940 rb
->GetValues
= get_values_ubyte
;
941 rb
->PutRow
= put_row_ubyte
;
942 rb
->PutRowRGB
= NULL
;
943 rb
->PutMonoRow
= put_mono_row_ubyte
;
944 rb
->PutValues
= put_values_ubyte
;
945 rb
->PutMonoValues
= put_mono_values_ubyte
;
948 case MESA_FORMAT_Z16
:
949 rb
->DataType
= GL_UNSIGNED_SHORT
;
950 rb
->GetRow
= get_row_ushort
;
951 rb
->GetValues
= get_values_ushort
;
952 rb
->PutRow
= put_row_ushort
;
953 rb
->PutRowRGB
= NULL
;
954 rb
->PutMonoRow
= put_mono_row_ushort
;
955 rb
->PutValues
= put_values_ushort
;
956 rb
->PutMonoValues
= put_mono_values_ushort
;
959 case MESA_FORMAT_Z32
:
960 case MESA_FORMAT_X8_Z24
:
961 case MESA_FORMAT_Z24_X8
:
962 rb
->DataType
= GL_UNSIGNED_INT
;
963 rb
->GetRow
= get_row_uint
;
964 rb
->GetValues
= get_values_uint
;
965 rb
->PutRow
= put_row_uint
;
966 rb
->PutRowRGB
= NULL
;
967 rb
->PutMonoRow
= put_mono_row_uint
;
968 rb
->PutValues
= put_values_uint
;
969 rb
->PutMonoValues
= put_mono_values_uint
;
972 case MESA_FORMAT_Z24_S8
:
973 case MESA_FORMAT_S8_Z24
:
974 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
975 rb
->GetRow
= get_row_uint
;
976 rb
->GetValues
= get_values_uint
;
977 rb
->PutRow
= put_row_uint
;
978 rb
->PutRowRGB
= NULL
;
979 rb
->PutMonoRow
= put_mono_row_uint
;
980 rb
->PutValues
= put_values_uint
;
981 rb
->PutMonoValues
= put_mono_values_uint
;
990 * This is a software fallback for the gl_renderbuffer->AllocStorage
992 * Device drivers will typically override this function for the buffers
993 * which it manages (typically color buffers, Z and stencil).
994 * Other buffers (like software accumulation and aux buffers) which the driver
995 * doesn't manage can be handled with this function.
997 * This one multi-purpose function can allocate stencil, depth, accum, color
998 * or color-index buffers!
1000 * This function also plugs in the appropriate GetPointer, Get/PutRow and
1001 * Get/PutValues functions.
1004 _mesa_soft_renderbuffer_storage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1005 GLenum internalFormat
,
1006 GLuint width
, GLuint height
)
1008 switch (internalFormat
) {
1017 rb
->Format
= MESA_FORMAT_RGB888
;
1028 rb
->Format
= MESA_FORMAT_RGBA8888
;
1031 case GL_RGBA16_SNORM
:
1032 /* for accum buffer */
1033 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
1037 rb
->Format
= MESA_FORMAT_A8
;
1040 case GL_STENCIL_INDEX
:
1041 case GL_STENCIL_INDEX1_EXT
:
1042 case GL_STENCIL_INDEX4_EXT
:
1043 case GL_STENCIL_INDEX8_EXT
:
1044 case GL_STENCIL_INDEX16_EXT
:
1045 rb
->Format
= MESA_FORMAT_S8
;
1047 case GL_DEPTH_COMPONENT
:
1048 case GL_DEPTH_COMPONENT16
:
1049 rb
->Format
= MESA_FORMAT_Z16
;
1051 case GL_DEPTH_COMPONENT24
:
1052 rb
->Format
= MESA_FORMAT_X8_Z24
;
1054 case GL_DEPTH_COMPONENT32
:
1055 rb
->Format
= MESA_FORMAT_Z32
;
1057 case GL_DEPTH_STENCIL_EXT
:
1058 case GL_DEPTH24_STENCIL8_EXT
:
1059 rb
->Format
= MESA_FORMAT_Z24_S8
;
1062 /* unsupported format */
1066 _mesa_set_renderbuffer_accessors(rb
);
1068 ASSERT(rb
->DataType
);
1069 ASSERT(rb
->GetPointer
);
1071 ASSERT(rb
->GetValues
);
1073 ASSERT(rb
->PutMonoRow
);
1074 ASSERT(rb
->PutValues
);
1075 ASSERT(rb
->PutMonoValues
);
1077 /* free old buffer storage */
1083 rb
->RowStride
= width
;
1085 if (width
> 0 && height
> 0) {
1086 /* allocate new buffer storage */
1087 rb
->Data
= malloc(width
* height
* _mesa_get_format_bytes(rb
->Format
));
1089 if (rb
->Data
== NULL
) {
1093 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1094 "software renderbuffer allocation (%d x %d x %d)",
1095 width
, height
, _mesa_get_format_bytes(rb
->Format
));
1101 rb
->Height
= height
;
1102 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
1104 if (rb
->Name
== 0 &&
1105 internalFormat
== GL_RGBA16_SNORM
&&
1106 rb
->_BaseFormat
== 0) {
1107 /* NOTE: This is a special case just for accumulation buffers.
1108 * This is a very limited use case- there's no snorm texturing or
1109 * rendering going on.
1111 rb
->_BaseFormat
= GL_RGBA
;
1114 /* the internalFormat should have been error checked long ago */
1115 ASSERT(rb
->_BaseFormat
);
1123 /**********************************************************************/
1124 /**********************************************************************/
1125 /**********************************************************************/
1129 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1130 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1132 * When PutRow is called (for example), we store the alpha values in
1133 * this buffer, then pass on the PutRow call to the wrapped RGB
1139 alloc_storage_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1140 GLenum internalFormat
, GLuint width
, GLuint height
)
1142 ASSERT(arb
!= arb
->Wrapped
);
1143 ASSERT(arb
->Format
== MESA_FORMAT_A8
);
1145 /* first, pass the call to the wrapped RGB buffer */
1146 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1151 /* next, resize my alpha buffer */
1156 arb
->Data
= malloc(width
* height
* sizeof(GLubyte
));
1157 if (arb
->Data
== NULL
) {
1160 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1165 arb
->Height
= height
;
1166 arb
->RowStride
= width
;
1173 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1176 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1181 ASSERT(arb
->Wrapped
);
1182 ASSERT(arb
!= arb
->Wrapped
);
1183 arb
->Wrapped
->Delete(arb
->Wrapped
);
1184 arb
->Wrapped
= NULL
;
1190 get_pointer_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1193 return NULL
; /* don't allow direct access! */
1198 get_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1199 GLint x
, GLint y
, void *values
)
1201 /* NOTE: 'values' is RGBA format! */
1202 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1203 GLubyte
*dst
= (GLubyte
*) values
;
1205 ASSERT(arb
!= arb
->Wrapped
);
1206 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1207 /* first, pass the call to the wrapped RGB buffer */
1208 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1209 /* second, fill in alpha values from this buffer! */
1210 for (i
= 0; i
< count
; i
++) {
1211 dst
[i
* 4 + 3] = src
[i
];
1217 get_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1218 const GLint x
[], const GLint y
[], void *values
)
1220 GLubyte
*dst
= (GLubyte
*) values
;
1222 ASSERT(arb
!= arb
->Wrapped
);
1223 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1224 /* first, pass the call to the wrapped RGB buffer */
1225 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1226 /* second, fill in alpha values from this buffer! */
1227 for (i
= 0; i
< count
; i
++) {
1228 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1229 dst
[i
* 4 + 3] = *src
;
1235 put_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1236 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1238 const GLubyte
*src
= (const GLubyte
*) values
;
1239 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1241 ASSERT(arb
!= arb
->Wrapped
);
1242 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1243 /* first, pass the call to the wrapped RGB buffer */
1244 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1245 /* second, store alpha in our buffer */
1246 for (i
= 0; i
< count
; i
++) {
1247 if (!mask
|| mask
[i
]) {
1248 dst
[i
] = src
[i
* 4 + 3];
1255 put_row_rgb_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1256 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1258 const GLubyte
*src
= (const GLubyte
*) values
;
1259 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1261 ASSERT(arb
!= arb
->Wrapped
);
1262 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1263 /* first, pass the call to the wrapped RGB buffer */
1264 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1265 /* second, store alpha in our buffer */
1266 for (i
= 0; i
< count
; i
++) {
1267 if (!mask
|| mask
[i
]) {
1268 dst
[i
] = src
[i
* 4 + 3];
1275 put_mono_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1276 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1278 const GLubyte val
= ((const GLubyte
*) value
)[3];
1279 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1280 ASSERT(arb
!= arb
->Wrapped
);
1281 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1282 /* first, pass the call to the wrapped RGB buffer */
1283 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1284 /* second, store alpha in our buffer */
1287 for (i
= 0; i
< count
; i
++) {
1294 memset(dst
, val
, count
);
1300 put_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1301 const GLint x
[], const GLint y
[],
1302 const void *values
, const GLubyte
*mask
)
1304 const GLubyte
*src
= (const GLubyte
*) values
;
1306 ASSERT(arb
!= arb
->Wrapped
);
1307 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1308 /* first, pass the call to the wrapped RGB buffer */
1309 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1310 /* second, store alpha in our buffer */
1311 for (i
= 0; i
< count
; i
++) {
1312 if (!mask
|| mask
[i
]) {
1313 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1314 *dst
= src
[i
* 4 + 3];
1321 put_mono_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1322 GLuint count
, const GLint x
[], const GLint y
[],
1323 const void *value
, const GLubyte
*mask
)
1325 const GLubyte val
= ((const GLubyte
*) value
)[3];
1327 ASSERT(arb
!= arb
->Wrapped
);
1328 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1329 /* first, pass the call to the wrapped RGB buffer */
1330 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1331 /* second, store alpha in our buffer */
1332 for (i
= 0; i
< count
; i
++) {
1333 if (!mask
|| mask
[i
]) {
1334 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1342 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1344 ASSERT(dst
->Format
== MESA_FORMAT_A8
);
1345 ASSERT(src
->Format
== MESA_FORMAT_A8
);
1346 ASSERT(dst
->Width
== src
->Width
);
1347 ASSERT(dst
->Height
== src
->Height
);
1348 ASSERT(dst
->RowStride
== src
->RowStride
);
1350 memcpy(dst
->Data
, src
->Data
, dst
->RowStride
* dst
->Height
* sizeof(GLubyte
));
1354 /**********************************************************************/
1355 /**********************************************************************/
1356 /**********************************************************************/
1360 * Default GetPointer routine. Always return NULL to indicate that
1361 * direct buffer access is not supported.
1364 nop_get_pointer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1371 * Initialize the fields of a gl_renderbuffer to default values.
1374 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1376 _glthread_INIT_MUTEX(rb
->Mutex
);
1381 rb
->Delete
= _mesa_delete_renderbuffer
;
1383 /* The rest of these should be set later by the caller of this function or
1384 * the AllocStorage method:
1386 rb
->AllocStorage
= NULL
;
1390 rb
->InternalFormat
= GL_NONE
;
1391 rb
->Format
= MESA_FORMAT_NONE
;
1393 rb
->DataType
= GL_NONE
;
1396 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1397 * all over the drivers.
1401 rb
->GetPointer
= nop_get_pointer
;
1403 rb
->GetValues
= NULL
;
1405 rb
->PutRowRGB
= NULL
;
1406 rb
->PutMonoRow
= NULL
;
1407 rb
->PutValues
= NULL
;
1408 rb
->PutMonoValues
= NULL
;
1413 * Allocate a new gl_renderbuffer object. This can be used for user-created
1414 * renderbuffers or window-system renderbuffers.
1416 struct gl_renderbuffer
*
1417 _mesa_new_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1419 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1421 _mesa_init_renderbuffer(rb
, name
);
1428 * Delete a gl_framebuffer.
1429 * This is the default function for renderbuffer->Delete().
1432 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1442 * Allocate a software-based renderbuffer. This is called via the
1443 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1445 * This would not be used for hardware-based renderbuffers.
1447 struct gl_renderbuffer
*
1448 _mesa_new_soft_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1450 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1452 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1453 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1454 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1463 * Add software-based color renderbuffers to the given framebuffer.
1464 * This is a helper routine for device drivers when creating a
1465 * window system framebuffer (not a user-created render/framebuffer).
1466 * Once this function is called, you can basically forget about this
1467 * renderbuffer; core Mesa will handle all the buffer management and
1471 _mesa_add_color_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1472 GLuint rgbBits
, GLuint alphaBits
,
1473 GLboolean frontLeft
, GLboolean backLeft
,
1474 GLboolean frontRight
, GLboolean backRight
)
1478 if (rgbBits
> 16 || alphaBits
> 16) {
1480 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1484 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1486 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1487 struct gl_renderbuffer
*rb
;
1489 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1491 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1493 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1495 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1498 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1500 rb
= _mesa_new_renderbuffer(ctx
, 0);
1502 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1508 rb
->Format
= MESA_FORMAT_RGBA8888
;
1510 rb
->Format
= MESA_FORMAT_RGB888
;
1513 assert(rgbBits
<= 16);
1514 rb
->Format
= MESA_FORMAT_NONE
; /*XXX RGBA16;*/
1516 rb
->InternalFormat
= GL_RGBA
;
1518 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1519 _mesa_add_renderbuffer(fb
, b
, rb
);
1527 * Add software-based alpha renderbuffers to the given framebuffer.
1528 * This is a helper routine for device drivers when creating a
1529 * window system framebuffer (not a user-created render/framebuffer).
1530 * Once this function is called, you can basically forget about this
1531 * renderbuffer; core Mesa will handle all the buffer management and
1535 _mesa_add_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1537 GLboolean frontLeft
, GLboolean backLeft
,
1538 GLboolean frontRight
, GLboolean backRight
)
1542 /* for window system framebuffers only! */
1543 assert(fb
->Name
== 0);
1545 if (alphaBits
> 8) {
1547 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1551 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1553 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1555 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1556 struct gl_renderbuffer
*arb
;
1558 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1560 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1562 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1564 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1567 /* the RGB buffer to wrap must already exist!! */
1568 assert(fb
->Attachment
[b
].Renderbuffer
);
1570 /* only GLubyte supported for now */
1571 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1573 /* allocate alpha renderbuffer */
1574 arb
= _mesa_new_renderbuffer(ctx
, 0);
1576 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1580 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1581 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1583 /* Set up my alphabuffer fields and plug in my functions.
1584 * The functions will put/get the alpha values from/to RGBA arrays
1585 * and then call the wrapped buffer's functions to handle the RGB
1588 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1589 arb
->Format
= MESA_FORMAT_A8
;
1590 arb
->DataType
= arb
->Wrapped
->DataType
;
1591 arb
->AllocStorage
= alloc_storage_alpha8
;
1592 arb
->Delete
= delete_renderbuffer_alpha8
;
1593 arb
->GetPointer
= get_pointer_alpha8
;
1594 arb
->GetRow
= get_row_alpha8
;
1595 arb
->GetValues
= get_values_alpha8
;
1596 arb
->PutRow
= put_row_alpha8
;
1597 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1598 arb
->PutMonoRow
= put_mono_row_alpha8
;
1599 arb
->PutValues
= put_values_alpha8
;
1600 arb
->PutMonoValues
= put_mono_values_alpha8
;
1602 /* clear the pointer to avoid assertion/sanity check failure later */
1603 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1605 /* plug the alpha renderbuffer into the colorbuffer attachment */
1606 _mesa_add_renderbuffer(fb
, b
, arb
);
1614 * For framebuffers that use a software alpha channel wrapper
1615 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
1616 * copy the back buffer alpha channel into the front buffer alpha channel.
1619 _mesa_copy_soft_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
1621 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
1622 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
1623 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
1624 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
1627 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
1628 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
1629 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
1630 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
1635 * Add a software-based depth renderbuffer to the given framebuffer.
1636 * This is a helper routine for device drivers when creating a
1637 * window system framebuffer (not a user-created render/framebuffer).
1638 * Once this function is called, you can basically forget about this
1639 * renderbuffer; core Mesa will handle all the buffer management and
1643 _mesa_add_depth_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1646 struct gl_renderbuffer
*rb
;
1648 if (depthBits
> 32) {
1650 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1654 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1656 rb
= _mesa_new_renderbuffer(ctx
, 0);
1658 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1662 if (depthBits
<= 16) {
1663 rb
->Format
= MESA_FORMAT_Z16
;
1664 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1666 else if (depthBits
<= 24) {
1667 rb
->Format
= MESA_FORMAT_X8_Z24
;
1668 rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
1671 rb
->Format
= MESA_FORMAT_Z32
;
1672 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1675 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1676 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1683 * Add a software-based stencil renderbuffer to the given framebuffer.
1684 * This is a helper routine for device drivers when creating a
1685 * window system framebuffer (not a user-created render/framebuffer).
1686 * Once this function is called, you can basically forget about this
1687 * renderbuffer; core Mesa will handle all the buffer management and
1691 _mesa_add_stencil_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1694 struct gl_renderbuffer
*rb
;
1696 if (stencilBits
> 16) {
1698 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1702 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1704 rb
= _mesa_new_renderbuffer(ctx
, 0);
1706 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1710 assert(stencilBits
<= 8);
1711 rb
->Format
= MESA_FORMAT_S8
;
1712 rb
->InternalFormat
= GL_STENCIL_INDEX8
;
1714 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1715 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1722 * Add a software-based accumulation renderbuffer to the given framebuffer.
1723 * This is a helper routine for device drivers when creating a
1724 * window system framebuffer (not a user-created render/framebuffer).
1725 * Once this function is called, you can basically forget about this
1726 * renderbuffer; core Mesa will handle all the buffer management and
1730 _mesa_add_accum_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1731 GLuint redBits
, GLuint greenBits
,
1732 GLuint blueBits
, GLuint alphaBits
)
1734 struct gl_renderbuffer
*rb
;
1736 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1738 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1742 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1744 rb
= _mesa_new_renderbuffer(ctx
, 0);
1746 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1750 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
1751 rb
->InternalFormat
= GL_RGBA16_SNORM
;
1752 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1753 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1761 * Add a software-based aux renderbuffer to the given framebuffer.
1762 * This is a helper routine for device drivers when creating a
1763 * window system framebuffer (not a user-created render/framebuffer).
1764 * Once this function is called, you can basically forget about this
1765 * renderbuffer; core Mesa will handle all the buffer management and
1768 * NOTE: color-index aux buffers not supported.
1771 _mesa_add_aux_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1772 GLuint colorBits
, GLuint numBuffers
)
1776 if (colorBits
> 16) {
1778 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1782 assert(numBuffers
<= MAX_AUX_BUFFERS
);
1784 for (i
= 0; i
< numBuffers
; i
++) {
1785 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1787 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1790 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating aux buffer");
1794 assert (colorBits
<= 8);
1795 rb
->Format
= MESA_FORMAT_RGBA8888
;
1796 rb
->InternalFormat
= GL_RGBA
;
1798 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1799 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1806 * Create/attach software-based renderbuffers to the given framebuffer.
1807 * This is a helper routine for device drivers. Drivers can just as well
1808 * call the individual _mesa_add_*_renderbuffer() routines directly.
1811 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1819 GLboolean frontLeft
= GL_TRUE
;
1820 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1821 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1822 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1825 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1826 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1827 _mesa_add_color_renderbuffers(NULL
, fb
,
1829 fb
->Visual
.alphaBits
,
1830 frontLeft
, backLeft
,
1831 frontRight
, backRight
);
1835 assert(fb
->Visual
.depthBits
> 0);
1836 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1840 assert(fb
->Visual
.stencilBits
> 0);
1841 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1845 assert(fb
->Visual
.accumRedBits
> 0);
1846 assert(fb
->Visual
.accumGreenBits
> 0);
1847 assert(fb
->Visual
.accumBlueBits
> 0);
1848 _mesa_add_accum_renderbuffer(NULL
, fb
,
1849 fb
->Visual
.accumRedBits
,
1850 fb
->Visual
.accumGreenBits
,
1851 fb
->Visual
.accumBlueBits
,
1852 fb
->Visual
.accumAlphaBits
);
1856 assert(fb
->Visual
.numAuxBuffers
> 0);
1857 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
1858 fb
->Visual
.numAuxBuffers
);
1862 assert(fb
->Visual
.alphaBits
> 0);
1863 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
1864 frontLeft
, backLeft
,
1865 frontRight
, backRight
);
1877 * Attach a renderbuffer to a framebuffer.
1878 * \param bufferName one of the BUFFER_x tokens
1881 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
1882 gl_buffer_index bufferName
, struct gl_renderbuffer
*rb
)
1886 assert(bufferName
< BUFFER_COUNT
);
1888 /* There should be no previous renderbuffer on this attachment point,
1889 * with the exception of depth/stencil since the same renderbuffer may
1892 assert(bufferName
== BUFFER_DEPTH
||
1893 bufferName
== BUFFER_STENCIL
||
1894 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
1896 /* winsys vs. user-created buffer cross check */
1904 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
1905 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
1906 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
1911 * Remove the named renderbuffer from the given framebuffer.
1912 * \param bufferName one of the BUFFER_x tokens
1915 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
,
1916 gl_buffer_index bufferName
)
1918 struct gl_renderbuffer
*rb
;
1920 assert(bufferName
< BUFFER_COUNT
);
1922 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
1926 _mesa_reference_renderbuffer(&rb
, NULL
);
1928 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
1933 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
1934 * dereference that buffer first. The new renderbuffer's refcount will
1935 * be incremented. The old renderbuffer's refcount will be decremented.
1938 _mesa_reference_renderbuffer(struct gl_renderbuffer
**ptr
,
1939 struct gl_renderbuffer
*rb
)
1948 /* Unreference the old renderbuffer */
1949 GLboolean deleteFlag
= GL_FALSE
;
1950 struct gl_renderbuffer
*oldRb
= *ptr
;
1952 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
1953 ASSERT(oldRb
->RefCount
> 0);
1955 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
1956 deleteFlag
= (oldRb
->RefCount
== 0);
1957 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
1960 oldRb
->Delete(oldRb
);
1968 /* reference new renderbuffer */
1969 _glthread_LOCK_MUTEX(rb
->Mutex
);
1971 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
1972 _glthread_UNLOCK_MUTEX(rb
->Mutex
);
1979 * Create a new combined depth/stencil renderbuffer for implementing
1980 * the GL_EXT_packed_depth_stencil extension.
1981 * \return new depth/stencil renderbuffer
1983 struct gl_renderbuffer
*
1984 _mesa_new_depthstencil_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1986 struct gl_renderbuffer
*dsrb
;
1988 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
1992 /* init fields not covered by _mesa_new_renderbuffer() */
1993 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
1994 dsrb
->Format
= MESA_FORMAT_Z24_S8
;
1995 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;