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