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
) {
69 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV
:
74 case GL_UNSIGNED_INT_24_8_EXT
:
77 case GL_UNSIGNED_SHORT
:
80 case GL_UNSIGNED_BYTE
:
88 switch (rb
->_BaseFormat
) {
89 case GL_DEPTH_COMPONENT
:
90 case GL_DEPTH_STENCIL
:
91 return component_size
;
93 return 4 * component_size
;
97 /* This is commonly used by most of the accessors. */
99 get_pointer_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
105 return ((char *) rb
->Data
+
106 (y
* rb
->RowStride
+ x
) * _mesa_get_format_bytes(rb
->Format
));
109 /* GetRow() implementation for formats where DataType matches the rb->Format.
112 get_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
113 GLuint count
, GLint x
, GLint y
, void *values
)
115 void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
116 memcpy(values
, src
, count
* _mesa_get_format_bytes(rb
->Format
));
119 /* Only used for float textures currently, but might also be used for
120 * RGBA8888, RGBA16, etc.
123 get_values_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
124 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
126 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
129 for (i
= 0; i
< count
; i
++) {
130 const void *src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
131 char *dst
= (char *) values
+ i
* format_bytes
;
132 memcpy(dst
, src
, format_bytes
);
136 /* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and
137 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of
138 * storing those initial components of the value per pixel into the
142 put_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
143 GLuint count
, GLint x
, GLint y
,
144 const void *values
, const GLubyte
*mask
)
146 void *row
= rb
->GetPointer(ctx
, rb
, x
, y
);
147 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
148 int datatype_bytes
= get_datatype_bytes(rb
);
152 for (i
= 0; i
< count
; i
++) {
153 char *dst
= (char *) row
+ i
* format_bytes
;
154 const char *src
= (const char *) values
+ i
* datatype_bytes
;
157 memcpy(dst
, src
, format_bytes
);
162 for (i
= 0; i
< count
; i
++) {
163 char *dst
= (char *) row
+ i
* format_bytes
;
164 const char *src
= (const char *) values
+ i
* datatype_bytes
;
165 memcpy(dst
, src
, format_bytes
);
171 put_mono_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
172 GLuint count
, GLint x
, GLint y
,
173 const void *value
, const GLubyte
*mask
)
175 void *row
= rb
->GetPointer(ctx
, rb
, x
, y
);
176 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
180 for (i
= 0; i
< count
; i
++) {
181 char *dst
= (char *) row
+ i
* format_bytes
;
183 memcpy(dst
, value
, format_bytes
);
188 for (i
= 0; i
< count
; i
++) {
189 char *dst
= (char *) row
+ i
* format_bytes
;
190 memcpy(dst
, value
, format_bytes
);
197 put_values_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
198 GLuint count
, const GLint x
[], const GLint y
[],
199 const void *values
, const GLubyte
*mask
)
201 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
202 int datatype_bytes
= get_datatype_bytes(rb
);
205 for (i
= 0; i
< count
; i
++) {
206 if (!mask
|| mask
[i
]) {
207 void *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
208 const char *src
= (const char *) values
+ i
* datatype_bytes
;
209 memcpy(dst
, src
, format_bytes
);
216 put_mono_values_generic(struct gl_context
*ctx
,
217 struct gl_renderbuffer
*rb
,
218 GLuint count
, const GLint x
[], const GLint y
[],
219 const void *value
, const GLubyte
*mask
)
221 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
224 for (i
= 0; i
< count
; i
++) {
225 if (!mask
|| mask
[i
]) {
226 void *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
227 memcpy(dst
, value
, format_bytes
);
232 /**********************************************************************
233 * Functions for buffers of 1 X GLubyte values.
238 get_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
239 const GLint x
[], const GLint y
[], void *values
)
241 GLubyte
*dst
= (GLubyte
*) values
;
243 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
244 for (i
= 0; i
< count
; i
++) {
245 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
252 put_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
253 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
255 const GLubyte
*src
= (const GLubyte
*) values
;
256 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
257 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
260 for (i
= 0; i
< count
; i
++) {
267 memcpy(dst
, values
, count
* sizeof(GLubyte
));
273 put_mono_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
274 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
276 const GLubyte val
= *((const GLubyte
*) value
);
277 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
278 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
281 for (i
= 0; i
< count
; i
++) {
289 for (i
= 0; i
< count
; i
++) {
297 put_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
298 const GLint x
[], const GLint y
[],
299 const void *values
, const GLubyte
*mask
)
301 const GLubyte
*src
= (const GLubyte
*) values
;
303 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
304 for (i
= 0; i
< count
; i
++) {
305 if (!mask
|| mask
[i
]) {
306 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
314 put_mono_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
315 const GLint x
[], const GLint y
[],
316 const void *value
, const GLubyte
*mask
)
318 const GLubyte val
= *((const GLubyte
*) value
);
320 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
321 for (i
= 0; i
< count
; i
++) {
322 if (!mask
|| mask
[i
]) {
323 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
330 /**********************************************************************
331 * Functions for buffers of 1 X GLushort values.
336 get_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
337 const GLint x
[], const GLint y
[], void *values
)
339 GLushort
*dst
= (GLushort
*) values
;
341 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
342 for (i
= 0; i
< count
; i
++) {
343 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
350 put_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
351 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
353 const GLushort
*src
= (const GLushort
*) values
;
354 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
355 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
358 for (i
= 0; i
< count
; i
++) {
365 memcpy(dst
, src
, count
* sizeof(GLushort
));
371 put_mono_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
372 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
374 const GLushort val
= *((const GLushort
*) value
);
375 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
376 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
379 for (i
= 0; i
< count
; i
++) {
387 for (i
= 0; i
< count
; i
++) {
395 put_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
396 const GLint x
[], const GLint y
[], const void *values
,
399 const GLushort
*src
= (const GLushort
*) values
;
401 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
402 for (i
= 0; i
< count
; i
++) {
403 if (!mask
|| mask
[i
]) {
404 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
412 put_mono_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
413 GLuint count
, const GLint x
[], const GLint y
[],
414 const void *value
, const GLubyte
*mask
)
416 const GLushort val
= *((const GLushort
*) value
);
417 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
420 for (i
= 0; i
< count
; i
++) {
422 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
429 for (i
= 0; i
< count
; i
++) {
430 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
437 /**********************************************************************
438 * Functions for buffers of 1 X GLuint values.
439 * Typically depth/Z or color index.
443 get_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
444 const GLint x
[], const GLint y
[], void *values
)
446 GLuint
*dst
= (GLuint
*) values
;
448 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
449 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
450 for (i
= 0; i
< count
; i
++) {
451 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
458 put_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
459 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
461 const GLuint
*src
= (const GLuint
*) values
;
462 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
463 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
464 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
467 for (i
= 0; i
< count
; i
++) {
474 memcpy(dst
, src
, count
* sizeof(GLuint
));
480 put_mono_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
481 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
483 const GLuint val
= *((const GLuint
*) value
);
484 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
485 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
486 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
489 for (i
= 0; i
< count
; i
++) {
497 for (i
= 0; i
< count
; i
++) {
505 put_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
506 const GLint x
[], const GLint y
[], const void *values
,
509 const GLuint
*src
= (const GLuint
*) values
;
511 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
512 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
513 for (i
= 0; i
< count
; i
++) {
514 if (!mask
|| mask
[i
]) {
515 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
523 put_mono_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
524 const GLint x
[], const GLint y
[], const void *value
,
527 const GLuint val
= *((const GLuint
*) value
);
529 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
530 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
531 for (i
= 0; i
< count
; i
++) {
532 if (!mask
|| mask
[i
]) {
533 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
540 /**********************************************************************
541 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
542 * Typically color buffers.
543 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
544 * alpha values and return 255 for outgoing alpha values.
548 get_pointer_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
551 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
552 /* No direct access since this buffer is RGB but caller will be
553 * treating it as if it were RGBA.
560 get_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
561 GLint x
, GLint y
, void *values
)
563 const GLubyte
*src
= ((const GLubyte
*) rb
->Data
) +
564 3 * (y
* rb
->RowStride
+ x
);
565 GLubyte
*dst
= (GLubyte
*) values
;
567 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
568 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
569 for (i
= 0; i
< count
; i
++) {
570 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
571 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
572 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
573 dst
[i
* 4 + 3] = 255;
579 get_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
580 const GLint x
[], const GLint y
[], void *values
)
582 GLubyte
*dst
= (GLubyte
*) values
;
584 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
585 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
586 for (i
= 0; i
< count
; i
++) {
588 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
589 dst
[i
* 4 + 0] = src
[0];
590 dst
[i
* 4 + 1] = src
[1];
591 dst
[i
* 4 + 2] = src
[2];
592 dst
[i
* 4 + 3] = 255;
598 put_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
599 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
601 /* note: incoming values are RGB+A! */
602 const GLubyte
*src
= (const GLubyte
*) values
;
603 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
605 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
606 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
607 for (i
= 0; i
< count
; i
++) {
608 if (!mask
|| mask
[i
]) {
609 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
610 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
611 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
618 put_row_rgb_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
619 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
621 /* note: incoming values are RGB+A! */
622 const GLubyte
*src
= (const GLubyte
*) values
;
623 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
625 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
626 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
627 for (i
= 0; i
< count
; i
++) {
628 if (!mask
|| mask
[i
]) {
629 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
630 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
631 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
638 put_mono_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
639 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
641 /* note: incoming value is RGB+A! */
642 const GLubyte val0
= ((const GLubyte
*) value
)[0];
643 const GLubyte val1
= ((const GLubyte
*) value
)[1];
644 const GLubyte val2
= ((const GLubyte
*) value
)[2];
645 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
646 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
647 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
648 if (!mask
&& val0
== val1
&& val1
== val2
) {
650 memset(dst
, val0
, 3 * count
);
654 for (i
= 0; i
< count
; i
++) {
655 if (!mask
|| mask
[i
]) {
656 dst
[i
* 3 + 0] = val0
;
657 dst
[i
* 3 + 1] = val1
;
658 dst
[i
* 3 + 2] = val2
;
666 put_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
667 const GLint x
[], const GLint y
[], const void *values
,
670 /* note: incoming values are RGB+A! */
671 const GLubyte
*src
= (const GLubyte
*) values
;
673 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
674 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
675 for (i
= 0; i
< count
; i
++) {
676 if (!mask
|| mask
[i
]) {
677 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
678 dst
[0] = src
[i
* 4 + 0];
679 dst
[1] = src
[i
* 4 + 1];
680 dst
[2] = src
[i
* 4 + 2];
687 put_mono_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
688 GLuint count
, const GLint x
[], const GLint y
[],
689 const void *value
, const GLubyte
*mask
)
691 /* note: incoming value is RGB+A! */
692 const GLubyte val0
= ((const GLubyte
*) value
)[0];
693 const GLubyte val1
= ((const GLubyte
*) value
)[1];
694 const GLubyte val2
= ((const GLubyte
*) value
)[2];
696 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
697 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
698 for (i
= 0; i
< count
; i
++) {
699 if (!mask
|| mask
[i
]) {
700 GLubyte
*dst
= ((GLubyte
*) rb
->Data
) +
701 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
710 /**********************************************************************
711 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
712 * Typically color buffers.
716 get_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
717 const GLint x
[], const GLint y
[], void *values
)
719 /* treat 4*GLubyte as 1*GLuint */
720 GLuint
*dst
= (GLuint
*) values
;
722 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
723 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
724 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
725 for (i
= 0; i
< count
; i
++) {
726 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
733 put_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
734 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
736 /* treat 4*GLubyte as 1*GLuint */
737 const GLuint
*src
= (const GLuint
*) values
;
738 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
739 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
740 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
741 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
744 for (i
= 0; i
< count
; i
++) {
751 memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
757 put_row_rgb_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
758 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
760 /* Store RGB values in RGBA buffer */
761 const GLubyte
*src
= (const GLubyte
*) values
;
762 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
764 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
765 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
766 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
767 for (i
= 0; i
< count
; i
++) {
768 if (!mask
|| mask
[i
]) {
769 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
770 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
771 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
772 dst
[i
* 4 + 3] = 0xff;
779 put_mono_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
780 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
782 /* treat 4*GLubyte as 1*GLuint */
783 const GLuint val
= *((const GLuint
*) value
);
784 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
785 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
786 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
787 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
788 if (!mask
&& val
== 0) {
790 memset(dst
, 0, count
* 4 * sizeof(GLubyte
));
796 for (i
= 0; i
< count
; i
++) {
804 for (i
= 0; i
< count
; i
++) {
813 put_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
814 const GLint x
[], const GLint y
[], const void *values
,
817 /* treat 4*GLubyte as 1*GLuint */
818 const GLuint
*src
= (const GLuint
*) values
;
820 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
821 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
822 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
823 for (i
= 0; i
< count
; i
++) {
824 if (!mask
|| mask
[i
]) {
825 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
833 put_mono_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
834 GLuint count
, const GLint x
[], const GLint y
[],
835 const void *value
, const GLubyte
*mask
)
837 /* treat 4*GLubyte as 1*GLuint */
838 const GLuint val
= *((const GLuint
*) value
);
840 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
841 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
842 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
843 for (i
= 0; i
< count
; i
++) {
844 if (!mask
|| mask
[i
]) {
845 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
852 /**********************************************************************
853 * Functions for buffers of 4 X GLushort (or GLshort) values.
854 * Typically accum buffer.
858 get_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
859 const GLint x
[], const GLint y
[], void *values
)
861 GLushort
*dst
= (GLushort
*) values
;
863 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
864 for (i
= 0; i
< count
; i
++) {
866 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
873 put_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
874 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
876 const GLushort
*src
= (const GLushort
*) values
;
877 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
878 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
881 for (i
= 0; i
< count
; i
++) {
883 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
884 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
885 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
886 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
891 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
897 put_row_rgb_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
898 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
900 /* Put RGB values in RGBA buffer */
901 const GLushort
*src
= (const GLushort
*) values
;
902 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
903 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
906 for (i
= 0; i
< count
; i
++) {
908 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
909 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
910 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
911 dst
[i
* 4 + 3] = 0xffff;
916 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
922 put_mono_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
923 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
925 const GLushort val0
= ((const GLushort
*) value
)[0];
926 const GLushort val1
= ((const GLushort
*) value
)[1];
927 const GLushort val2
= ((const GLushort
*) value
)[2];
928 const GLushort val3
= ((const GLushort
*) value
)[3];
929 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
930 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
931 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
932 /* common case for clearing accum buffer */
933 memset(dst
, 0, count
* 4 * sizeof(GLushort
));
937 for (i
= 0; i
< count
; i
++) {
938 if (!mask
|| mask
[i
]) {
939 dst
[i
* 4 + 0] = val0
;
940 dst
[i
* 4 + 1] = val1
;
941 dst
[i
* 4 + 2] = val2
;
942 dst
[i
* 4 + 3] = val3
;
950 put_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
951 const GLint x
[], const GLint y
[], const void *values
,
954 const GLushort
*src
= (const GLushort
*) values
;
956 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
957 for (i
= 0; i
< count
; i
++) {
958 if (!mask
|| mask
[i
]) {
960 ((GLushort
*) rb
->Data
) + 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
961 dst
[0] = src
[i
* 4 + 0];
962 dst
[1] = src
[i
* 4 + 1];
963 dst
[2] = src
[i
* 4 + 2];
964 dst
[3] = src
[i
* 4 + 3];
971 put_mono_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
972 GLuint count
, const GLint x
[], const GLint y
[],
973 const void *value
, const GLubyte
*mask
)
975 const GLushort val0
= ((const GLushort
*) value
)[0];
976 const GLushort val1
= ((const GLushort
*) value
)[1];
977 const GLushort val2
= ((const GLushort
*) value
)[2];
978 const GLushort val3
= ((const GLushort
*) value
)[3];
980 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
981 for (i
= 0; i
< count
; i
++) {
982 if (!mask
|| mask
[i
]) {
983 GLushort
*dst
= ((GLushort
*) rb
->Data
) +
984 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
993 /**********************************************************************
994 * Functions for MESA_FORMAT_R8.
997 get_row_r8(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
998 GLint x
, GLint y
, void *values
)
1000 const GLubyte
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1001 GLuint
*dst
= values
;
1004 for (i
= 0; i
< count
; i
++) {
1005 dst
[i
] = 0xff000000 | src
[i
];
1010 get_values_r8(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1011 const GLint x
[], const GLint y
[], void *values
)
1013 GLuint
*dst
= (GLuint
*) values
;
1016 for (i
= 0; i
< count
; i
++) {
1017 const GLubyte
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1018 dst
[i
] = 0xff000000 | *src
;
1022 /**********************************************************************
1023 * Functions for MESA_FORMAT_RG88.
1026 get_row_rg88(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1027 GLint x
, GLint y
, void *values
)
1029 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1030 GLuint
*dst
= values
;
1033 for (i
= 0; i
< count
; i
++) {
1034 dst
[i
] = 0xff000000 | src
[i
];
1039 get_values_rg88(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1040 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
1042 GLuint
*dst
= (GLuint
*) values
;
1045 for (i
= 0; i
< count
; i
++) {
1046 const GLshort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1047 dst
[i
] = 0xff000000 | *src
;
1051 /**********************************************************************
1052 * Functions for MESA_FORMAT_R16.
1055 get_row_r16(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1056 GLint x
, GLint y
, void *values
)
1058 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1059 GLushort
*dst
= values
;
1062 for (i
= 0; i
< count
; i
++) {
1063 dst
[i
* 4 + RCOMP
] = src
[i
];
1064 dst
[i
* 4 + GCOMP
] = 0;
1065 dst
[i
* 4 + BCOMP
] = 0;
1066 dst
[i
* 4 + ACOMP
] = 0xffff;
1071 get_values_r16(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1072 const GLint x
[], const GLint y
[], void *values
)
1074 GLushort
*dst
= values
;
1077 for (i
= 0; i
< count
; i
++) {
1078 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1079 dst
[i
* 4 + RCOMP
] = *src
;
1080 dst
[i
* 4 + GCOMP
] = 0;
1081 dst
[i
* 4 + BCOMP
] = 0;
1082 dst
[i
* 4 + ACOMP
] = 0xffff;
1086 /**********************************************************************
1087 * Functions for MESA_FORMAT_RG1616.
1090 get_row_rg1616(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1091 GLint x
, GLint y
, void *values
)
1093 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1094 GLushort
*dst
= values
;
1097 for (i
= 0; i
< count
; i
++) {
1098 dst
[i
* 4 + RCOMP
] = src
[i
* 2];
1099 dst
[i
* 4 + GCOMP
] = src
[i
* 2 + 1];
1100 dst
[i
* 4 + BCOMP
] = 0;
1101 dst
[i
* 4 + ACOMP
] = 0xffff;
1106 get_values_rg1616(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1107 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
1109 GLushort
*dst
= values
;
1112 for (i
= 0; i
< count
; i
++) {
1113 const GLshort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1114 dst
[i
* 4 + RCOMP
] = src
[0];
1115 dst
[i
* 4 + GCOMP
] = src
[1];
1116 dst
[i
* 4 + BCOMP
] = 0;
1117 dst
[i
* 4 + ACOMP
] = 0xffff;
1121 /**********************************************************************
1122 * Functions for MESA_FORMAT_INTENSITY_FLOAT32.
1125 get_row_i_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1126 GLuint count
, GLint x
, GLint y
, void *values
)
1128 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1129 GLfloat
*dst
= values
;
1132 for (i
= 0; i
< count
; i
++) {
1133 dst
[i
* 4 + RCOMP
] =
1134 dst
[i
* 4 + GCOMP
] =
1135 dst
[i
* 4 + BCOMP
] =
1136 dst
[i
* 4 + ACOMP
] = src
[i
];
1141 get_values_i_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1142 GLuint count
, const GLint x
[], const GLint y
[],
1145 GLfloat
*dst
= values
;
1148 for (i
= 0; i
< count
; i
++) {
1149 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1150 dst
[i
* 4 + RCOMP
] =
1151 dst
[i
* 4 + GCOMP
] =
1152 dst
[i
* 4 + BCOMP
] =
1153 dst
[i
* 4 + ACOMP
] = src
[0];
1157 /**********************************************************************
1158 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32.
1161 get_row_l_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1162 GLuint count
, GLint x
, GLint y
, void *values
)
1164 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1165 GLfloat
*dst
= values
;
1168 for (i
= 0; i
< count
; i
++) {
1169 dst
[i
* 4 + RCOMP
] =
1170 dst
[i
* 4 + GCOMP
] =
1171 dst
[i
* 4 + BCOMP
] = src
[i
];
1172 dst
[i
* 4 + ACOMP
] = 1.0;
1177 get_values_l_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1178 GLuint count
, const GLint x
[], const GLint y
[],
1181 GLfloat
*dst
= values
;
1184 for (i
= 0; i
< count
; i
++) {
1185 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1186 dst
[i
* 4 + RCOMP
] =
1187 dst
[i
* 4 + GCOMP
] =
1188 dst
[i
* 4 + BCOMP
] = src
[0];
1189 dst
[i
* 4 + ACOMP
] = 1.0;
1193 /**********************************************************************
1194 * Functions for MESA_FORMAT_ALPHA_FLOAT32.
1197 get_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1198 GLuint count
, GLint x
, GLint y
, void *values
)
1200 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1201 GLfloat
*dst
= values
;
1204 for (i
= 0; i
< count
; i
++) {
1205 dst
[i
* 4 + RCOMP
] = 0.0;
1206 dst
[i
* 4 + GCOMP
] = 0.0;
1207 dst
[i
* 4 + BCOMP
] = 0.0;
1208 dst
[i
* 4 + ACOMP
] = src
[i
];
1213 get_values_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1214 GLuint count
, const GLint x
[], const GLint y
[],
1217 GLfloat
*dst
= values
;
1220 for (i
= 0; i
< count
; i
++) {
1221 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1222 dst
[i
* 4 + RCOMP
] = 0.0;
1223 dst
[i
* 4 + GCOMP
] = 0.0;
1224 dst
[i
* 4 + BCOMP
] = 0.0;
1225 dst
[i
* 4 + ACOMP
] = src
[0];
1230 put_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1231 GLuint count
, GLint x
, GLint y
,
1232 const void *values
, const GLubyte
*mask
)
1234 float *dst
= rb
->GetPointer(ctx
, rb
, x
, y
);
1235 const float *src
= values
;
1239 for (i
= 0; i
< count
; i
++) {
1241 dst
[i
] = src
[i
* 4 + ACOMP
];
1246 for (i
= 0; i
< count
; i
++) {
1247 dst
[i
] = src
[i
* 4 + ACOMP
];
1253 put_mono_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1254 GLuint count
, GLint x
, GLint y
,
1255 const void *value
, const GLubyte
*mask
)
1257 float *dst
= rb
->GetPointer(ctx
, rb
, x
, y
);
1258 const float *src
= value
;
1262 for (i
= 0; i
< count
; i
++) {
1264 dst
[i
] = src
[ACOMP
];
1269 for (i
= 0; i
< count
; i
++) {
1270 dst
[i
] = src
[ACOMP
];
1276 put_values_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1277 GLuint count
, const GLint x
[], const GLint y
[],
1278 const void *values
, const GLubyte
*mask
)
1280 const float *src
= values
;
1283 for (i
= 0; i
< count
; i
++) {
1284 if (!mask
|| mask
[i
]) {
1285 float *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1287 *dst
= src
[i
* 4 + ACOMP
];
1293 put_mono_values_a_float32(struct gl_context
*ctx
,
1294 struct gl_renderbuffer
*rb
,
1295 GLuint count
, const GLint x
[], const GLint y
[],
1296 const void *value
, const GLubyte
*mask
)
1298 const float *src
= value
;
1301 for (i
= 0; i
< count
; i
++) {
1302 if (!mask
|| mask
[i
]) {
1303 float *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1309 /**********************************************************************
1310 * Functions for MESA_FORMAT_R_FLOAT32.
1313 get_row_r_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1314 GLuint count
, GLint x
, GLint y
, void *values
)
1316 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1317 GLfloat
*dst
= values
;
1320 for (i
= 0; i
< count
; i
++) {
1321 dst
[i
* 4 + RCOMP
] = src
[i
];
1322 dst
[i
* 4 + GCOMP
] = 0.0;
1323 dst
[i
* 4 + BCOMP
] = 0.0;
1324 dst
[i
* 4 + ACOMP
] = 1.0;
1329 get_values_r_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1330 GLuint count
, const GLint x
[], const GLint y
[],
1333 GLfloat
*dst
= values
;
1336 for (i
= 0; i
< count
; i
++) {
1337 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1338 dst
[i
* 4 + RCOMP
] = src
[0];
1339 dst
[i
* 4 + GCOMP
] = 0.0;
1340 dst
[i
* 4 + BCOMP
] = 0.0;
1341 dst
[i
* 4 + ACOMP
] = 1.0;
1345 /**********************************************************************
1346 * Functions for MESA_FORMAT_RG_FLOAT32.
1349 get_row_rg_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1350 GLuint count
, GLint x
, GLint y
, void *values
)
1352 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1353 GLfloat
*dst
= values
;
1356 for (i
= 0; i
< count
; i
++) {
1357 dst
[i
* 4 + RCOMP
] = src
[i
* 2 + 0];
1358 dst
[i
* 4 + GCOMP
] = src
[i
* 2 + 1];
1359 dst
[i
* 4 + BCOMP
] = 0.0;
1360 dst
[i
* 4 + ACOMP
] = 1.0;
1365 get_values_rg_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1366 GLuint count
, const GLint x
[], const GLint y
[],
1369 GLfloat
*dst
= values
;
1372 for (i
= 0; i
< count
; i
++) {
1373 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1374 dst
[i
* 4 + RCOMP
] = src
[0];
1375 dst
[i
* 4 + GCOMP
] = src
[1];
1376 dst
[i
* 4 + BCOMP
] = 0.0;
1377 dst
[i
* 4 + ACOMP
] = 1.0;
1382 * This is the default software fallback for gl_renderbuffer's span
1385 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
1386 * are packed in the type of rb->Format, and that subsequent rows appear
1387 * rb->RowStride pixels later.
1390 _mesa_set_renderbuffer_accessors(struct gl_renderbuffer
*rb
)
1392 rb
->GetPointer
= get_pointer_generic
;
1393 rb
->GetRow
= get_row_generic
;
1395 switch (rb
->Format
) {
1396 case MESA_FORMAT_RGB888
:
1397 rb
->DataType
= GL_UNSIGNED_BYTE
;
1398 rb
->GetPointer
= get_pointer_ubyte3
;
1399 rb
->GetRow
= get_row_ubyte3
;
1400 rb
->GetValues
= get_values_ubyte3
;
1401 rb
->PutRow
= put_row_ubyte3
;
1402 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
1403 rb
->PutMonoRow
= put_mono_row_ubyte3
;
1404 rb
->PutValues
= put_values_ubyte3
;
1405 rb
->PutMonoValues
= put_mono_values_ubyte3
;
1408 case MESA_FORMAT_RGBA8888
:
1409 case MESA_FORMAT_RGBA8888_REV
:
1410 rb
->DataType
= GL_UNSIGNED_BYTE
;
1411 rb
->GetValues
= get_values_ubyte4
;
1412 rb
->PutRow
= put_row_ubyte4
;
1413 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
1414 rb
->PutMonoRow
= put_mono_row_ubyte4
;
1415 rb
->PutValues
= put_values_ubyte4
;
1416 rb
->PutMonoValues
= put_mono_values_ubyte4
;
1419 case MESA_FORMAT_R8
:
1420 rb
->DataType
= GL_UNSIGNED_BYTE
;
1421 rb
->GetValues
= get_values_r8
;
1422 rb
->GetRow
= get_row_r8
;
1423 rb
->PutRow
= put_row_generic
;
1424 rb
->PutRowRGB
= put_row_generic
;
1425 rb
->PutMonoRow
= put_mono_row_generic
;
1426 rb
->PutValues
= put_values_generic
;
1427 rb
->PutMonoValues
= put_mono_values_generic
;
1430 case MESA_FORMAT_RG88
:
1431 rb
->DataType
= GL_UNSIGNED_BYTE
;
1432 rb
->GetValues
= get_values_rg88
;
1433 rb
->GetRow
= get_row_rg88
;
1434 rb
->PutRow
= put_row_generic
;
1435 rb
->PutRowRGB
= put_row_generic
;
1436 rb
->PutMonoRow
= put_mono_row_generic
;
1437 rb
->PutValues
= put_values_generic
;
1438 rb
->PutMonoValues
= put_mono_values_generic
;
1441 case MESA_FORMAT_R16
:
1442 rb
->DataType
= GL_UNSIGNED_SHORT
;
1443 rb
->GetValues
= get_values_r16
;
1444 rb
->GetRow
= get_row_r16
;
1445 rb
->PutRow
= put_row_generic
;
1446 rb
->PutRowRGB
= put_row_generic
;
1447 rb
->PutMonoRow
= put_mono_row_generic
;
1448 rb
->PutValues
= put_values_generic
;
1449 rb
->PutMonoValues
= put_mono_values_generic
;
1452 case MESA_FORMAT_RG1616
:
1453 rb
->DataType
= GL_UNSIGNED_SHORT
;
1454 rb
->GetValues
= get_values_rg1616
;
1455 rb
->GetRow
= get_row_rg1616
;
1456 rb
->PutRow
= put_row_generic
;
1457 rb
->PutRowRGB
= put_row_generic
;
1458 rb
->PutMonoRow
= put_mono_row_generic
;
1459 rb
->PutValues
= put_values_generic
;
1460 rb
->PutMonoValues
= put_mono_values_generic
;
1463 case MESA_FORMAT_SIGNED_RGBA_16
:
1464 rb
->DataType
= GL_SHORT
;
1465 rb
->GetValues
= get_values_ushort4
;
1466 rb
->PutRow
= put_row_ushort4
;
1467 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1468 rb
->PutMonoRow
= put_mono_row_ushort4
;
1469 rb
->PutValues
= put_values_ushort4
;
1470 rb
->PutMonoValues
= put_mono_values_ushort4
;
1474 case MESA_FORMAT_A8
:
1475 rb
->DataType
= GL_UNSIGNED_BYTE
;
1476 rb
->GetValues
= get_values_alpha8
;
1477 rb
->PutRow
= put_row_alpha8
;
1478 rb
->PutRowRGB
= NULL
;
1479 rb
->PutMonoRow
= put_mono_row_alpha8
;
1480 rb
->PutValues
= put_values_alpha8
;
1481 rb
->PutMonoValues
= put_mono_values_alpha8
;
1485 case MESA_FORMAT_S8
:
1486 rb
->DataType
= GL_UNSIGNED_BYTE
;
1487 rb
->GetValues
= get_values_ubyte
;
1488 rb
->PutRow
= put_row_ubyte
;
1489 rb
->PutRowRGB
= NULL
;
1490 rb
->PutMonoRow
= put_mono_row_ubyte
;
1491 rb
->PutValues
= put_values_ubyte
;
1492 rb
->PutMonoValues
= put_mono_values_ubyte
;
1495 case MESA_FORMAT_Z16
:
1496 rb
->DataType
= GL_UNSIGNED_SHORT
;
1497 rb
->GetValues
= get_values_ushort
;
1498 rb
->PutRow
= put_row_ushort
;
1499 rb
->PutRowRGB
= NULL
;
1500 rb
->PutMonoRow
= put_mono_row_ushort
;
1501 rb
->PutValues
= put_values_ushort
;
1502 rb
->PutMonoValues
= put_mono_values_ushort
;
1505 case MESA_FORMAT_Z32
:
1506 case MESA_FORMAT_X8_Z24
:
1507 case MESA_FORMAT_Z24_X8
:
1508 rb
->DataType
= GL_UNSIGNED_INT
;
1509 rb
->GetValues
= get_values_uint
;
1510 rb
->PutRow
= put_row_uint
;
1511 rb
->PutRowRGB
= NULL
;
1512 rb
->PutMonoRow
= put_mono_row_uint
;
1513 rb
->PutValues
= put_values_uint
;
1514 rb
->PutMonoValues
= put_mono_values_uint
;
1517 case MESA_FORMAT_Z24_S8
:
1518 case MESA_FORMAT_S8_Z24
:
1519 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1520 rb
->GetValues
= get_values_uint
;
1521 rb
->PutRow
= put_row_uint
;
1522 rb
->PutRowRGB
= NULL
;
1523 rb
->PutMonoRow
= put_mono_row_uint
;
1524 rb
->PutValues
= put_values_uint
;
1525 rb
->PutMonoValues
= put_mono_values_uint
;
1528 case MESA_FORMAT_RGBA_FLOAT32
:
1529 rb
->GetRow
= get_row_generic
;
1530 rb
->GetValues
= get_values_generic
;
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_INTENSITY_FLOAT32
:
1539 rb
->GetRow
= get_row_i_float32
;
1540 rb
->GetValues
= get_values_i_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_LUMINANCE_FLOAT32
:
1549 rb
->GetRow
= get_row_l_float32
;
1550 rb
->GetValues
= get_values_l_float32
;
1551 rb
->PutRow
= put_row_generic
;
1552 rb
->PutRowRGB
= NULL
;
1553 rb
->PutMonoRow
= put_mono_row_generic
;
1554 rb
->PutValues
= put_values_generic
;
1555 rb
->PutMonoValues
= put_mono_values_generic
;
1558 case MESA_FORMAT_ALPHA_FLOAT32
:
1559 rb
->GetRow
= get_row_a_float32
;
1560 rb
->GetValues
= get_values_a_float32
;
1561 rb
->PutRow
= put_row_a_float32
;
1562 rb
->PutRowRGB
= NULL
;
1563 rb
->PutMonoRow
= put_mono_row_a_float32
;
1564 rb
->PutValues
= put_values_a_float32
;
1565 rb
->PutMonoValues
= put_mono_values_a_float32
;
1568 case MESA_FORMAT_RG_FLOAT32
:
1569 rb
->GetRow
= get_row_rg_float32
;
1570 rb
->GetValues
= get_values_rg_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
;
1578 case MESA_FORMAT_R_FLOAT32
:
1579 rb
->GetRow
= get_row_r_float32
;
1580 rb
->GetValues
= get_values_r_float32
;
1581 rb
->PutRow
= put_row_generic
;
1582 rb
->PutRowRGB
= NULL
;
1583 rb
->PutMonoRow
= put_mono_row_generic
;
1584 rb
->PutValues
= put_values_generic
;
1585 rb
->PutMonoValues
= put_mono_values_generic
;
1594 * This is a software fallback for the gl_renderbuffer->AllocStorage
1596 * Device drivers will typically override this function for the buffers
1597 * which it manages (typically color buffers, Z and stencil).
1598 * Other buffers (like software accumulation and aux buffers) which the driver
1599 * doesn't manage can be handled with this function.
1601 * This one multi-purpose function can allocate stencil, depth, accum, color
1602 * or color-index buffers!
1604 * This function also plugs in the appropriate GetPointer, Get/PutRow and
1605 * Get/PutValues functions.
1608 _mesa_soft_renderbuffer_storage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1609 GLenum internalFormat
,
1610 GLuint width
, GLuint height
)
1612 switch (internalFormat
) {
1621 rb
->Format
= MESA_FORMAT_RGB888
;
1632 if (_mesa_little_endian())
1633 rb
->Format
= MESA_FORMAT_RGBA8888_REV
;
1635 rb
->Format
= MESA_FORMAT_RGBA8888
;
1638 case GL_RGBA16_SNORM
:
1639 /* for accum buffer */
1640 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
1644 rb
->Format
= MESA_FORMAT_A8
;
1647 case GL_STENCIL_INDEX
:
1648 case GL_STENCIL_INDEX1_EXT
:
1649 case GL_STENCIL_INDEX4_EXT
:
1650 case GL_STENCIL_INDEX8_EXT
:
1651 case GL_STENCIL_INDEX16_EXT
:
1652 rb
->Format
= MESA_FORMAT_S8
;
1654 case GL_DEPTH_COMPONENT
:
1655 case GL_DEPTH_COMPONENT16
:
1656 rb
->Format
= MESA_FORMAT_Z16
;
1658 case GL_DEPTH_COMPONENT24
:
1659 rb
->Format
= MESA_FORMAT_X8_Z24
;
1661 case GL_DEPTH_COMPONENT32
:
1662 rb
->Format
= MESA_FORMAT_Z32
;
1664 case GL_DEPTH_STENCIL_EXT
:
1665 case GL_DEPTH24_STENCIL8_EXT
:
1666 rb
->Format
= MESA_FORMAT_Z24_S8
;
1669 /* unsupported format */
1673 _mesa_set_renderbuffer_accessors(rb
);
1675 ASSERT(rb
->DataType
);
1676 ASSERT(rb
->GetPointer
);
1678 ASSERT(rb
->GetValues
);
1680 ASSERT(rb
->PutMonoRow
);
1681 ASSERT(rb
->PutValues
);
1682 ASSERT(rb
->PutMonoValues
);
1684 /* free old buffer storage */
1690 rb
->RowStride
= width
;
1692 if (width
> 0 && height
> 0) {
1693 /* allocate new buffer storage */
1694 rb
->Data
= malloc(width
* height
* _mesa_get_format_bytes(rb
->Format
));
1696 if (rb
->Data
== NULL
) {
1700 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1701 "software renderbuffer allocation (%d x %d x %d)",
1702 width
, height
, _mesa_get_format_bytes(rb
->Format
));
1708 rb
->Height
= height
;
1709 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
1711 if (rb
->Name
== 0 &&
1712 internalFormat
== GL_RGBA16_SNORM
&&
1713 rb
->_BaseFormat
== 0) {
1714 /* NOTE: This is a special case just for accumulation buffers.
1715 * This is a very limited use case- there's no snorm texturing or
1716 * rendering going on.
1718 rb
->_BaseFormat
= GL_RGBA
;
1721 /* the internalFormat should have been error checked long ago */
1722 ASSERT(rb
->_BaseFormat
);
1730 _mesa_map_soft_renderbuffer(struct gl_context
*ctx
,
1731 struct gl_renderbuffer
*rb
,
1732 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
1737 GLubyte
*map
= rb
->Data
;
1738 int cpp
= _mesa_get_format_bytes(rb
->Format
);
1739 int stride
= rb
->RowStride
* cpp
;
1747 *out_stride
= stride
;
1751 _mesa_unmap_soft_renderbuffer(struct gl_context
*ctx
,
1752 struct gl_renderbuffer
*rb
)
1757 /**********************************************************************/
1758 /**********************************************************************/
1759 /**********************************************************************/
1763 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1764 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1766 * When PutRow is called (for example), we store the alpha values in
1767 * this buffer, then pass on the PutRow call to the wrapped RGB
1773 alloc_storage_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1774 GLenum internalFormat
, GLuint width
, GLuint height
)
1776 ASSERT(arb
!= arb
->Wrapped
);
1777 ASSERT(arb
->Format
== MESA_FORMAT_A8
);
1779 /* first, pass the call to the wrapped RGB buffer */
1780 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1785 /* next, resize my alpha buffer */
1790 arb
->Data
= malloc(width
* height
* sizeof(GLubyte
));
1791 if (arb
->Data
== NULL
) {
1794 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1799 arb
->Height
= height
;
1800 arb
->RowStride
= width
;
1807 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1810 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1815 ASSERT(arb
->Wrapped
);
1816 ASSERT(arb
!= arb
->Wrapped
);
1817 arb
->Wrapped
->Delete(arb
->Wrapped
);
1818 arb
->Wrapped
= NULL
;
1824 get_pointer_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1827 return NULL
; /* don't allow direct access! */
1832 get_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1833 GLint x
, GLint y
, void *values
)
1835 /* NOTE: 'values' is RGBA format! */
1836 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1837 GLubyte
*dst
= (GLubyte
*) values
;
1839 ASSERT(arb
!= arb
->Wrapped
);
1840 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1841 /* first, pass the call to the wrapped RGB buffer */
1842 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1843 /* second, fill in alpha values from this buffer! */
1844 for (i
= 0; i
< count
; i
++) {
1845 dst
[i
* 4 + 3] = src
[i
];
1851 get_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1852 const GLint x
[], const GLint y
[], void *values
)
1854 GLubyte
*dst
= (GLubyte
*) values
;
1856 ASSERT(arb
!= arb
->Wrapped
);
1857 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1858 /* first, pass the call to the wrapped RGB buffer */
1859 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1860 /* second, fill in alpha values from this buffer! */
1861 for (i
= 0; i
< count
; i
++) {
1862 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1863 dst
[i
* 4 + 3] = *src
;
1869 put_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1870 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1872 const GLubyte
*src
= (const GLubyte
*) values
;
1873 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1875 ASSERT(arb
!= arb
->Wrapped
);
1876 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1877 /* first, pass the call to the wrapped RGB buffer */
1878 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1879 /* second, store alpha in our buffer */
1880 for (i
= 0; i
< count
; i
++) {
1881 if (!mask
|| mask
[i
]) {
1882 dst
[i
] = src
[i
* 4 + 3];
1889 put_row_rgb_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1890 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1892 const GLubyte
*src
= (const GLubyte
*) values
;
1893 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1895 ASSERT(arb
!= arb
->Wrapped
);
1896 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1897 /* first, pass the call to the wrapped RGB buffer */
1898 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1899 /* second, store alpha in our buffer */
1900 for (i
= 0; i
< count
; i
++) {
1901 if (!mask
|| mask
[i
]) {
1902 dst
[i
] = src
[i
* 4 + 3];
1909 put_mono_row_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1910 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1912 const GLubyte val
= ((const GLubyte
*) value
)[3];
1913 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->RowStride
+ x
;
1914 ASSERT(arb
!= arb
->Wrapped
);
1915 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1916 /* first, pass the call to the wrapped RGB buffer */
1917 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1918 /* second, store alpha in our buffer */
1921 for (i
= 0; i
< count
; i
++) {
1928 memset(dst
, val
, count
);
1934 put_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1935 const GLint x
[], const GLint y
[],
1936 const void *values
, const GLubyte
*mask
)
1938 const GLubyte
*src
= (const GLubyte
*) values
;
1940 ASSERT(arb
!= arb
->Wrapped
);
1941 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1942 /* first, pass the call to the wrapped RGB buffer */
1943 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1944 /* second, store alpha in our buffer */
1945 for (i
= 0; i
< count
; i
++) {
1946 if (!mask
|| mask
[i
]) {
1947 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1948 *dst
= src
[i
* 4 + 3];
1955 put_mono_values_alpha8(struct gl_context
*ctx
, struct gl_renderbuffer
*arb
,
1956 GLuint count
, const GLint x
[], const GLint y
[],
1957 const void *value
, const GLubyte
*mask
)
1959 const GLubyte val
= ((const GLubyte
*) value
)[3];
1961 ASSERT(arb
!= arb
->Wrapped
);
1962 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1963 /* first, pass the call to the wrapped RGB buffer */
1964 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1965 /* second, store alpha in our buffer */
1966 for (i
= 0; i
< count
; i
++) {
1967 if (!mask
|| mask
[i
]) {
1968 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->RowStride
+ x
[i
];
1976 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1978 ASSERT(dst
->Format
== MESA_FORMAT_A8
);
1979 ASSERT(src
->Format
== MESA_FORMAT_A8
);
1980 ASSERT(dst
->Width
== src
->Width
);
1981 ASSERT(dst
->Height
== src
->Height
);
1982 ASSERT(dst
->RowStride
== src
->RowStride
);
1984 memcpy(dst
->Data
, src
->Data
, dst
->RowStride
* dst
->Height
* sizeof(GLubyte
));
1988 /**********************************************************************/
1989 /**********************************************************************/
1990 /**********************************************************************/
1994 * Default GetPointer routine. Always return NULL to indicate that
1995 * direct buffer access is not supported.
1998 nop_get_pointer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
2005 * Initialize the fields of a gl_renderbuffer to default values.
2008 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
2010 _glthread_INIT_MUTEX(rb
->Mutex
);
2015 rb
->Delete
= _mesa_delete_renderbuffer
;
2017 /* The rest of these should be set later by the caller of this function or
2018 * the AllocStorage method:
2020 rb
->AllocStorage
= NULL
;
2024 rb
->InternalFormat
= GL_RGBA
;
2025 rb
->Format
= MESA_FORMAT_NONE
;
2027 rb
->DataType
= GL_NONE
;
2030 /* Point back to ourself so that we don't have to check for Wrapped==NULL
2031 * all over the drivers.
2035 rb
->GetPointer
= nop_get_pointer
;
2037 rb
->GetValues
= NULL
;
2039 rb
->PutRowRGB
= NULL
;
2040 rb
->PutMonoRow
= NULL
;
2041 rb
->PutValues
= NULL
;
2042 rb
->PutMonoValues
= NULL
;
2047 * Allocate a new gl_renderbuffer object. This can be used for user-created
2048 * renderbuffers or window-system renderbuffers.
2050 struct gl_renderbuffer
*
2051 _mesa_new_renderbuffer(struct gl_context
*ctx
, GLuint name
)
2053 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
2055 _mesa_init_renderbuffer(rb
, name
);
2062 * Delete a gl_framebuffer.
2063 * This is the default function for renderbuffer->Delete().
2066 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
2076 * Allocate a software-based renderbuffer. This is called via the
2077 * ctx->Driver.NewRenderbuffer() function when the user creates a new
2079 * This would not be used for hardware-based renderbuffers.
2081 struct gl_renderbuffer
*
2082 _mesa_new_soft_renderbuffer(struct gl_context
*ctx
, GLuint name
)
2084 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
2086 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2087 /* Normally, one would setup the PutRow, GetRow, etc functions here.
2088 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
2097 * Add software-based color renderbuffers to the given framebuffer.
2098 * This is a helper routine for device drivers when creating a
2099 * window system framebuffer (not a user-created render/framebuffer).
2100 * Once this function is called, you can basically forget about this
2101 * renderbuffer; core Mesa will handle all the buffer management and
2105 _mesa_add_color_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2106 GLuint rgbBits
, GLuint alphaBits
,
2107 GLboolean frontLeft
, GLboolean backLeft
,
2108 GLboolean frontRight
, GLboolean backRight
)
2112 if (rgbBits
> 16 || alphaBits
> 16) {
2114 "Unsupported bit depth in _mesa_add_color_renderbuffers");
2118 assert(MAX_COLOR_ATTACHMENTS
>= 4);
2120 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
2121 struct gl_renderbuffer
*rb
;
2123 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
2125 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
2127 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
2129 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
2132 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
2134 rb
= _mesa_new_renderbuffer(ctx
, 0);
2136 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
2140 rb
->InternalFormat
= GL_RGBA
;
2142 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2143 _mesa_add_renderbuffer(fb
, b
, rb
);
2151 * Add software-based alpha renderbuffers to the given framebuffer.
2152 * This is a helper routine for device drivers when creating a
2153 * window system framebuffer (not a user-created render/framebuffer).
2154 * Once this function is called, you can basically forget about this
2155 * renderbuffer; core Mesa will handle all the buffer management and
2159 _mesa_add_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2161 GLboolean frontLeft
, GLboolean backLeft
,
2162 GLboolean frontRight
, GLboolean backRight
)
2166 /* for window system framebuffers only! */
2167 assert(fb
->Name
== 0);
2169 if (alphaBits
> 8) {
2171 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
2175 assert(MAX_COLOR_ATTACHMENTS
>= 4);
2177 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
2179 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
2180 struct gl_renderbuffer
*arb
;
2182 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
2184 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
2186 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
2188 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
2191 /* the RGB buffer to wrap must already exist!! */
2192 assert(fb
->Attachment
[b
].Renderbuffer
);
2194 /* only GLubyte supported for now */
2195 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
2197 /* allocate alpha renderbuffer */
2198 arb
= _mesa_new_renderbuffer(ctx
, 0);
2200 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
2204 /* wrap the alpha renderbuffer around the RGB renderbuffer */
2205 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
2207 /* Set up my alphabuffer fields and plug in my functions.
2208 * The functions will put/get the alpha values from/to RGBA arrays
2209 * and then call the wrapped buffer's functions to handle the RGB
2212 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
2213 arb
->Format
= MESA_FORMAT_A8
;
2214 arb
->DataType
= arb
->Wrapped
->DataType
;
2215 arb
->AllocStorage
= alloc_storage_alpha8
;
2216 arb
->Delete
= delete_renderbuffer_alpha8
;
2217 arb
->GetPointer
= get_pointer_alpha8
;
2218 arb
->GetRow
= get_row_alpha8
;
2219 arb
->GetValues
= get_values_alpha8
;
2220 arb
->PutRow
= put_row_alpha8
;
2221 arb
->PutRowRGB
= put_row_rgb_alpha8
;
2222 arb
->PutMonoRow
= put_mono_row_alpha8
;
2223 arb
->PutValues
= put_values_alpha8
;
2224 arb
->PutMonoValues
= put_mono_values_alpha8
;
2226 /* clear the pointer to avoid assertion/sanity check failure later */
2227 fb
->Attachment
[b
].Renderbuffer
= NULL
;
2229 /* plug the alpha renderbuffer into the colorbuffer attachment */
2230 _mesa_add_renderbuffer(fb
, b
, arb
);
2238 * For framebuffers that use a software alpha channel wrapper
2239 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
2240 * copy the back buffer alpha channel into the front buffer alpha channel.
2243 _mesa_copy_soft_alpha_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
2245 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
2246 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
2247 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
2248 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
2251 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
2252 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
2253 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
2254 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
2259 * Add a software-based depth renderbuffer to the given framebuffer.
2260 * This is a helper routine for device drivers when creating a
2261 * window system framebuffer (not a user-created render/framebuffer).
2262 * Once this function is called, you can basically forget about this
2263 * renderbuffer; core Mesa will handle all the buffer management and
2267 _mesa_add_depth_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2270 struct gl_renderbuffer
*rb
;
2272 if (depthBits
> 32) {
2274 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
2278 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
2280 rb
= _mesa_new_renderbuffer(ctx
, 0);
2282 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
2286 if (depthBits
<= 16) {
2287 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
2289 else if (depthBits
<= 24) {
2290 rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
2293 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
2296 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2297 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
2304 * Add a software-based stencil renderbuffer to the given framebuffer.
2305 * This is a helper routine for device drivers when creating a
2306 * window system framebuffer (not a user-created render/framebuffer).
2307 * Once this function is called, you can basically forget about this
2308 * renderbuffer; core Mesa will handle all the buffer management and
2312 _mesa_add_stencil_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2315 struct gl_renderbuffer
*rb
;
2317 if (stencilBits
> 16) {
2319 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
2323 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
2325 rb
= _mesa_new_renderbuffer(ctx
, 0);
2327 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
2331 assert(stencilBits
<= 8);
2332 rb
->InternalFormat
= GL_STENCIL_INDEX8
;
2334 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2335 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
2342 * Add a software-based accumulation renderbuffer to the given framebuffer.
2343 * This is a helper routine for device drivers when creating a
2344 * window system framebuffer (not a user-created render/framebuffer).
2345 * Once this function is called, you can basically forget about this
2346 * renderbuffer; core Mesa will handle all the buffer management and
2350 _mesa_add_accum_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2351 GLuint redBits
, GLuint greenBits
,
2352 GLuint blueBits
, GLuint alphaBits
)
2354 struct gl_renderbuffer
*rb
;
2356 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
2358 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
2362 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
2364 rb
= _mesa_new_renderbuffer(ctx
, 0);
2366 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
2370 rb
->InternalFormat
= GL_RGBA16_SNORM
;
2371 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2372 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
2380 * Add a software-based aux renderbuffer to the given framebuffer.
2381 * This is a helper routine for device drivers when creating a
2382 * window system framebuffer (not a user-created render/framebuffer).
2383 * Once this function is called, you can basically forget about this
2384 * renderbuffer; core Mesa will handle all the buffer management and
2387 * NOTE: color-index aux buffers not supported.
2390 _mesa_add_aux_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2391 GLuint colorBits
, GLuint numBuffers
)
2395 if (colorBits
> 16) {
2397 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
2401 assert(numBuffers
<= MAX_AUX_BUFFERS
);
2403 for (i
= 0; i
< numBuffers
; i
++) {
2404 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
2406 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
2409 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating aux buffer");
2413 assert (colorBits
<= 8);
2414 rb
->InternalFormat
= GL_RGBA
;
2416 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2417 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
2424 * Create/attach software-based renderbuffers to the given framebuffer.
2425 * This is a helper routine for device drivers. Drivers can just as well
2426 * call the individual _mesa_add_*_renderbuffer() routines directly.
2429 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
2437 GLboolean frontLeft
= GL_TRUE
;
2438 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
2439 GLboolean frontRight
= fb
->Visual
.stereoMode
;
2440 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
2443 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
2444 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
2445 _mesa_add_color_renderbuffers(NULL
, fb
,
2447 fb
->Visual
.alphaBits
,
2448 frontLeft
, backLeft
,
2449 frontRight
, backRight
);
2453 assert(fb
->Visual
.depthBits
> 0);
2454 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
2458 assert(fb
->Visual
.stencilBits
> 0);
2459 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
2463 assert(fb
->Visual
.accumRedBits
> 0);
2464 assert(fb
->Visual
.accumGreenBits
> 0);
2465 assert(fb
->Visual
.accumBlueBits
> 0);
2466 _mesa_add_accum_renderbuffer(NULL
, fb
,
2467 fb
->Visual
.accumRedBits
,
2468 fb
->Visual
.accumGreenBits
,
2469 fb
->Visual
.accumBlueBits
,
2470 fb
->Visual
.accumAlphaBits
);
2474 assert(fb
->Visual
.numAuxBuffers
> 0);
2475 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
2476 fb
->Visual
.numAuxBuffers
);
2480 assert(fb
->Visual
.alphaBits
> 0);
2481 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
2482 frontLeft
, backLeft
,
2483 frontRight
, backRight
);
2495 * Attach a renderbuffer to a framebuffer.
2496 * \param bufferName one of the BUFFER_x tokens
2499 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
2500 gl_buffer_index bufferName
, struct gl_renderbuffer
*rb
)
2504 assert(bufferName
< BUFFER_COUNT
);
2506 /* There should be no previous renderbuffer on this attachment point,
2507 * with the exception of depth/stencil since the same renderbuffer may
2510 assert(bufferName
== BUFFER_DEPTH
||
2511 bufferName
== BUFFER_STENCIL
||
2512 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
2514 /* winsys vs. user-created buffer cross check */
2522 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
2523 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
2524 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
2529 * Remove the named renderbuffer from the given framebuffer.
2530 * \param bufferName one of the BUFFER_x tokens
2533 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
,
2534 gl_buffer_index bufferName
)
2536 struct gl_renderbuffer
*rb
;
2538 assert(bufferName
< BUFFER_COUNT
);
2540 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
2544 _mesa_reference_renderbuffer(&rb
, NULL
);
2546 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
2551 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
2552 * dereference that buffer first. The new renderbuffer's refcount will
2553 * be incremented. The old renderbuffer's refcount will be decremented.
2554 * This is normally only called from the _mesa_reference_renderbuffer() macro
2555 * when there's a real pointer change.
2558 _mesa_reference_renderbuffer_(struct gl_renderbuffer
**ptr
,
2559 struct gl_renderbuffer
*rb
)
2562 /* Unreference the old renderbuffer */
2563 GLboolean deleteFlag
= GL_FALSE
;
2564 struct gl_renderbuffer
*oldRb
= *ptr
;
2566 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
2567 ASSERT(oldRb
->RefCount
> 0);
2569 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
2570 deleteFlag
= (oldRb
->RefCount
== 0);
2571 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
2574 oldRb
->Delete(oldRb
);
2582 /* reference new renderbuffer */
2583 _glthread_LOCK_MUTEX(rb
->Mutex
);
2585 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
2586 _glthread_UNLOCK_MUTEX(rb
->Mutex
);