renderbuffer.c revision 7117f1b4
17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
37117f1b4Smrg * Version:  6.5
47117f1b4Smrg *
57117f1b4Smrg * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
67117f1b4Smrg *
77117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
87117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
97117f1b4Smrg * to deal in the Software without restriction, including without limitation
107117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
117117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
127117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
137117f1b4Smrg *
147117f1b4Smrg * The above copyright notice and this permission notice shall be included
157117f1b4Smrg * in all copies or substantial portions of the Software.
167117f1b4Smrg *
177117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
187117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
197117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
207117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
217117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
227117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
237117f1b4Smrg */
247117f1b4Smrg
257117f1b4Smrg
267117f1b4Smrg/**
277117f1b4Smrg * Functions for allocating/managing renderbuffers.
287117f1b4Smrg * Also, routines for reading/writing software-based renderbuffer data as
297117f1b4Smrg * ubytes, ushorts, uints, etc.
307117f1b4Smrg *
317117f1b4Smrg * The 'alpha8' renderbuffer is interesting.  It's used to add a software-based
327117f1b4Smrg * alpha channel to RGB renderbuffers.  This is done by wrapping the RGB
337117f1b4Smrg * renderbuffer with the alpha renderbuffer.  We can do this because of the
347117f1b4Smrg * OO-nature of renderbuffers.
357117f1b4Smrg *
367117f1b4Smrg * Down the road we'll use this for run-time support of 8, 16 and 32-bit
377117f1b4Smrg * color channels.  For example, Mesa may use 32-bit/float color channels
387117f1b4Smrg * internally (swrast) and use wrapper renderbuffers to convert 32-bit
397117f1b4Smrg * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
407117f1b4Smrg */
417117f1b4Smrg
427117f1b4Smrg
437117f1b4Smrg#include "glheader.h"
447117f1b4Smrg#include "imports.h"
457117f1b4Smrg#include "context.h"
467117f1b4Smrg#include "mtypes.h"
477117f1b4Smrg#include "fbobject.h"
487117f1b4Smrg#include "renderbuffer.h"
497117f1b4Smrg
507117f1b4Smrg#include "rbadaptors.h"
517117f1b4Smrg
527117f1b4Smrg
537117f1b4Smrg/* 32-bit color index format.  Not a public format. */
547117f1b4Smrg#define COLOR_INDEX32 0x424243
557117f1b4Smrg
567117f1b4Smrg
577117f1b4Smrg/*
587117f1b4Smrg * Routines for get/put values in common buffer formats follow.
597117f1b4Smrg * Someday add support for arbitrary row stride to make them more
607117f1b4Smrg * flexible.
617117f1b4Smrg */
627117f1b4Smrg
637117f1b4Smrg/**********************************************************************
647117f1b4Smrg * Functions for buffers of 1 X GLubyte values.
657117f1b4Smrg * Typically stencil.
667117f1b4Smrg */
677117f1b4Smrg
687117f1b4Smrgstatic void *
697117f1b4Smrgget_pointer_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb,
707117f1b4Smrg                  GLint x, GLint y)
717117f1b4Smrg{
727117f1b4Smrg   if (!rb->Data)
737117f1b4Smrg      return NULL;
747117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
757117f1b4Smrg   /* Can't assert _ActualFormat since these funcs may be used for serveral
767117f1b4Smrg    * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
777117f1b4Smrg    */
787117f1b4Smrg   return (GLubyte *) rb->Data + y * rb->Width + x;
797117f1b4Smrg}
807117f1b4Smrg
817117f1b4Smrg
827117f1b4Smrgstatic void
837117f1b4Smrgget_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
847117f1b4Smrg              GLint x, GLint y, void *values)
857117f1b4Smrg{
867117f1b4Smrg   const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x;
877117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
887117f1b4Smrg   _mesa_memcpy(values, src, count * sizeof(GLubyte));
897117f1b4Smrg}
907117f1b4Smrg
917117f1b4Smrg
927117f1b4Smrgstatic void
937117f1b4Smrgget_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
947117f1b4Smrg                 const GLint x[], const GLint y[], void *values)
957117f1b4Smrg{
967117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
977117f1b4Smrg   GLuint i;
987117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
997117f1b4Smrg   for (i = 0; i < count; i++) {
1007117f1b4Smrg      const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
1017117f1b4Smrg      dst[i] = *src;
1027117f1b4Smrg   }
1037117f1b4Smrg}
1047117f1b4Smrg
1057117f1b4Smrg
1067117f1b4Smrgstatic void
1077117f1b4Smrgput_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1087117f1b4Smrg              GLint x, GLint y, const void *values, const GLubyte *mask)
1097117f1b4Smrg{
1107117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
1117117f1b4Smrg   GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
1127117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
1137117f1b4Smrg   if (mask) {
1147117f1b4Smrg      GLuint i;
1157117f1b4Smrg      for (i = 0; i < count; i++) {
1167117f1b4Smrg         if (mask[i]) {
1177117f1b4Smrg            dst[i] = src[i];
1187117f1b4Smrg         }
1197117f1b4Smrg      }
1207117f1b4Smrg   }
1217117f1b4Smrg   else {
1227117f1b4Smrg      _mesa_memcpy(dst, values, count * sizeof(GLubyte));
1237117f1b4Smrg   }
1247117f1b4Smrg}
1257117f1b4Smrg
1267117f1b4Smrg
1277117f1b4Smrgstatic void
1287117f1b4Smrgput_mono_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1297117f1b4Smrg                   GLint x, GLint y, const void *value, const GLubyte *mask)
1307117f1b4Smrg{
1317117f1b4Smrg   const GLubyte val = *((const GLubyte *) value);
1327117f1b4Smrg   GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
1337117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
1347117f1b4Smrg   if (mask) {
1357117f1b4Smrg      GLuint i;
1367117f1b4Smrg      for (i = 0; i < count; i++) {
1377117f1b4Smrg         if (mask[i]) {
1387117f1b4Smrg            dst[i] = val;
1397117f1b4Smrg         }
1407117f1b4Smrg      }
1417117f1b4Smrg   }
1427117f1b4Smrg   else {
1437117f1b4Smrg      GLuint i;
1447117f1b4Smrg      for (i = 0; i < count; i++) {
1457117f1b4Smrg         dst[i] = val;
1467117f1b4Smrg      }
1477117f1b4Smrg   }
1487117f1b4Smrg}
1497117f1b4Smrg
1507117f1b4Smrg
1517117f1b4Smrgstatic void
1527117f1b4Smrgput_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1537117f1b4Smrg                 const GLint x[], const GLint y[],
1547117f1b4Smrg                 const void *values, const GLubyte *mask)
1557117f1b4Smrg{
1567117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
1577117f1b4Smrg   GLuint i;
1587117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
1597117f1b4Smrg   for (i = 0; i < count; i++) {
1607117f1b4Smrg      if (!mask || mask[i]) {
1617117f1b4Smrg         GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
1627117f1b4Smrg         *dst = src[i];
1637117f1b4Smrg      }
1647117f1b4Smrg   }
1657117f1b4Smrg}
1667117f1b4Smrg
1677117f1b4Smrg
1687117f1b4Smrgstatic void
1697117f1b4Smrgput_mono_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1707117f1b4Smrg                      const GLint x[], const GLint y[],
1717117f1b4Smrg                      const void *value, const GLubyte *mask)
1727117f1b4Smrg{
1737117f1b4Smrg   const GLubyte val = *((const GLubyte *) value);
1747117f1b4Smrg   GLuint i;
1757117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
1767117f1b4Smrg   for (i = 0; i < count; i++) {
1777117f1b4Smrg      if (!mask || mask[i]) {
1787117f1b4Smrg         GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
1797117f1b4Smrg         *dst = val;
1807117f1b4Smrg      }
1817117f1b4Smrg   }
1827117f1b4Smrg}
1837117f1b4Smrg
1847117f1b4Smrg
1857117f1b4Smrg/**********************************************************************
1867117f1b4Smrg * Functions for buffers of 1 X GLushort values.
1877117f1b4Smrg * Typically depth/Z.
1887117f1b4Smrg */
1897117f1b4Smrg
1907117f1b4Smrgstatic void *
1917117f1b4Smrgget_pointer_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
1927117f1b4Smrg                   GLint x, GLint y)
1937117f1b4Smrg{
1947117f1b4Smrg   if (!rb->Data)
1957117f1b4Smrg      return NULL;
1967117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
1977117f1b4Smrg   ASSERT(rb->Width > 0);
1987117f1b4Smrg   return (GLushort *) rb->Data + y * rb->Width + x;
1997117f1b4Smrg}
2007117f1b4Smrg
2017117f1b4Smrg
2027117f1b4Smrgstatic void
2037117f1b4Smrgget_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
2047117f1b4Smrg               GLint x, GLint y, void *values)
2057117f1b4Smrg{
2067117f1b4Smrg   const void *src = rb->GetPointer(ctx, rb, x, y);
2077117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
2087117f1b4Smrg   _mesa_memcpy(values, src, count * sizeof(GLushort));
2097117f1b4Smrg}
2107117f1b4Smrg
2117117f1b4Smrg
2127117f1b4Smrgstatic void
2137117f1b4Smrgget_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
2147117f1b4Smrg                  const GLint x[], const GLint y[], void *values)
2157117f1b4Smrg{
2167117f1b4Smrg   GLushort *dst = (GLushort *) values;
2177117f1b4Smrg   GLuint i;
2187117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
2197117f1b4Smrg   for (i = 0; i < count; i++) {
2207117f1b4Smrg      const GLushort *src = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
2217117f1b4Smrg      dst[i] = *src;
2227117f1b4Smrg   }
2237117f1b4Smrg}
2247117f1b4Smrg
2257117f1b4Smrg
2267117f1b4Smrgstatic void
2277117f1b4Smrgput_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
2287117f1b4Smrg               GLint x, GLint y, const void *values, const GLubyte *mask)
2297117f1b4Smrg{
2307117f1b4Smrg   const GLushort *src = (const GLushort *) values;
2317117f1b4Smrg   GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
2327117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
2337117f1b4Smrg   if (mask) {
2347117f1b4Smrg      GLuint i;
2357117f1b4Smrg      for (i = 0; i < count; i++) {
2367117f1b4Smrg         if (mask[i]) {
2377117f1b4Smrg            dst[i] = src[i];
2387117f1b4Smrg         }
2397117f1b4Smrg      }
2407117f1b4Smrg   }
2417117f1b4Smrg   else {
2427117f1b4Smrg      _mesa_memcpy(dst, src, count * sizeof(GLushort));
2437117f1b4Smrg   }
2447117f1b4Smrg}
2457117f1b4Smrg
2467117f1b4Smrg
2477117f1b4Smrgstatic void
2487117f1b4Smrgput_mono_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
2497117f1b4Smrg                    GLint x, GLint y, const void *value, const GLubyte *mask)
2507117f1b4Smrg{
2517117f1b4Smrg   const GLushort val = *((const GLushort *) value);
2527117f1b4Smrg   GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
2537117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
2547117f1b4Smrg   if (mask) {
2557117f1b4Smrg      GLuint i;
2567117f1b4Smrg      for (i = 0; i < count; i++) {
2577117f1b4Smrg         if (mask[i]) {
2587117f1b4Smrg            dst[i] = val;
2597117f1b4Smrg         }
2607117f1b4Smrg      }
2617117f1b4Smrg   }
2627117f1b4Smrg   else {
2637117f1b4Smrg      GLuint i;
2647117f1b4Smrg      for (i = 0; i < count; i++) {
2657117f1b4Smrg         dst[i] = val;
2667117f1b4Smrg      }
2677117f1b4Smrg   }
2687117f1b4Smrg}
2697117f1b4Smrg
2707117f1b4Smrg
2717117f1b4Smrgstatic void
2727117f1b4Smrgput_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
2737117f1b4Smrg                  const GLint x[], const GLint y[], const void *values,
2747117f1b4Smrg                  const GLubyte *mask)
2757117f1b4Smrg{
2767117f1b4Smrg   const GLushort *src = (const GLushort *) values;
2777117f1b4Smrg   GLuint i;
2787117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
2797117f1b4Smrg   for (i = 0; i < count; i++) {
2807117f1b4Smrg      if (!mask || mask[i]) {
2817117f1b4Smrg         GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
2827117f1b4Smrg         *dst = src[i];
2837117f1b4Smrg      }
2847117f1b4Smrg   }
2857117f1b4Smrg}
2867117f1b4Smrg
2877117f1b4Smrg
2887117f1b4Smrgstatic void
2897117f1b4Smrgput_mono_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
2907117f1b4Smrg                       GLuint count, const GLint x[], const GLint y[],
2917117f1b4Smrg                       const void *value, const GLubyte *mask)
2927117f1b4Smrg{
2937117f1b4Smrg   const GLushort val = *((const GLushort *) value);
2947117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
2957117f1b4Smrg   if (mask) {
2967117f1b4Smrg      GLuint i;
2977117f1b4Smrg      for (i = 0; i < count; i++) {
2987117f1b4Smrg         if (mask[i]) {
2997117f1b4Smrg            GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
3007117f1b4Smrg            *dst = val;
3017117f1b4Smrg         }
3027117f1b4Smrg      }
3037117f1b4Smrg   }
3047117f1b4Smrg   else {
3057117f1b4Smrg      GLuint i;
3067117f1b4Smrg      for (i = 0; i < count; i++) {
3077117f1b4Smrg         GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
3087117f1b4Smrg         *dst = val;
3097117f1b4Smrg      }
3107117f1b4Smrg   }
3117117f1b4Smrg}
3127117f1b4Smrg
3137117f1b4Smrg
3147117f1b4Smrg/**********************************************************************
3157117f1b4Smrg * Functions for buffers of 1 X GLuint values.
3167117f1b4Smrg * Typically depth/Z or color index.
3177117f1b4Smrg */
3187117f1b4Smrg
3197117f1b4Smrgstatic void *
3207117f1b4Smrgget_pointer_uint(GLcontext *ctx, struct gl_renderbuffer *rb,
3217117f1b4Smrg                 GLint x, GLint y)
3227117f1b4Smrg{
3237117f1b4Smrg   if (!rb->Data)
3247117f1b4Smrg      return NULL;
3257117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
3267117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
3277117f1b4Smrg   return (GLuint *) rb->Data + y * rb->Width + x;
3287117f1b4Smrg}
3297117f1b4Smrg
3307117f1b4Smrg
3317117f1b4Smrgstatic void
3327117f1b4Smrgget_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
3337117f1b4Smrg             GLint x, GLint y, void *values)
3347117f1b4Smrg{
3357117f1b4Smrg   const void *src = rb->GetPointer(ctx, rb, x, y);
3367117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
3377117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
3387117f1b4Smrg   _mesa_memcpy(values, src, count * sizeof(GLuint));
3397117f1b4Smrg}
3407117f1b4Smrg
3417117f1b4Smrg
3427117f1b4Smrgstatic void
3437117f1b4Smrgget_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
3447117f1b4Smrg                const GLint x[], const GLint y[], void *values)
3457117f1b4Smrg{
3467117f1b4Smrg   GLuint *dst = (GLuint *) values;
3477117f1b4Smrg   GLuint i;
3487117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
3497117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
3507117f1b4Smrg   for (i = 0; i < count; i++) {
3517117f1b4Smrg      const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
3527117f1b4Smrg      dst[i] = *src;
3537117f1b4Smrg   }
3547117f1b4Smrg}
3557117f1b4Smrg
3567117f1b4Smrg
3577117f1b4Smrgstatic void
3587117f1b4Smrgput_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
3597117f1b4Smrg             GLint x, GLint y, const void *values, const GLubyte *mask)
3607117f1b4Smrg{
3617117f1b4Smrg   const GLuint *src = (const GLuint *) values;
3627117f1b4Smrg   GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
3637117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
3647117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
3657117f1b4Smrg   if (mask) {
3667117f1b4Smrg      GLuint i;
3677117f1b4Smrg      for (i = 0; i < count; i++) {
3687117f1b4Smrg         if (mask[i]) {
3697117f1b4Smrg            dst[i] = src[i];
3707117f1b4Smrg         }
3717117f1b4Smrg      }
3727117f1b4Smrg   }
3737117f1b4Smrg   else {
3747117f1b4Smrg      _mesa_memcpy(dst, src, count * sizeof(GLuint));
3757117f1b4Smrg   }
3767117f1b4Smrg}
3777117f1b4Smrg
3787117f1b4Smrg
3797117f1b4Smrgstatic void
3807117f1b4Smrgput_mono_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
3817117f1b4Smrg                  GLint x, GLint y, const void *value, const GLubyte *mask)
3827117f1b4Smrg{
3837117f1b4Smrg   const GLuint val = *((const GLuint *) value);
3847117f1b4Smrg   GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
3857117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
3867117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
3877117f1b4Smrg   if (mask) {
3887117f1b4Smrg      GLuint i;
3897117f1b4Smrg      for (i = 0; i < count; i++) {
3907117f1b4Smrg         if (mask[i]) {
3917117f1b4Smrg            dst[i] = val;
3927117f1b4Smrg         }
3937117f1b4Smrg      }
3947117f1b4Smrg   }
3957117f1b4Smrg   else {
3967117f1b4Smrg      GLuint i;
3977117f1b4Smrg      for (i = 0; i < count; i++) {
3987117f1b4Smrg         dst[i] = val;
3997117f1b4Smrg      }
4007117f1b4Smrg   }
4017117f1b4Smrg}
4027117f1b4Smrg
4037117f1b4Smrg
4047117f1b4Smrgstatic void
4057117f1b4Smrgput_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
4067117f1b4Smrg                const GLint x[], const GLint y[], const void *values,
4077117f1b4Smrg                const GLubyte *mask)
4087117f1b4Smrg{
4097117f1b4Smrg   const GLuint *src = (const GLuint *) values;
4107117f1b4Smrg   GLuint i;
4117117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
4127117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
4137117f1b4Smrg   for (i = 0; i < count; i++) {
4147117f1b4Smrg      if (!mask || mask[i]) {
4157117f1b4Smrg         GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
4167117f1b4Smrg         *dst = src[i];
4177117f1b4Smrg      }
4187117f1b4Smrg   }
4197117f1b4Smrg}
4207117f1b4Smrg
4217117f1b4Smrg
4227117f1b4Smrgstatic void
4237117f1b4Smrgput_mono_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
4247117f1b4Smrg                     const GLint x[], const GLint y[], const void *value,
4257117f1b4Smrg                     const GLubyte *mask)
4267117f1b4Smrg{
4277117f1b4Smrg   const GLuint val = *((const GLuint *) value);
4287117f1b4Smrg   GLuint i;
4297117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
4307117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
4317117f1b4Smrg   for (i = 0; i < count; i++) {
4327117f1b4Smrg      if (!mask || mask[i]) {
4337117f1b4Smrg         GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
4347117f1b4Smrg         *dst = val;
4357117f1b4Smrg      }
4367117f1b4Smrg   }
4377117f1b4Smrg}
4387117f1b4Smrg
4397117f1b4Smrg
4407117f1b4Smrg/**********************************************************************
4417117f1b4Smrg * Functions for buffers of 3 X GLubyte (or GLbyte) values.
4427117f1b4Smrg * Typically color buffers.
4437117f1b4Smrg * NOTE: the incoming and outgoing colors are RGBA!  We ignore incoming
4447117f1b4Smrg * alpha values and return 255 for outgoing alpha values.
4457117f1b4Smrg */
4467117f1b4Smrg
4477117f1b4Smrgstatic void *
4487117f1b4Smrgget_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
4497117f1b4Smrg                   GLint x, GLint y)
4507117f1b4Smrg{
4517117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGB8);
4527117f1b4Smrg   /* No direct access since this buffer is RGB but caller will be
4537117f1b4Smrg    * treating it as if it were RGBA.
4547117f1b4Smrg    */
4557117f1b4Smrg   return NULL;
4567117f1b4Smrg}
4577117f1b4Smrg
4587117f1b4Smrg
4597117f1b4Smrgstatic void
4607117f1b4Smrgget_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
4617117f1b4Smrg               GLint x, GLint y, void *values)
4627117f1b4Smrg{
4637117f1b4Smrg   const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x);
4647117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
4657117f1b4Smrg   GLuint i;
4667117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGB8);
4677117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
4687117f1b4Smrg   for (i = 0; i < count; i++) {
4697117f1b4Smrg      dst[i * 4 + 0] = src[i * 3 + 0];
4707117f1b4Smrg      dst[i * 4 + 1] = src[i * 3 + 1];
4717117f1b4Smrg      dst[i * 4 + 2] = src[i * 3 + 2];
4727117f1b4Smrg      dst[i * 4 + 3] = 255;
4737117f1b4Smrg   }
4747117f1b4Smrg}
4757117f1b4Smrg
4767117f1b4Smrg
4777117f1b4Smrgstatic void
4787117f1b4Smrgget_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
4797117f1b4Smrg                  const GLint x[], const GLint y[], void *values)
4807117f1b4Smrg{
4817117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
4827117f1b4Smrg   GLuint i;
4837117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGB8);
4847117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
4857117f1b4Smrg   for (i = 0; i < count; i++) {
4867117f1b4Smrg      const GLubyte *src
4877117f1b4Smrg         = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
4887117f1b4Smrg      dst[i * 4 + 0] = src[0];
4897117f1b4Smrg      dst[i * 4 + 1] = src[1];
4907117f1b4Smrg      dst[i * 4 + 2] = src[2];
4917117f1b4Smrg      dst[i * 4 + 3] = 255;
4927117f1b4Smrg   }
4937117f1b4Smrg}
4947117f1b4Smrg
4957117f1b4Smrg
4967117f1b4Smrgstatic void
4977117f1b4Smrgput_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
4987117f1b4Smrg               GLint x, GLint y, const void *values, const GLubyte *mask)
4997117f1b4Smrg{
5007117f1b4Smrg   /* note: incoming values are RGB+A! */
5017117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
5027117f1b4Smrg   GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
5037117f1b4Smrg   GLuint i;
5047117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGB8);
5057117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
5067117f1b4Smrg   for (i = 0; i < count; i++) {
5077117f1b4Smrg      if (!mask || mask[i]) {
5087117f1b4Smrg         dst[i * 3 + 0] = src[i * 4 + 0];
5097117f1b4Smrg         dst[i * 3 + 1] = src[i * 4 + 1];
5107117f1b4Smrg         dst[i * 3 + 2] = src[i * 4 + 2];
5117117f1b4Smrg      }
5127117f1b4Smrg   }
5137117f1b4Smrg}
5147117f1b4Smrg
5157117f1b4Smrg
5167117f1b4Smrgstatic void
5177117f1b4Smrgput_row_rgb_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
5187117f1b4Smrg                   GLint x, GLint y, const void *values, const GLubyte *mask)
5197117f1b4Smrg{
5207117f1b4Smrg   /* note: incoming values are RGB+A! */
5217117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
5227117f1b4Smrg   GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
5237117f1b4Smrg   GLuint i;
5247117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGB8);
5257117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
5267117f1b4Smrg   for (i = 0; i < count; i++) {
5277117f1b4Smrg      if (!mask || mask[i]) {
5287117f1b4Smrg         dst[i * 3 + 0] = src[i * 3 + 0];
5297117f1b4Smrg         dst[i * 3 + 1] = src[i * 3 + 1];
5307117f1b4Smrg         dst[i * 3 + 2] = src[i * 3 + 2];
5317117f1b4Smrg      }
5327117f1b4Smrg   }
5337117f1b4Smrg}
5347117f1b4Smrg
5357117f1b4Smrg
5367117f1b4Smrgstatic void
5377117f1b4Smrgput_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
5387117f1b4Smrg                    GLint x, GLint y, const void *value, const GLubyte *mask)
5397117f1b4Smrg{
5407117f1b4Smrg   /* note: incoming value is RGB+A! */
5417117f1b4Smrg   const GLubyte val0 = ((const GLubyte *) value)[0];
5427117f1b4Smrg   const GLubyte val1 = ((const GLubyte *) value)[1];
5437117f1b4Smrg   const GLubyte val2 = ((const GLubyte *) value)[2];
5447117f1b4Smrg   GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
5457117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGB8);
5467117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
5477117f1b4Smrg   if (!mask && val0 == val1 && val1 == val2) {
5487117f1b4Smrg      /* optimized case */
5497117f1b4Smrg      _mesa_memset(dst, val0, 3 * count);
5507117f1b4Smrg   }
5517117f1b4Smrg   else {
5527117f1b4Smrg      GLuint i;
5537117f1b4Smrg      for (i = 0; i < count; i++) {
5547117f1b4Smrg         if (!mask || mask[i]) {
5557117f1b4Smrg            dst[i * 3 + 0] = val0;
5567117f1b4Smrg            dst[i * 3 + 1] = val1;
5577117f1b4Smrg            dst[i * 3 + 2] = val2;
5587117f1b4Smrg         }
5597117f1b4Smrg      }
5607117f1b4Smrg   }
5617117f1b4Smrg}
5627117f1b4Smrg
5637117f1b4Smrg
5647117f1b4Smrgstatic void
5657117f1b4Smrgput_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
5667117f1b4Smrg                  const GLint x[], const GLint y[], const void *values,
5677117f1b4Smrg                  const GLubyte *mask)
5687117f1b4Smrg{
5697117f1b4Smrg   /* note: incoming values are RGB+A! */
5707117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
5717117f1b4Smrg   GLuint i;
5727117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGB8);
5737117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
5747117f1b4Smrg   for (i = 0; i < count; i++) {
5757117f1b4Smrg      if (!mask || mask[i]) {
5767117f1b4Smrg         GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
5777117f1b4Smrg         dst[0] = src[i * 4 + 0];
5787117f1b4Smrg         dst[1] = src[i * 4 + 1];
5797117f1b4Smrg         dst[2] = src[i * 4 + 2];
5807117f1b4Smrg      }
5817117f1b4Smrg   }
5827117f1b4Smrg}
5837117f1b4Smrg
5847117f1b4Smrg
5857117f1b4Smrgstatic void
5867117f1b4Smrgput_mono_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
5877117f1b4Smrg                       GLuint count, const GLint x[], const GLint y[],
5887117f1b4Smrg                       const void *value, const GLubyte *mask)
5897117f1b4Smrg{
5907117f1b4Smrg   /* note: incoming value is RGB+A! */
5917117f1b4Smrg   const GLubyte val0 = ((const GLubyte *) value)[0];
5927117f1b4Smrg   const GLubyte val1 = ((const GLubyte *) value)[1];
5937117f1b4Smrg   const GLubyte val2 = ((const GLubyte *) value)[2];
5947117f1b4Smrg   GLuint i;
5957117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGB8);
5967117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
5977117f1b4Smrg   for (i = 0; i < count; i++) {
5987117f1b4Smrg      if (!mask || mask[i]) {
5997117f1b4Smrg         GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
6007117f1b4Smrg         dst[0] = val0;
6017117f1b4Smrg         dst[1] = val1;
6027117f1b4Smrg         dst[2] = val2;
6037117f1b4Smrg      }
6047117f1b4Smrg   }
6057117f1b4Smrg}
6067117f1b4Smrg
6077117f1b4Smrg
6087117f1b4Smrg/**********************************************************************
6097117f1b4Smrg * Functions for buffers of 4 X GLubyte (or GLbyte) values.
6107117f1b4Smrg * Typically color buffers.
6117117f1b4Smrg */
6127117f1b4Smrg
6137117f1b4Smrgstatic void *
6147117f1b4Smrgget_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
6157117f1b4Smrg                   GLint x, GLint y)
6167117f1b4Smrg{
6177117f1b4Smrg   if (!rb->Data)
6187117f1b4Smrg      return NULL;
6197117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6207117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGBA8);
6217117f1b4Smrg   return (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
6227117f1b4Smrg}
6237117f1b4Smrg
6247117f1b4Smrg
6257117f1b4Smrgstatic void
6267117f1b4Smrgget_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
6277117f1b4Smrg               GLint x, GLint y, void *values)
6287117f1b4Smrg{
6297117f1b4Smrg   const GLubyte *src = (const GLubyte *) rb->Data + 4 * (y * rb->Width + x);
6307117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6317117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGBA8);
6327117f1b4Smrg   _mesa_memcpy(values, src, 4 * count * sizeof(GLubyte));
6337117f1b4Smrg}
6347117f1b4Smrg
6357117f1b4Smrg
6367117f1b4Smrgstatic void
6377117f1b4Smrgget_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
6387117f1b4Smrg                  const GLint x[], const GLint y[], void *values)
6397117f1b4Smrg{
6407117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
6417117f1b4Smrg   GLuint *dst = (GLuint *) values;
6427117f1b4Smrg   GLuint i;
6437117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6447117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGBA8);
6457117f1b4Smrg   for (i = 0; i < count; i++) {
6467117f1b4Smrg      const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
6477117f1b4Smrg      dst[i] = *src;
6487117f1b4Smrg   }
6497117f1b4Smrg}
6507117f1b4Smrg
6517117f1b4Smrg
6527117f1b4Smrgstatic void
6537117f1b4Smrgput_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
6547117f1b4Smrg               GLint x, GLint y, const void *values, const GLubyte *mask)
6557117f1b4Smrg{
6567117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
6577117f1b4Smrg   const GLuint *src = (const GLuint *) values;
6587117f1b4Smrg   GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
6597117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6607117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGBA8);
6617117f1b4Smrg   if (mask) {
6627117f1b4Smrg      GLuint i;
6637117f1b4Smrg      for (i = 0; i < count; i++) {
6647117f1b4Smrg         if (mask[i]) {
6657117f1b4Smrg            dst[i] = src[i];
6667117f1b4Smrg         }
6677117f1b4Smrg      }
6687117f1b4Smrg   }
6697117f1b4Smrg   else {
6707117f1b4Smrg      _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte));
6717117f1b4Smrg   }
6727117f1b4Smrg}
6737117f1b4Smrg
6747117f1b4Smrg
6757117f1b4Smrgstatic void
6767117f1b4Smrgput_row_rgb_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
6777117f1b4Smrg                   GLint x, GLint y, const void *values, const GLubyte *mask)
6787117f1b4Smrg{
6797117f1b4Smrg   /* Store RGB values in RGBA buffer */
6807117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
6817117f1b4Smrg   GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
6827117f1b4Smrg   GLuint i;
6837117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6847117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGBA8);
6857117f1b4Smrg   for (i = 0; i < count; i++) {
6867117f1b4Smrg      if (!mask || mask[i]) {
6877117f1b4Smrg         dst[i * 4 + 0] = src[i * 3 + 0];
6887117f1b4Smrg         dst[i * 4 + 1] = src[i * 3 + 1];
6897117f1b4Smrg         dst[i * 4 + 2] = src[i * 3 + 2];
6907117f1b4Smrg         dst[i * 4 + 3] = 0xff;
6917117f1b4Smrg      }
6927117f1b4Smrg   }
6937117f1b4Smrg}
6947117f1b4Smrg
6957117f1b4Smrg
6967117f1b4Smrgstatic void
6977117f1b4Smrgput_mono_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
6987117f1b4Smrg                    GLint x, GLint y, const void *value, const GLubyte *mask)
6997117f1b4Smrg{
7007117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
7017117f1b4Smrg   const GLuint val = *((const GLuint *) value);
7027117f1b4Smrg   GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
7037117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
7047117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGBA8);
7057117f1b4Smrg   if (!mask && val == 0) {
7067117f1b4Smrg      /* common case */
7077117f1b4Smrg      _mesa_bzero(dst, count * 4 * sizeof(GLubyte));
7087117f1b4Smrg   }
7097117f1b4Smrg   else {
7107117f1b4Smrg      /* general case */
7117117f1b4Smrg      if (mask) {
7127117f1b4Smrg         GLuint i;
7137117f1b4Smrg         for (i = 0; i < count; i++) {
7147117f1b4Smrg            if (mask[i]) {
7157117f1b4Smrg               dst[i] = val;
7167117f1b4Smrg            }
7177117f1b4Smrg         }
7187117f1b4Smrg      }
7197117f1b4Smrg      else {
7207117f1b4Smrg         GLuint i;
7217117f1b4Smrg         for (i = 0; i < count; i++) {
7227117f1b4Smrg            dst[i] = val;
7237117f1b4Smrg         }
7247117f1b4Smrg      }
7257117f1b4Smrg   }
7267117f1b4Smrg}
7277117f1b4Smrg
7287117f1b4Smrg
7297117f1b4Smrgstatic void
7307117f1b4Smrgput_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
7317117f1b4Smrg                  const GLint x[], const GLint y[], const void *values,
7327117f1b4Smrg                  const GLubyte *mask)
7337117f1b4Smrg{
7347117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
7357117f1b4Smrg   const GLuint *src = (const GLuint *) values;
7367117f1b4Smrg   GLuint i;
7377117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
7387117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGBA8);
7397117f1b4Smrg   for (i = 0; i < count; i++) {
7407117f1b4Smrg      if (!mask || mask[i]) {
7417117f1b4Smrg         GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
7427117f1b4Smrg         *dst = src[i];
7437117f1b4Smrg      }
7447117f1b4Smrg   }
7457117f1b4Smrg}
7467117f1b4Smrg
7477117f1b4Smrg
7487117f1b4Smrgstatic void
7497117f1b4Smrgput_mono_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
7507117f1b4Smrg                       GLuint count, const GLint x[], const GLint y[],
7517117f1b4Smrg                       const void *value, const GLubyte *mask)
7527117f1b4Smrg{
7537117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
7547117f1b4Smrg   const GLuint val = *((const GLuint *) value);
7557117f1b4Smrg   GLuint i;
7567117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
7577117f1b4Smrg   ASSERT(rb->_ActualFormat == GL_RGBA8);
7587117f1b4Smrg   for (i = 0; i < count; i++) {
7597117f1b4Smrg      if (!mask || mask[i]) {
7607117f1b4Smrg         GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
7617117f1b4Smrg         *dst = val;
7627117f1b4Smrg      }
7637117f1b4Smrg   }
7647117f1b4Smrg}
7657117f1b4Smrg
7667117f1b4Smrg
7677117f1b4Smrg/**********************************************************************
7687117f1b4Smrg * Functions for buffers of 4 X GLushort (or GLshort) values.
7697117f1b4Smrg * Typically accum buffer.
7707117f1b4Smrg */
7717117f1b4Smrg
7727117f1b4Smrgstatic void *
7737117f1b4Smrgget_pointer_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
7747117f1b4Smrg                    GLint x, GLint y)
7757117f1b4Smrg{
7767117f1b4Smrg   if (!rb->Data)
7777117f1b4Smrg      return NULL;
7787117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
7797117f1b4Smrg   return (GLushort *) rb->Data + 4 * (y * rb->Width + x);
7807117f1b4Smrg}
7817117f1b4Smrg
7827117f1b4Smrg
7837117f1b4Smrgstatic void
7847117f1b4Smrgget_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
7857117f1b4Smrg                GLint x, GLint y, void *values)
7867117f1b4Smrg{
7877117f1b4Smrg   const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x);
7887117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
7897117f1b4Smrg   _mesa_memcpy(values, src, 4 * count * sizeof(GLshort));
7907117f1b4Smrg}
7917117f1b4Smrg
7927117f1b4Smrg
7937117f1b4Smrgstatic void
7947117f1b4Smrgget_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
7957117f1b4Smrg                   const GLint x[], const GLint y[], void *values)
7967117f1b4Smrg{
7977117f1b4Smrg   GLushort *dst = (GLushort *) values;
7987117f1b4Smrg   GLuint i;
7997117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
8007117f1b4Smrg   for (i = 0; i < count; i++) {
8017117f1b4Smrg      const GLushort *src
8027117f1b4Smrg         = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
8037117f1b4Smrg      dst[i] = *src;
8047117f1b4Smrg   }
8057117f1b4Smrg}
8067117f1b4Smrg
8077117f1b4Smrg
8087117f1b4Smrgstatic void
8097117f1b4Smrgput_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
8107117f1b4Smrg                GLint x, GLint y, const void *values, const GLubyte *mask)
8117117f1b4Smrg{
8127117f1b4Smrg   const GLushort *src = (const GLushort *) values;
8137117f1b4Smrg   GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
8147117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
8157117f1b4Smrg   if (mask) {
8167117f1b4Smrg      GLuint i;
8177117f1b4Smrg      for (i = 0; i < count; i++) {
8187117f1b4Smrg         if (mask[i]) {
8197117f1b4Smrg            dst[i * 4 + 0] = src[i * 4 + 0];
8207117f1b4Smrg            dst[i * 4 + 1] = src[i * 4 + 1];
8217117f1b4Smrg            dst[i * 4 + 2] = src[i * 4 + 2];
8227117f1b4Smrg            dst[i * 4 + 3] = src[i * 4 + 3];
8237117f1b4Smrg         }
8247117f1b4Smrg      }
8257117f1b4Smrg   }
8267117f1b4Smrg   else {
8277117f1b4Smrg      _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
8287117f1b4Smrg   }
8297117f1b4Smrg}
8307117f1b4Smrg
8317117f1b4Smrg
8327117f1b4Smrgstatic void
8337117f1b4Smrgput_row_rgb_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
8347117f1b4Smrg                    GLint x, GLint y, const void *values, const GLubyte *mask)
8357117f1b4Smrg{
8367117f1b4Smrg   /* Put RGB values in RGBA buffer */
8377117f1b4Smrg   const GLushort *src = (const GLushort *) values;
8387117f1b4Smrg   GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
8397117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
8407117f1b4Smrg   if (mask) {
8417117f1b4Smrg      GLuint i;
8427117f1b4Smrg      for (i = 0; i < count; i++) {
8437117f1b4Smrg         if (mask[i]) {
8447117f1b4Smrg            dst[i * 4 + 0] = src[i * 3 + 0];
8457117f1b4Smrg            dst[i * 4 + 1] = src[i * 3 + 1];
8467117f1b4Smrg            dst[i * 4 + 2] = src[i * 3 + 2];
8477117f1b4Smrg            dst[i * 4 + 3] = 0xffff;
8487117f1b4Smrg         }
8497117f1b4Smrg      }
8507117f1b4Smrg   }
8517117f1b4Smrg   else {
8527117f1b4Smrg      _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
8537117f1b4Smrg   }
8547117f1b4Smrg}
8557117f1b4Smrg
8567117f1b4Smrg
8577117f1b4Smrgstatic void
8587117f1b4Smrgput_mono_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
8597117f1b4Smrg                     GLint x, GLint y, const void *value, const GLubyte *mask)
8607117f1b4Smrg{
8617117f1b4Smrg   const GLushort val0 = ((const GLushort *) value)[0];
8627117f1b4Smrg   const GLushort val1 = ((const GLushort *) value)[1];
8637117f1b4Smrg   const GLushort val2 = ((const GLushort *) value)[2];
8647117f1b4Smrg   const GLushort val3 = ((const GLushort *) value)[3];
8657117f1b4Smrg   GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
8667117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
8677117f1b4Smrg   if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) {
8687117f1b4Smrg      /* common case for clearing accum buffer */
8697117f1b4Smrg      _mesa_bzero(dst, count * 4 * sizeof(GLushort));
8707117f1b4Smrg   }
8717117f1b4Smrg   else {
8727117f1b4Smrg      GLuint i;
8737117f1b4Smrg      for (i = 0; i < count; i++) {
8747117f1b4Smrg         if (!mask || mask[i]) {
8757117f1b4Smrg            dst[i * 4 + 0] = val0;
8767117f1b4Smrg            dst[i * 4 + 1] = val1;
8777117f1b4Smrg            dst[i * 4 + 2] = val2;
8787117f1b4Smrg            dst[i * 4 + 3] = val3;
8797117f1b4Smrg         }
8807117f1b4Smrg      }
8817117f1b4Smrg   }
8827117f1b4Smrg}
8837117f1b4Smrg
8847117f1b4Smrg
8857117f1b4Smrgstatic void
8867117f1b4Smrgput_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
8877117f1b4Smrg                   const GLint x[], const GLint y[], const void *values,
8887117f1b4Smrg                   const GLubyte *mask)
8897117f1b4Smrg{
8907117f1b4Smrg   const GLushort *src = (const GLushort *) values;
8917117f1b4Smrg   GLuint i;
8927117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
8937117f1b4Smrg   for (i = 0; i < count; i++) {
8947117f1b4Smrg      if (!mask || mask[i]) {
8957117f1b4Smrg         GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
8967117f1b4Smrg         dst[0] = src[i * 4 + 0];
8977117f1b4Smrg         dst[1] = src[i * 4 + 1];
8987117f1b4Smrg         dst[2] = src[i * 4 + 2];
8997117f1b4Smrg         dst[3] = src[i * 4 + 3];
9007117f1b4Smrg      }
9017117f1b4Smrg   }
9027117f1b4Smrg}
9037117f1b4Smrg
9047117f1b4Smrg
9057117f1b4Smrgstatic void
9067117f1b4Smrgput_mono_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
9077117f1b4Smrg                        GLuint count, const GLint x[], const GLint y[],
9087117f1b4Smrg                        const void *value, const GLubyte *mask)
9097117f1b4Smrg{
9107117f1b4Smrg   const GLushort val0 = ((const GLushort *) value)[0];
9117117f1b4Smrg   const GLushort val1 = ((const GLushort *) value)[1];
9127117f1b4Smrg   const GLushort val2 = ((const GLushort *) value)[2];
9137117f1b4Smrg   const GLushort val3 = ((const GLushort *) value)[3];
9147117f1b4Smrg   GLuint i;
9157117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
9167117f1b4Smrg   for (i = 0; i < count; i++) {
9177117f1b4Smrg      if (!mask || mask[i]) {
9187117f1b4Smrg         GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
9197117f1b4Smrg         dst[0] = val0;
9207117f1b4Smrg         dst[1] = val1;
9217117f1b4Smrg         dst[2] = val2;
9227117f1b4Smrg         dst[3] = val3;
9237117f1b4Smrg      }
9247117f1b4Smrg   }
9257117f1b4Smrg}
9267117f1b4Smrg
9277117f1b4Smrg
9287117f1b4Smrg
9297117f1b4Smrg/**
9307117f1b4Smrg * This is a software fallback for the gl_renderbuffer->AllocStorage
9317117f1b4Smrg * function.
9327117f1b4Smrg * Device drivers will typically override this function for the buffers
9337117f1b4Smrg * which it manages (typically color buffers, Z and stencil).
9347117f1b4Smrg * Other buffers (like software accumulation and aux buffers) which the driver
9357117f1b4Smrg * doesn't manage can be handled with this function.
9367117f1b4Smrg *
9377117f1b4Smrg * This one multi-purpose function can allocate stencil, depth, accum, color
9387117f1b4Smrg * or color-index buffers!
9397117f1b4Smrg *
9407117f1b4Smrg * This function also plugs in the appropriate GetPointer, Get/PutRow and
9417117f1b4Smrg * Get/PutValues functions.
9427117f1b4Smrg */
9437117f1b4SmrgGLboolean
9447117f1b4Smrg_mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
9457117f1b4Smrg                                GLenum internalFormat,
9467117f1b4Smrg                                GLuint width, GLuint height)
9477117f1b4Smrg{
9487117f1b4Smrg   GLuint pixelSize;
9497117f1b4Smrg
9507117f1b4Smrg   /* first clear these fields */
9517117f1b4Smrg   rb->RedBits =
9527117f1b4Smrg   rb->GreenBits =
9537117f1b4Smrg   rb->BlueBits =
9547117f1b4Smrg   rb->AlphaBits =
9557117f1b4Smrg   rb->IndexBits =
9567117f1b4Smrg   rb->DepthBits =
9577117f1b4Smrg   rb->StencilBits = 0;
9587117f1b4Smrg
9597117f1b4Smrg   switch (internalFormat) {
9607117f1b4Smrg   case GL_RGB:
9617117f1b4Smrg   case GL_R3_G3_B2:
9627117f1b4Smrg   case GL_RGB4:
9637117f1b4Smrg   case GL_RGB5:
9647117f1b4Smrg   case GL_RGB8:
9657117f1b4Smrg   case GL_RGB10:
9667117f1b4Smrg   case GL_RGB12:
9677117f1b4Smrg   case GL_RGB16:
9687117f1b4Smrg      rb->_ActualFormat = GL_RGB8;
9697117f1b4Smrg      rb->_BaseFormat = GL_RGB;
9707117f1b4Smrg      rb->DataType = GL_UNSIGNED_BYTE;
9717117f1b4Smrg      rb->GetPointer = get_pointer_ubyte3;
9727117f1b4Smrg      rb->GetRow = get_row_ubyte3;
9737117f1b4Smrg      rb->GetValues = get_values_ubyte3;
9747117f1b4Smrg      rb->PutRow = put_row_ubyte3;
9757117f1b4Smrg      rb->PutRowRGB = put_row_rgb_ubyte3;
9767117f1b4Smrg      rb->PutMonoRow = put_mono_row_ubyte3;
9777117f1b4Smrg      rb->PutValues = put_values_ubyte3;
9787117f1b4Smrg      rb->PutMonoValues = put_mono_values_ubyte3;
9797117f1b4Smrg      rb->RedBits   = 8 * sizeof(GLubyte);
9807117f1b4Smrg      rb->GreenBits = 8 * sizeof(GLubyte);
9817117f1b4Smrg      rb->BlueBits  = 8 * sizeof(GLubyte);
9827117f1b4Smrg      rb->AlphaBits = 0;
9837117f1b4Smrg      pixelSize = 3 * sizeof(GLubyte);
9847117f1b4Smrg      break;
9857117f1b4Smrg   case GL_RGBA:
9867117f1b4Smrg   case GL_RGBA2:
9877117f1b4Smrg   case GL_RGBA4:
9887117f1b4Smrg   case GL_RGB5_A1:
9897117f1b4Smrg   case GL_RGBA8:
9907117f1b4Smrg      rb->_ActualFormat = GL_RGBA8;
9917117f1b4Smrg      rb->_BaseFormat = GL_RGBA;
9927117f1b4Smrg      rb->DataType = GL_UNSIGNED_BYTE;
9937117f1b4Smrg      rb->GetPointer = get_pointer_ubyte4;
9947117f1b4Smrg      rb->GetRow = get_row_ubyte4;
9957117f1b4Smrg      rb->GetValues = get_values_ubyte4;
9967117f1b4Smrg      rb->PutRow = put_row_ubyte4;
9977117f1b4Smrg      rb->PutRowRGB = put_row_rgb_ubyte4;
9987117f1b4Smrg      rb->PutMonoRow = put_mono_row_ubyte4;
9997117f1b4Smrg      rb->PutValues = put_values_ubyte4;
10007117f1b4Smrg      rb->PutMonoValues = put_mono_values_ubyte4;
10017117f1b4Smrg      rb->RedBits   = 8 * sizeof(GLubyte);
10027117f1b4Smrg      rb->GreenBits = 8 * sizeof(GLubyte);
10037117f1b4Smrg      rb->BlueBits  = 8 * sizeof(GLubyte);
10047117f1b4Smrg      rb->AlphaBits = 8 * sizeof(GLubyte);
10057117f1b4Smrg      pixelSize = 4 * sizeof(GLubyte);
10067117f1b4Smrg      break;
10077117f1b4Smrg   case GL_RGB10_A2:
10087117f1b4Smrg   case GL_RGBA12:
10097117f1b4Smrg   case GL_RGBA16:
10107117f1b4Smrg      rb->_ActualFormat = GL_RGBA16;
10117117f1b4Smrg      rb->_BaseFormat = GL_RGBA;
10127117f1b4Smrg      rb->DataType = GL_UNSIGNED_SHORT;
10137117f1b4Smrg      rb->GetPointer = get_pointer_ushort4;
10147117f1b4Smrg      rb->GetRow = get_row_ushort4;
10157117f1b4Smrg      rb->GetValues = get_values_ushort4;
10167117f1b4Smrg      rb->PutRow = put_row_ushort4;
10177117f1b4Smrg      rb->PutRowRGB = put_row_rgb_ushort4;
10187117f1b4Smrg      rb->PutMonoRow = put_mono_row_ushort4;
10197117f1b4Smrg      rb->PutValues = put_values_ushort4;
10207117f1b4Smrg      rb->PutMonoValues = put_mono_values_ushort4;
10217117f1b4Smrg      rb->RedBits   = 8 * sizeof(GLushort);
10227117f1b4Smrg      rb->GreenBits = 8 * sizeof(GLushort);
10237117f1b4Smrg      rb->BlueBits  = 8 * sizeof(GLushort);
10247117f1b4Smrg      rb->AlphaBits = 8 * sizeof(GLushort);
10257117f1b4Smrg      pixelSize = 4 * sizeof(GLushort);
10267117f1b4Smrg      break;
10277117f1b4Smrg#if 00
10287117f1b4Smrg   case GL_ALPHA8:
10297117f1b4Smrg      rb->_ActualFormat = GL_ALPHA8;
10307117f1b4Smrg      rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */
10317117f1b4Smrg      rb->DataType = GL_UNSIGNED_BYTE;
10327117f1b4Smrg      rb->GetPointer = get_pointer_alpha8;
10337117f1b4Smrg      rb->GetRow = get_row_alpha8;
10347117f1b4Smrg      rb->GetValues = get_values_alpha8;
10357117f1b4Smrg      rb->PutRow = put_row_alpha8;
10367117f1b4Smrg      rb->PutRowRGB = NULL;
10377117f1b4Smrg      rb->PutMonoRow = put_mono_row_alpha8;
10387117f1b4Smrg      rb->PutValues = put_values_alpha8;
10397117f1b4Smrg      rb->PutMonoValues = put_mono_values_alpha8;
10407117f1b4Smrg      rb->RedBits   = 0; /*red*/
10417117f1b4Smrg      rb->GreenBits = 0; /*green*/
10427117f1b4Smrg      rb->BlueBits  = 0; /*blue*/
10437117f1b4Smrg      rb->AlphaBits = 8 * sizeof(GLubyte);
10447117f1b4Smrg      pixelSize = sizeof(GLubyte);
10457117f1b4Smrg      break;
10467117f1b4Smrg#endif
10477117f1b4Smrg   case GL_STENCIL_INDEX:
10487117f1b4Smrg   case GL_STENCIL_INDEX1_EXT:
10497117f1b4Smrg   case GL_STENCIL_INDEX4_EXT:
10507117f1b4Smrg   case GL_STENCIL_INDEX8_EXT:
10517117f1b4Smrg      rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
10527117f1b4Smrg      rb->_BaseFormat = GL_STENCIL_INDEX;
10537117f1b4Smrg      rb->DataType = GL_UNSIGNED_BYTE;
10547117f1b4Smrg      rb->GetPointer = get_pointer_ubyte;
10557117f1b4Smrg      rb->GetRow = get_row_ubyte;
10567117f1b4Smrg      rb->GetValues = get_values_ubyte;
10577117f1b4Smrg      rb->PutRow = put_row_ubyte;
10587117f1b4Smrg      rb->PutRowRGB = NULL;
10597117f1b4Smrg      rb->PutMonoRow = put_mono_row_ubyte;
10607117f1b4Smrg      rb->PutValues = put_values_ubyte;
10617117f1b4Smrg      rb->PutMonoValues = put_mono_values_ubyte;
10627117f1b4Smrg      rb->StencilBits = 8 * sizeof(GLubyte);
10637117f1b4Smrg      pixelSize = sizeof(GLubyte);
10647117f1b4Smrg      break;
10657117f1b4Smrg   case GL_STENCIL_INDEX16_EXT:
10667117f1b4Smrg      rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
10677117f1b4Smrg      rb->_BaseFormat = GL_STENCIL_INDEX;
10687117f1b4Smrg      rb->DataType = GL_UNSIGNED_SHORT;
10697117f1b4Smrg      rb->GetPointer = get_pointer_ushort;
10707117f1b4Smrg      rb->GetRow = get_row_ushort;
10717117f1b4Smrg      rb->GetValues = get_values_ushort;
10727117f1b4Smrg      rb->PutRow = put_row_ushort;
10737117f1b4Smrg      rb->PutRowRGB = NULL;
10747117f1b4Smrg      rb->PutMonoRow = put_mono_row_ushort;
10757117f1b4Smrg      rb->PutValues = put_values_ushort;
10767117f1b4Smrg      rb->PutMonoValues = put_mono_values_ushort;
10777117f1b4Smrg      rb->StencilBits = 8 * sizeof(GLushort);
10787117f1b4Smrg      pixelSize = sizeof(GLushort);
10797117f1b4Smrg      break;
10807117f1b4Smrg   case GL_DEPTH_COMPONENT:
10817117f1b4Smrg   case GL_DEPTH_COMPONENT16:
10827117f1b4Smrg      rb->_ActualFormat = GL_DEPTH_COMPONENT16;
10837117f1b4Smrg      rb->_BaseFormat = GL_DEPTH_COMPONENT;
10847117f1b4Smrg      rb->DataType = GL_UNSIGNED_SHORT;
10857117f1b4Smrg      rb->GetPointer = get_pointer_ushort;
10867117f1b4Smrg      rb->GetRow = get_row_ushort;
10877117f1b4Smrg      rb->GetValues = get_values_ushort;
10887117f1b4Smrg      rb->PutRow = put_row_ushort;
10897117f1b4Smrg      rb->PutRowRGB = NULL;
10907117f1b4Smrg      rb->PutMonoRow = put_mono_row_ushort;
10917117f1b4Smrg      rb->PutValues = put_values_ushort;
10927117f1b4Smrg      rb->PutMonoValues = put_mono_values_ushort;
10937117f1b4Smrg      rb->DepthBits = 8 * sizeof(GLushort);
10947117f1b4Smrg      pixelSize = sizeof(GLushort);
10957117f1b4Smrg      break;
10967117f1b4Smrg   case GL_DEPTH_COMPONENT24:
10977117f1b4Smrg   case GL_DEPTH_COMPONENT32:
10987117f1b4Smrg      rb->_BaseFormat = GL_DEPTH_COMPONENT;
10997117f1b4Smrg      rb->DataType = GL_UNSIGNED_INT;
11007117f1b4Smrg      rb->GetPointer = get_pointer_uint;
11017117f1b4Smrg      rb->GetRow = get_row_uint;
11027117f1b4Smrg      rb->GetValues = get_values_uint;
11037117f1b4Smrg      rb->PutRow = put_row_uint;
11047117f1b4Smrg      rb->PutRowRGB = NULL;
11057117f1b4Smrg      rb->PutMonoRow = put_mono_row_uint;
11067117f1b4Smrg      rb->PutValues = put_values_uint;
11077117f1b4Smrg      rb->PutMonoValues = put_mono_values_uint;
11087117f1b4Smrg      if (internalFormat == GL_DEPTH_COMPONENT24) {
11097117f1b4Smrg         rb->_ActualFormat = GL_DEPTH_COMPONENT24;
11107117f1b4Smrg         rb->DepthBits = 24;
11117117f1b4Smrg      }
11127117f1b4Smrg      else {
11137117f1b4Smrg         rb->_ActualFormat = GL_DEPTH_COMPONENT32;
11147117f1b4Smrg         rb->DepthBits = 32;
11157117f1b4Smrg      }
11167117f1b4Smrg      pixelSize = sizeof(GLuint);
11177117f1b4Smrg      break;
11187117f1b4Smrg   case GL_DEPTH_STENCIL_EXT:
11197117f1b4Smrg   case GL_DEPTH24_STENCIL8_EXT:
11207117f1b4Smrg      rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
11217117f1b4Smrg      rb->_BaseFormat = GL_DEPTH_STENCIL_EXT;
11227117f1b4Smrg      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
11237117f1b4Smrg      rb->GetPointer = get_pointer_uint;
11247117f1b4Smrg      rb->GetRow = get_row_uint;
11257117f1b4Smrg      rb->GetValues = get_values_uint;
11267117f1b4Smrg      rb->PutRow = put_row_uint;
11277117f1b4Smrg      rb->PutRowRGB = NULL;
11287117f1b4Smrg      rb->PutMonoRow = put_mono_row_uint;
11297117f1b4Smrg      rb->PutValues = put_values_uint;
11307117f1b4Smrg      rb->PutMonoValues = put_mono_values_uint;
11317117f1b4Smrg      rb->DepthBits = 24;
11327117f1b4Smrg      rb->StencilBits = 8;
11337117f1b4Smrg      pixelSize = sizeof(GLuint);
11347117f1b4Smrg      break;
11357117f1b4Smrg   case GL_COLOR_INDEX8_EXT:
11367117f1b4Smrg      rb->_ActualFormat = GL_COLOR_INDEX8_EXT;
11377117f1b4Smrg      rb->_BaseFormat = GL_COLOR_INDEX;
11387117f1b4Smrg      rb->DataType = GL_UNSIGNED_BYTE;
11397117f1b4Smrg      rb->GetPointer = get_pointer_ubyte;
11407117f1b4Smrg      rb->GetRow = get_row_ubyte;
11417117f1b4Smrg      rb->GetValues = get_values_ubyte;
11427117f1b4Smrg      rb->PutRow = put_row_ubyte;
11437117f1b4Smrg      rb->PutRowRGB = NULL;
11447117f1b4Smrg      rb->PutMonoRow = put_mono_row_ubyte;
11457117f1b4Smrg      rb->PutValues = put_values_ubyte;
11467117f1b4Smrg      rb->PutMonoValues = put_mono_values_ubyte;
11477117f1b4Smrg      rb->IndexBits = 8 * sizeof(GLubyte);
11487117f1b4Smrg      pixelSize = sizeof(GLubyte);
11497117f1b4Smrg      break;
11507117f1b4Smrg   case GL_COLOR_INDEX16_EXT:
11517117f1b4Smrg      rb->_ActualFormat = GL_COLOR_INDEX16_EXT;
11527117f1b4Smrg      rb->_BaseFormat = GL_COLOR_INDEX;
11537117f1b4Smrg      rb->DataType = GL_UNSIGNED_SHORT;
11547117f1b4Smrg      rb->GetPointer = get_pointer_ushort;
11557117f1b4Smrg      rb->GetRow = get_row_ushort;
11567117f1b4Smrg      rb->GetValues = get_values_ushort;
11577117f1b4Smrg      rb->PutRow = put_row_ushort;
11587117f1b4Smrg      rb->PutRowRGB = NULL;
11597117f1b4Smrg      rb->PutMonoRow = put_mono_row_ushort;
11607117f1b4Smrg      rb->PutValues = put_values_ushort;
11617117f1b4Smrg      rb->PutMonoValues = put_mono_values_ushort;
11627117f1b4Smrg      rb->IndexBits = 8 * sizeof(GLushort);
11637117f1b4Smrg      pixelSize = sizeof(GLushort);
11647117f1b4Smrg      break;
11657117f1b4Smrg   case COLOR_INDEX32:
11667117f1b4Smrg      rb->_ActualFormat = COLOR_INDEX32;
11677117f1b4Smrg      rb->_BaseFormat = GL_COLOR_INDEX;
11687117f1b4Smrg      rb->DataType = GL_UNSIGNED_INT;
11697117f1b4Smrg      rb->GetPointer = get_pointer_uint;
11707117f1b4Smrg      rb->GetRow = get_row_uint;
11717117f1b4Smrg      rb->GetValues = get_values_uint;
11727117f1b4Smrg      rb->PutRow = put_row_uint;
11737117f1b4Smrg      rb->PutRowRGB = NULL;
11747117f1b4Smrg      rb->PutMonoRow = put_mono_row_uint;
11757117f1b4Smrg      rb->PutValues = put_values_uint;
11767117f1b4Smrg      rb->PutMonoValues = put_mono_values_uint;
11777117f1b4Smrg      rb->IndexBits = 8 * sizeof(GLuint);
11787117f1b4Smrg      pixelSize = sizeof(GLuint);
11797117f1b4Smrg      break;
11807117f1b4Smrg   default:
11817117f1b4Smrg      _mesa_problem(ctx, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
11827117f1b4Smrg      return GL_FALSE;
11837117f1b4Smrg   }
11847117f1b4Smrg
11857117f1b4Smrg   ASSERT(rb->DataType);
11867117f1b4Smrg   ASSERT(rb->GetPointer);
11877117f1b4Smrg   ASSERT(rb->GetRow);
11887117f1b4Smrg   ASSERT(rb->GetValues);
11897117f1b4Smrg   ASSERT(rb->PutRow);
11907117f1b4Smrg   ASSERT(rb->PutMonoRow);
11917117f1b4Smrg   ASSERT(rb->PutValues);
11927117f1b4Smrg   ASSERT(rb->PutMonoValues);
11937117f1b4Smrg
11947117f1b4Smrg   /* free old buffer storage */
11957117f1b4Smrg   if (rb->Data) {
11967117f1b4Smrg      _mesa_free(rb->Data);
11977117f1b4Smrg      rb->Data = NULL;
11987117f1b4Smrg   }
11997117f1b4Smrg
12007117f1b4Smrg   if (width > 0 && height > 0) {
12017117f1b4Smrg      /* allocate new buffer storage */
12027117f1b4Smrg      rb->Data = _mesa_malloc(width * height * pixelSize);
12037117f1b4Smrg      if (rb->Data == NULL) {
12047117f1b4Smrg         rb->Width = 0;
12057117f1b4Smrg         rb->Height = 0;
12067117f1b4Smrg         _mesa_error(ctx, GL_OUT_OF_MEMORY,
12077117f1b4Smrg                     "software renderbuffer allocation (%d x %d x %d)",
12087117f1b4Smrg                     width, height, pixelSize);
12097117f1b4Smrg         return GL_FALSE;
12107117f1b4Smrg      }
12117117f1b4Smrg   }
12127117f1b4Smrg
12137117f1b4Smrg   rb->Width = width;
12147117f1b4Smrg   rb->Height = height;
12157117f1b4Smrg
12167117f1b4Smrg   return GL_TRUE;
12177117f1b4Smrg}
12187117f1b4Smrg
12197117f1b4Smrg
12207117f1b4Smrg
12217117f1b4Smrg/**********************************************************************/
12227117f1b4Smrg/**********************************************************************/
12237117f1b4Smrg/**********************************************************************/
12247117f1b4Smrg
12257117f1b4Smrg
12267117f1b4Smrg/**
12277117f1b4Smrg * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
12287117f1b4Smrg * buffer wrapper around an existing RGB renderbuffer (hw or sw).
12297117f1b4Smrg *
12307117f1b4Smrg * When PutRow is called (for example), we store the alpha values in
12317117f1b4Smrg * this buffer, then pass on the PutRow call to the wrapped RGB
12327117f1b4Smrg * buffer.
12337117f1b4Smrg */
12347117f1b4Smrg
12357117f1b4Smrg
12367117f1b4Smrgstatic GLboolean
12377117f1b4Smrgalloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
12387117f1b4Smrg                     GLenum internalFormat, GLuint width, GLuint height)
12397117f1b4Smrg{
12407117f1b4Smrg   ASSERT(arb != arb->Wrapped);
12417117f1b4Smrg   ASSERT(arb->_ActualFormat == GL_ALPHA8);
12427117f1b4Smrg
12437117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
12447117f1b4Smrg   if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat,
12457117f1b4Smrg                                  width, height)) {
12467117f1b4Smrg      return GL_FALSE;
12477117f1b4Smrg   }
12487117f1b4Smrg
12497117f1b4Smrg   /* next, resize my alpha buffer */
12507117f1b4Smrg   if (arb->Data) {
12517117f1b4Smrg      _mesa_free(arb->Data);
12527117f1b4Smrg   }
12537117f1b4Smrg
12547117f1b4Smrg   arb->Data = _mesa_malloc(width * height * sizeof(GLubyte));
12557117f1b4Smrg   if (arb->Data == NULL) {
12567117f1b4Smrg      arb->Width = 0;
12577117f1b4Smrg      arb->Height = 0;
12587117f1b4Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation");
12597117f1b4Smrg      return GL_FALSE;
12607117f1b4Smrg   }
12617117f1b4Smrg
12627117f1b4Smrg   arb->Width = width;
12637117f1b4Smrg   arb->Height = height;
12647117f1b4Smrg
12657117f1b4Smrg   return GL_TRUE;
12667117f1b4Smrg}
12677117f1b4Smrg
12687117f1b4Smrg
12697117f1b4Smrg/**
12707117f1b4Smrg * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
12717117f1b4Smrg */
12727117f1b4Smrgstatic void
12737117f1b4Smrgdelete_renderbuffer_alpha8(struct gl_renderbuffer *arb)
12747117f1b4Smrg{
12757117f1b4Smrg   if (arb->Data) {
12767117f1b4Smrg      _mesa_free(arb->Data);
12777117f1b4Smrg   }
12787117f1b4Smrg   ASSERT(arb->Wrapped);
12797117f1b4Smrg   ASSERT(arb != arb->Wrapped);
12807117f1b4Smrg   arb->Wrapped->Delete(arb->Wrapped);
12817117f1b4Smrg   arb->Wrapped = NULL;
12827117f1b4Smrg   _mesa_free(arb);
12837117f1b4Smrg}
12847117f1b4Smrg
12857117f1b4Smrg
12867117f1b4Smrgstatic void *
12877117f1b4Smrgget_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
12887117f1b4Smrg                   GLint x, GLint y)
12897117f1b4Smrg{
12907117f1b4Smrg   return NULL;   /* don't allow direct access! */
12917117f1b4Smrg}
12927117f1b4Smrg
12937117f1b4Smrg
12947117f1b4Smrgstatic void
12957117f1b4Smrgget_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
12967117f1b4Smrg               GLint x, GLint y, void *values)
12977117f1b4Smrg{
12987117f1b4Smrg   /* NOTE: 'values' is RGBA format! */
12997117f1b4Smrg   const GLubyte *src = (const GLubyte *) arb->Data + y * arb->Width + x;
13007117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
13017117f1b4Smrg   GLuint i;
13027117f1b4Smrg   ASSERT(arb != arb->Wrapped);
13037117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
13047117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
13057117f1b4Smrg   arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values);
13067117f1b4Smrg   /* second, fill in alpha values from this buffer! */
13077117f1b4Smrg   for (i = 0; i < count; i++) {
13087117f1b4Smrg      dst[i * 4 + 3] = src[i];
13097117f1b4Smrg   }
13107117f1b4Smrg}
13117117f1b4Smrg
13127117f1b4Smrg
13137117f1b4Smrgstatic void
13147117f1b4Smrgget_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
13157117f1b4Smrg                  const GLint x[], const GLint y[], void *values)
13167117f1b4Smrg{
13177117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
13187117f1b4Smrg   GLuint i;
13197117f1b4Smrg   ASSERT(arb != arb->Wrapped);
13207117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
13217117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
13227117f1b4Smrg   arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values);
13237117f1b4Smrg   /* second, fill in alpha values from this buffer! */
13247117f1b4Smrg   for (i = 0; i < count; i++) {
13257117f1b4Smrg      const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
13267117f1b4Smrg      dst[i * 4 + 3] = *src;
13277117f1b4Smrg   }
13287117f1b4Smrg}
13297117f1b4Smrg
13307117f1b4Smrg
13317117f1b4Smrgstatic void
13327117f1b4Smrgput_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
13337117f1b4Smrg               GLint x, GLint y, const void *values, const GLubyte *mask)
13347117f1b4Smrg{
13357117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
13367117f1b4Smrg   GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
13377117f1b4Smrg   GLuint i;
13387117f1b4Smrg   ASSERT(arb != arb->Wrapped);
13397117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
13407117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
13417117f1b4Smrg   arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask);
13427117f1b4Smrg   /* second, store alpha in our buffer */
13437117f1b4Smrg   for (i = 0; i < count; i++) {
13447117f1b4Smrg      if (!mask || mask[i]) {
13457117f1b4Smrg         dst[i] = src[i * 4 + 3];
13467117f1b4Smrg      }
13477117f1b4Smrg   }
13487117f1b4Smrg}
13497117f1b4Smrg
13507117f1b4Smrg
13517117f1b4Smrgstatic void
13527117f1b4Smrgput_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
13537117f1b4Smrg                   GLint x, GLint y, const void *values, const GLubyte *mask)
13547117f1b4Smrg{
13557117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
13567117f1b4Smrg   GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
13577117f1b4Smrg   GLuint i;
13587117f1b4Smrg   ASSERT(arb != arb->Wrapped);
13597117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
13607117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
13617117f1b4Smrg   arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask);
13627117f1b4Smrg   /* second, store alpha in our buffer */
13637117f1b4Smrg   for (i = 0; i < count; i++) {
13647117f1b4Smrg      if (!mask || mask[i]) {
13657117f1b4Smrg         dst[i] = src[i * 4 + 3];
13667117f1b4Smrg      }
13677117f1b4Smrg   }
13687117f1b4Smrg}
13697117f1b4Smrg
13707117f1b4Smrg
13717117f1b4Smrgstatic void
13727117f1b4Smrgput_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
13737117f1b4Smrg                    GLint x, GLint y, const void *value, const GLubyte *mask)
13747117f1b4Smrg{
13757117f1b4Smrg   const GLubyte val = ((const GLubyte *) value)[3];
13767117f1b4Smrg   GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
13777117f1b4Smrg   ASSERT(arb != arb->Wrapped);
13787117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
13797117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
13807117f1b4Smrg   arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask);
13817117f1b4Smrg   /* second, store alpha in our buffer */
13827117f1b4Smrg   if (mask) {
13837117f1b4Smrg      GLuint i;
13847117f1b4Smrg      for (i = 0; i < count; i++) {
13857117f1b4Smrg         if (mask[i]) {
13867117f1b4Smrg            dst[i] = val;
13877117f1b4Smrg         }
13887117f1b4Smrg      }
13897117f1b4Smrg   }
13907117f1b4Smrg   else {
13917117f1b4Smrg      _mesa_memset(dst, val, count);
13927117f1b4Smrg   }
13937117f1b4Smrg}
13947117f1b4Smrg
13957117f1b4Smrg
13967117f1b4Smrgstatic void
13977117f1b4Smrgput_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
13987117f1b4Smrg                  const GLint x[], const GLint y[],
13997117f1b4Smrg                  const void *values, const GLubyte *mask)
14007117f1b4Smrg{
14017117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
14027117f1b4Smrg   GLuint i;
14037117f1b4Smrg   ASSERT(arb != arb->Wrapped);
14047117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
14057117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
14067117f1b4Smrg   arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask);
14077117f1b4Smrg   /* second, store alpha in our buffer */
14087117f1b4Smrg   for (i = 0; i < count; i++) {
14097117f1b4Smrg      if (!mask || mask[i]) {
14107117f1b4Smrg         GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
14117117f1b4Smrg         *dst = src[i * 4 + 3];
14127117f1b4Smrg      }
14137117f1b4Smrg   }
14147117f1b4Smrg}
14157117f1b4Smrg
14167117f1b4Smrg
14177117f1b4Smrgstatic void
14187117f1b4Smrgput_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
14197117f1b4Smrg                       GLuint count, const GLint x[], const GLint y[],
14207117f1b4Smrg                       const void *value, const GLubyte *mask)
14217117f1b4Smrg{
14227117f1b4Smrg   const GLubyte val = ((const GLubyte *) value)[3];
14237117f1b4Smrg   GLuint i;
14247117f1b4Smrg   ASSERT(arb != arb->Wrapped);
14257117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
14267117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
14277117f1b4Smrg   arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask);
14287117f1b4Smrg   /* second, store alpha in our buffer */
14297117f1b4Smrg   for (i = 0; i < count; i++) {
14307117f1b4Smrg      if (!mask || mask[i]) {
14317117f1b4Smrg         GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
14327117f1b4Smrg         *dst = val;
14337117f1b4Smrg      }
14347117f1b4Smrg   }
14357117f1b4Smrg}
14367117f1b4Smrg
14377117f1b4Smrg
14387117f1b4Smrgstatic void
14397117f1b4Smrgcopy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src)
14407117f1b4Smrg{
14417117f1b4Smrg   ASSERT(dst->_ActualFormat == GL_ALPHA8);
14427117f1b4Smrg   ASSERT(src->_ActualFormat == GL_ALPHA8);
14437117f1b4Smrg   ASSERT(dst->Width == src->Width);
14447117f1b4Smrg   ASSERT(dst->Height == src->Height);
14457117f1b4Smrg
14467117f1b4Smrg   _mesa_memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte));
14477117f1b4Smrg}
14487117f1b4Smrg
14497117f1b4Smrg
14507117f1b4Smrg/**********************************************************************/
14517117f1b4Smrg/**********************************************************************/
14527117f1b4Smrg/**********************************************************************/
14537117f1b4Smrg
14547117f1b4Smrg
14557117f1b4Smrg/**
14567117f1b4Smrg * Default GetPointer routine.  Always return NULL to indicate that
14577117f1b4Smrg * direct buffer access is not supported.
14587117f1b4Smrg */
14597117f1b4Smrgstatic void *
14607117f1b4Smrgnop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
14617117f1b4Smrg{
14627117f1b4Smrg   return NULL;
14637117f1b4Smrg}
14647117f1b4Smrg
14657117f1b4Smrg
14667117f1b4Smrg/**
14677117f1b4Smrg * Initialize the fields of a gl_renderbuffer to default values.
14687117f1b4Smrg */
14697117f1b4Smrgvoid
14707117f1b4Smrg_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
14717117f1b4Smrg{
14727117f1b4Smrg   _glthread_INIT_MUTEX(rb->Mutex);
14737117f1b4Smrg
14747117f1b4Smrg   rb->Magic = RB_MAGIC;
14757117f1b4Smrg   rb->ClassID = 0;
14767117f1b4Smrg   rb->Name = name;
14777117f1b4Smrg   rb->RefCount = 0;
14787117f1b4Smrg   rb->Delete = _mesa_delete_renderbuffer;
14797117f1b4Smrg
14807117f1b4Smrg   /* The rest of these should be set later by the caller of this function or
14817117f1b4Smrg    * the AllocStorage method:
14827117f1b4Smrg    */
14837117f1b4Smrg   rb->AllocStorage = NULL;
14847117f1b4Smrg
14857117f1b4Smrg   rb->Width = 0;
14867117f1b4Smrg   rb->Height = 0;
14877117f1b4Smrg   rb->InternalFormat = GL_NONE;
14887117f1b4Smrg   rb->_ActualFormat = GL_NONE;
14897117f1b4Smrg   rb->_BaseFormat = GL_NONE;
14907117f1b4Smrg   rb->DataType = GL_NONE;
14917117f1b4Smrg   rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 0;
14927117f1b4Smrg   rb->IndexBits = 0;
14937117f1b4Smrg   rb->DepthBits = 0;
14947117f1b4Smrg   rb->StencilBits = 0;
14957117f1b4Smrg   rb->Data = NULL;
14967117f1b4Smrg
14977117f1b4Smrg   /* Point back to ourself so that we don't have to check for Wrapped==NULL
14987117f1b4Smrg    * all over the drivers.
14997117f1b4Smrg    */
15007117f1b4Smrg   rb->Wrapped = rb;
15017117f1b4Smrg
15027117f1b4Smrg   rb->GetPointer = nop_get_pointer;
15037117f1b4Smrg   rb->GetRow = NULL;
15047117f1b4Smrg   rb->GetValues = NULL;
15057117f1b4Smrg   rb->PutRow = NULL;
15067117f1b4Smrg   rb->PutRowRGB = NULL;
15077117f1b4Smrg   rb->PutMonoRow = NULL;
15087117f1b4Smrg   rb->PutValues = NULL;
15097117f1b4Smrg   rb->PutMonoValues = NULL;
15107117f1b4Smrg}
15117117f1b4Smrg
15127117f1b4Smrg
15137117f1b4Smrg/**
15147117f1b4Smrg * Allocate a new gl_renderbuffer object.  This can be used for user-created
15157117f1b4Smrg * renderbuffers or window-system renderbuffers.
15167117f1b4Smrg */
15177117f1b4Smrgstruct gl_renderbuffer *
15187117f1b4Smrg_mesa_new_renderbuffer(GLcontext *ctx, GLuint name)
15197117f1b4Smrg{
15207117f1b4Smrg   struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
15217117f1b4Smrg   if (rb) {
15227117f1b4Smrg      _mesa_init_renderbuffer(rb, name);
15237117f1b4Smrg   }
15247117f1b4Smrg   return rb;
15257117f1b4Smrg}
15267117f1b4Smrg
15277117f1b4Smrg
15287117f1b4Smrg/**
15297117f1b4Smrg * Delete a gl_framebuffer.
15307117f1b4Smrg * This is the default function for renderbuffer->Delete().
15317117f1b4Smrg */
15327117f1b4Smrgvoid
15337117f1b4Smrg_mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
15347117f1b4Smrg{
15357117f1b4Smrg   if (rb->Data) {
15367117f1b4Smrg      _mesa_free(rb->Data);
15377117f1b4Smrg   }
15387117f1b4Smrg   _mesa_free(rb);
15397117f1b4Smrg}
15407117f1b4Smrg
15417117f1b4Smrg
15427117f1b4Smrg/**
15437117f1b4Smrg * Allocate a software-based renderbuffer.  This is called via the
15447117f1b4Smrg * ctx->Driver.NewRenderbuffer() function when the user creates a new
15457117f1b4Smrg * renderbuffer.
15467117f1b4Smrg * This would not be used for hardware-based renderbuffers.
15477117f1b4Smrg */
15487117f1b4Smrgstruct gl_renderbuffer *
15497117f1b4Smrg_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name)
15507117f1b4Smrg{
15517117f1b4Smrg   struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
15527117f1b4Smrg   if (rb) {
15537117f1b4Smrg      rb->AllocStorage = _mesa_soft_renderbuffer_storage;
15547117f1b4Smrg      /* Normally, one would setup the PutRow, GetRow, etc functions here.
15557117f1b4Smrg       * But we're doing that in the _mesa_soft_renderbuffer_storage() function
15567117f1b4Smrg       * instead.
15577117f1b4Smrg       */
15587117f1b4Smrg   }
15597117f1b4Smrg   return rb;
15607117f1b4Smrg}
15617117f1b4Smrg
15627117f1b4Smrg
15637117f1b4Smrg/**
15647117f1b4Smrg * Add software-based color renderbuffers to the given framebuffer.
15657117f1b4Smrg * This is a helper routine for device drivers when creating a
15667117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
15677117f1b4Smrg * Once this function is called, you can basically forget about this
15687117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
15697117f1b4Smrg * rendering!
15707117f1b4Smrg */
15717117f1b4SmrgGLboolean
15727117f1b4Smrg_mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
15737117f1b4Smrg                              GLuint rgbBits, GLuint alphaBits,
15747117f1b4Smrg                              GLboolean frontLeft, GLboolean backLeft,
15757117f1b4Smrg                              GLboolean frontRight, GLboolean backRight)
15767117f1b4Smrg{
15777117f1b4Smrg   GLuint b;
15787117f1b4Smrg
15797117f1b4Smrg   if (rgbBits > 16 || alphaBits > 16) {
15807117f1b4Smrg      _mesa_problem(ctx,
15817117f1b4Smrg                    "Unsupported bit depth in _mesa_add_color_renderbuffers");
15827117f1b4Smrg      return GL_FALSE;
15837117f1b4Smrg   }
15847117f1b4Smrg
15857117f1b4Smrg   assert(MAX_COLOR_ATTACHMENTS >= 4);
15867117f1b4Smrg
15877117f1b4Smrg   for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
15887117f1b4Smrg      struct gl_renderbuffer *rb;
15897117f1b4Smrg
15907117f1b4Smrg      if (b == BUFFER_FRONT_LEFT && !frontLeft)
15917117f1b4Smrg         continue;
15927117f1b4Smrg      else if (b == BUFFER_BACK_LEFT && !backLeft)
15937117f1b4Smrg         continue;
15947117f1b4Smrg      else if (b == BUFFER_FRONT_RIGHT && !frontRight)
15957117f1b4Smrg         continue;
15967117f1b4Smrg      else if (b == BUFFER_BACK_RIGHT && !backRight)
15977117f1b4Smrg         continue;
15987117f1b4Smrg
15997117f1b4Smrg      assert(fb->Attachment[b].Renderbuffer == NULL);
16007117f1b4Smrg
16017117f1b4Smrg      rb = _mesa_new_renderbuffer(ctx, 0);
16027117f1b4Smrg      if (!rb) {
16037117f1b4Smrg         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
16047117f1b4Smrg         return GL_FALSE;
16057117f1b4Smrg      }
16067117f1b4Smrg
16077117f1b4Smrg      if (rgbBits <= 8) {
16087117f1b4Smrg         if (alphaBits)
16097117f1b4Smrg            rb->_ActualFormat = GL_RGBA8;
16107117f1b4Smrg         else
16117117f1b4Smrg            rb->_ActualFormat = GL_RGB8;
16127117f1b4Smrg      }
16137117f1b4Smrg      else {
16147117f1b4Smrg         assert(rgbBits <= 16);
16157117f1b4Smrg         if (alphaBits)
16167117f1b4Smrg            rb->_ActualFormat = GL_RGBA16;
16177117f1b4Smrg         else
16187117f1b4Smrg            rb->_ActualFormat = GL_RGBA16; /* don't really have RGB16 yet */
16197117f1b4Smrg      }
16207117f1b4Smrg      rb->InternalFormat = rb->_ActualFormat;
16217117f1b4Smrg
16227117f1b4Smrg      rb->AllocStorage = _mesa_soft_renderbuffer_storage;
16237117f1b4Smrg      _mesa_add_renderbuffer(fb, b, rb);
16247117f1b4Smrg   }
16257117f1b4Smrg
16267117f1b4Smrg   return GL_TRUE;
16277117f1b4Smrg}
16287117f1b4Smrg
16297117f1b4Smrg
16307117f1b4Smrg/**
16317117f1b4Smrg * Add software-based color index renderbuffers to the given framebuffer.
16327117f1b4Smrg * This is a helper routine for device drivers when creating a
16337117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
16347117f1b4Smrg * Once this function is called, you can basically forget about this
16357117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
16367117f1b4Smrg * rendering!
16377117f1b4Smrg */
16387117f1b4SmrgGLboolean
16397117f1b4Smrg_mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
16407117f1b4Smrg                                    GLuint indexBits,
16417117f1b4Smrg                                    GLboolean frontLeft, GLboolean backLeft,
16427117f1b4Smrg                                    GLboolean frontRight, GLboolean backRight)
16437117f1b4Smrg{
16447117f1b4Smrg   GLuint b;
16457117f1b4Smrg
16467117f1b4Smrg   if (indexBits > 8) {
16477117f1b4Smrg      _mesa_problem(ctx,
16487117f1b4Smrg                "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
16497117f1b4Smrg      return GL_FALSE;
16507117f1b4Smrg   }
16517117f1b4Smrg
16527117f1b4Smrg   assert(MAX_COLOR_ATTACHMENTS >= 4);
16537117f1b4Smrg
16547117f1b4Smrg   for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
16557117f1b4Smrg      struct gl_renderbuffer *rb;
16567117f1b4Smrg
16577117f1b4Smrg      if (b == BUFFER_FRONT_LEFT && !frontLeft)
16587117f1b4Smrg         continue;
16597117f1b4Smrg      else if (b == BUFFER_BACK_LEFT && !backLeft)
16607117f1b4Smrg         continue;
16617117f1b4Smrg      else if (b == BUFFER_FRONT_RIGHT && !frontRight)
16627117f1b4Smrg         continue;
16637117f1b4Smrg      else if (b == BUFFER_BACK_RIGHT && !backRight)
16647117f1b4Smrg         continue;
16657117f1b4Smrg
16667117f1b4Smrg      assert(fb->Attachment[b].Renderbuffer == NULL);
16677117f1b4Smrg
16687117f1b4Smrg      rb = _mesa_new_renderbuffer(ctx, 0);
16697117f1b4Smrg      if (!rb) {
16707117f1b4Smrg         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
16717117f1b4Smrg         return GL_FALSE;
16727117f1b4Smrg      }
16737117f1b4Smrg
16747117f1b4Smrg      if (indexBits <= 8) {
16757117f1b4Smrg         /* only support GLuint for now */
16767117f1b4Smrg         /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
16777117f1b4Smrg         rb->_ActualFormat = COLOR_INDEX32;
16787117f1b4Smrg      }
16797117f1b4Smrg      else {
16807117f1b4Smrg         rb->_ActualFormat = COLOR_INDEX32;
16817117f1b4Smrg      }
16827117f1b4Smrg      rb->InternalFormat = rb->_ActualFormat;
16837117f1b4Smrg
16847117f1b4Smrg      rb->AllocStorage = _mesa_soft_renderbuffer_storage;
16857117f1b4Smrg      _mesa_add_renderbuffer(fb, b, rb);
16867117f1b4Smrg   }
16877117f1b4Smrg
16887117f1b4Smrg   return GL_TRUE;
16897117f1b4Smrg}
16907117f1b4Smrg
16917117f1b4Smrg
16927117f1b4Smrg/**
16937117f1b4Smrg * Add software-based alpha renderbuffers to the given framebuffer.
16947117f1b4Smrg * This is a helper routine for device drivers when creating a
16957117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
16967117f1b4Smrg * Once this function is called, you can basically forget about this
16977117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
16987117f1b4Smrg * rendering!
16997117f1b4Smrg */
17007117f1b4SmrgGLboolean
17017117f1b4Smrg_mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
17027117f1b4Smrg                              GLuint alphaBits,
17037117f1b4Smrg                              GLboolean frontLeft, GLboolean backLeft,
17047117f1b4Smrg                              GLboolean frontRight, GLboolean backRight)
17057117f1b4Smrg{
17067117f1b4Smrg   GLuint b;
17077117f1b4Smrg
17087117f1b4Smrg   /* for window system framebuffers only! */
17097117f1b4Smrg   assert(fb->Name == 0);
17107117f1b4Smrg
17117117f1b4Smrg   if (alphaBits > 8) {
17127117f1b4Smrg      _mesa_problem(ctx,
17137117f1b4Smrg                    "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
17147117f1b4Smrg      return GL_FALSE;
17157117f1b4Smrg   }
17167117f1b4Smrg
17177117f1b4Smrg   assert(MAX_COLOR_ATTACHMENTS >= 4);
17187117f1b4Smrg
17197117f1b4Smrg   /* Wrap each of the RGB color buffers with an alpha renderbuffer.
17207117f1b4Smrg    */
17217117f1b4Smrg   for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
17227117f1b4Smrg      struct gl_renderbuffer *arb;
17237117f1b4Smrg
17247117f1b4Smrg      if (b == BUFFER_FRONT_LEFT && !frontLeft)
17257117f1b4Smrg         continue;
17267117f1b4Smrg      else if (b == BUFFER_BACK_LEFT && !backLeft)
17277117f1b4Smrg         continue;
17287117f1b4Smrg      else if (b == BUFFER_FRONT_RIGHT && !frontRight)
17297117f1b4Smrg         continue;
17307117f1b4Smrg      else if (b == BUFFER_BACK_RIGHT && !backRight)
17317117f1b4Smrg         continue;
17327117f1b4Smrg
17337117f1b4Smrg      /* the RGB buffer to wrap must already exist!! */
17347117f1b4Smrg      assert(fb->Attachment[b].Renderbuffer);
17357117f1b4Smrg
17367117f1b4Smrg      /* only GLubyte supported for now */
17377117f1b4Smrg      assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
17387117f1b4Smrg
17397117f1b4Smrg      /* allocate alpha renderbuffer */
17407117f1b4Smrg      arb = _mesa_new_renderbuffer(ctx, 0);
17417117f1b4Smrg      if (!arb) {
17427117f1b4Smrg         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
17437117f1b4Smrg         return GL_FALSE;
17447117f1b4Smrg      }
17457117f1b4Smrg
17467117f1b4Smrg      /* wrap the alpha renderbuffer around the RGB renderbuffer */
17477117f1b4Smrg      arb->Wrapped = fb->Attachment[b].Renderbuffer;
17487117f1b4Smrg
17497117f1b4Smrg      /* Set up my alphabuffer fields and plug in my functions.
17507117f1b4Smrg       * The functions will put/get the alpha values from/to RGBA arrays
17517117f1b4Smrg       * and then call the wrapped buffer's functions to handle the RGB
17527117f1b4Smrg       * values.
17537117f1b4Smrg       */
17547117f1b4Smrg      arb->InternalFormat = arb->Wrapped->InternalFormat;
17557117f1b4Smrg      arb->_ActualFormat  = GL_ALPHA8;
17567117f1b4Smrg      arb->_BaseFormat    = arb->Wrapped->_BaseFormat;
17577117f1b4Smrg      arb->DataType       = arb->Wrapped->DataType;
17587117f1b4Smrg      arb->AllocStorage   = alloc_storage_alpha8;
17597117f1b4Smrg      arb->Delete         = delete_renderbuffer_alpha8;
17607117f1b4Smrg      arb->GetPointer     = get_pointer_alpha8;
17617117f1b4Smrg      arb->GetRow         = get_row_alpha8;
17627117f1b4Smrg      arb->GetValues      = get_values_alpha8;
17637117f1b4Smrg      arb->PutRow         = put_row_alpha8;
17647117f1b4Smrg      arb->PutRowRGB      = put_row_rgb_alpha8;
17657117f1b4Smrg      arb->PutMonoRow     = put_mono_row_alpha8;
17667117f1b4Smrg      arb->PutValues      = put_values_alpha8;
17677117f1b4Smrg      arb->PutMonoValues  = put_mono_values_alpha8;
17687117f1b4Smrg
17697117f1b4Smrg      /* clear the pointer to avoid assertion/sanity check failure later */
17707117f1b4Smrg      fb->Attachment[b].Renderbuffer = NULL;
17717117f1b4Smrg
17727117f1b4Smrg      /* plug the alpha renderbuffer into the colorbuffer attachment */
17737117f1b4Smrg      _mesa_add_renderbuffer(fb, b, arb);
17747117f1b4Smrg   }
17757117f1b4Smrg
17767117f1b4Smrg   return GL_TRUE;
17777117f1b4Smrg}
17787117f1b4Smrg
17797117f1b4Smrg
17807117f1b4Smrg/**
17817117f1b4Smrg * For framebuffers that use a software alpha channel wrapper
17827117f1b4Smrg * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
17837117f1b4Smrg * copy the back buffer alpha channel into the front buffer alpha channel.
17847117f1b4Smrg */
17857117f1b4Smrgvoid
17867117f1b4Smrg_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb)
17877117f1b4Smrg{
17887117f1b4Smrg   if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
17897117f1b4Smrg       fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer)
17907117f1b4Smrg      copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer,
17917117f1b4Smrg                         fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
17927117f1b4Smrg
17937117f1b4Smrg
17947117f1b4Smrg   if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
17957117f1b4Smrg       fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer)
17967117f1b4Smrg      copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer,
17977117f1b4Smrg                         fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
17987117f1b4Smrg}
17997117f1b4Smrg
18007117f1b4Smrg
18017117f1b4Smrg/**
18027117f1b4Smrg * Add a software-based depth renderbuffer to the given framebuffer.
18037117f1b4Smrg * This is a helper routine for device drivers when creating a
18047117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
18057117f1b4Smrg * Once this function is called, you can basically forget about this
18067117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
18077117f1b4Smrg * rendering!
18087117f1b4Smrg */
18097117f1b4SmrgGLboolean
18107117f1b4Smrg_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
18117117f1b4Smrg                             GLuint depthBits)
18127117f1b4Smrg{
18137117f1b4Smrg   struct gl_renderbuffer *rb;
18147117f1b4Smrg
18157117f1b4Smrg   if (depthBits > 32) {
18167117f1b4Smrg      _mesa_problem(ctx,
18177117f1b4Smrg                    "Unsupported depthBits in _mesa_add_depth_renderbuffer");
18187117f1b4Smrg      return GL_FALSE;
18197117f1b4Smrg   }
18207117f1b4Smrg
18217117f1b4Smrg   assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
18227117f1b4Smrg
18237117f1b4Smrg   rb = _mesa_new_renderbuffer(ctx, 0);
18247117f1b4Smrg   if (!rb) {
18257117f1b4Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
18267117f1b4Smrg      return GL_FALSE;
18277117f1b4Smrg   }
18287117f1b4Smrg
18297117f1b4Smrg   if (depthBits <= 16) {
18307117f1b4Smrg      rb->_ActualFormat = GL_DEPTH_COMPONENT16;
18317117f1b4Smrg   }
18327117f1b4Smrg   else if (depthBits <= 24) {
18337117f1b4Smrg      rb->_ActualFormat = GL_DEPTH_COMPONENT24;
18347117f1b4Smrg   }
18357117f1b4Smrg   else {
18367117f1b4Smrg      rb->_ActualFormat = GL_DEPTH_COMPONENT32;
18377117f1b4Smrg   }
18387117f1b4Smrg   rb->InternalFormat = rb->_ActualFormat;
18397117f1b4Smrg
18407117f1b4Smrg   rb->AllocStorage = _mesa_soft_renderbuffer_storage;
18417117f1b4Smrg   _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
18427117f1b4Smrg
18437117f1b4Smrg   return GL_TRUE;
18447117f1b4Smrg}
18457117f1b4Smrg
18467117f1b4Smrg
18477117f1b4Smrg/**
18487117f1b4Smrg * Add a software-based stencil renderbuffer to the given framebuffer.
18497117f1b4Smrg * This is a helper routine for device drivers when creating a
18507117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
18517117f1b4Smrg * Once this function is called, you can basically forget about this
18527117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
18537117f1b4Smrg * rendering!
18547117f1b4Smrg */
18557117f1b4SmrgGLboolean
18567117f1b4Smrg_mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
18577117f1b4Smrg                               GLuint stencilBits)
18587117f1b4Smrg{
18597117f1b4Smrg   struct gl_renderbuffer *rb;
18607117f1b4Smrg
18617117f1b4Smrg   if (stencilBits > 16) {
18627117f1b4Smrg      _mesa_problem(ctx,
18637117f1b4Smrg                  "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
18647117f1b4Smrg      return GL_FALSE;
18657117f1b4Smrg   }
18667117f1b4Smrg
18677117f1b4Smrg   assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
18687117f1b4Smrg
18697117f1b4Smrg   rb = _mesa_new_renderbuffer(ctx, 0);
18707117f1b4Smrg   if (!rb) {
18717117f1b4Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
18727117f1b4Smrg      return GL_FALSE;
18737117f1b4Smrg   }
18747117f1b4Smrg
18757117f1b4Smrg   if (stencilBits <= 8) {
18767117f1b4Smrg      rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
18777117f1b4Smrg   }
18787117f1b4Smrg   else {
18797117f1b4Smrg      /* not really supported (see s_stencil.c code) */
18807117f1b4Smrg      rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
18817117f1b4Smrg   }
18827117f1b4Smrg   rb->InternalFormat = rb->_ActualFormat;
18837117f1b4Smrg
18847117f1b4Smrg   rb->AllocStorage = _mesa_soft_renderbuffer_storage;
18857117f1b4Smrg   _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
18867117f1b4Smrg
18877117f1b4Smrg   return GL_TRUE;
18887117f1b4Smrg}
18897117f1b4Smrg
18907117f1b4Smrg
18917117f1b4Smrg/**
18927117f1b4Smrg * Add a software-based accumulation renderbuffer to the given framebuffer.
18937117f1b4Smrg * This is a helper routine for device drivers when creating a
18947117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
18957117f1b4Smrg * Once this function is called, you can basically forget about this
18967117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
18977117f1b4Smrg * rendering!
18987117f1b4Smrg */
18997117f1b4SmrgGLboolean
19007117f1b4Smrg_mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
19017117f1b4Smrg                             GLuint redBits, GLuint greenBits,
19027117f1b4Smrg                             GLuint blueBits, GLuint alphaBits)
19037117f1b4Smrg{
19047117f1b4Smrg   struct gl_renderbuffer *rb;
19057117f1b4Smrg
19067117f1b4Smrg   if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
19077117f1b4Smrg      _mesa_problem(ctx,
19087117f1b4Smrg                    "Unsupported accumBits in _mesa_add_accum_renderbuffer");
19097117f1b4Smrg      return GL_FALSE;
19107117f1b4Smrg   }
19117117f1b4Smrg
19127117f1b4Smrg   assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
19137117f1b4Smrg
19147117f1b4Smrg   rb = _mesa_new_renderbuffer(ctx, 0);
19157117f1b4Smrg   if (!rb) {
19167117f1b4Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
19177117f1b4Smrg      return GL_FALSE;
19187117f1b4Smrg   }
19197117f1b4Smrg
19207117f1b4Smrg   rb->_ActualFormat = GL_RGBA16;
19217117f1b4Smrg   rb->InternalFormat = GL_RGBA16;
19227117f1b4Smrg   rb->AllocStorage = _mesa_soft_renderbuffer_storage;
19237117f1b4Smrg   _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
19247117f1b4Smrg
19257117f1b4Smrg   return GL_TRUE;
19267117f1b4Smrg}
19277117f1b4Smrg
19287117f1b4Smrg
19297117f1b4Smrg
19307117f1b4Smrg/**
19317117f1b4Smrg * Add a software-based accumulation renderbuffer to the given framebuffer.
19327117f1b4Smrg * This is a helper routine for device drivers when creating a
19337117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
19347117f1b4Smrg * Once this function is called, you can basically forget about this
19357117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
19367117f1b4Smrg * rendering!
19377117f1b4Smrg *
19387117f1b4Smrg * NOTE: color-index aux buffers not supported.
19397117f1b4Smrg */
19407117f1b4SmrgGLboolean
19417117f1b4Smrg_mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
19427117f1b4Smrg                            GLuint colorBits, GLuint numBuffers)
19437117f1b4Smrg{
19447117f1b4Smrg   GLuint i;
19457117f1b4Smrg
19467117f1b4Smrg   if (colorBits > 16) {
19477117f1b4Smrg      _mesa_problem(ctx,
19487117f1b4Smrg                    "Unsupported accumBits in _mesa_add_aux_renderbuffers");
19497117f1b4Smrg      return GL_FALSE;
19507117f1b4Smrg   }
19517117f1b4Smrg
19527117f1b4Smrg   assert(numBuffers < MAX_AUX_BUFFERS);
19537117f1b4Smrg
19547117f1b4Smrg   for (i = 0; i < numBuffers; i++) {
19557117f1b4Smrg      struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
19567117f1b4Smrg
19577117f1b4Smrg      assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
19587117f1b4Smrg
19597117f1b4Smrg      if (!rb) {
19607117f1b4Smrg         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
19617117f1b4Smrg         return GL_FALSE;
19627117f1b4Smrg      }
19637117f1b4Smrg
19647117f1b4Smrg      if (colorBits <= 8) {
19657117f1b4Smrg         rb->_ActualFormat = GL_RGBA8;
19667117f1b4Smrg      }
19677117f1b4Smrg      else {
19687117f1b4Smrg         rb->_ActualFormat = GL_RGBA16;
19697117f1b4Smrg      }
19707117f1b4Smrg      rb->InternalFormat = rb->_ActualFormat;
19717117f1b4Smrg
19727117f1b4Smrg      rb->AllocStorage = _mesa_soft_renderbuffer_storage;
19737117f1b4Smrg      _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
19747117f1b4Smrg   }
19757117f1b4Smrg   return GL_TRUE;
19767117f1b4Smrg}
19777117f1b4Smrg
19787117f1b4Smrg
19797117f1b4Smrg/**
19807117f1b4Smrg * Create/attach software-based renderbuffers to the given framebuffer.
19817117f1b4Smrg * This is a helper routine for device drivers.  Drivers can just as well
19827117f1b4Smrg * call the individual _mesa_add_*_renderbuffer() routines directly.
19837117f1b4Smrg */
19847117f1b4Smrgvoid
19857117f1b4Smrg_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
19867117f1b4Smrg                             GLboolean color,
19877117f1b4Smrg                             GLboolean depth,
19887117f1b4Smrg                             GLboolean stencil,
19897117f1b4Smrg                             GLboolean accum,
19907117f1b4Smrg                             GLboolean alpha,
19917117f1b4Smrg                             GLboolean aux)
19927117f1b4Smrg{
19937117f1b4Smrg   GLboolean frontLeft = GL_TRUE;
19947117f1b4Smrg   GLboolean backLeft = fb->Visual.doubleBufferMode;
19957117f1b4Smrg   GLboolean frontRight = fb->Visual.stereoMode;
19967117f1b4Smrg   GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
19977117f1b4Smrg
19987117f1b4Smrg   if (color) {
19997117f1b4Smrg      if (fb->Visual.rgbMode) {
20007117f1b4Smrg         assert(fb->Visual.redBits == fb->Visual.greenBits);
20017117f1b4Smrg         assert(fb->Visual.redBits == fb->Visual.blueBits);
20027117f1b4Smrg         _mesa_add_color_renderbuffers(NULL, fb,
20037117f1b4Smrg                                       fb->Visual.redBits,
20047117f1b4Smrg                                       fb->Visual.alphaBits,
20057117f1b4Smrg                                       frontLeft, backLeft,
20067117f1b4Smrg                                       frontRight, backRight);
20077117f1b4Smrg      }
20087117f1b4Smrg      else {
20097117f1b4Smrg         _mesa_add_color_index_renderbuffers(NULL, fb,
20107117f1b4Smrg                                             fb->Visual.indexBits,
20117117f1b4Smrg                                             frontLeft, backLeft,
20127117f1b4Smrg                                             frontRight, backRight);
20137117f1b4Smrg      }
20147117f1b4Smrg   }
20157117f1b4Smrg
20167117f1b4Smrg   if (depth) {
20177117f1b4Smrg      assert(fb->Visual.depthBits > 0);
20187117f1b4Smrg      _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
20197117f1b4Smrg   }
20207117f1b4Smrg
20217117f1b4Smrg   if (stencil) {
20227117f1b4Smrg      assert(fb->Visual.stencilBits > 0);
20237117f1b4Smrg      _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
20247117f1b4Smrg   }
20257117f1b4Smrg
20267117f1b4Smrg   if (accum) {
20277117f1b4Smrg      assert(fb->Visual.rgbMode);
20287117f1b4Smrg      assert(fb->Visual.accumRedBits > 0);
20297117f1b4Smrg      assert(fb->Visual.accumGreenBits > 0);
20307117f1b4Smrg      assert(fb->Visual.accumBlueBits > 0);
20317117f1b4Smrg      _mesa_add_accum_renderbuffer(NULL, fb,
20327117f1b4Smrg                                   fb->Visual.accumRedBits,
20337117f1b4Smrg                                   fb->Visual.accumGreenBits,
20347117f1b4Smrg                                   fb->Visual.accumBlueBits,
20357117f1b4Smrg                                   fb->Visual.accumAlphaBits);
20367117f1b4Smrg   }
20377117f1b4Smrg
20387117f1b4Smrg   if (aux) {
20397117f1b4Smrg      assert(fb->Visual.rgbMode);
20407117f1b4Smrg      assert(fb->Visual.numAuxBuffers > 0);
20417117f1b4Smrg      _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
20427117f1b4Smrg                                  fb->Visual.numAuxBuffers);
20437117f1b4Smrg   }
20447117f1b4Smrg
20457117f1b4Smrg   if (alpha) {
20467117f1b4Smrg      assert(fb->Visual.rgbMode);
20477117f1b4Smrg      assert(fb->Visual.alphaBits > 0);
20487117f1b4Smrg      _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits,
20497117f1b4Smrg                                    frontLeft, backLeft,
20507117f1b4Smrg                                    frontRight, backRight);
20517117f1b4Smrg   }
20527117f1b4Smrg
20537117f1b4Smrg#if 0
20547117f1b4Smrg   if (multisample) {
20557117f1b4Smrg      /* maybe someday */
20567117f1b4Smrg   }
20577117f1b4Smrg#endif
20587117f1b4Smrg}
20597117f1b4Smrg
20607117f1b4Smrg
20617117f1b4Smrg/**
20627117f1b4Smrg * Attach a renderbuffer to a framebuffer.
20637117f1b4Smrg */
20647117f1b4Smrgvoid
20657117f1b4Smrg_mesa_add_renderbuffer(struct gl_framebuffer *fb,
20667117f1b4Smrg                       GLuint bufferName, struct gl_renderbuffer *rb)
20677117f1b4Smrg{
20687117f1b4Smrg   assert(fb);
20697117f1b4Smrg   assert(rb);
20707117f1b4Smrg   assert(bufferName < BUFFER_COUNT);
20717117f1b4Smrg
20727117f1b4Smrg   /* There should be no previous renderbuffer on this attachment point,
20737117f1b4Smrg    * with the exception of depth/stencil since the same renderbuffer may
20747117f1b4Smrg    * be used for both.
20757117f1b4Smrg    */
20767117f1b4Smrg   assert(bufferName == BUFFER_DEPTH ||
20777117f1b4Smrg          bufferName == BUFFER_STENCIL ||
20787117f1b4Smrg          fb->Attachment[bufferName].Renderbuffer == NULL);
20797117f1b4Smrg
20807117f1b4Smrg   /* winsys vs. user-created buffer cross check */
20817117f1b4Smrg   if (fb->Name) {
20827117f1b4Smrg      assert(rb->Name);
20837117f1b4Smrg   }
20847117f1b4Smrg   else {
20857117f1b4Smrg      assert(!rb->Name);
20867117f1b4Smrg   }
20877117f1b4Smrg
20887117f1b4Smrg   /* If Mesa's compiled with deep color channels (16 or 32 bits / channel)
20897117f1b4Smrg    * and the device driver is expecting 8-bit values (GLubyte), we can
20907117f1b4Smrg    * use a "renderbuffer adaptor/wrapper" to do the necessary conversions.
20917117f1b4Smrg    */
20927117f1b4Smrg   if (rb->_BaseFormat == GL_RGBA) {
20937117f1b4Smrg      if (CHAN_BITS == 16 && rb->DataType == GL_UNSIGNED_BYTE) {
20947117f1b4Smrg         GET_CURRENT_CONTEXT(ctx);
20957117f1b4Smrg         rb = _mesa_new_renderbuffer_16wrap8(ctx, rb);
20967117f1b4Smrg      }
20977117f1b4Smrg      else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_BYTE) {
20987117f1b4Smrg         GET_CURRENT_CONTEXT(ctx);
20997117f1b4Smrg         rb = _mesa_new_renderbuffer_32wrap8(ctx, rb);
21007117f1b4Smrg      }
21017117f1b4Smrg      else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_SHORT) {
21027117f1b4Smrg         GET_CURRENT_CONTEXT(ctx);
21037117f1b4Smrg         rb = _mesa_new_renderbuffer_32wrap16(ctx, rb);
21047117f1b4Smrg      }
21057117f1b4Smrg   }
21067117f1b4Smrg
21077117f1b4Smrg   fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
21087117f1b4Smrg   fb->Attachment[bufferName].Complete = GL_TRUE;
21097117f1b4Smrg   _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
21107117f1b4Smrg}
21117117f1b4Smrg
21127117f1b4Smrg
21137117f1b4Smrg/**
21147117f1b4Smrg * Remove the named renderbuffer from the given framebuffer.
21157117f1b4Smrg */
21167117f1b4Smrgvoid
21177117f1b4Smrg_mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName)
21187117f1b4Smrg{
21197117f1b4Smrg   struct gl_renderbuffer *rb;
21207117f1b4Smrg
21217117f1b4Smrg   assert(bufferName < BUFFER_COUNT);
21227117f1b4Smrg
21237117f1b4Smrg   rb = fb->Attachment[bufferName].Renderbuffer;
21247117f1b4Smrg   if (!rb)
21257117f1b4Smrg      return;
21267117f1b4Smrg
21277117f1b4Smrg   _mesa_reference_renderbuffer(&rb, NULL);
21287117f1b4Smrg
21297117f1b4Smrg   fb->Attachment[bufferName].Renderbuffer = NULL;
21307117f1b4Smrg}
21317117f1b4Smrg
21327117f1b4Smrg
21337117f1b4Smrg/**
21347117f1b4Smrg * Set *ptr to point to rb.  If *ptr points to another renderbuffer,
21357117f1b4Smrg * dereference that buffer first.  The new renderbuffer's refcount will
21367117f1b4Smrg * be incremented.  The old renderbuffer's refcount will be decremented.
21377117f1b4Smrg */
21387117f1b4Smrgvoid
21397117f1b4Smrg_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
21407117f1b4Smrg                             struct gl_renderbuffer *rb)
21417117f1b4Smrg{
21427117f1b4Smrg   assert(ptr);
21437117f1b4Smrg   if (*ptr == rb) {
21447117f1b4Smrg      /* no change */
21457117f1b4Smrg      return;
21467117f1b4Smrg   }
21477117f1b4Smrg
21487117f1b4Smrg   if (*ptr) {
21497117f1b4Smrg      /* Unreference the old renderbuffer */
21507117f1b4Smrg      GLboolean deleteFlag = GL_FALSE;
21517117f1b4Smrg      struct gl_renderbuffer *oldRb = *ptr;
21527117f1b4Smrg
21537117f1b4Smrg      assert(oldRb->Magic == RB_MAGIC);
21547117f1b4Smrg      _glthread_LOCK_MUTEX(oldRb->Mutex);
21557117f1b4Smrg      assert(oldRb->Magic == RB_MAGIC);
21567117f1b4Smrg      ASSERT(oldRb->RefCount > 0);
21577117f1b4Smrg      oldRb->RefCount--;
21587117f1b4Smrg      /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
21597117f1b4Smrg      deleteFlag = (oldRb->RefCount == 0);
21607117f1b4Smrg      _glthread_UNLOCK_MUTEX(oldRb->Mutex);
21617117f1b4Smrg
21627117f1b4Smrg      if (deleteFlag) {
21637117f1b4Smrg         oldRb->Magic = 0; /* now invalid memory! */
21647117f1b4Smrg         oldRb->Delete(oldRb);
21657117f1b4Smrg      }
21667117f1b4Smrg
21677117f1b4Smrg      *ptr = NULL;
21687117f1b4Smrg   }
21697117f1b4Smrg   assert(!*ptr);
21707117f1b4Smrg
21717117f1b4Smrg   if (rb) {
21727117f1b4Smrg      assert(rb->Magic == RB_MAGIC);
21737117f1b4Smrg      /* reference new renderbuffer */
21747117f1b4Smrg      _glthread_LOCK_MUTEX(rb->Mutex);
21757117f1b4Smrg      rb->RefCount++;
21767117f1b4Smrg      /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
21777117f1b4Smrg      _glthread_UNLOCK_MUTEX(rb->Mutex);
21787117f1b4Smrg      *ptr = rb;
21797117f1b4Smrg   }
21807117f1b4Smrg}
21817117f1b4Smrg
21827117f1b4Smrg
21837117f1b4Smrg/**
21847117f1b4Smrg * Create a new combined depth/stencil renderbuffer for implementing
21857117f1b4Smrg * the GL_EXT_packed_depth_stencil extension.
21867117f1b4Smrg * \return new depth/stencil renderbuffer
21877117f1b4Smrg */
21887117f1b4Smrgstruct gl_renderbuffer *
21897117f1b4Smrg_mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
21907117f1b4Smrg{
21917117f1b4Smrg   struct gl_renderbuffer *dsrb;
21927117f1b4Smrg
21937117f1b4Smrg   dsrb = _mesa_new_renderbuffer(ctx, name);
21947117f1b4Smrg   if (!dsrb)
21957117f1b4Smrg      return NULL;
21967117f1b4Smrg
21977117f1b4Smrg   /* init fields not covered by _mesa_new_renderbuffer() */
21987117f1b4Smrg   dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT;
21997117f1b4Smrg   dsrb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
22007117f1b4Smrg   dsrb->AllocStorage = _mesa_soft_renderbuffer_storage;
22017117f1b4Smrg
22027117f1b4Smrg   return dsrb;
22037117f1b4Smrg}
2204