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.
56 /* Returns a bytes per pixel of the DataType in the get/put span
57 * functions for at least a subset of the available combinations a
58 * renderbuffer can have.
60 * It would be nice to see gl_renderbuffer start talking about a
61 * gl_format instead of a GLenum DataType.
64 get_datatype_bytes(struct gl_renderbuffer
*rb
)
68 switch (rb
->DataType
) {
71 case GL_UNSIGNED_INT_24_8_EXT
:
74 case GL_UNSIGNED_SHORT
:
77 case GL_UNSIGNED_BYTE
:
85 switch (rb
->_BaseFormat
) {
86 case GL_DEPTH_COMPONENT
:
87 case GL_DEPTH_STENCIL
:
88 return component_size
;
90 return 4 * component_size
;
94 /* This is commonly used by most of the accessors. */
96 get_pointer_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
102 return ((char *) rb
->Data
+
103 (y
* rb
->RowStride
+ x
) * _mesa_get_format_bytes(rb
->Format
));
106 /* GetRow() implementation for formats where DataType matches the rb->Format.
109 get_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
110 GLuint count
, GLint x
, GLint y
, void *values
)
112 void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
113 memcpy(values
, src
, count
* _mesa_get_format_bytes(rb
->Format
));
116 /* Only used for float textures currently, but might also be used for
117 * RGBA8888, RGBA16, etc.
120 get_values_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
121 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
123 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
126 for (i
= 0; i
< count
; i
++) {
127 const void *src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
128 char *dst
= (char *) values
+ i
* format_bytes
;
129 memcpy(dst
, src
, format_bytes
);
133 /* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and
134 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of
135 * storing those initial components of the value per pixel into the
139 put_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
140 GLuint count
, GLint x
, GLint y
,
141 const void *values
, const GLubyte
*mask
)
143 void *row
= rb
->GetPointer(ctx
, rb
, x
, y
);
144 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
145 int datatype_bytes
= get_datatype_bytes(rb
);
149 for (i
= 0; i
< count
; i
++) {
150 char *dst
= (char *) row
+ i
* format_bytes
;
151 const char *src
= (const char *) values
+ i
* datatype_bytes
;
154 memcpy(dst
, src
, format_bytes
);
159 for (i
= 0; i
< count
; i
++) {
160 char *dst
= (char *) row
+ i
* format_bytes
;
161 const char *src
= (const char *) values
+ i
* datatype_bytes
;
162 memcpy(dst
, src
, format_bytes
);
168 put_mono_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
169 GLuint count
, GLint x
, GLint y
,
170 const void *value
, const GLubyte
*mask
)
172 void *row
= rb
->GetPointer(ctx
, rb
, x
, y
);
173 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
177 for (i
= 0; i
< count
; i
++) {
178 char *dst
= (char *) row
+ i
* format_bytes
;
180 memcpy(dst
, value
, format_bytes
);
185 for (i
= 0; i
< count
; i
++) {
186 char *dst
= (char *) row
+ i
* format_bytes
;
187 memcpy(dst
, value
, format_bytes
);
194 put_values_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
195 GLuint count
, const GLint x
[], const GLint y
[],
196 const void *values
, const GLubyte
*mask
)
198 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
199 int datatype_bytes
= get_datatype_bytes(rb
);
202 for (i
= 0; i
< count
; i
++) {
203 if (!mask
|| mask
[i
]) {
204 void *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
205 const char *src
= (const char *) values
+ i
* datatype_bytes
;
206 memcpy(dst
, src
, format_bytes
);
213 put_mono_values_generic(struct gl_context
*ctx
,
214 struct gl_renderbuffer
*rb
,
215 GLuint count
, const GLint x
[], const GLint y
[],
216 const void *value
, const GLubyte
*mask
)
218 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
221 for (i
= 0; i
< count
; i
++) {
222 if (!mask
|| mask
[i
]) {
223 void *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
224 memcpy(dst
, value
, format_bytes
);
229 /**********************************************************************
230 * Functions for buffers of 1 X GLubyte values.
235 get_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
236 const GLint x
[], const GLint y
[], void *values
)
238 GLubyte
*dst
= (GLubyte
*) values
;
240 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
241 for (i
= 0; i
< count
; i
++) {
242 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
249 put_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
250 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
252 const GLubyte
*src
= (const GLubyte
*) values
;
253 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
254 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
257 for (i
= 0; i
< count
; i
++) {
264 memcpy(dst
, values
, count
* sizeof(GLubyte
));
270 put_mono_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
271 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
273 const GLubyte val
= *((const GLubyte
*) value
);
274 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
275 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
278 for (i
= 0; i
< count
; i
++) {
286 for (i
= 0; i
< count
; i
++) {
294 put_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
295 const GLint x
[], const GLint y
[],
296 const void *values
, const GLubyte
*mask
)
298 const GLubyte
*src
= (const GLubyte
*) values
;
300 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
301 for (i
= 0; i
< count
; i
++) {
302 if (!mask
|| mask
[i
]) {
303 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
311 put_mono_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
312 const GLint x
[], const GLint y
[],
313 const void *value
, const GLubyte
*mask
)
315 const GLubyte val
= *((const GLubyte
*) value
);
317 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
318 for (i
= 0; i
< count
; i
++) {
319 if (!mask
|| mask
[i
]) {
320 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
327 /**********************************************************************
328 * Functions for buffers of 1 X GLushort values.
333 get_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
334 const GLint x
[], const GLint y
[], void *values
)
336 GLushort
*dst
= (GLushort
*) values
;
338 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
339 for (i
= 0; i
< count
; i
++) {
340 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
347 put_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
348 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
350 const GLushort
*src
= (const GLushort
*) values
;
351 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
352 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
355 for (i
= 0; i
< count
; i
++) {
362 memcpy(dst
, src
, count
* sizeof(GLushort
));
368 put_mono_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
369 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
371 const GLushort val
= *((const GLushort
*) value
);
372 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
373 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
376 for (i
= 0; i
< count
; i
++) {
384 for (i
= 0; i
< count
; i
++) {
392 put_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
393 const GLint x
[], const GLint y
[], const void *values
,
396 const GLushort
*src
= (const GLushort
*) values
;
398 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
399 for (i
= 0; i
< count
; i
++) {
400 if (!mask
|| mask
[i
]) {
401 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
409 put_mono_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
410 GLuint count
, const GLint x
[], const GLint y
[],
411 const void *value
, const GLubyte
*mask
)
413 const GLushort val
= *((const GLushort
*) value
);
414 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
417 for (i
= 0; i
< count
; i
++) {
419 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
426 for (i
= 0; i
< count
; i
++) {
427 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
434 /**********************************************************************
435 * Functions for buffers of 1 X GLuint values.
436 * Typically depth/Z or color index.
440 get_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
441 const GLint x
[], const GLint y
[], void *values
)
443 GLuint
*dst
= (GLuint
*) values
;
445 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
446 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
447 for (i
= 0; i
< count
; i
++) {
448 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
455 put_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
456 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
458 const GLuint
*src
= (const GLuint
*) values
;
459 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
460 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
461 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
464 for (i
= 0; i
< count
; i
++) {
471 memcpy(dst
, src
, count
* sizeof(GLuint
));
477 put_mono_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
478 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
480 const GLuint val
= *((const GLuint
*) value
);
481 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
482 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
483 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
486 for (i
= 0; i
< count
; i
++) {
494 for (i
= 0; i
< count
; i
++) {
502 put_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
503 const GLint x
[], const GLint y
[], const void *values
,
506 const GLuint
*src
= (const GLuint
*) values
;
508 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
509 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
510 for (i
= 0; i
< count
; i
++) {
511 if (!mask
|| mask
[i
]) {
512 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
520 put_mono_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
521 const GLint x
[], const GLint y
[], const void *value
,
524 const GLuint val
= *((const GLuint
*) value
);
526 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
527 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
528 for (i
= 0; i
< count
; i
++) {
529 if (!mask
|| mask
[i
]) {
530 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
537 /**********************************************************************
538 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
539 * Typically color buffers.
540 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
541 * alpha values and return 255 for outgoing alpha values.
545 get_pointer_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
548 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
549 /* No direct access since this buffer is RGB but caller will be
550 * treating it as if it were RGBA.
557 get_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
558 GLint x
, GLint y
, void *values
)
560 const GLubyte
*src
= ((const GLubyte
*) rb
->Data
) +
561 3 * (y
* rb
->RowStride
+ x
);
562 GLubyte
*dst
= (GLubyte
*) values
;
564 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
565 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
566 for (i
= 0; i
< count
; i
++) {
567 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
568 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
569 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
570 dst
[i
* 4 + 3] = 255;
576 get_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
577 const GLint x
[], const GLint y
[], void *values
)
579 GLubyte
*dst
= (GLubyte
*) values
;
581 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
582 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
583 for (i
= 0; i
< count
; i
++) {
585 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
586 dst
[i
* 4 + 0] = src
[0];
587 dst
[i
* 4 + 1] = src
[1];
588 dst
[i
* 4 + 2] = src
[2];
589 dst
[i
* 4 + 3] = 255;
595 put_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
596 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
598 /* note: incoming values are RGB+A! */
599 const GLubyte
*src
= (const GLubyte
*) values
;
600 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
602 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
603 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
604 for (i
= 0; i
< count
; i
++) {
605 if (!mask
|| mask
[i
]) {
606 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
607 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
608 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
615 put_row_rgb_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
616 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
618 /* note: incoming values are RGB+A! */
619 const GLubyte
*src
= (const GLubyte
*) values
;
620 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
622 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
623 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
624 for (i
= 0; i
< count
; i
++) {
625 if (!mask
|| mask
[i
]) {
626 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
627 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
628 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
635 put_mono_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
636 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
638 /* note: incoming value is RGB+A! */
639 const GLubyte val0
= ((const GLubyte
*) value
)[0];
640 const GLubyte val1
= ((const GLubyte
*) value
)[1];
641 const GLubyte val2
= ((const GLubyte
*) value
)[2];
642 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
643 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
644 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
645 if (!mask
&& val0
== val1
&& val1
== val2
) {
647 memset(dst
, val0
, 3 * count
);
651 for (i
= 0; i
< count
; i
++) {
652 if (!mask
|| mask
[i
]) {
653 dst
[i
* 3 + 0] = val0
;
654 dst
[i
* 3 + 1] = val1
;
655 dst
[i
* 3 + 2] = val2
;
663 put_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
664 const GLint x
[], const GLint y
[], const void *values
,
667 /* note: incoming values are RGB+A! */
668 const GLubyte
*src
= (const GLubyte
*) values
;
670 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
671 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
672 for (i
= 0; i
< count
; i
++) {
673 if (!mask
|| mask
[i
]) {
674 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
675 dst
[0] = src
[i
* 4 + 0];
676 dst
[1] = src
[i
* 4 + 1];
677 dst
[2] = src
[i
* 4 + 2];
684 put_mono_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
685 GLuint count
, const GLint x
[], const GLint y
[],
686 const void *value
, const GLubyte
*mask
)
688 /* note: incoming value is RGB+A! */
689 const GLubyte val0
= ((const GLubyte
*) value
)[0];
690 const GLubyte val1
= ((const GLubyte
*) value
)[1];
691 const GLubyte val2
= ((const GLubyte
*) value
)[2];
693 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
694 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
695 for (i
= 0; i
< count
; i
++) {
696 if (!mask
|| mask
[i
]) {
697 GLubyte
*dst
= ((GLubyte
*) rb
->Data
) +
698 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
707 /**********************************************************************
708 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
709 * Typically color buffers.
713 get_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
714 const GLint x
[], const GLint y
[], void *values
)
716 /* treat 4*GLubyte as 1*GLuint */
717 GLuint
*dst
= (GLuint
*) values
;
719 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
720 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
721 for (i
= 0; i
< count
; i
++) {
722 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
729 put_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
730 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
732 /* treat 4*GLubyte as 1*GLuint */
733 const GLuint
*src
= (const GLuint
*) values
;
734 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
735 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
736 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
739 for (i
= 0; i
< count
; i
++) {
746 memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
752 put_row_rgb_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
753 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
755 /* Store RGB values in RGBA buffer */
756 const GLubyte
*src
= (const GLubyte
*) values
;
757 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
759 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
760 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
761 for (i
= 0; i
< count
; i
++) {
762 if (!mask
|| mask
[i
]) {
763 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
764 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
765 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
766 dst
[i
* 4 + 3] = 0xff;
773 put_mono_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
774 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
776 /* treat 4*GLubyte as 1*GLuint */
777 const GLuint val
= *((const GLuint
*) value
);
778 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
779 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
780 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
781 if (!mask
&& val
== 0) {
783 memset(dst
, 0, count
* 4 * sizeof(GLubyte
));
789 for (i
= 0; i
< count
; i
++) {
797 for (i
= 0; i
< count
; i
++) {
806 put_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
807 const GLint x
[], const GLint y
[], const void *values
,
810 /* treat 4*GLubyte as 1*GLuint */
811 const GLuint
*src
= (const GLuint
*) values
;
813 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
814 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
815 for (i
= 0; i
< count
; i
++) {
816 if (!mask
|| mask
[i
]) {
817 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
825 put_mono_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
826 GLuint count
, const GLint x
[], const GLint y
[],
827 const void *value
, const GLubyte
*mask
)
829 /* treat 4*GLubyte as 1*GLuint */
830 const GLuint val
= *((const GLuint
*) value
);
832 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
833 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
834 for (i
= 0; i
< count
; i
++) {
835 if (!mask
|| mask
[i
]) {
836 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
843 /**********************************************************************
844 * Functions for buffers of 4 X GLushort (or GLshort) values.
845 * Typically accum buffer.
849 get_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
850 const GLint x
[], const GLint y
[], void *values
)
852 GLushort
*dst
= (GLushort
*) values
;
854 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
855 for (i
= 0; i
< count
; i
++) {
857 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
864 put_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
865 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
867 const GLushort
*src
= (const GLushort
*) values
;
868 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
869 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
872 for (i
= 0; i
< count
; i
++) {
874 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
875 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
876 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
877 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
882 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
888 put_row_rgb_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
889 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
891 /* Put RGB values in RGBA buffer */
892 const GLushort
*src
= (const GLushort
*) values
;
893 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
894 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
897 for (i
= 0; i
< count
; i
++) {
899 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
900 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
901 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
902 dst
[i
* 4 + 3] = 0xffff;
907 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
913 put_mono_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
914 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
916 const GLushort val0
= ((const GLushort
*) value
)[0];
917 const GLushort val1
= ((const GLushort
*) value
)[1];
918 const GLushort val2
= ((const GLushort
*) value
)[2];
919 const GLushort val3
= ((const GLushort
*) value
)[3];
920 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
921 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
922 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
923 /* common case for clearing accum buffer */
924 memset(dst
, 0, count
* 4 * sizeof(GLushort
));
928 for (i
= 0; i
< count
; i
++) {
929 if (!mask
|| mask
[i
]) {
930 dst
[i
* 4 + 0] = val0
;
931 dst
[i
* 4 + 1] = val1
;
932 dst
[i
* 4 + 2] = val2
;
933 dst
[i
* 4 + 3] = val3
;
941 put_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
942 const GLint x
[], const GLint y
[], const void *values
,
945 const GLushort
*src
= (const GLushort
*) values
;
947 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
948 for (i
= 0; i
< count
; i
++) {
949 if (!mask
|| mask
[i
]) {
951 ((GLushort
*) rb
->Data
) + 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
952 dst
[0] = src
[i
* 4 + 0];
953 dst
[1] = src
[i
* 4 + 1];
954 dst
[2] = src
[i
* 4 + 2];
955 dst
[3] = src
[i
* 4 + 3];
962 put_mono_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
963 GLuint count
, const GLint x
[], const GLint y
[],
964 const void *value
, const GLubyte
*mask
)
966 const GLushort val0
= ((const GLushort
*) value
)[0];
967 const GLushort val1
= ((const GLushort
*) value
)[1];
968 const GLushort val2
= ((const GLushort
*) value
)[2];
969 const GLushort val3
= ((const GLushort
*) value
)[3];
971 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
972 for (i
= 0; i
< count
; i
++) {
973 if (!mask
|| mask
[i
]) {
974 GLushort
*dst
= ((GLushort
*) rb
->Data
) +
975 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
984 /**********************************************************************
985 * Functions for MESA_FORMAT_R8.
988 get_row_r8(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
989 GLint x
, GLint y
, void *values
)
991 const GLubyte
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
992 GLuint
*dst
= values
;
995 for (i
= 0; i
< count
; i
++) {
996 dst
[i
] = 0xff000000 | src
[i
];
1001 get_values_r8(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1002 const GLint x
[], const GLint y
[], void *values
)
1004 GLuint
*dst
= (GLuint
*) values
;
1007 for (i
= 0; i
< count
; i
++) {
1008 const GLubyte
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1009 dst
[i
] = 0xff000000 | *src
;
1013 /**********************************************************************
1014 * Functions for MESA_FORMAT_RG88.
1017 get_row_rg88(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1018 GLint x
, GLint y
, void *values
)
1020 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1021 GLuint
*dst
= values
;
1024 for (i
= 0; i
< count
; i
++) {
1025 dst
[i
] = 0xff000000 | src
[i
];
1030 get_values_rg88(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1031 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
1033 GLuint
*dst
= (GLuint
*) values
;
1036 for (i
= 0; i
< count
; i
++) {
1037 const GLshort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1038 dst
[i
] = 0xff000000 | *src
;
1042 /**********************************************************************
1043 * Functions for MESA_FORMAT_R16.
1046 get_row_r16(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1047 GLint x
, GLint y
, void *values
)
1049 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1050 GLushort
*dst
= values
;
1053 for (i
= 0; i
< count
; i
++) {
1054 dst
[i
* 4 + RCOMP
] = src
[i
];
1055 dst
[i
* 4 + GCOMP
] = 0;
1056 dst
[i
* 4 + BCOMP
] = 0;
1057 dst
[i
* 4 + ACOMP
] = 0xffff;
1062 get_values_r16(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1063 const GLint x
[], const GLint y
[], void *values
)
1065 GLushort
*dst
= values
;
1068 for (i
= 0; i
< count
; i
++) {
1069 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1070 dst
[i
* 4 + RCOMP
] = *src
;
1071 dst
[i
* 4 + GCOMP
] = 0;
1072 dst
[i
* 4 + BCOMP
] = 0;
1073 dst
[i
* 4 + ACOMP
] = 0xffff;
1077 /**********************************************************************
1078 * Functions for MESA_FORMAT_RG1616.
1081 get_row_rg1616(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1082 GLint x
, GLint y
, void *values
)
1084 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1085 GLushort
*dst
= values
;
1088 for (i
= 0; i
< count
; i
++) {
1089 dst
[i
* 4 + RCOMP
] = src
[i
* 2];
1090 dst
[i
* 4 + GCOMP
] = src
[i
* 2 + 1];
1091 dst
[i
* 4 + BCOMP
] = 0;
1092 dst
[i
* 4 + ACOMP
] = 0xffff;
1097 get_values_rg1616(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1098 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
1100 GLushort
*dst
= values
;
1103 for (i
= 0; i
< count
; i
++) {
1104 const GLshort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1105 dst
[i
* 4 + RCOMP
] = src
[0];
1106 dst
[i
* 4 + GCOMP
] = src
[1];
1107 dst
[i
* 4 + BCOMP
] = 0;
1108 dst
[i
* 4 + ACOMP
] = 0xffff;
1112 /**********************************************************************
1113 * Functions for MESA_FORMAT_INTENSITY_FLOAT32.
1116 get_row_i_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1117 GLuint count
, GLint x
, GLint y
, void *values
)
1119 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1120 GLfloat
*dst
= values
;
1123 for (i
= 0; i
< count
; i
++) {
1124 dst
[i
* 4 + RCOMP
] =
1125 dst
[i
* 4 + GCOMP
] =
1126 dst
[i
* 4 + BCOMP
] =
1127 dst
[i
* 4 + ACOMP
] = src
[i
];
1132 get_values_i_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1133 GLuint count
, const GLint x
[], const GLint y
[],
1136 GLfloat
*dst
= values
;
1139 for (i
= 0; i
< count
; i
++) {
1140 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1141 dst
[i
* 4 + RCOMP
] =
1142 dst
[i
* 4 + GCOMP
] =
1143 dst
[i
* 4 + BCOMP
] =
1144 dst
[i
* 4 + ACOMP
] = src
[0];
1148 /**********************************************************************
1149 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32.
1152 get_row_l_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1153 GLuint count
, GLint x
, GLint y
, void *values
)
1155 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1156 GLfloat
*dst
= values
;
1159 for (i
= 0; i
< count
; i
++) {
1160 dst
[i
* 4 + RCOMP
] =
1161 dst
[i
* 4 + GCOMP
] =
1162 dst
[i
* 4 + BCOMP
] = src
[i
];
1163 dst
[i
* 4 + ACOMP
] = 1.0;
1168 get_values_l_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1169 GLuint count
, const GLint x
[], const GLint y
[],
1172 GLfloat
*dst
= values
;
1175 for (i
= 0; i
< count
; i
++) {
1176 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1177 dst
[i
* 4 + RCOMP
] =
1178 dst
[i
* 4 + GCOMP
] =
1179 dst
[i
* 4 + BCOMP
] = src
[0];
1180 dst
[i
* 4 + ACOMP
] = 1.0;
1184 /**********************************************************************
1185 * Functions for MESA_FORMAT_ALPHA_FLOAT32.
1188 get_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1189 GLuint count
, GLint x
, GLint y
, void *values
)
1191 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1192 GLfloat
*dst
= values
;
1195 for (i
= 0; i
< count
; i
++) {
1196 dst
[i
* 4 + RCOMP
] = 0.0;
1197 dst
[i
* 4 + GCOMP
] = 0.0;
1198 dst
[i
* 4 + BCOMP
] = 0.0;
1199 dst
[i
* 4 + ACOMP
] = src
[i
];
1204 get_values_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1205 GLuint count
, const GLint x
[], const GLint y
[],
1208 GLfloat
*dst
= values
;
1211 for (i
= 0; i
< count
; i
++) {
1212 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1213 dst
[i
* 4 + RCOMP
] = 0.0;
1214 dst
[i
* 4 + GCOMP
] = 0.0;
1215 dst
[i
* 4 + BCOMP
] = 0.0;
1216 dst
[i
* 4 + ACOMP
] = src
[0];
1221 put_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1222 GLuint count
, GLint x
, GLint y
,
1223 const void *values
, const GLubyte
*mask
)
1225 float *dst
= rb
->GetPointer(ctx
, rb
, x
, y
);
1226 const float *src
= values
;
1230 for (i
= 0; i
< count
; i
++) {
1232 dst
[i
] = src
[i
* 4 + ACOMP
];
1237 for (i
= 0; i
< count
; i
++) {
1238 dst
[i
] = src
[i
* 4 + ACOMP
];
1244 put_mono_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1245 GLuint count
, GLint x
, GLint y
,
1246 const void *value
, const GLubyte
*mask
)
1248 float *dst
= rb
->GetPointer(ctx
, rb
, x
, y
);
1249 const float *src
= value
;
1253 for (i
= 0; i
< count
; i
++) {
1255 dst
[i
] = src
[ACOMP
];
1260 for (i
= 0; i
< count
; i
++) {
1261 dst
[i
] = src
[ACOMP
];
1267 put_values_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1268 GLuint count
, const GLint x
[], const GLint y
[],
1269 const void *values
, const GLubyte
*mask
)
1271 const float *src
= values
;
1274 for (i
= 0; i
< count
; i
++) {
1275 if (!mask
|| mask
[i
]) {
1276 float *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1278 *dst
= src
[i
* 4 + ACOMP
];
1284 put_mono_values_a_float32(struct gl_context
*ctx
,
1285 struct gl_renderbuffer
*rb
,
1286 GLuint count
, const GLint x
[], const GLint y
[],
1287 const void *value
, const GLubyte
*mask
)
1289 const float *src
= value
;
1292 for (i
= 0; i
< count
; i
++) {
1293 if (!mask
|| mask
[i
]) {
1294 float *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1300 /**********************************************************************
1301 * Functions for MESA_FORMAT_R_FLOAT32.
1304 get_row_r_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1305 GLuint count
, GLint x
, GLint y
, void *values
)
1307 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1308 GLfloat
*dst
= values
;
1311 for (i
= 0; i
< count
; i
++) {
1312 dst
[i
* 4 + RCOMP
] = src
[i
];
1313 dst
[i
* 4 + GCOMP
] = 0.0;
1314 dst
[i
* 4 + BCOMP
] = 0.0;
1315 dst
[i
* 4 + ACOMP
] = 1.0;
1320 get_values_r_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1321 GLuint count
, const GLint x
[], const GLint y
[],
1324 GLfloat
*dst
= values
;
1327 for (i
= 0; i
< count
; i
++) {
1328 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1329 dst
[i
* 4 + RCOMP
] = src
[0];
1330 dst
[i
* 4 + GCOMP
] = 0.0;
1331 dst
[i
* 4 + BCOMP
] = 0.0;
1332 dst
[i
* 4 + ACOMP
] = 1.0;
1336 /**********************************************************************
1337 * Functions for MESA_FORMAT_RG_FLOAT32.
1340 get_row_rg_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1341 GLuint count
, GLint x
, GLint y
, void *values
)
1343 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1344 GLfloat
*dst
= values
;
1347 for (i
= 0; i
< count
; i
++) {
1348 dst
[i
* 4 + RCOMP
] = src
[i
* 2 + 0];
1349 dst
[i
* 4 + GCOMP
] = src
[i
* 2 + 1];
1350 dst
[i
* 4 + BCOMP
] = 0.0;
1351 dst
[i
* 4 + ACOMP
] = 1.0;
1356 get_values_rg_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1357 GLuint count
, const GLint x
[], const GLint y
[],
1360 GLfloat
*dst
= values
;
1363 for (i
= 0; i
< count
; i
++) {
1364 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1365 dst
[i
* 4 + RCOMP
] = src
[0];
1366 dst
[i
* 4 + GCOMP
] = src
[1];
1367 dst
[i
* 4 + BCOMP
] = 0.0;
1368 dst
[i
* 4 + ACOMP
] = 1.0;
1373 * This is the default software fallback for gl_renderbuffer's span
1376 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
1377 * are packed in the type of rb->Format, and that subsequent rows appear
1378 * rb->RowStride pixels later.
1381 _mesa_set_renderbuffer_accessors(struct gl_renderbuffer
*rb
)
1383 rb
->GetPointer
= get_pointer_generic
;
1384 rb
->GetRow
= get_row_generic
;
1386 switch (rb
->Format
) {
1387 case MESA_FORMAT_RGB888
:
1388 rb
->DataType
= GL_UNSIGNED_BYTE
;
1389 rb
->GetPointer
= get_pointer_ubyte3
;
1390 rb
->GetRow
= get_row_ubyte3
;
1391 rb
->GetValues
= get_values_ubyte3
;
1392 rb
->PutRow
= put_row_ubyte3
;
1393 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
1394 rb
->PutMonoRow
= put_mono_row_ubyte3
;
1395 rb
->PutValues
= put_values_ubyte3
;
1396 rb
->PutMonoValues
= put_mono_values_ubyte3
;
1399 case MESA_FORMAT_RGBA8888
:
1400 rb
->DataType
= GL_UNSIGNED_BYTE
;
1401 rb
->GetValues
= get_values_ubyte4
;
1402 rb
->PutRow
= put_row_ubyte4
;
1403 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
1404 rb
->PutMonoRow
= put_mono_row_ubyte4
;
1405 rb
->PutValues
= put_values_ubyte4
;
1406 rb
->PutMonoValues
= put_mono_values_ubyte4
;
1409 case MESA_FORMAT_R8
:
1410 rb
->DataType
= GL_UNSIGNED_BYTE
;
1411 rb
->GetValues
= get_values_r8
;
1412 rb
->GetRow
= get_row_r8
;
1413 rb
->PutRow
= put_row_generic
;
1414 rb
->PutRowRGB
= put_row_generic
;
1415 rb
->PutMonoRow
= put_mono_row_generic
;
1416 rb
->PutValues
= put_values_generic
;
1417 rb
->PutMonoValues
= put_mono_values_generic
;
1420 case MESA_FORMAT_RG88
:
1421 rb
->DataType
= GL_UNSIGNED_BYTE
;
1422 rb
->GetValues
= get_values_rg88
;
1423 rb
->GetRow
= get_row_rg88
;
1424 rb
->PutRow
= put_row_generic
;
1425 rb
->PutRowRGB
= put_row_generic
;
1426 rb
->PutMonoRow
= put_mono_row_generic
;
1427 rb
->PutValues
= put_values_generic
;
1428 rb
->PutMonoValues
= put_mono_values_generic
;
1431 case MESA_FORMAT_R16
:
1432 rb
->DataType
= GL_UNSIGNED_SHORT
;
1433 rb
->GetValues
= get_values_r16
;
1434 rb
->GetRow
= get_row_r16
;
1435 rb
->PutRow
= put_row_generic
;
1436 rb
->PutRowRGB
= put_row_generic
;
1437 rb
->PutMonoRow
= put_mono_row_generic
;
1438 rb
->PutValues
= put_values_generic
;
1439 rb
->PutMonoValues
= put_mono_values_generic
;
1442 case MESA_FORMAT_RG1616
:
1443 rb
->DataType
= GL_UNSIGNED_SHORT
;
1444 rb
->GetValues
= get_values_rg1616
;
1445 rb
->GetRow
= get_row_rg1616
;
1446 rb
->PutRow
= put_row_generic
;
1447 rb
->PutRowRGB
= put_row_generic
;
1448 rb
->PutMonoRow
= put_mono_row_generic
;
1449 rb
->PutValues
= put_values_generic
;
1450 rb
->PutMonoValues
= put_mono_values_generic
;
1453 case MESA_FORMAT_SIGNED_RGBA_16
:
1454 rb
->DataType
= GL_SHORT
;
1455 rb
->GetValues
= get_values_ushort4
;
1456 rb
->PutRow
= put_row_ushort4
;
1457 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1458 rb
->PutMonoRow
= put_mono_row_ushort4
;
1459 rb
->PutValues
= put_values_ushort4
;
1460 rb
->PutMonoValues
= put_mono_values_ushort4
;
1464 case MESA_FORMAT_A8
:
1465 rb
->DataType
= GL_UNSIGNED_BYTE
;
1466 rb
->GetValues
= get_values_alpha8
;
1467 rb
->PutRow
= put_row_alpha8
;
1468 rb
->PutRowRGB
= NULL
;
1469 rb
->PutMonoRow
= put_mono_row_alpha8
;
1470 rb
->PutValues
= put_values_alpha8
;
1471 rb
->PutMonoValues
= put_mono_values_alpha8
;
1475 case MESA_FORMAT_S8
:
1476 rb
->DataType
= GL_UNSIGNED_BYTE
;
1477 rb
->GetValues
= get_values_ubyte
;
1478 rb
->PutRow
= put_row_ubyte
;
1479 rb
->PutRowRGB
= NULL
;
1480 rb
->PutMonoRow
= put_mono_row_ubyte
;
1481 rb
->PutValues
= put_values_ubyte
;
1482 rb
->PutMonoValues
= put_mono_values_ubyte
;
1485 case MESA_FORMAT_Z16
:
1486 rb
->DataType
= GL_UNSIGNED_SHORT
;
1487 rb
->GetValues
= get_values_ushort
;
1488 rb
->PutRow
= put_row_ushort
;
1489 rb
->PutRowRGB
= NULL
;
1490 rb
->PutMonoRow
= put_mono_row_ushort
;
1491 rb
->PutValues
= put_values_ushort
;
1492 rb
->PutMonoValues
= put_mono_values_ushort
;
1495 case MESA_FORMAT_Z32
:
1496 case MESA_FORMAT_X8_Z24
:
1497 case MESA_FORMAT_Z24_X8
:
1498 rb
->DataType
= GL_UNSIGNED_INT
;
1499 rb
->GetValues
= get_values_uint
;
1500 rb
->PutRow
= put_row_uint
;
1501 rb
->PutRowRGB
= NULL
;
1502 rb
->PutMonoRow
= put_mono_row_uint
;
1503 rb
->PutValues
= put_values_uint
;
1504 rb
->PutMonoValues
= put_mono_values_uint
;
1507 case MESA_FORMAT_Z24_S8
:
1508 case MESA_FORMAT_S8_Z24
:
1509 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1510 rb
->GetValues
= get_values_uint
;
1511 rb
->PutRow
= put_row_uint
;
1512 rb
->PutRowRGB
= NULL
;
1513 rb
->PutMonoRow
= put_mono_row_uint
;
1514 rb
->PutValues
= put_values_uint
;
1515 rb
->PutMonoValues
= put_mono_values_uint
;
1518 case MESA_FORMAT_RGBA_FLOAT32
:
1519 rb
->GetRow
= get_row_generic
;
1520 rb
->GetValues
= get_values_generic
;
1521 rb
->PutRow
= put_row_generic
;
1522 rb
->PutRowRGB
= NULL
;
1523 rb
->PutMonoRow
= put_mono_row_generic
;
1524 rb
->PutValues
= put_values_generic
;
1525 rb
->PutMonoValues
= put_mono_values_generic
;
1528 case MESA_FORMAT_INTENSITY_FLOAT32
:
1529 rb
->GetRow
= get_row_i_float32
;
1530 rb
->GetValues
= get_values_i_float32
;
1531 rb
->PutRow
= put_row_generic
;
1532 rb
->PutRowRGB
= NULL
;
1533 rb
->PutMonoRow
= put_mono_row_generic
;
1534 rb
->PutValues
= put_values_generic
;
1535 rb
->PutMonoValues
= put_mono_values_generic
;
1538 case MESA_FORMAT_LUMINANCE_FLOAT32
:
1539 rb
->GetRow
= get_row_l_float32
;
1540 rb
->GetValues
= get_values_l_float32
;
1541 rb
->PutRow
= put_row_generic
;
1542 rb
->PutRowRGB
= NULL
;
1543 rb
->PutMonoRow
= put_mono_row_generic
;
1544 rb
->PutValues
= put_values_generic
;
1545 rb
->PutMonoValues
= put_mono_values_generic
;
1548 case MESA_FORMAT_ALPHA_FLOAT32
:
1549 rb
->GetRow
= get_row_a_float32
;
1550 rb
->GetValues
= get_values_a_float32
;
1551 rb
->PutRow
= put_row_a_float32
;
1552 rb
->PutRowRGB
= NULL
;
1553 rb
->PutMonoRow
= put_mono_row_a_float32
;
1554 rb
->PutValues
= put_values_a_float32
;
1555 rb
->PutMonoValues
= put_mono_values_a_float32
;
1558 case MESA_FORMAT_RG_FLOAT32
:
1559 rb
->GetRow
= get_row_rg_float32
;
1560 rb
->GetValues
= get_values_rg_float32
;
1561 rb
->PutRow
= put_row_generic
;
1562 rb
->PutRowRGB
= NULL
;
1563 rb
->PutMonoRow
= put_mono_row_generic
;
1564 rb
->PutValues
= put_values_generic
;
1565 rb
->PutMonoValues
= put_mono_values_generic
;
1568 case MESA_FORMAT_R_FLOAT32
:
1569 rb
->GetRow
= get_row_r_float32
;
1570 rb
->GetValues
= get_values_r_float32
;
1571 rb
->PutRow
= put_row_generic
;
1572 rb
->PutRowRGB
= NULL
;
1573 rb
->PutMonoRow
= put_mono_row_generic
;
1574 rb
->PutValues
= put_values_generic
;
1575 rb
->PutMonoValues
= put_mono_values_generic
;
1584 * This is a software fallback for the gl_renderbuffer->AllocStorage
1586 * Device drivers will typically override this function for the buffers
1587 * which it manages (typically color buffers, Z and stencil).
1588 * Other buffers (like software accumulation and aux buffers) which the driver
1589 * doesn't manage can be handled with this function.
1591 * This one multi-purpose function can allocate stencil, depth, accum, color
1592 * or color-index buffers!
1594 * This function also plugs in the appropriate GetPointer, Get/PutRow and
1595 * Get/PutValues functions.
1598 _mesa_soft_renderbuffer_storage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1599 GLenum internalFormat
,
1600 GLuint width
, GLuint height
)
1602 switch (internalFormat
) {
1611 rb
->Format
= MESA_FORMAT_RGB888
;
1622 rb
->Format
= MESA_FORMAT_RGBA8888
;
1625 case GL_RGBA16_SNORM
:
1626 /* for accum buffer */
1627 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
1631 rb
->Format
= MESA_FORMAT_A8
;
1634 case GL_STENCIL_INDEX
:
1635 case GL_STENCIL_INDEX1_EXT
:
1636 case GL_STENCIL_INDEX4_EXT
:
1637 case GL_STENCIL_INDEX8_EXT
:
1638 case GL_STENCIL_INDEX16_EXT
:
1639 rb
->Format
= MESA_FORMAT_S8
;
1641 case GL_DEPTH_COMPONENT
:
1642 case GL_DEPTH_COMPONENT16
:
1643 rb
->Format
= MESA_FORMAT_Z16
;
1645 case GL_DEPTH_COMPONENT24
:
1646 rb
->Format
= MESA_FORMAT_X8_Z24
;
1648 case GL_DEPTH_COMPONENT32
:
1649 rb
->Format
= MESA_FORMAT_Z32
;
1651 case GL_DEPTH_STENCIL_EXT
:
1652 case GL_DEPTH24_STENCIL8_EXT
:
1653 rb
->Format
= MESA_FORMAT_Z24_S8
;
1656 /* unsupported format */
1660 _mesa_set_renderbuffer_accessors(rb
);
1662 ASSERT(rb
->DataType
);
1663 ASSERT(rb
->GetPointer
);
1665 ASSERT(rb
->GetValues
);
1667 ASSERT(rb
->PutMonoRow
);
1668 ASSERT(rb
->PutValues
);
1669 ASSERT(rb
->PutMonoValues
);
1671 /* free old buffer storage */
1677 rb
->RowStride
= width
;
1679 if (width
> 0 && height
> 0) {
1680 /* allocate new buffer storage */
1681 rb
->Data
= malloc(width
* height
* _mesa_get_format_bytes(rb
->Format
));
1683 if (rb
->Data
== NULL
) {
1687 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1688 "software renderbuffer allocation (%d x %d x %d)",
1689 width
, height
, _mesa_get_format_bytes(rb
->Format
));
1695 rb
->Height
= height
;
1696 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
1698 if (rb
->Name
== 0 &&
1699 internalFormat
== GL_RGBA16_SNORM
&&
1700 rb
->_BaseFormat
== 0) {
1701 /* NOTE: This is a special case just for accumulation buffers.
1702 * This is a very limited use case- there's no snorm texturing or
1703 * rendering going on.
1705 rb
->_BaseFormat
= GL_RGBA
;
1708 /* the internalFormat should have been error checked long ago */
1709 ASSERT(rb
->_BaseFormat
);
1717 /**********************************************************************/
1718 /**********************************************************************/
1719 /**********************************************************************/
1723 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1724 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1726 * When PutRow is called (for example), we store the alpha values in
1727 * this buffer, then pass on the PutRow call to the wrapped RGB
1733 alloc_storage_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1734 GLenum internalFormat
, GLuint width
, GLuint height
)
1736 ASSERT(arb
!= arb
->Wrapped
);
1737 ASSERT(arb
->Format
== MESA_FORMAT_A8
);
1739 /* first, pass the call to the wrapped RGB buffer */
1740 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1745 /* next, resize my alpha buffer */
1750 arb
->Data
= malloc(width
* height
* sizeof(GLubyte
));
1751 if (arb
->Data
== NULL
) {
1754 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1759 arb
->Height
= height
;
1760 arb
->RowStride
= width
;
1767 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1770 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1775 ASSERT(arb
->Wrapped
);
1776 ASSERT(arb
!= arb
->Wrapped
);
1777 arb
->Wrapped
->Delete(arb
->Wrapped
);
1778 arb
->Wrapped
= NULL
;
1784 get_pointer_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1787 return NULL
; /* don't allow direct access! */
1792 get_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1793 GLint x
, GLint y
, void *values
)
1795 /* NOTE: 'values' is RGBA format! */
1796 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1797 GLubyte
*dst
= (GLubyte
*) values
;
1799 ASSERT(arb
!= arb
->Wrapped
);
1800 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1801 /* first, pass the call to the wrapped RGB buffer */
1802 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1803 /* second, fill in alpha values from this buffer! */
1804 for (i
= 0; i
< count
; i
++) {
1805 dst
[i
* 4 + 3] = src
[i
];
1811 get_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1812 const GLint x
[], const GLint y
[], void *values
)
1814 GLubyte
*dst
= (GLubyte
*) values
;
1816 ASSERT(arb
!= arb
->Wrapped
);
1817 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1818 /* first, pass the call to the wrapped RGB buffer */
1819 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1820 /* second, fill in alpha values from this buffer! */
1821 for (i
= 0; i
< count
; i
++) {
1822 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1823 dst
[i
* 4 + 3] = *src
;
1829 put_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1830 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1832 const GLubyte
*src
= (const GLubyte
*) values
;
1833 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1835 ASSERT(arb
!= arb
->Wrapped
);
1836 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1837 /* first, pass the call to the wrapped RGB buffer */
1838 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1839 /* second, store alpha in our buffer */
1840 for (i
= 0; i
< count
; i
++) {
1841 if (!mask
|| mask
[i
]) {
1842 dst
[i
] = src
[i
* 4 + 3];
1849 put_row_rgb_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1850 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1852 const GLubyte
*src
= (const GLubyte
*) values
;
1853 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1855 ASSERT(arb
!= arb
->Wrapped
);
1856 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1857 /* first, pass the call to the wrapped RGB buffer */
1858 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1859 /* second, store alpha in our buffer */
1860 for (i
= 0; i
< count
; i
++) {
1861 if (!mask
|| mask
[i
]) {
1862 dst
[i
] = src
[i
* 4 + 3];
1869 put_mono_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1870 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1872 const GLubyte val
= ((const GLubyte
*) value
)[3];
1873 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1874 ASSERT(arb
!= arb
->Wrapped
);
1875 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1876 /* first, pass the call to the wrapped RGB buffer */
1877 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1878 /* second, store alpha in our buffer */
1881 for (i
= 0; i
< count
; i
++) {
1888 memset(dst
, val
, count
);
1894 put_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1895 const GLint x
[], const GLint y
[],
1896 const void *values
, const GLubyte
*mask
)
1898 const GLubyte
*src
= (const GLubyte
*) values
;
1900 ASSERT(arb
!= arb
->Wrapped
);
1901 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1902 /* first, pass the call to the wrapped RGB buffer */
1903 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1904 /* second, store alpha in our buffer */
1905 for (i
= 0; i
< count
; i
++) {
1906 if (!mask
|| mask
[i
]) {
1907 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1908 *dst
= src
[i
* 4 + 3];
1915 put_mono_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1916 GLuint count
, const GLint x
[], const GLint y
[],
1917 const void *value
, const GLubyte
*mask
)
1919 const GLubyte val
= ((const GLubyte
*) value
)[3];
1921 ASSERT(arb
!= arb
->Wrapped
);
1922 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1923 /* first, pass the call to the wrapped RGB buffer */
1924 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1925 /* second, store alpha in our buffer */
1926 for (i
= 0; i
< count
; i
++) {
1927 if (!mask
|| mask
[i
]) {
1928 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1936 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1938 ASSERT(dst
->Format
== MESA_FORMAT_A8
);
1939 ASSERT(src
->Format
== MESA_FORMAT_A8
);
1940 ASSERT(dst
->Width
== src
->Width
);
1941 ASSERT(dst
->Height
== src
->Height
);
1942 ASSERT(dst
->RowStride
== src
->RowStride
);
1944 memcpy(dst
->Data
, src
->Data
, dst
->RowStride
* dst
->Height
* sizeof(GLubyte
));
1948 /**********************************************************************/
1949 /**********************************************************************/
1950 /**********************************************************************/
1954 * Default GetPointer routine. Always return NULL to indicate that
1955 * direct buffer access is not supported.
1958 nop_get_pointer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1965 * Initialize the fields of a gl_renderbuffer to default values.
1968 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1970 _glthread_INIT_MUTEX(rb
->Mutex
);
1975 rb
->Delete
= _mesa_delete_renderbuffer
;
1977 /* The rest of these should be set later by the caller of this function or
1978 * the AllocStorage method:
1980 rb
->AllocStorage
= NULL
;
1984 rb
->InternalFormat
= GL_NONE
;
1985 rb
->Format
= MESA_FORMAT_NONE
;
1987 rb
->DataType
= GL_NONE
;
1990 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1991 * all over the drivers.
1995 rb
->GetPointer
= nop_get_pointer
;
1997 rb
->GetValues
= NULL
;
1999 rb
->PutRowRGB
= NULL
;
2000 rb
->PutMonoRow
= NULL
;
2001 rb
->PutValues
= NULL
;
2002 rb
->PutMonoValues
= NULL
;
2007 * Allocate a new gl_renderbuffer object. This can be used for user-created
2008 * renderbuffers or window-system renderbuffers.
2010 struct gl_renderbuffer
*
2011 _mesa_new_renderbuffer(struct gl_context
*ctx
, GLuint name
)
2013 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
2015 _mesa_init_renderbuffer(rb
, name
);
2022 * Delete a gl_framebuffer.
2023 * This is the default function for renderbuffer->Delete().
2026 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
2036 * Allocate a software-based renderbuffer. This is called via the
2037 * ctx->Driver.NewRenderbuffer() function when the user creates a new
2039 * This would not be used for hardware-based renderbuffers.
2041 struct gl_renderbuffer
*
2042 _mesa_new_soft_renderbuffer(struct gl_context
*ctx
, GLuint name
)
2044 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
2046 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2047 /* Normally, one would setup the PutRow, GetRow, etc functions here.
2048 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
2057 * Add software-based color renderbuffers to the given framebuffer.
2058 * This is a helper routine for device drivers when creating a
2059 * window system framebuffer (not a user-created render/framebuffer).
2060 * Once this function is called, you can basically forget about this
2061 * renderbuffer; core Mesa will handle all the buffer management and
2065 _mesa_add_color_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2066 GLuint rgbBits
, GLuint alphaBits
,
2067 GLboolean frontLeft
, GLboolean backLeft
,
2068 GLboolean frontRight
, GLboolean backRight
)
2072 if (rgbBits
> 16 || alphaBits
> 16) {
2074 "Unsupported bit depth in _mesa_add_color_renderbuffers");
2078 assert(MAX_COLOR_ATTACHMENTS
>= 4);
2080 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
2081 struct gl_renderbuffer
*rb
;
2083 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
2085 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
2087 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
2089 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
2092 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
2094 rb
= _mesa_new_renderbuffer(ctx
, 0);
2096 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
2102 rb
->Format
= MESA_FORMAT_RGBA8888
;
2104 rb
->Format
= MESA_FORMAT_RGB888
;
2107 assert(rgbBits
<= 16);
2108 rb
->Format
= MESA_FORMAT_NONE
; /*XXX RGBA16;*/
2110 rb
->InternalFormat
= GL_RGBA
;
2112 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2113 _mesa_add_renderbuffer(fb
, b
, rb
);
2121 * Add software-based alpha renderbuffers to the given framebuffer.
2122 * This is a helper routine for device drivers when creating a
2123 * window system framebuffer (not a user-created render/framebuffer).
2124 * Once this function is called, you can basically forget about this
2125 * renderbuffer; core Mesa will handle all the buffer management and
2129 _mesa_add_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2131 GLboolean frontLeft
, GLboolean backLeft
,
2132 GLboolean frontRight
, GLboolean backRight
)
2136 /* for window system framebuffers only! */
2137 assert(fb
->Name
== 0);
2139 if (alphaBits
> 8) {
2141 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
2145 assert(MAX_COLOR_ATTACHMENTS
>= 4);
2147 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
2149 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
2150 struct gl_renderbuffer
*arb
;
2152 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
2154 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
2156 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
2158 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
2161 /* the RGB buffer to wrap must already exist!! */
2162 assert(fb
->Attachment
[b
].Renderbuffer
);
2164 /* only GLubyte supported for now */
2165 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
2167 /* allocate alpha renderbuffer */
2168 arb
= _mesa_new_renderbuffer(ctx
, 0);
2170 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
2174 /* wrap the alpha renderbuffer around the RGB renderbuffer */
2175 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
2177 /* Set up my alphabuffer fields and plug in my functions.
2178 * The functions will put/get the alpha values from/to RGBA arrays
2179 * and then call the wrapped buffer's functions to handle the RGB
2182 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
2183 arb
->Format
= MESA_FORMAT_A8
;
2184 arb
->DataType
= arb
->Wrapped
->DataType
;
2185 arb
->AllocStorage
= alloc_storage_alpha8
;
2186 arb
->Delete
= delete_renderbuffer_alpha8
;
2187 arb
->GetPointer
= get_pointer_alpha8
;
2188 arb
->GetRow
= get_row_alpha8
;
2189 arb
->GetValues
= get_values_alpha8
;
2190 arb
->PutRow
= put_row_alpha8
;
2191 arb
->PutRowRGB
= put_row_rgb_alpha8
;
2192 arb
->PutMonoRow
= put_mono_row_alpha8
;
2193 arb
->PutValues
= put_values_alpha8
;
2194 arb
->PutMonoValues
= put_mono_values_alpha8
;
2196 /* clear the pointer to avoid assertion/sanity check failure later */
2197 fb
->Attachment
[b
].Renderbuffer
= NULL
;
2199 /* plug the alpha renderbuffer into the colorbuffer attachment */
2200 _mesa_add_renderbuffer(fb
, b
, arb
);
2208 * For framebuffers that use a software alpha channel wrapper
2209 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
2210 * copy the back buffer alpha channel into the front buffer alpha channel.
2213 _mesa_copy_soft_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
2215 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
2216 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
2217 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
2218 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
2221 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
2222 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
2223 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
2224 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
2229 * Add a software-based depth renderbuffer to the given framebuffer.
2230 * This is a helper routine for device drivers when creating a
2231 * window system framebuffer (not a user-created render/framebuffer).
2232 * Once this function is called, you can basically forget about this
2233 * renderbuffer; core Mesa will handle all the buffer management and
2237 _mesa_add_depth_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2240 struct gl_renderbuffer
*rb
;
2242 if (depthBits
> 32) {
2244 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
2248 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
2250 rb
= _mesa_new_renderbuffer(ctx
, 0);
2252 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
2256 if (depthBits
<= 16) {
2257 rb
->Format
= MESA_FORMAT_Z16
;
2258 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
2260 else if (depthBits
<= 24) {
2261 rb
->Format
= MESA_FORMAT_X8_Z24
;
2262 rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
2265 rb
->Format
= MESA_FORMAT_Z32
;
2266 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
2269 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2270 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
2277 * Add a software-based stencil renderbuffer to the given framebuffer.
2278 * This is a helper routine for device drivers when creating a
2279 * window system framebuffer (not a user-created render/framebuffer).
2280 * Once this function is called, you can basically forget about this
2281 * renderbuffer; core Mesa will handle all the buffer management and
2285 _mesa_add_stencil_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2288 struct gl_renderbuffer
*rb
;
2290 if (stencilBits
> 16) {
2292 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
2296 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
2298 rb
= _mesa_new_renderbuffer(ctx
, 0);
2300 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
2304 assert(stencilBits
<= 8);
2305 rb
->Format
= MESA_FORMAT_S8
;
2306 rb
->InternalFormat
= GL_STENCIL_INDEX8
;
2308 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2309 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
2316 * Add a software-based accumulation renderbuffer to the given framebuffer.
2317 * This is a helper routine for device drivers when creating a
2318 * window system framebuffer (not a user-created render/framebuffer).
2319 * Once this function is called, you can basically forget about this
2320 * renderbuffer; core Mesa will handle all the buffer management and
2324 _mesa_add_accum_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2325 GLuint redBits
, GLuint greenBits
,
2326 GLuint blueBits
, GLuint alphaBits
)
2328 struct gl_renderbuffer
*rb
;
2330 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
2332 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
2336 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
2338 rb
= _mesa_new_renderbuffer(ctx
, 0);
2340 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
2344 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
2345 rb
->InternalFormat
= GL_RGBA16_SNORM
;
2346 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2347 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
2355 * Add a software-based aux renderbuffer to the given framebuffer.
2356 * This is a helper routine for device drivers when creating a
2357 * window system framebuffer (not a user-created render/framebuffer).
2358 * Once this function is called, you can basically forget about this
2359 * renderbuffer; core Mesa will handle all the buffer management and
2362 * NOTE: color-index aux buffers not supported.
2365 _mesa_add_aux_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2366 GLuint colorBits
, GLuint numBuffers
)
2370 if (colorBits
> 16) {
2372 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
2376 assert(numBuffers
<= MAX_AUX_BUFFERS
);
2378 for (i
= 0; i
< numBuffers
; i
++) {
2379 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
2381 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
2384 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating aux buffer");
2388 assert (colorBits
<= 8);
2389 rb
->Format
= MESA_FORMAT_RGBA8888
;
2390 rb
->InternalFormat
= GL_RGBA
;
2392 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2393 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
2400 * Create/attach software-based renderbuffers to the given framebuffer.
2401 * This is a helper routine for device drivers. Drivers can just as well
2402 * call the individual _mesa_add_*_renderbuffer() routines directly.
2405 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
2413 GLboolean frontLeft
= GL_TRUE
;
2414 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
2415 GLboolean frontRight
= fb
->Visual
.stereoMode
;
2416 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
2419 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
2420 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
2421 _mesa_add_color_renderbuffers(NULL
, fb
,
2423 fb
->Visual
.alphaBits
,
2424 frontLeft
, backLeft
,
2425 frontRight
, backRight
);
2429 assert(fb
->Visual
.depthBits
> 0);
2430 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
2434 assert(fb
->Visual
.stencilBits
> 0);
2435 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
2439 assert(fb
->Visual
.accumRedBits
> 0);
2440 assert(fb
->Visual
.accumGreenBits
> 0);
2441 assert(fb
->Visual
.accumBlueBits
> 0);
2442 _mesa_add_accum_renderbuffer(NULL
, fb
,
2443 fb
->Visual
.accumRedBits
,
2444 fb
->Visual
.accumGreenBits
,
2445 fb
->Visual
.accumBlueBits
,
2446 fb
->Visual
.accumAlphaBits
);
2450 assert(fb
->Visual
.numAuxBuffers
> 0);
2451 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
2452 fb
->Visual
.numAuxBuffers
);
2456 assert(fb
->Visual
.alphaBits
> 0);
2457 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
2458 frontLeft
, backLeft
,
2459 frontRight
, backRight
);
2471 * Attach a renderbuffer to a framebuffer.
2472 * \param bufferName one of the BUFFER_x tokens
2475 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
2476 gl_buffer_index bufferName
, struct gl_renderbuffer
*rb
)
2480 assert(bufferName
< BUFFER_COUNT
);
2482 /* There should be no previous renderbuffer on this attachment point,
2483 * with the exception of depth/stencil since the same renderbuffer may
2486 assert(bufferName
== BUFFER_DEPTH
||
2487 bufferName
== BUFFER_STENCIL
||
2488 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
2490 /* winsys vs. user-created buffer cross check */
2498 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
2499 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
2500 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
2505 * Remove the named renderbuffer from the given framebuffer.
2506 * \param bufferName one of the BUFFER_x tokens
2509 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
,
2510 gl_buffer_index bufferName
)
2512 struct gl_renderbuffer
*rb
;
2514 assert(bufferName
< BUFFER_COUNT
);
2516 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
2520 _mesa_reference_renderbuffer(&rb
, NULL
);
2522 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
2527 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
2528 * dereference that buffer first. The new renderbuffer's refcount will
2529 * be incremented. The old renderbuffer's refcount will be decremented.
2532 _mesa_reference_renderbuffer(struct gl_renderbuffer
**ptr
,
2533 struct gl_renderbuffer
*rb
)
2542 /* Unreference the old renderbuffer */
2543 GLboolean deleteFlag
= GL_FALSE
;
2544 struct gl_renderbuffer
*oldRb
= *ptr
;
2546 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
2547 ASSERT(oldRb
->RefCount
> 0);
2549 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
2550 deleteFlag
= (oldRb
->RefCount
== 0);
2551 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
2554 oldRb
->Delete(oldRb
);
2562 /* reference new renderbuffer */
2563 _glthread_LOCK_MUTEX(rb
->Mutex
);
2565 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
2566 _glthread_UNLOCK_MUTEX(rb
->Mutex
);