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