Merge branch 'xa_branch'
[mesa.git] / src / mesa / main / renderbuffer.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
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.
23 */
24
25
26 /**
27 * Functions for allocating/managing renderbuffers.
28 * Also, routines for reading/writing software-based renderbuffer data as
29 * ubytes, ushorts, uints, etc.
30 *
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.
35 *
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.
40 */
41
42
43 #include "glheader.h"
44 #include "imports.h"
45 #include "context.h"
46 #include "fbobject.h"
47 #include "formats.h"
48 #include "mtypes.h"
49 #include "renderbuffer.h"
50
51
52 /*
53 * Routines for get/put values in common buffer formats follow.
54 */
55
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.
59 *
60 * It would be nice to see gl_renderbuffer start talking about a
61 * gl_format instead of a GLenum DataType.
62 */
63 static int
64 get_datatype_bytes(struct gl_renderbuffer *rb)
65 {
66 int component_size;
67
68 switch (rb->DataType) {
69 case GL_FLOAT:
70 case GL_UNSIGNED_INT:
71 case GL_UNSIGNED_INT_24_8_EXT:
72 component_size = 4;
73 break;
74 case GL_UNSIGNED_SHORT:
75 component_size = 2;
76 break;
77 case GL_UNSIGNED_BYTE:
78 component_size = 1;
79 break;
80 default:
81 component_size = 1;
82 assert(0);
83 }
84
85 switch (rb->_BaseFormat) {
86 case GL_DEPTH_COMPONENT:
87 case GL_DEPTH_STENCIL:
88 return component_size;
89 default:
90 return 4 * component_size;
91 }
92 }
93
94 /* This is commonly used by most of the accessors. */
95 static void *
96 get_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
97 GLint x, GLint y)
98 {
99 if (!rb->Data)
100 return NULL;
101
102 return ((char *) rb->Data +
103 (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format));
104 }
105
106 /* GetRow() implementation for formats where DataType matches the rb->Format.
107 */
108 static void
109 get_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
110 GLuint count, GLint x, GLint y, void *values)
111 {
112 void *src = rb->GetPointer(ctx, rb, x, y);
113 memcpy(values, src, count * _mesa_get_format_bytes(rb->Format));
114 }
115
116 /* Only used for float textures currently, but might also be used for
117 * RGBA8888, RGBA16, etc.
118 */
119 static void
120 get_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
121 GLuint count, const GLint x[], const GLint y[], void *values)
122 {
123 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
124 GLuint i;
125
126 for (i = 0; i < count; i++) {
127 const void *src = rb->GetPointer(ctx, rb, x[i], y[i]);
128 char *dst = (char *) values + i * format_bytes;
129 memcpy(dst, src, format_bytes);
130 }
131 }
132
133 /* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and
134 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of
135 * storing those initial components of the value per pixel into the
136 * destination.
137 */
138 static void
139 put_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
140 GLuint count, GLint x, GLint y,
141 const void *values, const GLubyte *mask)
142 {
143 void *row = rb->GetPointer(ctx, rb, x, y);
144 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
145 int datatype_bytes = get_datatype_bytes(rb);
146 unsigned int i;
147
148 if (mask) {
149 for (i = 0; i < count; i++) {
150 char *dst = (char *) row + i * format_bytes;
151 const char *src = (const char *) values + i * datatype_bytes;
152
153 if (mask[i]) {
154 memcpy(dst, src, format_bytes);
155 }
156 }
157 }
158 else {
159 for (i = 0; i < count; i++) {
160 char *dst = (char *) row + i * format_bytes;
161 const char *src = (const char *) values + i * datatype_bytes;
162 memcpy(dst, src, format_bytes);
163 }
164 }
165 }
166
167 static void
168 put_mono_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
169 GLuint count, GLint x, GLint y,
170 const void *value, const GLubyte *mask)
171 {
172 void *row = rb->GetPointer(ctx, rb, x, y);
173 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
174 unsigned int i;
175
176 if (mask) {
177 for (i = 0; i < count; i++) {
178 char *dst = (char *) row + i * format_bytes;
179 if (mask[i]) {
180 memcpy(dst, value, format_bytes);
181 }
182 }
183 }
184 else {
185 for (i = 0; i < count; i++) {
186 char *dst = (char *) row + i * format_bytes;
187 memcpy(dst, value, format_bytes);
188 }
189 }
190 }
191
192
193 static void
194 put_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
195 GLuint count, const GLint x[], const GLint y[],
196 const void *values, const GLubyte *mask)
197 {
198 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
199 int datatype_bytes = get_datatype_bytes(rb);
200 unsigned int i;
201
202 for (i = 0; i < count; i++) {
203 if (!mask || mask[i]) {
204 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
205 const char *src = (const char *) values + i * datatype_bytes;
206 memcpy(dst, src, format_bytes);
207 }
208 }
209 }
210
211
212 static void
213 put_mono_values_generic(struct gl_context *ctx,
214 struct gl_renderbuffer *rb,
215 GLuint count, const GLint x[], const GLint y[],
216 const void *value, const GLubyte *mask)
217 {
218 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
219 unsigned int i;
220
221 for (i = 0; i < count; i++) {
222 if (!mask || mask[i]) {
223 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
224 memcpy(dst, value, format_bytes);
225 }
226 }
227 }
228
229 /**********************************************************************
230 * Functions for buffers of 1 X GLubyte values.
231 * Typically stencil.
232 */
233
234 static void
235 get_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
236 const GLint x[], const GLint y[], void *values)
237 {
238 GLubyte *dst = (GLubyte *) values;
239 GLuint i;
240 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
241 for (i = 0; i < count; i++) {
242 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
243 dst[i] = *src;
244 }
245 }
246
247
248 static void
249 put_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
250 GLint x, GLint y, const void *values, const GLubyte *mask)
251 {
252 const GLubyte *src = (const GLubyte *) values;
253 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x;
254 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
255 if (mask) {
256 GLuint i;
257 for (i = 0; i < count; i++) {
258 if (mask[i]) {
259 dst[i] = src[i];
260 }
261 }
262 }
263 else {
264 memcpy(dst, values, count * sizeof(GLubyte));
265 }
266 }
267
268
269 static void
270 put_mono_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
271 GLint x, GLint y, const void *value, const GLubyte *mask)
272 {
273 const GLubyte val = *((const GLubyte *) value);
274 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x;
275 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
276 if (mask) {
277 GLuint i;
278 for (i = 0; i < count; i++) {
279 if (mask[i]) {
280 dst[i] = val;
281 }
282 }
283 }
284 else {
285 GLuint i;
286 for (i = 0; i < count; i++) {
287 dst[i] = val;
288 }
289 }
290 }
291
292
293 static void
294 put_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
295 const GLint x[], const GLint y[],
296 const void *values, const GLubyte *mask)
297 {
298 const GLubyte *src = (const GLubyte *) values;
299 GLuint i;
300 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
301 for (i = 0; i < count; i++) {
302 if (!mask || mask[i]) {
303 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
304 *dst = src[i];
305 }
306 }
307 }
308
309
310 static void
311 put_mono_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
312 const GLint x[], const GLint y[],
313 const void *value, const GLubyte *mask)
314 {
315 const GLubyte val = *((const GLubyte *) value);
316 GLuint i;
317 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
318 for (i = 0; i < count; i++) {
319 if (!mask || mask[i]) {
320 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
321 *dst = val;
322 }
323 }
324 }
325
326
327 /**********************************************************************
328 * Functions for buffers of 1 X GLushort values.
329 * Typically depth/Z.
330 */
331
332 static void
333 get_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
334 const GLint x[], const GLint y[], void *values)
335 {
336 GLushort *dst = (GLushort *) values;
337 GLuint i;
338 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
339 for (i = 0; i < count; i++) {
340 const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
341 dst[i] = *src;
342 }
343 }
344
345
346 static void
347 put_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
348 GLint x, GLint y, const void *values, const GLubyte *mask)
349 {
350 const GLushort *src = (const GLushort *) values;
351 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x;
352 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
353 if (mask) {
354 GLuint i;
355 for (i = 0; i < count; i++) {
356 if (mask[i]) {
357 dst[i] = src[i];
358 }
359 }
360 }
361 else {
362 memcpy(dst, src, count * sizeof(GLushort));
363 }
364 }
365
366
367 static void
368 put_mono_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
369 GLint x, GLint y, const void *value, const GLubyte *mask)
370 {
371 const GLushort val = *((const GLushort *) value);
372 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x;
373 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
374 if (mask) {
375 GLuint i;
376 for (i = 0; i < count; i++) {
377 if (mask[i]) {
378 dst[i] = val;
379 }
380 }
381 }
382 else {
383 GLuint i;
384 for (i = 0; i < count; i++) {
385 dst[i] = val;
386 }
387 }
388 }
389
390
391 static void
392 put_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
393 const GLint x[], const GLint y[], const void *values,
394 const GLubyte *mask)
395 {
396 const GLushort *src = (const GLushort *) values;
397 GLuint i;
398 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
399 for (i = 0; i < count; i++) {
400 if (!mask || mask[i]) {
401 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
402 *dst = src[i];
403 }
404 }
405 }
406
407
408 static void
409 put_mono_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb,
410 GLuint count, const GLint x[], const GLint y[],
411 const void *value, const GLubyte *mask)
412 {
413 const GLushort val = *((const GLushort *) value);
414 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
415 if (mask) {
416 GLuint i;
417 for (i = 0; i < count; i++) {
418 if (mask[i]) {
419 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
420 *dst = val;
421 }
422 }
423 }
424 else {
425 GLuint i;
426 for (i = 0; i < count; i++) {
427 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
428 *dst = val;
429 }
430 }
431 }
432
433
434 /**********************************************************************
435 * Functions for buffers of 1 X GLuint values.
436 * Typically depth/Z or color index.
437 */
438
439 static void
440 get_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
441 const GLint x[], const GLint y[], void *values)
442 {
443 GLuint *dst = (GLuint *) values;
444 GLuint i;
445 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
446 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
447 for (i = 0; i < count; i++) {
448 const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
449 dst[i] = *src;
450 }
451 }
452
453
454 static void
455 put_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
456 GLint x, GLint y, const void *values, const GLubyte *mask)
457 {
458 const GLuint *src = (const GLuint *) values;
459 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x;
460 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
461 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
462 if (mask) {
463 GLuint i;
464 for (i = 0; i < count; i++) {
465 if (mask[i]) {
466 dst[i] = src[i];
467 }
468 }
469 }
470 else {
471 memcpy(dst, src, count * sizeof(GLuint));
472 }
473 }
474
475
476 static void
477 put_mono_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
478 GLint x, GLint y, const void *value, const GLubyte *mask)
479 {
480 const GLuint val = *((const GLuint *) value);
481 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x;
482 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
483 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
484 if (mask) {
485 GLuint i;
486 for (i = 0; i < count; i++) {
487 if (mask[i]) {
488 dst[i] = val;
489 }
490 }
491 }
492 else {
493 GLuint i;
494 for (i = 0; i < count; i++) {
495 dst[i] = val;
496 }
497 }
498 }
499
500
501 static void
502 put_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
503 const GLint x[], const GLint y[], const void *values,
504 const GLubyte *mask)
505 {
506 const GLuint *src = (const GLuint *) values;
507 GLuint i;
508 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
509 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
510 for (i = 0; i < count; i++) {
511 if (!mask || mask[i]) {
512 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
513 *dst = src[i];
514 }
515 }
516 }
517
518
519 static void
520 put_mono_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
521 const GLint x[], const GLint y[], const void *value,
522 const GLubyte *mask)
523 {
524 const GLuint val = *((const GLuint *) value);
525 GLuint i;
526 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
527 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
528 for (i = 0; i < count; i++) {
529 if (!mask || mask[i]) {
530 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
531 *dst = val;
532 }
533 }
534 }
535
536
537 /**********************************************************************
538 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
539 * Typically color buffers.
540 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
541 * alpha values and return 255 for outgoing alpha values.
542 */
543
544 static void *
545 get_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
546 GLint x, GLint y)
547 {
548 ASSERT(rb->Format == MESA_FORMAT_RGB888);
549 /* No direct access since this buffer is RGB but caller will be
550 * treating it as if it were RGBA.
551 */
552 return NULL;
553 }
554
555
556 static void
557 get_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
558 GLint x, GLint y, void *values)
559 {
560 const GLubyte *src = ((const GLubyte *) rb->Data) +
561 3 * (y * rb->RowStride + x);
562 GLubyte *dst = (GLubyte *) values;
563 GLuint i;
564 ASSERT(rb->Format == MESA_FORMAT_RGB888);
565 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
566 for (i = 0; i < count; i++) {
567 dst[i * 4 + 0] = src[i * 3 + 0];
568 dst[i * 4 + 1] = src[i * 3 + 1];
569 dst[i * 4 + 2] = src[i * 3 + 2];
570 dst[i * 4 + 3] = 255;
571 }
572 }
573
574
575 static void
576 get_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
577 const GLint x[], const GLint y[], void *values)
578 {
579 GLubyte *dst = (GLubyte *) values;
580 GLuint i;
581 ASSERT(rb->Format == MESA_FORMAT_RGB888);
582 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
583 for (i = 0; i < count; i++) {
584 const GLubyte *src
585 = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
586 dst[i * 4 + 0] = src[0];
587 dst[i * 4 + 1] = src[1];
588 dst[i * 4 + 2] = src[2];
589 dst[i * 4 + 3] = 255;
590 }
591 }
592
593
594 static void
595 put_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
596 GLint x, GLint y, const void *values, const GLubyte *mask)
597 {
598 /* note: incoming values are RGB+A! */
599 const GLubyte *src = (const GLubyte *) values;
600 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
601 GLuint i;
602 ASSERT(rb->Format == MESA_FORMAT_RGB888);
603 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
604 for (i = 0; i < count; i++) {
605 if (!mask || mask[i]) {
606 dst[i * 3 + 0] = src[i * 4 + 0];
607 dst[i * 3 + 1] = src[i * 4 + 1];
608 dst[i * 3 + 2] = src[i * 4 + 2];
609 }
610 }
611 }
612
613
614 static void
615 put_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
616 GLint x, GLint y, const void *values, const GLubyte *mask)
617 {
618 /* note: incoming values are RGB+A! */
619 const GLubyte *src = (const GLubyte *) values;
620 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
621 GLuint i;
622 ASSERT(rb->Format == MESA_FORMAT_RGB888);
623 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
624 for (i = 0; i < count; i++) {
625 if (!mask || mask[i]) {
626 dst[i * 3 + 0] = src[i * 3 + 0];
627 dst[i * 3 + 1] = src[i * 3 + 1];
628 dst[i * 3 + 2] = src[i * 3 + 2];
629 }
630 }
631 }
632
633
634 static void
635 put_mono_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
636 GLint x, GLint y, const void *value, const GLubyte *mask)
637 {
638 /* note: incoming value is RGB+A! */
639 const GLubyte val0 = ((const GLubyte *) value)[0];
640 const GLubyte val1 = ((const GLubyte *) value)[1];
641 const GLubyte val2 = ((const GLubyte *) value)[2];
642 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
643 ASSERT(rb->Format == MESA_FORMAT_RGB888);
644 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
645 if (!mask && val0 == val1 && val1 == val2) {
646 /* optimized case */
647 memset(dst, val0, 3 * count);
648 }
649 else {
650 GLuint i;
651 for (i = 0; i < count; i++) {
652 if (!mask || mask[i]) {
653 dst[i * 3 + 0] = val0;
654 dst[i * 3 + 1] = val1;
655 dst[i * 3 + 2] = val2;
656 }
657 }
658 }
659 }
660
661
662 static void
663 put_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
664 const GLint x[], const GLint y[], const void *values,
665 const GLubyte *mask)
666 {
667 /* note: incoming values are RGB+A! */
668 const GLubyte *src = (const GLubyte *) values;
669 GLuint i;
670 ASSERT(rb->Format == MESA_FORMAT_RGB888);
671 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
672 for (i = 0; i < count; i++) {
673 if (!mask || mask[i]) {
674 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
675 dst[0] = src[i * 4 + 0];
676 dst[1] = src[i * 4 + 1];
677 dst[2] = src[i * 4 + 2];
678 }
679 }
680 }
681
682
683 static void
684 put_mono_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
685 GLuint count, const GLint x[], const GLint y[],
686 const void *value, const GLubyte *mask)
687 {
688 /* note: incoming value is RGB+A! */
689 const GLubyte val0 = ((const GLubyte *) value)[0];
690 const GLubyte val1 = ((const GLubyte *) value)[1];
691 const GLubyte val2 = ((const GLubyte *) value)[2];
692 GLuint i;
693 ASSERT(rb->Format == MESA_FORMAT_RGB888);
694 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
695 for (i = 0; i < count; i++) {
696 if (!mask || mask[i]) {
697 GLubyte *dst = ((GLubyte *) rb->Data) +
698 3 * (y[i] * rb->RowStride + x[i]);
699 dst[0] = val0;
700 dst[1] = val1;
701 dst[2] = val2;
702 }
703 }
704 }
705
706
707 /**********************************************************************
708 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
709 * Typically color buffers.
710 */
711
712 static void
713 get_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
714 const GLint x[], const GLint y[], void *values)
715 {
716 /* treat 4*GLubyte as 1*GLuint */
717 GLuint *dst = (GLuint *) values;
718 GLuint i;
719 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
720 ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
721 for (i = 0; i < count; i++) {
722 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
723 dst[i] = *src;
724 }
725 }
726
727
728 static void
729 put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
730 GLint x, GLint y, const void *values, const GLubyte *mask)
731 {
732 /* treat 4*GLubyte as 1*GLuint */
733 const GLuint *src = (const GLuint *) values;
734 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x);
735 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
736 ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
737 if (mask) {
738 GLuint i;
739 for (i = 0; i < count; i++) {
740 if (mask[i]) {
741 dst[i] = src[i];
742 }
743 }
744 }
745 else {
746 memcpy(dst, src, 4 * count * sizeof(GLubyte));
747 }
748 }
749
750
751 static void
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)
754 {
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);
758 GLuint i;
759 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
760 ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
761 for (i = 0; i < count; i++) {
762 if (!mask || mask[i]) {
763 dst[i * 4 + 0] = src[i * 3 + 0];
764 dst[i * 4 + 1] = src[i * 3 + 1];
765 dst[i * 4 + 2] = src[i * 3 + 2];
766 dst[i * 4 + 3] = 0xff;
767 }
768 }
769 }
770
771
772 static void
773 put_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
774 GLint x, GLint y, const void *value, const GLubyte *mask)
775 {
776 /* treat 4*GLubyte as 1*GLuint */
777 const GLuint val = *((const GLuint *) value);
778 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x);
779 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
780 ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
781 if (!mask && val == 0) {
782 /* common case */
783 memset(dst, 0, count * 4 * sizeof(GLubyte));
784 }
785 else {
786 /* general case */
787 if (mask) {
788 GLuint i;
789 for (i = 0; i < count; i++) {
790 if (mask[i]) {
791 dst[i] = val;
792 }
793 }
794 }
795 else {
796 GLuint i;
797 for (i = 0; i < count; i++) {
798 dst[i] = val;
799 }
800 }
801 }
802 }
803
804
805 static void
806 put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
807 const GLint x[], const GLint y[], const void *values,
808 const GLubyte *mask)
809 {
810 /* treat 4*GLubyte as 1*GLuint */
811 const GLuint *src = (const GLuint *) values;
812 GLuint i;
813 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
814 ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
815 for (i = 0; i < count; i++) {
816 if (!mask || mask[i]) {
817 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
818 *dst = src[i];
819 }
820 }
821 }
822
823
824 static void
825 put_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb,
826 GLuint count, const GLint x[], const GLint y[],
827 const void *value, const GLubyte *mask)
828 {
829 /* treat 4*GLubyte as 1*GLuint */
830 const GLuint val = *((const GLuint *) value);
831 GLuint i;
832 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
833 ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
834 for (i = 0; i < count; i++) {
835 if (!mask || mask[i]) {
836 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
837 *dst = val;
838 }
839 }
840 }
841
842
843 /**********************************************************************
844 * Functions for buffers of 4 X GLushort (or GLshort) values.
845 * Typically accum buffer.
846 */
847
848 static void
849 get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
850 const GLint x[], const GLint y[], void *values)
851 {
852 GLushort *dst = (GLushort *) values;
853 GLuint i;
854 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
855 for (i = 0; i < count; i++) {
856 const GLushort *src
857 = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]);
858 dst[i] = *src;
859 }
860 }
861
862
863 static void
864 put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
865 GLint x, GLint y, const void *values, const GLubyte *mask)
866 {
867 const GLushort *src = (const GLushort *) values;
868 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
869 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
870 if (mask) {
871 GLuint i;
872 for (i = 0; i < count; i++) {
873 if (mask[i]) {
874 dst[i * 4 + 0] = src[i * 4 + 0];
875 dst[i * 4 + 1] = src[i * 4 + 1];
876 dst[i * 4 + 2] = src[i * 4 + 2];
877 dst[i * 4 + 3] = src[i * 4 + 3];
878 }
879 }
880 }
881 else {
882 memcpy(dst, src, 4 * count * sizeof(GLushort));
883 }
884 }
885
886
887 static void
888 put_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
889 GLint x, GLint y, const void *values, const GLubyte *mask)
890 {
891 /* Put RGB values in RGBA buffer */
892 const GLushort *src = (const GLushort *) values;
893 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
894 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
895 if (mask) {
896 GLuint i;
897 for (i = 0; i < count; i++) {
898 if (mask[i]) {
899 dst[i * 4 + 0] = src[i * 3 + 0];
900 dst[i * 4 + 1] = src[i * 3 + 1];
901 dst[i * 4 + 2] = src[i * 3 + 2];
902 dst[i * 4 + 3] = 0xffff;
903 }
904 }
905 }
906 else {
907 memcpy(dst, src, 4 * count * sizeof(GLushort));
908 }
909 }
910
911
912 static void
913 put_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
914 GLint x, GLint y, const void *value, const GLubyte *mask)
915 {
916 const GLushort val0 = ((const GLushort *) value)[0];
917 const GLushort val1 = ((const GLushort *) value)[1];
918 const GLushort val2 = ((const GLushort *) value)[2];
919 const GLushort val3 = ((const GLushort *) value)[3];
920 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
921 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
922 if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) {
923 /* common case for clearing accum buffer */
924 memset(dst, 0, count * 4 * sizeof(GLushort));
925 }
926 else {
927 GLuint i;
928 for (i = 0; i < count; i++) {
929 if (!mask || mask[i]) {
930 dst[i * 4 + 0] = val0;
931 dst[i * 4 + 1] = val1;
932 dst[i * 4 + 2] = val2;
933 dst[i * 4 + 3] = val3;
934 }
935 }
936 }
937 }
938
939
940 static void
941 put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
942 const GLint x[], const GLint y[], const void *values,
943 const GLubyte *mask)
944 {
945 const GLushort *src = (const GLushort *) values;
946 GLuint i;
947 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
948 for (i = 0; i < count; i++) {
949 if (!mask || mask[i]) {
950 GLushort *dst =
951 ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]);
952 dst[0] = src[i * 4 + 0];
953 dst[1] = src[i * 4 + 1];
954 dst[2] = src[i * 4 + 2];
955 dst[3] = src[i * 4 + 3];
956 }
957 }
958 }
959
960
961 static void
962 put_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb,
963 GLuint count, const GLint x[], const GLint y[],
964 const void *value, const GLubyte *mask)
965 {
966 const GLushort val0 = ((const GLushort *) value)[0];
967 const GLushort val1 = ((const GLushort *) value)[1];
968 const GLushort val2 = ((const GLushort *) value)[2];
969 const GLushort val3 = ((const GLushort *) value)[3];
970 GLuint i;
971 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
972 for (i = 0; i < count; i++) {
973 if (!mask || mask[i]) {
974 GLushort *dst = ((GLushort *) rb->Data) +
975 4 * (y[i] * rb->RowStride + x[i]);
976 dst[0] = val0;
977 dst[1] = val1;
978 dst[2] = val2;
979 dst[3] = val3;
980 }
981 }
982 }
983
984 /**********************************************************************
985 * Functions for MESA_FORMAT_R8.
986 */
987 static void
988 get_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
989 GLint x, GLint y, void *values)
990 {
991 const GLubyte *src = rb->GetPointer(ctx, rb, x, y);
992 GLuint *dst = values;
993 GLuint i;
994
995 for (i = 0; i < count; i++) {
996 dst[i] = 0xff000000 | src[i];
997 }
998 }
999
1000 static void
1001 get_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1002 const GLint x[], const GLint y[], void *values)
1003 {
1004 GLuint *dst = (GLuint *) values;
1005 GLuint i;
1006
1007 for (i = 0; i < count; i++) {
1008 const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1009 dst[i] = 0xff000000 | *src;
1010 }
1011 }
1012
1013 /**********************************************************************
1014 * Functions for MESA_FORMAT_RG88.
1015 */
1016 static void
1017 get_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1018 GLint x, GLint y, void *values)
1019 {
1020 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
1021 GLuint *dst = values;
1022 GLuint i;
1023
1024 for (i = 0; i < count; i++) {
1025 dst[i] = 0xff000000 | src[i];
1026 }
1027 }
1028
1029 static void
1030 get_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb,
1031 GLuint count, const GLint x[], const GLint y[], void *values)
1032 {
1033 GLuint *dst = (GLuint *) values;
1034 GLuint i;
1035
1036 for (i = 0; i < count; i++) {
1037 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1038 dst[i] = 0xff000000 | *src;
1039 }
1040 }
1041
1042 /**********************************************************************
1043 * Functions for MESA_FORMAT_R16.
1044 */
1045 static void
1046 get_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1047 GLint x, GLint y, void *values)
1048 {
1049 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
1050 GLushort *dst = values;
1051 GLuint i;
1052
1053 for (i = 0; i < count; i++) {
1054 dst[i * 4 + RCOMP] = src[i];
1055 dst[i * 4 + GCOMP] = 0;
1056 dst[i * 4 + BCOMP] = 0;
1057 dst[i * 4 + ACOMP] = 0xffff;
1058 }
1059 }
1060
1061 static void
1062 get_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1063 const GLint x[], const GLint y[], void *values)
1064 {
1065 GLushort *dst = values;
1066 GLuint i;
1067
1068 for (i = 0; i < count; i++) {
1069 const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1070 dst[i * 4 + RCOMP] = *src;
1071 dst[i * 4 + GCOMP] = 0;
1072 dst[i * 4 + BCOMP] = 0;
1073 dst[i * 4 + ACOMP] = 0xffff;
1074 }
1075 }
1076
1077 /**********************************************************************
1078 * Functions for MESA_FORMAT_RG1616.
1079 */
1080 static void
1081 get_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1082 GLint x, GLint y, void *values)
1083 {
1084 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
1085 GLushort *dst = values;
1086 GLuint i;
1087
1088 for (i = 0; i < count; i++) {
1089 dst[i * 4 + RCOMP] = src[i * 2];
1090 dst[i * 4 + GCOMP] = src[i * 2 + 1];
1091 dst[i * 4 + BCOMP] = 0;
1092 dst[i * 4 + ACOMP] = 0xffff;
1093 }
1094 }
1095
1096 static void
1097 get_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb,
1098 GLuint count, const GLint x[], const GLint y[], void *values)
1099 {
1100 GLushort *dst = values;
1101 GLuint i;
1102
1103 for (i = 0; i < count; i++) {
1104 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1105 dst[i * 4 + RCOMP] = src[0];
1106 dst[i * 4 + GCOMP] = src[1];
1107 dst[i * 4 + BCOMP] = 0;
1108 dst[i * 4 + ACOMP] = 0xffff;
1109 }
1110 }
1111
1112 /**********************************************************************
1113 * Functions for MESA_FORMAT_INTENSITY_FLOAT32.
1114 */
1115 static void
1116 get_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1117 GLuint count, GLint x, GLint y, void *values)
1118 {
1119 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1120 GLfloat *dst = values;
1121 GLuint i;
1122
1123 for (i = 0; i < count; i++) {
1124 dst[i * 4 + RCOMP] =
1125 dst[i * 4 + GCOMP] =
1126 dst[i * 4 + BCOMP] =
1127 dst[i * 4 + ACOMP] = src[i];
1128 }
1129 }
1130
1131 static void
1132 get_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1133 GLuint count, const GLint x[], const GLint y[],
1134 void *values)
1135 {
1136 GLfloat *dst = values;
1137 GLuint i;
1138
1139 for (i = 0; i < count; i++) {
1140 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1141 dst[i * 4 + RCOMP] =
1142 dst[i * 4 + GCOMP] =
1143 dst[i * 4 + BCOMP] =
1144 dst[i * 4 + ACOMP] = src[0];
1145 }
1146 }
1147
1148 /**********************************************************************
1149 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32.
1150 */
1151 static void
1152 get_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1153 GLuint count, GLint x, GLint y, void *values)
1154 {
1155 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1156 GLfloat *dst = values;
1157 GLuint i;
1158
1159 for (i = 0; i < count; i++) {
1160 dst[i * 4 + RCOMP] =
1161 dst[i * 4 + GCOMP] =
1162 dst[i * 4 + BCOMP] = src[i];
1163 dst[i * 4 + ACOMP] = 1.0;
1164 }
1165 }
1166
1167 static void
1168 get_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1169 GLuint count, const GLint x[], const GLint y[],
1170 void *values)
1171 {
1172 GLfloat *dst = values;
1173 GLuint i;
1174
1175 for (i = 0; i < count; i++) {
1176 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1177 dst[i * 4 + RCOMP] =
1178 dst[i * 4 + GCOMP] =
1179 dst[i * 4 + BCOMP] = src[0];
1180 dst[i * 4 + ACOMP] = 1.0;
1181 }
1182 }
1183
1184 /**********************************************************************
1185 * Functions for MESA_FORMAT_ALPHA_FLOAT32.
1186 */
1187 static void
1188 get_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1189 GLuint count, GLint x, GLint y, void *values)
1190 {
1191 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1192 GLfloat *dst = values;
1193 GLuint i;
1194
1195 for (i = 0; i < count; i++) {
1196 dst[i * 4 + RCOMP] = 0.0;
1197 dst[i * 4 + GCOMP] = 0.0;
1198 dst[i * 4 + BCOMP] = 0.0;
1199 dst[i * 4 + ACOMP] = src[i];
1200 }
1201 }
1202
1203 static void
1204 get_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1205 GLuint count, const GLint x[], const GLint y[],
1206 void *values)
1207 {
1208 GLfloat *dst = values;
1209 GLuint i;
1210
1211 for (i = 0; i < count; i++) {
1212 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1213 dst[i * 4 + RCOMP] = 0.0;
1214 dst[i * 4 + GCOMP] = 0.0;
1215 dst[i * 4 + BCOMP] = 0.0;
1216 dst[i * 4 + ACOMP] = src[0];
1217 }
1218 }
1219
1220 static void
1221 put_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1222 GLuint count, GLint x, GLint y,
1223 const void *values, const GLubyte *mask)
1224 {
1225 float *dst = rb->GetPointer(ctx, rb, x, y);
1226 const float *src = values;
1227 unsigned int i;
1228
1229 if (mask) {
1230 for (i = 0; i < count; i++) {
1231 if (mask[i]) {
1232 dst[i] = src[i * 4 + ACOMP];
1233 }
1234 }
1235 }
1236 else {
1237 for (i = 0; i < count; i++) {
1238 dst[i] = src[i * 4 + ACOMP];
1239 }
1240 }
1241 }
1242
1243 static void
1244 put_mono_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1245 GLuint count, GLint x, GLint y,
1246 const void *value, const GLubyte *mask)
1247 {
1248 float *dst = rb->GetPointer(ctx, rb, x, y);
1249 const float *src = value;
1250 unsigned int i;
1251
1252 if (mask) {
1253 for (i = 0; i < count; i++) {
1254 if (mask[i]) {
1255 dst[i] = src[ACOMP];
1256 }
1257 }
1258 }
1259 else {
1260 for (i = 0; i < count; i++) {
1261 dst[i] = src[ACOMP];
1262 }
1263 }
1264 }
1265
1266 static void
1267 put_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1268 GLuint count, const GLint x[], const GLint y[],
1269 const void *values, const GLubyte *mask)
1270 {
1271 const float *src = values;
1272 unsigned int i;
1273
1274 for (i = 0; i < count; i++) {
1275 if (!mask || mask[i]) {
1276 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
1277
1278 *dst = src[i * 4 + ACOMP];
1279 }
1280 }
1281 }
1282
1283 static void
1284 put_mono_values_a_float32(struct gl_context *ctx,
1285 struct gl_renderbuffer *rb,
1286 GLuint count, const GLint x[], const GLint y[],
1287 const void *value, const GLubyte *mask)
1288 {
1289 const float *src = value;
1290 unsigned int i;
1291
1292 for (i = 0; i < count; i++) {
1293 if (!mask || mask[i]) {
1294 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
1295 *dst = src[ACOMP];
1296 }
1297 }
1298 }
1299
1300 /**********************************************************************
1301 * Functions for MESA_FORMAT_R_FLOAT32.
1302 */
1303 static void
1304 get_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1305 GLuint count, GLint x, GLint y, void *values)
1306 {
1307 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1308 GLfloat *dst = values;
1309 GLuint i;
1310
1311 for (i = 0; i < count; i++) {
1312 dst[i * 4 + RCOMP] = src[i];
1313 dst[i * 4 + GCOMP] = 0.0;
1314 dst[i * 4 + BCOMP] = 0.0;
1315 dst[i * 4 + ACOMP] = 1.0;
1316 }
1317 }
1318
1319 static void
1320 get_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1321 GLuint count, const GLint x[], const GLint y[],
1322 void *values)
1323 {
1324 GLfloat *dst = values;
1325 GLuint i;
1326
1327 for (i = 0; i < count; i++) {
1328 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1329 dst[i * 4 + RCOMP] = src[0];
1330 dst[i * 4 + GCOMP] = 0.0;
1331 dst[i * 4 + BCOMP] = 0.0;
1332 dst[i * 4 + ACOMP] = 1.0;
1333 }
1334 }
1335
1336 /**********************************************************************
1337 * Functions for MESA_FORMAT_RG_FLOAT32.
1338 */
1339 static void
1340 get_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1341 GLuint count, GLint x, GLint y, void *values)
1342 {
1343 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1344 GLfloat *dst = values;
1345 GLuint i;
1346
1347 for (i = 0; i < count; i++) {
1348 dst[i * 4 + RCOMP] = src[i * 2 + 0];
1349 dst[i * 4 + GCOMP] = src[i * 2 + 1];
1350 dst[i * 4 + BCOMP] = 0.0;
1351 dst[i * 4 + ACOMP] = 1.0;
1352 }
1353 }
1354
1355 static void
1356 get_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1357 GLuint count, const GLint x[], const GLint y[],
1358 void *values)
1359 {
1360 GLfloat *dst = values;
1361 GLuint i;
1362
1363 for (i = 0; i < count; i++) {
1364 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1365 dst[i * 4 + RCOMP] = src[0];
1366 dst[i * 4 + GCOMP] = src[1];
1367 dst[i * 4 + BCOMP] = 0.0;
1368 dst[i * 4 + ACOMP] = 1.0;
1369 }
1370 }
1371
1372 /**
1373 * This is the default software fallback for gl_renderbuffer's span
1374 * access functions.
1375 *
1376 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
1377 * are packed in the type of rb->Format, and that subsequent rows appear
1378 * rb->RowStride pixels later.
1379 */
1380 void
1381 _mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb)
1382 {
1383 rb->GetPointer = get_pointer_generic;
1384 rb->GetRow = get_row_generic;
1385
1386 switch (rb->Format) {
1387 case MESA_FORMAT_RGB888:
1388 rb->DataType = GL_UNSIGNED_BYTE;
1389 rb->GetPointer = get_pointer_ubyte3;
1390 rb->GetRow = get_row_ubyte3;
1391 rb->GetValues = get_values_ubyte3;
1392 rb->PutRow = put_row_ubyte3;
1393 rb->PutRowRGB = put_row_rgb_ubyte3;
1394 rb->PutMonoRow = put_mono_row_ubyte3;
1395 rb->PutValues = put_values_ubyte3;
1396 rb->PutMonoValues = put_mono_values_ubyte3;
1397 break;
1398
1399 case MESA_FORMAT_RGBA8888:
1400 rb->DataType = GL_UNSIGNED_BYTE;
1401 rb->GetValues = get_values_ubyte4;
1402 rb->PutRow = put_row_ubyte4;
1403 rb->PutRowRGB = put_row_rgb_ubyte4;
1404 rb->PutMonoRow = put_mono_row_ubyte4;
1405 rb->PutValues = put_values_ubyte4;
1406 rb->PutMonoValues = put_mono_values_ubyte4;
1407 break;
1408
1409 case MESA_FORMAT_R8:
1410 rb->DataType = GL_UNSIGNED_BYTE;
1411 rb->GetValues = get_values_r8;
1412 rb->GetRow = get_row_r8;
1413 rb->PutRow = put_row_generic;
1414 rb->PutRowRGB = put_row_generic;
1415 rb->PutMonoRow = put_mono_row_generic;
1416 rb->PutValues = put_values_generic;
1417 rb->PutMonoValues = put_mono_values_generic;
1418 break;
1419
1420 case MESA_FORMAT_RG88:
1421 rb->DataType = GL_UNSIGNED_BYTE;
1422 rb->GetValues = get_values_rg88;
1423 rb->GetRow = get_row_rg88;
1424 rb->PutRow = put_row_generic;
1425 rb->PutRowRGB = put_row_generic;
1426 rb->PutMonoRow = put_mono_row_generic;
1427 rb->PutValues = put_values_generic;
1428 rb->PutMonoValues = put_mono_values_generic;
1429 break;
1430
1431 case MESA_FORMAT_R16:
1432 rb->DataType = GL_UNSIGNED_SHORT;
1433 rb->GetValues = get_values_r16;
1434 rb->GetRow = get_row_r16;
1435 rb->PutRow = put_row_generic;
1436 rb->PutRowRGB = put_row_generic;
1437 rb->PutMonoRow = put_mono_row_generic;
1438 rb->PutValues = put_values_generic;
1439 rb->PutMonoValues = put_mono_values_generic;
1440 break;
1441
1442 case MESA_FORMAT_RG1616:
1443 rb->DataType = GL_UNSIGNED_SHORT;
1444 rb->GetValues = get_values_rg1616;
1445 rb->GetRow = get_row_rg1616;
1446 rb->PutRow = put_row_generic;
1447 rb->PutRowRGB = put_row_generic;
1448 rb->PutMonoRow = put_mono_row_generic;
1449 rb->PutValues = put_values_generic;
1450 rb->PutMonoValues = put_mono_values_generic;
1451 break;
1452
1453 case MESA_FORMAT_SIGNED_RGBA_16:
1454 rb->DataType = GL_SHORT;
1455 rb->GetValues = get_values_ushort4;
1456 rb->PutRow = put_row_ushort4;
1457 rb->PutRowRGB = put_row_rgb_ushort4;
1458 rb->PutMonoRow = put_mono_row_ushort4;
1459 rb->PutValues = put_values_ushort4;
1460 rb->PutMonoValues = put_mono_values_ushort4;
1461 break;
1462
1463 #if 0
1464 case MESA_FORMAT_A8:
1465 rb->DataType = GL_UNSIGNED_BYTE;
1466 rb->GetValues = get_values_alpha8;
1467 rb->PutRow = put_row_alpha8;
1468 rb->PutRowRGB = NULL;
1469 rb->PutMonoRow = put_mono_row_alpha8;
1470 rb->PutValues = put_values_alpha8;
1471 rb->PutMonoValues = put_mono_values_alpha8;
1472 break;
1473 #endif
1474
1475 case MESA_FORMAT_S8:
1476 rb->DataType = GL_UNSIGNED_BYTE;
1477 rb->GetValues = get_values_ubyte;
1478 rb->PutRow = put_row_ubyte;
1479 rb->PutRowRGB = NULL;
1480 rb->PutMonoRow = put_mono_row_ubyte;
1481 rb->PutValues = put_values_ubyte;
1482 rb->PutMonoValues = put_mono_values_ubyte;
1483 break;
1484
1485 case MESA_FORMAT_Z16:
1486 rb->DataType = GL_UNSIGNED_SHORT;
1487 rb->GetValues = get_values_ushort;
1488 rb->PutRow = put_row_ushort;
1489 rb->PutRowRGB = NULL;
1490 rb->PutMonoRow = put_mono_row_ushort;
1491 rb->PutValues = put_values_ushort;
1492 rb->PutMonoValues = put_mono_values_ushort;
1493 break;
1494
1495 case MESA_FORMAT_Z32:
1496 case MESA_FORMAT_X8_Z24:
1497 case MESA_FORMAT_Z24_X8:
1498 rb->DataType = GL_UNSIGNED_INT;
1499 rb->GetValues = get_values_uint;
1500 rb->PutRow = put_row_uint;
1501 rb->PutRowRGB = NULL;
1502 rb->PutMonoRow = put_mono_row_uint;
1503 rb->PutValues = put_values_uint;
1504 rb->PutMonoValues = put_mono_values_uint;
1505 break;
1506
1507 case MESA_FORMAT_Z24_S8:
1508 case MESA_FORMAT_S8_Z24:
1509 rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
1510 rb->GetValues = get_values_uint;
1511 rb->PutRow = put_row_uint;
1512 rb->PutRowRGB = NULL;
1513 rb->PutMonoRow = put_mono_row_uint;
1514 rb->PutValues = put_values_uint;
1515 rb->PutMonoValues = put_mono_values_uint;
1516 break;
1517
1518 case MESA_FORMAT_RGBA_FLOAT32:
1519 rb->GetRow = get_row_generic;
1520 rb->GetValues = get_values_generic;
1521 rb->PutRow = put_row_generic;
1522 rb->PutRowRGB = NULL;
1523 rb->PutMonoRow = put_mono_row_generic;
1524 rb->PutValues = put_values_generic;
1525 rb->PutMonoValues = put_mono_values_generic;
1526 break;
1527
1528 case MESA_FORMAT_INTENSITY_FLOAT32:
1529 rb->GetRow = get_row_i_float32;
1530 rb->GetValues = get_values_i_float32;
1531 rb->PutRow = put_row_generic;
1532 rb->PutRowRGB = NULL;
1533 rb->PutMonoRow = put_mono_row_generic;
1534 rb->PutValues = put_values_generic;
1535 rb->PutMonoValues = put_mono_values_generic;
1536 break;
1537
1538 case MESA_FORMAT_LUMINANCE_FLOAT32:
1539 rb->GetRow = get_row_l_float32;
1540 rb->GetValues = get_values_l_float32;
1541 rb->PutRow = put_row_generic;
1542 rb->PutRowRGB = NULL;
1543 rb->PutMonoRow = put_mono_row_generic;
1544 rb->PutValues = put_values_generic;
1545 rb->PutMonoValues = put_mono_values_generic;
1546 break;
1547
1548 case MESA_FORMAT_ALPHA_FLOAT32:
1549 rb->GetRow = get_row_a_float32;
1550 rb->GetValues = get_values_a_float32;
1551 rb->PutRow = put_row_a_float32;
1552 rb->PutRowRGB = NULL;
1553 rb->PutMonoRow = put_mono_row_a_float32;
1554 rb->PutValues = put_values_a_float32;
1555 rb->PutMonoValues = put_mono_values_a_float32;
1556 break;
1557
1558 case MESA_FORMAT_RG_FLOAT32:
1559 rb->GetRow = get_row_rg_float32;
1560 rb->GetValues = get_values_rg_float32;
1561 rb->PutRow = put_row_generic;
1562 rb->PutRowRGB = NULL;
1563 rb->PutMonoRow = put_mono_row_generic;
1564 rb->PutValues = put_values_generic;
1565 rb->PutMonoValues = put_mono_values_generic;
1566 break;
1567
1568 case MESA_FORMAT_R_FLOAT32:
1569 rb->GetRow = get_row_r_float32;
1570 rb->GetValues = get_values_r_float32;
1571 rb->PutRow = put_row_generic;
1572 rb->PutRowRGB = NULL;
1573 rb->PutMonoRow = put_mono_row_generic;
1574 rb->PutValues = put_values_generic;
1575 rb->PutMonoValues = put_mono_values_generic;
1576 break;
1577
1578 default:
1579 break;
1580 }
1581 }
1582
1583 /**
1584 * This is a software fallback for the gl_renderbuffer->AllocStorage
1585 * function.
1586 * Device drivers will typically override this function for the buffers
1587 * which it manages (typically color buffers, Z and stencil).
1588 * Other buffers (like software accumulation and aux buffers) which the driver
1589 * doesn't manage can be handled with this function.
1590 *
1591 * This one multi-purpose function can allocate stencil, depth, accum, color
1592 * or color-index buffers!
1593 *
1594 * This function also plugs in the appropriate GetPointer, Get/PutRow and
1595 * Get/PutValues functions.
1596 */
1597 GLboolean
1598 _mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
1599 GLenum internalFormat,
1600 GLuint width, GLuint height)
1601 {
1602 switch (internalFormat) {
1603 case GL_RGB:
1604 case GL_R3_G3_B2:
1605 case GL_RGB4:
1606 case GL_RGB5:
1607 case GL_RGB8:
1608 case GL_RGB10:
1609 case GL_RGB12:
1610 case GL_RGB16:
1611 rb->Format = MESA_FORMAT_RGB888;
1612 break;
1613 case GL_RGBA:
1614 case GL_RGBA2:
1615 case GL_RGBA4:
1616 case GL_RGB5_A1:
1617 case GL_RGBA8:
1618 #if 1
1619 case GL_RGB10_A2:
1620 case GL_RGBA12:
1621 #endif
1622 rb->Format = MESA_FORMAT_RGBA8888;
1623 break;
1624 case GL_RGBA16:
1625 case GL_RGBA16_SNORM:
1626 /* for accum buffer */
1627 rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
1628 break;
1629 #if 0
1630 case GL_ALPHA8:
1631 rb->Format = MESA_FORMAT_A8;
1632 break;
1633 #endif
1634 case GL_STENCIL_INDEX:
1635 case GL_STENCIL_INDEX1_EXT:
1636 case GL_STENCIL_INDEX4_EXT:
1637 case GL_STENCIL_INDEX8_EXT:
1638 case GL_STENCIL_INDEX16_EXT:
1639 rb->Format = MESA_FORMAT_S8;
1640 break;
1641 case GL_DEPTH_COMPONENT:
1642 case GL_DEPTH_COMPONENT16:
1643 rb->Format = MESA_FORMAT_Z16;
1644 break;
1645 case GL_DEPTH_COMPONENT24:
1646 rb->Format = MESA_FORMAT_X8_Z24;
1647 break;
1648 case GL_DEPTH_COMPONENT32:
1649 rb->Format = MESA_FORMAT_Z32;
1650 break;
1651 case GL_DEPTH_STENCIL_EXT:
1652 case GL_DEPTH24_STENCIL8_EXT:
1653 rb->Format = MESA_FORMAT_Z24_S8;
1654 break;
1655 default:
1656 /* unsupported format */
1657 return GL_FALSE;
1658 }
1659
1660 _mesa_set_renderbuffer_accessors(rb);
1661
1662 ASSERT(rb->DataType);
1663 ASSERT(rb->GetPointer);
1664 ASSERT(rb->GetRow);
1665 ASSERT(rb->GetValues);
1666 ASSERT(rb->PutRow);
1667 ASSERT(rb->PutMonoRow);
1668 ASSERT(rb->PutValues);
1669 ASSERT(rb->PutMonoValues);
1670
1671 /* free old buffer storage */
1672 if (rb->Data) {
1673 free(rb->Data);
1674 rb->Data = NULL;
1675 }
1676
1677 rb->RowStride = width;
1678
1679 if (width > 0 && height > 0) {
1680 /* allocate new buffer storage */
1681 rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format));
1682
1683 if (rb->Data == NULL) {
1684 rb->Width = 0;
1685 rb->Height = 0;
1686 rb->RowStride = 0;
1687 _mesa_error(ctx, GL_OUT_OF_MEMORY,
1688 "software renderbuffer allocation (%d x %d x %d)",
1689 width, height, _mesa_get_format_bytes(rb->Format));
1690 return GL_FALSE;
1691 }
1692 }
1693
1694 rb->Width = width;
1695 rb->Height = height;
1696 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
1697
1698 if (rb->Name == 0 &&
1699 internalFormat == GL_RGBA16_SNORM &&
1700 rb->_BaseFormat == 0) {
1701 /* NOTE: This is a special case just for accumulation buffers.
1702 * This is a very limited use case- there's no snorm texturing or
1703 * rendering going on.
1704 */
1705 rb->_BaseFormat = GL_RGBA;
1706 }
1707 else {
1708 /* the internalFormat should have been error checked long ago */
1709 ASSERT(rb->_BaseFormat);
1710 }
1711
1712 return GL_TRUE;
1713 }
1714
1715
1716
1717 /**********************************************************************/
1718 /**********************************************************************/
1719 /**********************************************************************/
1720
1721
1722 /**
1723 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1724 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1725 *
1726 * When PutRow is called (for example), we store the alpha values in
1727 * this buffer, then pass on the PutRow call to the wrapped RGB
1728 * buffer.
1729 */
1730
1731
1732 static GLboolean
1733 alloc_storage_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb,
1734 GLenum internalFormat, GLuint width, GLuint height)
1735 {
1736 ASSERT(arb != arb->Wrapped);
1737 ASSERT(arb->Format == MESA_FORMAT_A8);
1738
1739 /* first, pass the call to the wrapped RGB buffer */
1740 if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat,
1741 width, height)) {
1742 return GL_FALSE;
1743 }
1744
1745 /* next, resize my alpha buffer */
1746 if (arb->Data) {
1747 free(arb->Data);
1748 }
1749
1750 arb->Data = malloc(width * height * sizeof(GLubyte));
1751 if (arb->Data == NULL) {
1752 arb->Width = 0;
1753 arb->Height = 0;
1754 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation");
1755 return GL_FALSE;
1756 }
1757
1758 arb->Width = width;
1759 arb->Height = height;
1760 arb->RowStride = width;
1761
1762 return GL_TRUE;
1763 }
1764
1765
1766 /**
1767 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1768 */
1769 static void
1770 delete_renderbuffer_alpha8(struct gl_renderbuffer *arb)
1771 {
1772 if (arb->Data) {
1773 free(arb->Data);
1774 }
1775 ASSERT(arb->Wrapped);
1776 ASSERT(arb != arb->Wrapped);
1777 arb->Wrapped->Delete(arb->Wrapped);
1778 arb->Wrapped = NULL;
1779 free(arb);
1780 }
1781
1782
1783 static void *
1784 get_pointer_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb,
1785 GLint x, GLint y)
1786 {
1787 return NULL; /* don't allow direct access! */
1788 }
1789
1790
1791 static void
1792 get_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
1793 GLint x, GLint y, void *values)
1794 {
1795 /* NOTE: 'values' is RGBA format! */
1796 const GLubyte *src = (const GLubyte *) arb->Data + y * arb->RowStride + x;
1797 GLubyte *dst = (GLubyte *) values;
1798 GLuint i;
1799 ASSERT(arb != arb->Wrapped);
1800 ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
1801 /* first, pass the call to the wrapped RGB buffer */
1802 arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values);
1803 /* second, fill in alpha values from this buffer! */
1804 for (i = 0; i < count; i++) {
1805 dst[i * 4 + 3] = src[i];
1806 }
1807 }
1808
1809
1810 static void
1811 get_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
1812 const GLint x[], const GLint y[], void *values)
1813 {
1814 GLubyte *dst = (GLubyte *) values;
1815 GLuint i;
1816 ASSERT(arb != arb->Wrapped);
1817 ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
1818 /* first, pass the call to the wrapped RGB buffer */
1819 arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values);
1820 /* second, fill in alpha values from this buffer! */
1821 for (i = 0; i < count; i++) {
1822 const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i];
1823 dst[i * 4 + 3] = *src;
1824 }
1825 }
1826
1827
1828 static void
1829 put_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
1830 GLint x, GLint y, const void *values, const GLubyte *mask)
1831 {
1832 const GLubyte *src = (const GLubyte *) values;
1833 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x;
1834 GLuint i;
1835 ASSERT(arb != arb->Wrapped);
1836 ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
1837 /* first, pass the call to the wrapped RGB buffer */
1838 arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask);
1839 /* second, store alpha in our buffer */
1840 for (i = 0; i < count; i++) {
1841 if (!mask || mask[i]) {
1842 dst[i] = src[i * 4 + 3];
1843 }
1844 }
1845 }
1846
1847
1848 static void
1849 put_row_rgb_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
1850 GLint x, GLint y, const void *values, const GLubyte *mask)
1851 {
1852 const GLubyte *src = (const GLubyte *) values;
1853 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x;
1854 GLuint i;
1855 ASSERT(arb != arb->Wrapped);
1856 ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
1857 /* first, pass the call to the wrapped RGB buffer */
1858 arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask);
1859 /* second, store alpha in our buffer */
1860 for (i = 0; i < count; i++) {
1861 if (!mask || mask[i]) {
1862 dst[i] = src[i * 4 + 3];
1863 }
1864 }
1865 }
1866
1867
1868 static void
1869 put_mono_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
1870 GLint x, GLint y, const void *value, const GLubyte *mask)
1871 {
1872 const GLubyte val = ((const GLubyte *) value)[3];
1873 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x;
1874 ASSERT(arb != arb->Wrapped);
1875 ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
1876 /* first, pass the call to the wrapped RGB buffer */
1877 arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask);
1878 /* second, store alpha in our buffer */
1879 if (mask) {
1880 GLuint i;
1881 for (i = 0; i < count; i++) {
1882 if (mask[i]) {
1883 dst[i] = val;
1884 }
1885 }
1886 }
1887 else {
1888 memset(dst, val, count);
1889 }
1890 }
1891
1892
1893 static void
1894 put_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
1895 const GLint x[], const GLint y[],
1896 const void *values, const GLubyte *mask)
1897 {
1898 const GLubyte *src = (const GLubyte *) values;
1899 GLuint i;
1900 ASSERT(arb != arb->Wrapped);
1901 ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
1902 /* first, pass the call to the wrapped RGB buffer */
1903 arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask);
1904 /* second, store alpha in our buffer */
1905 for (i = 0; i < count; i++) {
1906 if (!mask || mask[i]) {
1907 GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i];
1908 *dst = src[i * 4 + 3];
1909 }
1910 }
1911 }
1912
1913
1914 static void
1915 put_mono_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb,
1916 GLuint count, const GLint x[], const GLint y[],
1917 const void *value, const GLubyte *mask)
1918 {
1919 const GLubyte val = ((const GLubyte *) value)[3];
1920 GLuint i;
1921 ASSERT(arb != arb->Wrapped);
1922 ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
1923 /* first, pass the call to the wrapped RGB buffer */
1924 arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask);
1925 /* second, store alpha in our buffer */
1926 for (i = 0; i < count; i++) {
1927 if (!mask || mask[i]) {
1928 GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i];
1929 *dst = val;
1930 }
1931 }
1932 }
1933
1934
1935 static void
1936 copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src)
1937 {
1938 ASSERT(dst->Format == MESA_FORMAT_A8);
1939 ASSERT(src->Format == MESA_FORMAT_A8);
1940 ASSERT(dst->Width == src->Width);
1941 ASSERT(dst->Height == src->Height);
1942 ASSERT(dst->RowStride == src->RowStride);
1943
1944 memcpy(dst->Data, src->Data, dst->RowStride * dst->Height * sizeof(GLubyte));
1945 }
1946
1947
1948 /**********************************************************************/
1949 /**********************************************************************/
1950 /**********************************************************************/
1951
1952
1953 /**
1954 * Default GetPointer routine. Always return NULL to indicate that
1955 * direct buffer access is not supported.
1956 */
1957 static void *
1958 nop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
1959 {
1960 return NULL;
1961 }
1962
1963
1964 /**
1965 * Initialize the fields of a gl_renderbuffer to default values.
1966 */
1967 void
1968 _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
1969 {
1970 _glthread_INIT_MUTEX(rb->Mutex);
1971
1972 rb->ClassID = 0;
1973 rb->Name = name;
1974 rb->RefCount = 0;
1975 rb->Delete = _mesa_delete_renderbuffer;
1976
1977 /* The rest of these should be set later by the caller of this function or
1978 * the AllocStorage method:
1979 */
1980 rb->AllocStorage = NULL;
1981
1982 rb->Width = 0;
1983 rb->Height = 0;
1984 rb->InternalFormat = GL_NONE;
1985 rb->Format = MESA_FORMAT_NONE;
1986
1987 rb->DataType = GL_NONE;
1988 rb->Data = NULL;
1989
1990 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1991 * all over the drivers.
1992 */
1993 rb->Wrapped = rb;
1994
1995 rb->GetPointer = nop_get_pointer;
1996 rb->GetRow = NULL;
1997 rb->GetValues = NULL;
1998 rb->PutRow = NULL;
1999 rb->PutRowRGB = NULL;
2000 rb->PutMonoRow = NULL;
2001 rb->PutValues = NULL;
2002 rb->PutMonoValues = NULL;
2003 }
2004
2005
2006 /**
2007 * Allocate a new gl_renderbuffer object. This can be used for user-created
2008 * renderbuffers or window-system renderbuffers.
2009 */
2010 struct gl_renderbuffer *
2011 _mesa_new_renderbuffer(struct gl_context *ctx, GLuint name)
2012 {
2013 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
2014 if (rb) {
2015 _mesa_init_renderbuffer(rb, name);
2016 }
2017 return rb;
2018 }
2019
2020
2021 /**
2022 * Delete a gl_framebuffer.
2023 * This is the default function for renderbuffer->Delete().
2024 */
2025 void
2026 _mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
2027 {
2028 if (rb->Data) {
2029 free(rb->Data);
2030 }
2031 free(rb);
2032 }
2033
2034
2035 /**
2036 * Allocate a software-based renderbuffer. This is called via the
2037 * ctx->Driver.NewRenderbuffer() function when the user creates a new
2038 * renderbuffer.
2039 * This would not be used for hardware-based renderbuffers.
2040 */
2041 struct gl_renderbuffer *
2042 _mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name)
2043 {
2044 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
2045 if (rb) {
2046 rb->AllocStorage = _mesa_soft_renderbuffer_storage;
2047 /* Normally, one would setup the PutRow, GetRow, etc functions here.
2048 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
2049 * instead.
2050 */
2051 }
2052 return rb;
2053 }
2054
2055
2056 /**
2057 * Add software-based color renderbuffers to the given framebuffer.
2058 * This is a helper routine for device drivers when creating a
2059 * window system framebuffer (not a user-created render/framebuffer).
2060 * Once this function is called, you can basically forget about this
2061 * renderbuffer; core Mesa will handle all the buffer management and
2062 * rendering!
2063 */
2064 GLboolean
2065 _mesa_add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
2066 GLuint rgbBits, GLuint alphaBits,
2067 GLboolean frontLeft, GLboolean backLeft,
2068 GLboolean frontRight, GLboolean backRight)
2069 {
2070 gl_buffer_index b;
2071
2072 if (rgbBits > 16 || alphaBits > 16) {
2073 _mesa_problem(ctx,
2074 "Unsupported bit depth in _mesa_add_color_renderbuffers");
2075 return GL_FALSE;
2076 }
2077
2078 assert(MAX_COLOR_ATTACHMENTS >= 4);
2079
2080 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
2081 struct gl_renderbuffer *rb;
2082
2083 if (b == BUFFER_FRONT_LEFT && !frontLeft)
2084 continue;
2085 else if (b == BUFFER_BACK_LEFT && !backLeft)
2086 continue;
2087 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
2088 continue;
2089 else if (b == BUFFER_BACK_RIGHT && !backRight)
2090 continue;
2091
2092 assert(fb->Attachment[b].Renderbuffer == NULL);
2093
2094 rb = _mesa_new_renderbuffer(ctx, 0);
2095 if (!rb) {
2096 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
2097 return GL_FALSE;
2098 }
2099
2100 if (rgbBits <= 8) {
2101 if (alphaBits)
2102 rb->Format = MESA_FORMAT_RGBA8888;
2103 else
2104 rb->Format = MESA_FORMAT_RGB888;
2105 }
2106 else {
2107 assert(rgbBits <= 16);
2108 rb->Format = MESA_FORMAT_NONE; /*XXX RGBA16;*/
2109 }
2110 rb->InternalFormat = GL_RGBA;
2111
2112 rb->AllocStorage = _mesa_soft_renderbuffer_storage;
2113 _mesa_add_renderbuffer(fb, b, rb);
2114 }
2115
2116 return GL_TRUE;
2117 }
2118
2119
2120 /**
2121 * Add software-based alpha renderbuffers to the given framebuffer.
2122 * This is a helper routine for device drivers when creating a
2123 * window system framebuffer (not a user-created render/framebuffer).
2124 * Once this function is called, you can basically forget about this
2125 * renderbuffer; core Mesa will handle all the buffer management and
2126 * rendering!
2127 */
2128 GLboolean
2129 _mesa_add_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
2130 GLuint alphaBits,
2131 GLboolean frontLeft, GLboolean backLeft,
2132 GLboolean frontRight, GLboolean backRight)
2133 {
2134 gl_buffer_index b;
2135
2136 /* for window system framebuffers only! */
2137 assert(fb->Name == 0);
2138
2139 if (alphaBits > 8) {
2140 _mesa_problem(ctx,
2141 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
2142 return GL_FALSE;
2143 }
2144
2145 assert(MAX_COLOR_ATTACHMENTS >= 4);
2146
2147 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
2148 */
2149 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
2150 struct gl_renderbuffer *arb;
2151
2152 if (b == BUFFER_FRONT_LEFT && !frontLeft)
2153 continue;
2154 else if (b == BUFFER_BACK_LEFT && !backLeft)
2155 continue;
2156 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
2157 continue;
2158 else if (b == BUFFER_BACK_RIGHT && !backRight)
2159 continue;
2160
2161 /* the RGB buffer to wrap must already exist!! */
2162 assert(fb->Attachment[b].Renderbuffer);
2163
2164 /* only GLubyte supported for now */
2165 assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
2166
2167 /* allocate alpha renderbuffer */
2168 arb = _mesa_new_renderbuffer(ctx, 0);
2169 if (!arb) {
2170 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
2171 return GL_FALSE;
2172 }
2173
2174 /* wrap the alpha renderbuffer around the RGB renderbuffer */
2175 arb->Wrapped = fb->Attachment[b].Renderbuffer;
2176
2177 /* Set up my alphabuffer fields and plug in my functions.
2178 * The functions will put/get the alpha values from/to RGBA arrays
2179 * and then call the wrapped buffer's functions to handle the RGB
2180 * values.
2181 */
2182 arb->InternalFormat = arb->Wrapped->InternalFormat;
2183 arb->Format = MESA_FORMAT_A8;
2184 arb->DataType = arb->Wrapped->DataType;
2185 arb->AllocStorage = alloc_storage_alpha8;
2186 arb->Delete = delete_renderbuffer_alpha8;
2187 arb->GetPointer = get_pointer_alpha8;
2188 arb->GetRow = get_row_alpha8;
2189 arb->GetValues = get_values_alpha8;
2190 arb->PutRow = put_row_alpha8;
2191 arb->PutRowRGB = put_row_rgb_alpha8;
2192 arb->PutMonoRow = put_mono_row_alpha8;
2193 arb->PutValues = put_values_alpha8;
2194 arb->PutMonoValues = put_mono_values_alpha8;
2195
2196 /* clear the pointer to avoid assertion/sanity check failure later */
2197 fb->Attachment[b].Renderbuffer = NULL;
2198
2199 /* plug the alpha renderbuffer into the colorbuffer attachment */
2200 _mesa_add_renderbuffer(fb, b, arb);
2201 }
2202
2203 return GL_TRUE;
2204 }
2205
2206
2207 /**
2208 * For framebuffers that use a software alpha channel wrapper
2209 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
2210 * copy the back buffer alpha channel into the front buffer alpha channel.
2211 */
2212 void
2213 _mesa_copy_soft_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb)
2214 {
2215 if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
2216 fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer)
2217 copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer,
2218 fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
2219
2220
2221 if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
2222 fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer)
2223 copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer,
2224 fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
2225 }
2226
2227
2228 /**
2229 * Add a software-based depth renderbuffer to the given framebuffer.
2230 * This is a helper routine for device drivers when creating a
2231 * window system framebuffer (not a user-created render/framebuffer).
2232 * Once this function is called, you can basically forget about this
2233 * renderbuffer; core Mesa will handle all the buffer management and
2234 * rendering!
2235 */
2236 GLboolean
2237 _mesa_add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
2238 GLuint depthBits)
2239 {
2240 struct gl_renderbuffer *rb;
2241
2242 if (depthBits > 32) {
2243 _mesa_problem(ctx,
2244 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
2245 return GL_FALSE;
2246 }
2247
2248 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
2249
2250 rb = _mesa_new_renderbuffer(ctx, 0);
2251 if (!rb) {
2252 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
2253 return GL_FALSE;
2254 }
2255
2256 if (depthBits <= 16) {
2257 rb->Format = MESA_FORMAT_Z16;
2258 rb->InternalFormat = GL_DEPTH_COMPONENT16;
2259 }
2260 else if (depthBits <= 24) {
2261 rb->Format = MESA_FORMAT_X8_Z24;
2262 rb->InternalFormat = GL_DEPTH_COMPONENT24;
2263 }
2264 else {
2265 rb->Format = MESA_FORMAT_Z32;
2266 rb->InternalFormat = GL_DEPTH_COMPONENT32;
2267 }
2268
2269 rb->AllocStorage = _mesa_soft_renderbuffer_storage;
2270 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
2271
2272 return GL_TRUE;
2273 }
2274
2275
2276 /**
2277 * Add a software-based stencil renderbuffer to the given framebuffer.
2278 * This is a helper routine for device drivers when creating a
2279 * window system framebuffer (not a user-created render/framebuffer).
2280 * Once this function is called, you can basically forget about this
2281 * renderbuffer; core Mesa will handle all the buffer management and
2282 * rendering!
2283 */
2284 GLboolean
2285 _mesa_add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
2286 GLuint stencilBits)
2287 {
2288 struct gl_renderbuffer *rb;
2289
2290 if (stencilBits > 16) {
2291 _mesa_problem(ctx,
2292 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
2293 return GL_FALSE;
2294 }
2295
2296 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
2297
2298 rb = _mesa_new_renderbuffer(ctx, 0);
2299 if (!rb) {
2300 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
2301 return GL_FALSE;
2302 }
2303
2304 assert(stencilBits <= 8);
2305 rb->Format = MESA_FORMAT_S8;
2306 rb->InternalFormat = GL_STENCIL_INDEX8;
2307
2308 rb->AllocStorage = _mesa_soft_renderbuffer_storage;
2309 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
2310
2311 return GL_TRUE;
2312 }
2313
2314
2315 /**
2316 * Add a software-based accumulation renderbuffer to the given framebuffer.
2317 * This is a helper routine for device drivers when creating a
2318 * window system framebuffer (not a user-created render/framebuffer).
2319 * Once this function is called, you can basically forget about this
2320 * renderbuffer; core Mesa will handle all the buffer management and
2321 * rendering!
2322 */
2323 GLboolean
2324 _mesa_add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
2325 GLuint redBits, GLuint greenBits,
2326 GLuint blueBits, GLuint alphaBits)
2327 {
2328 struct gl_renderbuffer *rb;
2329
2330 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
2331 _mesa_problem(ctx,
2332 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
2333 return GL_FALSE;
2334 }
2335
2336 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
2337
2338 rb = _mesa_new_renderbuffer(ctx, 0);
2339 if (!rb) {
2340 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
2341 return GL_FALSE;
2342 }
2343
2344 rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
2345 rb->InternalFormat = GL_RGBA16_SNORM;
2346 rb->AllocStorage = _mesa_soft_renderbuffer_storage;
2347 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
2348
2349 return GL_TRUE;
2350 }
2351
2352
2353
2354 /**
2355 * Add a software-based aux renderbuffer to the given framebuffer.
2356 * This is a helper routine for device drivers when creating a
2357 * window system framebuffer (not a user-created render/framebuffer).
2358 * Once this function is called, you can basically forget about this
2359 * renderbuffer; core Mesa will handle all the buffer management and
2360 * rendering!
2361 *
2362 * NOTE: color-index aux buffers not supported.
2363 */
2364 GLboolean
2365 _mesa_add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
2366 GLuint colorBits, GLuint numBuffers)
2367 {
2368 GLuint i;
2369
2370 if (colorBits > 16) {
2371 _mesa_problem(ctx,
2372 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
2373 return GL_FALSE;
2374 }
2375
2376 assert(numBuffers <= MAX_AUX_BUFFERS);
2377
2378 for (i = 0; i < numBuffers; i++) {
2379 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
2380
2381 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
2382
2383 if (!rb) {
2384 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer");
2385 return GL_FALSE;
2386 }
2387
2388 assert (colorBits <= 8);
2389 rb->Format = MESA_FORMAT_RGBA8888;
2390 rb->InternalFormat = GL_RGBA;
2391
2392 rb->AllocStorage = _mesa_soft_renderbuffer_storage;
2393 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
2394 }
2395 return GL_TRUE;
2396 }
2397
2398
2399 /**
2400 * Create/attach software-based renderbuffers to the given framebuffer.
2401 * This is a helper routine for device drivers. Drivers can just as well
2402 * call the individual _mesa_add_*_renderbuffer() routines directly.
2403 */
2404 void
2405 _mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
2406 GLboolean color,
2407 GLboolean depth,
2408 GLboolean stencil,
2409 GLboolean accum,
2410 GLboolean alpha,
2411 GLboolean aux)
2412 {
2413 GLboolean frontLeft = GL_TRUE;
2414 GLboolean backLeft = fb->Visual.doubleBufferMode;
2415 GLboolean frontRight = fb->Visual.stereoMode;
2416 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
2417
2418 if (color) {
2419 assert(fb->Visual.redBits == fb->Visual.greenBits);
2420 assert(fb->Visual.redBits == fb->Visual.blueBits);
2421 _mesa_add_color_renderbuffers(NULL, fb,
2422 fb->Visual.redBits,
2423 fb->Visual.alphaBits,
2424 frontLeft, backLeft,
2425 frontRight, backRight);
2426 }
2427
2428 if (depth) {
2429 assert(fb->Visual.depthBits > 0);
2430 _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
2431 }
2432
2433 if (stencil) {
2434 assert(fb->Visual.stencilBits > 0);
2435 _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
2436 }
2437
2438 if (accum) {
2439 assert(fb->Visual.accumRedBits > 0);
2440 assert(fb->Visual.accumGreenBits > 0);
2441 assert(fb->Visual.accumBlueBits > 0);
2442 _mesa_add_accum_renderbuffer(NULL, fb,
2443 fb->Visual.accumRedBits,
2444 fb->Visual.accumGreenBits,
2445 fb->Visual.accumBlueBits,
2446 fb->Visual.accumAlphaBits);
2447 }
2448
2449 if (aux) {
2450 assert(fb->Visual.numAuxBuffers > 0);
2451 _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
2452 fb->Visual.numAuxBuffers);
2453 }
2454
2455 if (alpha) {
2456 assert(fb->Visual.alphaBits > 0);
2457 _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits,
2458 frontLeft, backLeft,
2459 frontRight, backRight);
2460 }
2461
2462 #if 0
2463 if (multisample) {
2464 /* maybe someday */
2465 }
2466 #endif
2467 }
2468
2469
2470 /**
2471 * Attach a renderbuffer to a framebuffer.
2472 * \param bufferName one of the BUFFER_x tokens
2473 */
2474 void
2475 _mesa_add_renderbuffer(struct gl_framebuffer *fb,
2476 gl_buffer_index bufferName, struct gl_renderbuffer *rb)
2477 {
2478 assert(fb);
2479 assert(rb);
2480 assert(bufferName < BUFFER_COUNT);
2481
2482 /* There should be no previous renderbuffer on this attachment point,
2483 * with the exception of depth/stencil since the same renderbuffer may
2484 * be used for both.
2485 */
2486 assert(bufferName == BUFFER_DEPTH ||
2487 bufferName == BUFFER_STENCIL ||
2488 fb->Attachment[bufferName].Renderbuffer == NULL);
2489
2490 /* winsys vs. user-created buffer cross check */
2491 if (fb->Name) {
2492 assert(rb->Name);
2493 }
2494 else {
2495 assert(!rb->Name);
2496 }
2497
2498 fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
2499 fb->Attachment[bufferName].Complete = GL_TRUE;
2500 _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
2501 }
2502
2503
2504 /**
2505 * Remove the named renderbuffer from the given framebuffer.
2506 * \param bufferName one of the BUFFER_x tokens
2507 */
2508 void
2509 _mesa_remove_renderbuffer(struct gl_framebuffer *fb,
2510 gl_buffer_index bufferName)
2511 {
2512 struct gl_renderbuffer *rb;
2513
2514 assert(bufferName < BUFFER_COUNT);
2515
2516 rb = fb->Attachment[bufferName].Renderbuffer;
2517 if (!rb)
2518 return;
2519
2520 _mesa_reference_renderbuffer(&rb, NULL);
2521
2522 fb->Attachment[bufferName].Renderbuffer = NULL;
2523 }
2524
2525
2526 /**
2527 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
2528 * dereference that buffer first. The new renderbuffer's refcount will
2529 * be incremented. The old renderbuffer's refcount will be decremented.
2530 */
2531 void
2532 _mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
2533 struct gl_renderbuffer *rb)
2534 {
2535 assert(ptr);
2536 if (*ptr == rb) {
2537 /* no change */
2538 return;
2539 }
2540
2541 if (*ptr) {
2542 /* Unreference the old renderbuffer */
2543 GLboolean deleteFlag = GL_FALSE;
2544 struct gl_renderbuffer *oldRb = *ptr;
2545
2546 _glthread_LOCK_MUTEX(oldRb->Mutex);
2547 ASSERT(oldRb->RefCount > 0);
2548 oldRb->RefCount--;
2549 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
2550 deleteFlag = (oldRb->RefCount == 0);
2551 _glthread_UNLOCK_MUTEX(oldRb->Mutex);
2552
2553 if (deleteFlag) {
2554 oldRb->Delete(oldRb);
2555 }
2556
2557 *ptr = NULL;
2558 }
2559 assert(!*ptr);
2560
2561 if (rb) {
2562 /* reference new renderbuffer */
2563 _glthread_LOCK_MUTEX(rb->Mutex);
2564 rb->RefCount++;
2565 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
2566 _glthread_UNLOCK_MUTEX(rb->Mutex);
2567 *ptr = rb;
2568 }
2569 }