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 * Down the road we'll use this for run-time support of 8, 16 and 32-bit
32 * color channels. For example, Mesa may use 32-bit/float color channels
33 * internally (swrast) and use wrapper renderbuffers to convert 32-bit
34 * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
44 #include "renderbuffer.h"
48 * Routines for get/put values in common buffer formats follow.
51 /* Returns a bytes per pixel of the DataType in the get/put span
52 * functions for at least a subset of the available combinations a
53 * renderbuffer can have.
55 * It would be nice to see gl_renderbuffer start talking about a
56 * gl_format instead of a GLenum DataType.
59 get_datatype_bytes(struct gl_renderbuffer
*rb
)
63 switch (rb
->DataType
) {
64 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV
:
69 case GL_UNSIGNED_INT_24_8_EXT
:
72 case GL_UNSIGNED_SHORT
:
75 case GL_UNSIGNED_BYTE
:
83 switch (rb
->_BaseFormat
) {
84 case GL_DEPTH_COMPONENT
:
85 case GL_DEPTH_STENCIL
:
86 return component_size
;
88 return 4 * component_size
;
92 /* This is commonly used by most of the accessors. */
94 get_pointer_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
100 return ((char *) rb
->Data
+
101 (y
* rb
->RowStride
+ x
) * _mesa_get_format_bytes(rb
->Format
));
104 /* GetRow() implementation for formats where DataType matches the rb->Format.
107 get_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
108 GLuint count
, GLint x
, GLint y
, void *values
)
110 void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
111 memcpy(values
, src
, count
* _mesa_get_format_bytes(rb
->Format
));
114 /* Only used for float textures currently, but might also be used for
115 * RGBA8888, RGBA16, etc.
118 get_values_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
119 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
121 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
124 for (i
= 0; i
< count
; i
++) {
125 const void *src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
126 char *dst
= (char *) values
+ i
* format_bytes
;
127 memcpy(dst
, src
, format_bytes
);
131 /* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and
132 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of
133 * storing those initial components of the value per pixel into the
137 put_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
138 GLuint count
, GLint x
, GLint y
,
139 const void *values
, const GLubyte
*mask
)
141 void *row
= rb
->GetPointer(ctx
, rb
, x
, y
);
142 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
143 int datatype_bytes
= get_datatype_bytes(rb
);
147 for (i
= 0; i
< count
; i
++) {
148 char *dst
= (char *) row
+ i
* format_bytes
;
149 const char *src
= (const char *) values
+ i
* datatype_bytes
;
152 memcpy(dst
, src
, format_bytes
);
157 for (i
= 0; i
< count
; i
++) {
158 char *dst
= (char *) row
+ i
* format_bytes
;
159 const char *src
= (const char *) values
+ i
* datatype_bytes
;
160 memcpy(dst
, src
, format_bytes
);
166 put_mono_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
167 GLuint count
, GLint x
, GLint y
,
168 const void *value
, const GLubyte
*mask
)
170 void *row
= rb
->GetPointer(ctx
, rb
, x
, y
);
171 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
175 for (i
= 0; i
< count
; i
++) {
176 char *dst
= (char *) row
+ i
* format_bytes
;
178 memcpy(dst
, value
, format_bytes
);
183 for (i
= 0; i
< count
; i
++) {
184 char *dst
= (char *) row
+ i
* format_bytes
;
185 memcpy(dst
, value
, format_bytes
);
192 put_values_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
193 GLuint count
, const GLint x
[], const GLint y
[],
194 const void *values
, const GLubyte
*mask
)
196 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
197 int datatype_bytes
= get_datatype_bytes(rb
);
200 for (i
= 0; i
< count
; i
++) {
201 if (!mask
|| mask
[i
]) {
202 void *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
203 const char *src
= (const char *) values
+ i
* datatype_bytes
;
204 memcpy(dst
, src
, format_bytes
);
211 put_mono_values_generic(struct gl_context
*ctx
,
212 struct gl_renderbuffer
*rb
,
213 GLuint count
, const GLint x
[], const GLint y
[],
214 const void *value
, const GLubyte
*mask
)
216 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
219 for (i
= 0; i
< count
; i
++) {
220 if (!mask
|| mask
[i
]) {
221 void *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
222 memcpy(dst
, value
, format_bytes
);
227 /**********************************************************************
228 * Functions for buffers of 1 X GLubyte values.
233 get_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
234 const GLint x
[], const GLint y
[], void *values
)
236 GLubyte
*dst
= (GLubyte
*) values
;
238 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
239 for (i
= 0; i
< count
; i
++) {
240 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
247 put_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
248 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
250 const GLubyte
*src
= (const GLubyte
*) values
;
251 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
252 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
255 for (i
= 0; i
< count
; i
++) {
262 memcpy(dst
, values
, count
* sizeof(GLubyte
));
268 put_mono_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
269 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
271 const GLubyte val
= *((const GLubyte
*) value
);
272 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
273 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
276 for (i
= 0; i
< count
; i
++) {
284 for (i
= 0; i
< count
; i
++) {
292 put_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
293 const GLint x
[], const GLint y
[],
294 const void *values
, const GLubyte
*mask
)
296 const GLubyte
*src
= (const GLubyte
*) values
;
298 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
299 for (i
= 0; i
< count
; i
++) {
300 if (!mask
|| mask
[i
]) {
301 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
309 put_mono_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
310 const GLint x
[], const GLint y
[],
311 const void *value
, const GLubyte
*mask
)
313 const GLubyte val
= *((const GLubyte
*) value
);
315 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
316 for (i
= 0; i
< count
; i
++) {
317 if (!mask
|| mask
[i
]) {
318 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
325 /**********************************************************************
326 * Functions for buffers of 1 X GLushort values.
331 get_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
332 const GLint x
[], const GLint y
[], void *values
)
334 GLushort
*dst
= (GLushort
*) values
;
336 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
337 for (i
= 0; i
< count
; i
++) {
338 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
345 put_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
346 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
348 const GLushort
*src
= (const GLushort
*) values
;
349 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
350 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
353 for (i
= 0; i
< count
; i
++) {
360 memcpy(dst
, src
, count
* sizeof(GLushort
));
366 put_mono_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
367 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
369 const GLushort val
= *((const GLushort
*) value
);
370 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
371 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
374 for (i
= 0; i
< count
; i
++) {
382 for (i
= 0; i
< count
; i
++) {
390 put_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
391 const GLint x
[], const GLint y
[], const void *values
,
394 const GLushort
*src
= (const GLushort
*) values
;
396 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
397 for (i
= 0; i
< count
; i
++) {
398 if (!mask
|| mask
[i
]) {
399 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
407 put_mono_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
408 GLuint count
, const GLint x
[], const GLint y
[],
409 const void *value
, const GLubyte
*mask
)
411 const GLushort val
= *((const GLushort
*) value
);
412 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
415 for (i
= 0; i
< count
; i
++) {
417 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
424 for (i
= 0; i
< count
; i
++) {
425 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
432 /**********************************************************************
433 * Functions for buffers of 1 X GLuint values.
434 * Typically depth/Z or color index.
438 get_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
439 const GLint x
[], const GLint y
[], void *values
)
441 GLuint
*dst
= (GLuint
*) values
;
443 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
444 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
445 for (i
= 0; i
< count
; i
++) {
446 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
453 put_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
454 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
456 const GLuint
*src
= (const GLuint
*) values
;
457 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
458 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
459 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
462 for (i
= 0; i
< count
; i
++) {
469 memcpy(dst
, src
, count
* sizeof(GLuint
));
475 put_mono_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
476 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
478 const GLuint val
= *((const GLuint
*) value
);
479 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
480 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
481 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
484 for (i
= 0; i
< count
; i
++) {
492 for (i
= 0; i
< count
; i
++) {
500 put_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
501 const GLint x
[], const GLint y
[], const void *values
,
504 const GLuint
*src
= (const GLuint
*) values
;
506 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
507 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
508 for (i
= 0; i
< count
; i
++) {
509 if (!mask
|| mask
[i
]) {
510 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
518 put_mono_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
519 const GLint x
[], const GLint y
[], const void *value
,
522 const GLuint val
= *((const GLuint
*) value
);
524 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
525 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
526 for (i
= 0; i
< count
; i
++) {
527 if (!mask
|| mask
[i
]) {
528 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
535 /**********************************************************************
536 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
537 * Typically color buffers.
538 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
539 * alpha values and return 255 for outgoing alpha values.
543 get_pointer_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
546 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
547 /* No direct access since this buffer is RGB but caller will be
548 * treating it as if it were RGBA.
555 get_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
556 GLint x
, GLint y
, void *values
)
558 const GLubyte
*src
= ((const GLubyte
*) rb
->Data
) +
559 3 * (y
* rb
->RowStride
+ x
);
560 GLubyte
*dst
= (GLubyte
*) values
;
562 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
563 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
564 for (i
= 0; i
< count
; i
++) {
565 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
566 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
567 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
568 dst
[i
* 4 + 3] = 255;
574 get_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
575 const GLint x
[], const GLint y
[], void *values
)
577 GLubyte
*dst
= (GLubyte
*) values
;
579 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
580 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
581 for (i
= 0; i
< count
; i
++) {
583 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
584 dst
[i
* 4 + 0] = src
[0];
585 dst
[i
* 4 + 1] = src
[1];
586 dst
[i
* 4 + 2] = src
[2];
587 dst
[i
* 4 + 3] = 255;
593 put_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
594 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
596 /* note: incoming values are RGB+A! */
597 const GLubyte
*src
= (const GLubyte
*) values
;
598 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
600 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
601 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
602 for (i
= 0; i
< count
; i
++) {
603 if (!mask
|| mask
[i
]) {
604 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
605 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
606 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
613 put_row_rgb_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
614 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
616 /* note: incoming values are RGB+A! */
617 const GLubyte
*src
= (const GLubyte
*) values
;
618 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
620 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
621 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
622 for (i
= 0; i
< count
; i
++) {
623 if (!mask
|| mask
[i
]) {
624 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
625 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
626 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
633 put_mono_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
634 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
636 /* note: incoming value is RGB+A! */
637 const GLubyte val0
= ((const GLubyte
*) value
)[0];
638 const GLubyte val1
= ((const GLubyte
*) value
)[1];
639 const GLubyte val2
= ((const GLubyte
*) value
)[2];
640 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
641 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
642 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
643 if (!mask
&& val0
== val1
&& val1
== val2
) {
645 memset(dst
, val0
, 3 * count
);
649 for (i
= 0; i
< count
; i
++) {
650 if (!mask
|| mask
[i
]) {
651 dst
[i
* 3 + 0] = val0
;
652 dst
[i
* 3 + 1] = val1
;
653 dst
[i
* 3 + 2] = val2
;
661 put_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
662 const GLint x
[], const GLint y
[], const void *values
,
665 /* note: incoming values are RGB+A! */
666 const GLubyte
*src
= (const GLubyte
*) values
;
668 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
669 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
670 for (i
= 0; i
< count
; i
++) {
671 if (!mask
|| mask
[i
]) {
672 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
673 dst
[0] = src
[i
* 4 + 0];
674 dst
[1] = src
[i
* 4 + 1];
675 dst
[2] = src
[i
* 4 + 2];
682 put_mono_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
683 GLuint count
, const GLint x
[], const GLint y
[],
684 const void *value
, const GLubyte
*mask
)
686 /* note: incoming value is RGB+A! */
687 const GLubyte val0
= ((const GLubyte
*) value
)[0];
688 const GLubyte val1
= ((const GLubyte
*) value
)[1];
689 const GLubyte val2
= ((const GLubyte
*) value
)[2];
691 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
692 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
693 for (i
= 0; i
< count
; i
++) {
694 if (!mask
|| mask
[i
]) {
695 GLubyte
*dst
= ((GLubyte
*) rb
->Data
) +
696 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
705 /**********************************************************************
706 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
707 * Typically color buffers.
711 get_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
712 const GLint x
[], const GLint y
[], void *values
)
714 /* treat 4*GLubyte as 1*GLuint */
715 GLuint
*dst
= (GLuint
*) values
;
717 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
718 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
719 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
720 for (i
= 0; i
< count
; i
++) {
721 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
728 put_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
729 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
731 /* treat 4*GLubyte as 1*GLuint */
732 const GLuint
*src
= (const GLuint
*) values
;
733 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
734 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
735 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
736 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
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 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
762 for (i
= 0; i
< count
; i
++) {
763 if (!mask
|| mask
[i
]) {
764 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
765 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
766 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
767 dst
[i
* 4 + 3] = 0xff;
774 put_mono_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
775 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
777 /* treat 4*GLubyte as 1*GLuint */
778 const GLuint val
= *((const GLuint
*) value
);
779 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
780 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
781 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
782 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
783 if (!mask
&& val
== 0) {
785 memset(dst
, 0, count
* 4 * sizeof(GLubyte
));
791 for (i
= 0; i
< count
; i
++) {
799 for (i
= 0; i
< count
; i
++) {
808 put_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
809 const GLint x
[], const GLint y
[], const void *values
,
812 /* treat 4*GLubyte as 1*GLuint */
813 const GLuint
*src
= (const GLuint
*) values
;
815 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
816 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
817 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
818 for (i
= 0; i
< count
; i
++) {
819 if (!mask
|| mask
[i
]) {
820 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
828 put_mono_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
829 GLuint count
, const GLint x
[], const GLint y
[],
830 const void *value
, const GLubyte
*mask
)
832 /* treat 4*GLubyte as 1*GLuint */
833 const GLuint val
= *((const GLuint
*) value
);
835 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
836 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
837 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
838 for (i
= 0; i
< count
; i
++) {
839 if (!mask
|| mask
[i
]) {
840 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
847 /**********************************************************************
848 * Functions for buffers of 4 X GLushort (or GLshort) values.
849 * Typically accum buffer.
853 get_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
854 const GLint x
[], const GLint y
[], void *values
)
856 GLushort
*dst
= (GLushort
*) values
;
858 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
859 for (i
= 0; i
< count
; i
++) {
861 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
868 put_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
869 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
871 const GLushort
*src
= (const GLushort
*) values
;
872 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
873 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
876 for (i
= 0; i
< count
; i
++) {
878 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
879 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
880 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
881 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
886 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
892 put_row_rgb_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
893 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
895 /* Put RGB values in RGBA buffer */
896 const GLushort
*src
= (const GLushort
*) values
;
897 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
898 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
901 for (i
= 0; i
< count
; i
++) {
903 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
904 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
905 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
906 dst
[i
* 4 + 3] = 0xffff;
911 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
917 put_mono_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
918 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
920 const GLushort val0
= ((const GLushort
*) value
)[0];
921 const GLushort val1
= ((const GLushort
*) value
)[1];
922 const GLushort val2
= ((const GLushort
*) value
)[2];
923 const GLushort val3
= ((const GLushort
*) value
)[3];
924 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
925 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
926 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
927 /* common case for clearing accum buffer */
928 memset(dst
, 0, count
* 4 * sizeof(GLushort
));
932 for (i
= 0; i
< count
; i
++) {
933 if (!mask
|| mask
[i
]) {
934 dst
[i
* 4 + 0] = val0
;
935 dst
[i
* 4 + 1] = val1
;
936 dst
[i
* 4 + 2] = val2
;
937 dst
[i
* 4 + 3] = val3
;
945 put_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
946 const GLint x
[], const GLint y
[], const void *values
,
949 const GLushort
*src
= (const GLushort
*) values
;
951 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
952 for (i
= 0; i
< count
; i
++) {
953 if (!mask
|| mask
[i
]) {
955 ((GLushort
*) rb
->Data
) + 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
956 dst
[0] = src
[i
* 4 + 0];
957 dst
[1] = src
[i
* 4 + 1];
958 dst
[2] = src
[i
* 4 + 2];
959 dst
[3] = src
[i
* 4 + 3];
966 put_mono_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
967 GLuint count
, const GLint x
[], const GLint y
[],
968 const void *value
, const GLubyte
*mask
)
970 const GLushort val0
= ((const GLushort
*) value
)[0];
971 const GLushort val1
= ((const GLushort
*) value
)[1];
972 const GLushort val2
= ((const GLushort
*) value
)[2];
973 const GLushort val3
= ((const GLushort
*) value
)[3];
975 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
976 for (i
= 0; i
< count
; i
++) {
977 if (!mask
|| mask
[i
]) {
978 GLushort
*dst
= ((GLushort
*) rb
->Data
) +
979 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
988 /**********************************************************************
989 * Functions for MESA_FORMAT_R8.
992 get_row_r8(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
993 GLint x
, GLint y
, void *values
)
995 const GLubyte
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
996 GLuint
*dst
= values
;
999 for (i
= 0; i
< count
; i
++) {
1000 dst
[i
] = 0xff000000 | src
[i
];
1005 get_values_r8(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1006 const GLint x
[], const GLint y
[], void *values
)
1008 GLuint
*dst
= (GLuint
*) values
;
1011 for (i
= 0; i
< count
; i
++) {
1012 const GLubyte
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1013 dst
[i
] = 0xff000000 | *src
;
1017 /**********************************************************************
1018 * Functions for MESA_FORMAT_RG88.
1021 get_row_rg88(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1022 GLint x
, GLint y
, void *values
)
1024 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1025 GLuint
*dst
= values
;
1028 for (i
= 0; i
< count
; i
++) {
1029 dst
[i
] = 0xff000000 | src
[i
];
1034 get_values_rg88(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1035 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
1037 GLuint
*dst
= (GLuint
*) values
;
1040 for (i
= 0; i
< count
; i
++) {
1041 const GLshort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1042 dst
[i
] = 0xff000000 | *src
;
1046 /**********************************************************************
1047 * Functions for MESA_FORMAT_R16.
1050 get_row_r16(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1051 GLint x
, GLint y
, void *values
)
1053 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1054 GLushort
*dst
= values
;
1057 for (i
= 0; i
< count
; i
++) {
1058 dst
[i
* 4 + RCOMP
] = src
[i
];
1059 dst
[i
* 4 + GCOMP
] = 0;
1060 dst
[i
* 4 + BCOMP
] = 0;
1061 dst
[i
* 4 + ACOMP
] = 0xffff;
1066 get_values_r16(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1067 const GLint x
[], const GLint y
[], void *values
)
1069 GLushort
*dst
= values
;
1072 for (i
= 0; i
< count
; i
++) {
1073 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1074 dst
[i
* 4 + RCOMP
] = *src
;
1075 dst
[i
* 4 + GCOMP
] = 0;
1076 dst
[i
* 4 + BCOMP
] = 0;
1077 dst
[i
* 4 + ACOMP
] = 0xffff;
1081 /**********************************************************************
1082 * Functions for MESA_FORMAT_RG1616.
1085 get_row_rg1616(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1086 GLint x
, GLint y
, void *values
)
1088 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1089 GLushort
*dst
= values
;
1092 for (i
= 0; i
< count
; i
++) {
1093 dst
[i
* 4 + RCOMP
] = src
[i
* 2];
1094 dst
[i
* 4 + GCOMP
] = src
[i
* 2 + 1];
1095 dst
[i
* 4 + BCOMP
] = 0;
1096 dst
[i
* 4 + ACOMP
] = 0xffff;
1101 get_values_rg1616(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1102 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
1104 GLushort
*dst
= values
;
1107 for (i
= 0; i
< count
; i
++) {
1108 const GLshort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1109 dst
[i
* 4 + RCOMP
] = src
[0];
1110 dst
[i
* 4 + GCOMP
] = src
[1];
1111 dst
[i
* 4 + BCOMP
] = 0;
1112 dst
[i
* 4 + ACOMP
] = 0xffff;
1116 /**********************************************************************
1117 * Functions for MESA_FORMAT_INTENSITY_FLOAT32.
1120 get_row_i_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1121 GLuint count
, GLint x
, GLint y
, void *values
)
1123 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1124 GLfloat
*dst
= values
;
1127 for (i
= 0; i
< count
; i
++) {
1128 dst
[i
* 4 + RCOMP
] =
1129 dst
[i
* 4 + GCOMP
] =
1130 dst
[i
* 4 + BCOMP
] =
1131 dst
[i
* 4 + ACOMP
] = src
[i
];
1136 get_values_i_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1137 GLuint count
, const GLint x
[], const GLint y
[],
1140 GLfloat
*dst
= values
;
1143 for (i
= 0; i
< count
; i
++) {
1144 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1145 dst
[i
* 4 + RCOMP
] =
1146 dst
[i
* 4 + GCOMP
] =
1147 dst
[i
* 4 + BCOMP
] =
1148 dst
[i
* 4 + ACOMP
] = src
[0];
1152 /**********************************************************************
1153 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32.
1156 get_row_l_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1157 GLuint count
, GLint x
, GLint y
, void *values
)
1159 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1160 GLfloat
*dst
= values
;
1163 for (i
= 0; i
< count
; i
++) {
1164 dst
[i
* 4 + RCOMP
] =
1165 dst
[i
* 4 + GCOMP
] =
1166 dst
[i
* 4 + BCOMP
] = src
[i
];
1167 dst
[i
* 4 + ACOMP
] = 1.0;
1172 get_values_l_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1173 GLuint count
, const GLint x
[], const GLint y
[],
1176 GLfloat
*dst
= values
;
1179 for (i
= 0; i
< count
; i
++) {
1180 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1181 dst
[i
* 4 + RCOMP
] =
1182 dst
[i
* 4 + GCOMP
] =
1183 dst
[i
* 4 + BCOMP
] = src
[0];
1184 dst
[i
* 4 + ACOMP
] = 1.0;
1188 /**********************************************************************
1189 * Functions for MESA_FORMAT_ALPHA_FLOAT32.
1192 get_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1193 GLuint count
, GLint x
, GLint y
, void *values
)
1195 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1196 GLfloat
*dst
= values
;
1199 for (i
= 0; i
< count
; i
++) {
1200 dst
[i
* 4 + RCOMP
] = 0.0;
1201 dst
[i
* 4 + GCOMP
] = 0.0;
1202 dst
[i
* 4 + BCOMP
] = 0.0;
1203 dst
[i
* 4 + ACOMP
] = src
[i
];
1208 get_values_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1209 GLuint count
, const GLint x
[], const GLint y
[],
1212 GLfloat
*dst
= values
;
1215 for (i
= 0; i
< count
; i
++) {
1216 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1217 dst
[i
* 4 + RCOMP
] = 0.0;
1218 dst
[i
* 4 + GCOMP
] = 0.0;
1219 dst
[i
* 4 + BCOMP
] = 0.0;
1220 dst
[i
* 4 + ACOMP
] = src
[0];
1225 put_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1226 GLuint count
, GLint x
, GLint y
,
1227 const void *values
, const GLubyte
*mask
)
1229 float *dst
= rb
->GetPointer(ctx
, rb
, x
, y
);
1230 const float *src
= values
;
1234 for (i
= 0; i
< count
; i
++) {
1236 dst
[i
] = src
[i
* 4 + ACOMP
];
1241 for (i
= 0; i
< count
; i
++) {
1242 dst
[i
] = src
[i
* 4 + ACOMP
];
1248 put_mono_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1249 GLuint count
, GLint x
, GLint y
,
1250 const void *value
, const GLubyte
*mask
)
1252 float *dst
= rb
->GetPointer(ctx
, rb
, x
, y
);
1253 const float *src
= value
;
1257 for (i
= 0; i
< count
; i
++) {
1259 dst
[i
] = src
[ACOMP
];
1264 for (i
= 0; i
< count
; i
++) {
1265 dst
[i
] = src
[ACOMP
];
1271 put_values_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1272 GLuint count
, const GLint x
[], const GLint y
[],
1273 const void *values
, const GLubyte
*mask
)
1275 const float *src
= values
;
1278 for (i
= 0; i
< count
; i
++) {
1279 if (!mask
|| mask
[i
]) {
1280 float *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1282 *dst
= src
[i
* 4 + ACOMP
];
1288 put_mono_values_a_float32(struct gl_context
*ctx
,
1289 struct gl_renderbuffer
*rb
,
1290 GLuint count
, const GLint x
[], const GLint y
[],
1291 const void *value
, const GLubyte
*mask
)
1293 const float *src
= value
;
1296 for (i
= 0; i
< count
; i
++) {
1297 if (!mask
|| mask
[i
]) {
1298 float *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1304 /**********************************************************************
1305 * Functions for MESA_FORMAT_R_FLOAT32.
1308 get_row_r_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1309 GLuint count
, GLint x
, GLint y
, void *values
)
1311 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1312 GLfloat
*dst
= values
;
1315 for (i
= 0; i
< count
; i
++) {
1316 dst
[i
* 4 + RCOMP
] = src
[i
];
1317 dst
[i
* 4 + GCOMP
] = 0.0;
1318 dst
[i
* 4 + BCOMP
] = 0.0;
1319 dst
[i
* 4 + ACOMP
] = 1.0;
1324 get_values_r_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1325 GLuint count
, const GLint x
[], const GLint y
[],
1328 GLfloat
*dst
= values
;
1331 for (i
= 0; i
< count
; i
++) {
1332 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1333 dst
[i
* 4 + RCOMP
] = src
[0];
1334 dst
[i
* 4 + GCOMP
] = 0.0;
1335 dst
[i
* 4 + BCOMP
] = 0.0;
1336 dst
[i
* 4 + ACOMP
] = 1.0;
1340 /**********************************************************************
1341 * Functions for MESA_FORMAT_RG_FLOAT32.
1344 get_row_rg_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1345 GLuint count
, GLint x
, GLint y
, void *values
)
1347 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
1348 GLfloat
*dst
= values
;
1351 for (i
= 0; i
< count
; i
++) {
1352 dst
[i
* 4 + RCOMP
] = src
[i
* 2 + 0];
1353 dst
[i
* 4 + GCOMP
] = src
[i
* 2 + 1];
1354 dst
[i
* 4 + BCOMP
] = 0.0;
1355 dst
[i
* 4 + ACOMP
] = 1.0;
1360 get_values_rg_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1361 GLuint count
, const GLint x
[], const GLint y
[],
1364 GLfloat
*dst
= values
;
1367 for (i
= 0; i
< count
; i
++) {
1368 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
1369 dst
[i
* 4 + RCOMP
] = src
[0];
1370 dst
[i
* 4 + GCOMP
] = src
[1];
1371 dst
[i
* 4 + BCOMP
] = 0.0;
1372 dst
[i
* 4 + ACOMP
] = 1.0;
1377 * This is the default software fallback for gl_renderbuffer's span
1380 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
1381 * are packed in the type of rb->Format, and that subsequent rows appear
1382 * rb->RowStride pixels later.
1385 _mesa_set_renderbuffer_accessors(struct gl_renderbuffer
*rb
)
1387 rb
->GetPointer
= get_pointer_generic
;
1388 rb
->GetRow
= get_row_generic
;
1390 switch (rb
->Format
) {
1391 case MESA_FORMAT_RGB888
:
1392 rb
->DataType
= GL_UNSIGNED_BYTE
;
1393 rb
->GetPointer
= get_pointer_ubyte3
;
1394 rb
->GetRow
= get_row_ubyte3
;
1395 rb
->GetValues
= get_values_ubyte3
;
1396 rb
->PutRow
= put_row_ubyte3
;
1397 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
1398 rb
->PutMonoRow
= put_mono_row_ubyte3
;
1399 rb
->PutValues
= put_values_ubyte3
;
1400 rb
->PutMonoValues
= put_mono_values_ubyte3
;
1403 case MESA_FORMAT_RGBA8888
:
1404 case MESA_FORMAT_RGBA8888_REV
:
1405 rb
->DataType
= GL_UNSIGNED_BYTE
;
1406 rb
->GetValues
= get_values_ubyte4
;
1407 rb
->PutRow
= put_row_ubyte4
;
1408 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
1409 rb
->PutMonoRow
= put_mono_row_ubyte4
;
1410 rb
->PutValues
= put_values_ubyte4
;
1411 rb
->PutMonoValues
= put_mono_values_ubyte4
;
1414 case MESA_FORMAT_R8
:
1415 rb
->DataType
= GL_UNSIGNED_BYTE
;
1416 rb
->GetValues
= get_values_r8
;
1417 rb
->GetRow
= get_row_r8
;
1418 rb
->PutRow
= put_row_generic
;
1419 rb
->PutRowRGB
= put_row_generic
;
1420 rb
->PutMonoRow
= put_mono_row_generic
;
1421 rb
->PutValues
= put_values_generic
;
1422 rb
->PutMonoValues
= put_mono_values_generic
;
1425 case MESA_FORMAT_RG88
:
1426 rb
->DataType
= GL_UNSIGNED_BYTE
;
1427 rb
->GetValues
= get_values_rg88
;
1428 rb
->GetRow
= get_row_rg88
;
1429 rb
->PutRow
= put_row_generic
;
1430 rb
->PutRowRGB
= put_row_generic
;
1431 rb
->PutMonoRow
= put_mono_row_generic
;
1432 rb
->PutValues
= put_values_generic
;
1433 rb
->PutMonoValues
= put_mono_values_generic
;
1436 case MESA_FORMAT_R16
:
1437 rb
->DataType
= GL_UNSIGNED_SHORT
;
1438 rb
->GetValues
= get_values_r16
;
1439 rb
->GetRow
= get_row_r16
;
1440 rb
->PutRow
= put_row_generic
;
1441 rb
->PutRowRGB
= put_row_generic
;
1442 rb
->PutMonoRow
= put_mono_row_generic
;
1443 rb
->PutValues
= put_values_generic
;
1444 rb
->PutMonoValues
= put_mono_values_generic
;
1447 case MESA_FORMAT_RG1616
:
1448 rb
->DataType
= GL_UNSIGNED_SHORT
;
1449 rb
->GetValues
= get_values_rg1616
;
1450 rb
->GetRow
= get_row_rg1616
;
1451 rb
->PutRow
= put_row_generic
;
1452 rb
->PutRowRGB
= put_row_generic
;
1453 rb
->PutMonoRow
= put_mono_row_generic
;
1454 rb
->PutValues
= put_values_generic
;
1455 rb
->PutMonoValues
= put_mono_values_generic
;
1458 case MESA_FORMAT_SIGNED_RGBA_16
:
1459 rb
->DataType
= GL_SHORT
;
1460 rb
->GetValues
= get_values_ushort4
;
1461 rb
->PutRow
= put_row_ushort4
;
1462 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1463 rb
->PutMonoRow
= put_mono_row_ushort4
;
1464 rb
->PutValues
= put_values_ushort4
;
1465 rb
->PutMonoValues
= put_mono_values_ushort4
;
1468 case MESA_FORMAT_S8
:
1469 rb
->DataType
= GL_UNSIGNED_BYTE
;
1470 rb
->GetValues
= get_values_ubyte
;
1471 rb
->PutRow
= put_row_ubyte
;
1472 rb
->PutRowRGB
= NULL
;
1473 rb
->PutMonoRow
= put_mono_row_ubyte
;
1474 rb
->PutValues
= put_values_ubyte
;
1475 rb
->PutMonoValues
= put_mono_values_ubyte
;
1478 case MESA_FORMAT_Z16
:
1479 rb
->DataType
= GL_UNSIGNED_SHORT
;
1480 rb
->GetValues
= get_values_ushort
;
1481 rb
->PutRow
= put_row_ushort
;
1482 rb
->PutRowRGB
= NULL
;
1483 rb
->PutMonoRow
= put_mono_row_ushort
;
1484 rb
->PutValues
= put_values_ushort
;
1485 rb
->PutMonoValues
= put_mono_values_ushort
;
1488 case MESA_FORMAT_Z32
:
1489 case MESA_FORMAT_X8_Z24
:
1490 case MESA_FORMAT_Z24_X8
:
1491 rb
->DataType
= GL_UNSIGNED_INT
;
1492 rb
->GetValues
= get_values_uint
;
1493 rb
->PutRow
= put_row_uint
;
1494 rb
->PutRowRGB
= NULL
;
1495 rb
->PutMonoRow
= put_mono_row_uint
;
1496 rb
->PutValues
= put_values_uint
;
1497 rb
->PutMonoValues
= put_mono_values_uint
;
1500 case MESA_FORMAT_Z24_S8
:
1501 case MESA_FORMAT_S8_Z24
:
1502 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1503 rb
->GetValues
= get_values_uint
;
1504 rb
->PutRow
= put_row_uint
;
1505 rb
->PutRowRGB
= NULL
;
1506 rb
->PutMonoRow
= put_mono_row_uint
;
1507 rb
->PutValues
= put_values_uint
;
1508 rb
->PutMonoValues
= put_mono_values_uint
;
1511 case MESA_FORMAT_RGBA_FLOAT32
:
1512 rb
->GetRow
= get_row_generic
;
1513 rb
->GetValues
= get_values_generic
;
1514 rb
->PutRow
= put_row_generic
;
1515 rb
->PutRowRGB
= NULL
;
1516 rb
->PutMonoRow
= put_mono_row_generic
;
1517 rb
->PutValues
= put_values_generic
;
1518 rb
->PutMonoValues
= put_mono_values_generic
;
1521 case MESA_FORMAT_INTENSITY_FLOAT32
:
1522 rb
->GetRow
= get_row_i_float32
;
1523 rb
->GetValues
= get_values_i_float32
;
1524 rb
->PutRow
= put_row_generic
;
1525 rb
->PutRowRGB
= NULL
;
1526 rb
->PutMonoRow
= put_mono_row_generic
;
1527 rb
->PutValues
= put_values_generic
;
1528 rb
->PutMonoValues
= put_mono_values_generic
;
1531 case MESA_FORMAT_LUMINANCE_FLOAT32
:
1532 rb
->GetRow
= get_row_l_float32
;
1533 rb
->GetValues
= get_values_l_float32
;
1534 rb
->PutRow
= put_row_generic
;
1535 rb
->PutRowRGB
= NULL
;
1536 rb
->PutMonoRow
= put_mono_row_generic
;
1537 rb
->PutValues
= put_values_generic
;
1538 rb
->PutMonoValues
= put_mono_values_generic
;
1541 case MESA_FORMAT_ALPHA_FLOAT32
:
1542 rb
->GetRow
= get_row_a_float32
;
1543 rb
->GetValues
= get_values_a_float32
;
1544 rb
->PutRow
= put_row_a_float32
;
1545 rb
->PutRowRGB
= NULL
;
1546 rb
->PutMonoRow
= put_mono_row_a_float32
;
1547 rb
->PutValues
= put_values_a_float32
;
1548 rb
->PutMonoValues
= put_mono_values_a_float32
;
1551 case MESA_FORMAT_RG_FLOAT32
:
1552 rb
->GetRow
= get_row_rg_float32
;
1553 rb
->GetValues
= get_values_rg_float32
;
1554 rb
->PutRow
= put_row_generic
;
1555 rb
->PutRowRGB
= NULL
;
1556 rb
->PutMonoRow
= put_mono_row_generic
;
1557 rb
->PutValues
= put_values_generic
;
1558 rb
->PutMonoValues
= put_mono_values_generic
;
1561 case MESA_FORMAT_R_FLOAT32
:
1562 rb
->GetRow
= get_row_r_float32
;
1563 rb
->GetValues
= get_values_r_float32
;
1564 rb
->PutRow
= put_row_generic
;
1565 rb
->PutRowRGB
= NULL
;
1566 rb
->PutMonoRow
= put_mono_row_generic
;
1567 rb
->PutValues
= put_values_generic
;
1568 rb
->PutMonoValues
= put_mono_values_generic
;
1577 * This is a software fallback for the gl_renderbuffer->AllocStorage
1579 * Device drivers will typically override this function for the buffers
1580 * which it manages (typically color buffers, Z and stencil).
1581 * Other buffers (like software accumulation and aux buffers) which the driver
1582 * doesn't manage can be handled with this function.
1584 * This one multi-purpose function can allocate stencil, depth, accum, color
1585 * or color-index buffers!
1587 * This function also plugs in the appropriate GetPointer, Get/PutRow and
1588 * Get/PutValues functions.
1591 _mesa_soft_renderbuffer_storage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1592 GLenum internalFormat
,
1593 GLuint width
, GLuint height
)
1595 switch (internalFormat
) {
1604 rb
->Format
= MESA_FORMAT_RGB888
;
1615 if (_mesa_little_endian())
1616 rb
->Format
= MESA_FORMAT_RGBA8888_REV
;
1618 rb
->Format
= MESA_FORMAT_RGBA8888
;
1621 case GL_RGBA16_SNORM
:
1622 /* for accum buffer */
1623 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
1625 case GL_STENCIL_INDEX
:
1626 case GL_STENCIL_INDEX1_EXT
:
1627 case GL_STENCIL_INDEX4_EXT
:
1628 case GL_STENCIL_INDEX8_EXT
:
1629 case GL_STENCIL_INDEX16_EXT
:
1630 rb
->Format
= MESA_FORMAT_S8
;
1632 case GL_DEPTH_COMPONENT
:
1633 case GL_DEPTH_COMPONENT16
:
1634 rb
->Format
= MESA_FORMAT_Z16
;
1636 case GL_DEPTH_COMPONENT24
:
1637 rb
->Format
= MESA_FORMAT_X8_Z24
;
1639 case GL_DEPTH_COMPONENT32
:
1640 rb
->Format
= MESA_FORMAT_Z32
;
1642 case GL_DEPTH_STENCIL_EXT
:
1643 case GL_DEPTH24_STENCIL8_EXT
:
1644 rb
->Format
= MESA_FORMAT_Z24_S8
;
1647 /* unsupported format */
1651 _mesa_set_renderbuffer_accessors(rb
);
1653 ASSERT(rb
->DataType
);
1654 ASSERT(rb
->GetPointer
);
1656 ASSERT(rb
->GetValues
);
1658 ASSERT(rb
->PutMonoRow
);
1659 ASSERT(rb
->PutValues
);
1660 ASSERT(rb
->PutMonoValues
);
1662 /* free old buffer storage */
1668 rb
->RowStride
= width
;
1670 if (width
> 0 && height
> 0) {
1671 /* allocate new buffer storage */
1672 rb
->Data
= malloc(width
* height
* _mesa_get_format_bytes(rb
->Format
));
1674 if (rb
->Data
== NULL
) {
1678 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1679 "software renderbuffer allocation (%d x %d x %d)",
1680 width
, height
, _mesa_get_format_bytes(rb
->Format
));
1686 rb
->Height
= height
;
1687 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
1689 if (rb
->Name
== 0 &&
1690 internalFormat
== GL_RGBA16_SNORM
&&
1691 rb
->_BaseFormat
== 0) {
1692 /* NOTE: This is a special case just for accumulation buffers.
1693 * This is a very limited use case- there's no snorm texturing or
1694 * rendering going on.
1696 rb
->_BaseFormat
= GL_RGBA
;
1699 /* the internalFormat should have been error checked long ago */
1700 ASSERT(rb
->_BaseFormat
);
1708 _mesa_map_soft_renderbuffer(struct gl_context
*ctx
,
1709 struct gl_renderbuffer
*rb
,
1710 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
1715 GLubyte
*map
= rb
->Data
;
1716 int cpp
= _mesa_get_format_bytes(rb
->Format
);
1717 int stride
= rb
->RowStride
* cpp
;
1725 *out_stride
= stride
;
1729 _mesa_unmap_soft_renderbuffer(struct gl_context
*ctx
,
1730 struct gl_renderbuffer
*rb
)
1736 /**********************************************************************/
1737 /**********************************************************************/
1738 /**********************************************************************/
1742 * Default GetPointer routine. Always return NULL to indicate that
1743 * direct buffer access is not supported.
1746 nop_get_pointer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1753 * Initialize the fields of a gl_renderbuffer to default values.
1756 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1758 _glthread_INIT_MUTEX(rb
->Mutex
);
1763 rb
->Delete
= _mesa_delete_renderbuffer
;
1765 /* The rest of these should be set later by the caller of this function or
1766 * the AllocStorage method:
1768 rb
->AllocStorage
= NULL
;
1772 rb
->InternalFormat
= GL_RGBA
;
1773 rb
->Format
= MESA_FORMAT_NONE
;
1775 rb
->DataType
= GL_NONE
;
1778 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1779 * all over the drivers.
1783 rb
->GetPointer
= nop_get_pointer
;
1785 rb
->GetValues
= NULL
;
1787 rb
->PutRowRGB
= NULL
;
1788 rb
->PutMonoRow
= NULL
;
1789 rb
->PutValues
= NULL
;
1790 rb
->PutMonoValues
= NULL
;
1795 * Allocate a new gl_renderbuffer object. This can be used for user-created
1796 * renderbuffers or window-system renderbuffers.
1798 struct gl_renderbuffer
*
1799 _mesa_new_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1801 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1803 _mesa_init_renderbuffer(rb
, name
);
1810 * Delete a gl_framebuffer.
1811 * This is the default function for renderbuffer->Delete().
1814 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1824 * Allocate a software-based renderbuffer. This is called via the
1825 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1827 * This would not be used for hardware-based renderbuffers.
1829 struct gl_renderbuffer
*
1830 _mesa_new_soft_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1832 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1834 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1835 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1836 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1845 * Add software-based color renderbuffers to the given framebuffer.
1846 * This is a helper routine for device drivers when creating a
1847 * window system framebuffer (not a user-created render/framebuffer).
1848 * Once this function is called, you can basically forget about this
1849 * renderbuffer; core Mesa will handle all the buffer management and
1853 _mesa_add_color_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1854 GLuint rgbBits
, GLuint alphaBits
,
1855 GLboolean frontLeft
, GLboolean backLeft
,
1856 GLboolean frontRight
, GLboolean backRight
)
1860 if (rgbBits
> 16 || alphaBits
> 16) {
1862 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1866 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1868 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1869 struct gl_renderbuffer
*rb
;
1871 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1873 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1875 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1877 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1880 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1882 rb
= _mesa_new_renderbuffer(ctx
, 0);
1884 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1888 rb
->InternalFormat
= GL_RGBA
;
1890 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1891 _mesa_add_renderbuffer(fb
, b
, rb
);
1899 * Add a software-based depth renderbuffer to the given framebuffer.
1900 * This is a helper routine for device drivers when creating a
1901 * window system framebuffer (not a user-created render/framebuffer).
1902 * Once this function is called, you can basically forget about this
1903 * renderbuffer; core Mesa will handle all the buffer management and
1907 _mesa_add_depth_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1910 struct gl_renderbuffer
*rb
;
1912 if (depthBits
> 32) {
1914 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1918 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1920 rb
= _mesa_new_renderbuffer(ctx
, 0);
1922 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1926 if (depthBits
<= 16) {
1927 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1929 else if (depthBits
<= 24) {
1930 rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
1933 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1936 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1937 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1944 * Add a software-based stencil renderbuffer to the given framebuffer.
1945 * This is a helper routine for device drivers when creating a
1946 * window system framebuffer (not a user-created render/framebuffer).
1947 * Once this function is called, you can basically forget about this
1948 * renderbuffer; core Mesa will handle all the buffer management and
1952 _mesa_add_stencil_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1955 struct gl_renderbuffer
*rb
;
1957 if (stencilBits
> 16) {
1959 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1963 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1965 rb
= _mesa_new_renderbuffer(ctx
, 0);
1967 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1971 assert(stencilBits
<= 8);
1972 rb
->InternalFormat
= GL_STENCIL_INDEX8
;
1974 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1975 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1982 * Add a software-based accumulation renderbuffer to the given framebuffer.
1983 * This is a helper routine for device drivers when creating a
1984 * window system framebuffer (not a user-created render/framebuffer).
1985 * Once this function is called, you can basically forget about this
1986 * renderbuffer; core Mesa will handle all the buffer management and
1990 _mesa_add_accum_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1991 GLuint redBits
, GLuint greenBits
,
1992 GLuint blueBits
, GLuint alphaBits
)
1994 struct gl_renderbuffer
*rb
;
1996 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1998 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
2002 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
2004 rb
= _mesa_new_renderbuffer(ctx
, 0);
2006 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
2010 rb
->InternalFormat
= GL_RGBA16_SNORM
;
2011 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2012 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
2020 * Add a software-based aux renderbuffer to the given framebuffer.
2021 * This is a helper routine for device drivers when creating a
2022 * window system framebuffer (not a user-created render/framebuffer).
2023 * Once this function is called, you can basically forget about this
2024 * renderbuffer; core Mesa will handle all the buffer management and
2027 * NOTE: color-index aux buffers not supported.
2030 _mesa_add_aux_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
2031 GLuint colorBits
, GLuint numBuffers
)
2035 if (colorBits
> 16) {
2037 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
2041 assert(numBuffers
<= MAX_AUX_BUFFERS
);
2043 for (i
= 0; i
< numBuffers
; i
++) {
2044 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
2046 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
2049 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating aux buffer");
2053 assert (colorBits
<= 8);
2054 rb
->InternalFormat
= GL_RGBA
;
2056 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
2057 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
2064 * Create/attach software-based renderbuffers to the given framebuffer.
2065 * This is a helper routine for device drivers. Drivers can just as well
2066 * call the individual _mesa_add_*_renderbuffer() routines directly.
2069 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
2077 GLboolean frontLeft
= GL_TRUE
;
2078 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
2079 GLboolean frontRight
= fb
->Visual
.stereoMode
;
2080 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
2083 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
2084 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
2085 _mesa_add_color_renderbuffers(NULL
, fb
,
2087 fb
->Visual
.alphaBits
,
2088 frontLeft
, backLeft
,
2089 frontRight
, backRight
);
2093 assert(fb
->Visual
.depthBits
> 0);
2094 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
2098 assert(fb
->Visual
.stencilBits
> 0);
2099 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
2103 assert(fb
->Visual
.accumRedBits
> 0);
2104 assert(fb
->Visual
.accumGreenBits
> 0);
2105 assert(fb
->Visual
.accumBlueBits
> 0);
2106 _mesa_add_accum_renderbuffer(NULL
, fb
,
2107 fb
->Visual
.accumRedBits
,
2108 fb
->Visual
.accumGreenBits
,
2109 fb
->Visual
.accumBlueBits
,
2110 fb
->Visual
.accumAlphaBits
);
2114 assert(fb
->Visual
.numAuxBuffers
> 0);
2115 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
2116 fb
->Visual
.numAuxBuffers
);
2128 * Attach a renderbuffer to a framebuffer.
2129 * \param bufferName one of the BUFFER_x tokens
2132 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
2133 gl_buffer_index bufferName
, struct gl_renderbuffer
*rb
)
2137 assert(bufferName
< BUFFER_COUNT
);
2139 /* There should be no previous renderbuffer on this attachment point,
2140 * with the exception of depth/stencil since the same renderbuffer may
2143 assert(bufferName
== BUFFER_DEPTH
||
2144 bufferName
== BUFFER_STENCIL
||
2145 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
2147 /* winsys vs. user-created buffer cross check */
2155 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
2156 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
2157 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
2162 * Remove the named renderbuffer from the given framebuffer.
2163 * \param bufferName one of the BUFFER_x tokens
2166 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
,
2167 gl_buffer_index bufferName
)
2169 struct gl_renderbuffer
*rb
;
2171 assert(bufferName
< BUFFER_COUNT
);
2173 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
2177 _mesa_reference_renderbuffer(&rb
, NULL
);
2179 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
2184 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
2185 * dereference that buffer first. The new renderbuffer's refcount will
2186 * be incremented. The old renderbuffer's refcount will be decremented.
2187 * This is normally only called from the _mesa_reference_renderbuffer() macro
2188 * when there's a real pointer change.
2191 _mesa_reference_renderbuffer_(struct gl_renderbuffer
**ptr
,
2192 struct gl_renderbuffer
*rb
)
2195 /* Unreference the old renderbuffer */
2196 GLboolean deleteFlag
= GL_FALSE
;
2197 struct gl_renderbuffer
*oldRb
= *ptr
;
2199 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
2200 ASSERT(oldRb
->RefCount
> 0);
2202 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
2203 deleteFlag
= (oldRb
->RefCount
== 0);
2204 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
2207 oldRb
->Delete(oldRb
);
2215 /* reference new renderbuffer */
2216 _glthread_LOCK_MUTEX(rb
->Mutex
);
2218 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
2219 _glthread_UNLOCK_MUTEX(rb
->Mutex
);