renderbuffer.c revision 3464ebd5
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"
464a49301eSmrg#include "fbobject.h"
474a49301eSmrg#include "formats.h"
487117f1b4Smrg#include "mtypes.h"
497117f1b4Smrg#include "renderbuffer.h"
507117f1b4Smrg
517117f1b4Smrg
527117f1b4Smrg/*
537117f1b4Smrg * Routines for get/put values in common buffer formats follow.
547117f1b4Smrg */
557117f1b4Smrg
563464ebd5Sriastradh/* Returns a bytes per pixel of the DataType in the get/put span
573464ebd5Sriastradh * functions for at least a subset of the available combinations a
583464ebd5Sriastradh * renderbuffer can have.
593464ebd5Sriastradh *
603464ebd5Sriastradh * It would be nice to see gl_renderbuffer start talking about a
613464ebd5Sriastradh * gl_format instead of a GLenum DataType.
627117f1b4Smrg */
633464ebd5Sriastradhstatic int
643464ebd5Sriastradhget_datatype_bytes(struct gl_renderbuffer *rb)
653464ebd5Sriastradh{
663464ebd5Sriastradh   int component_size;
677117f1b4Smrg
683464ebd5Sriastradh   switch (rb->DataType) {
693464ebd5Sriastradh   case GL_FLOAT:
703464ebd5Sriastradh   case GL_UNSIGNED_INT:
713464ebd5Sriastradh   case GL_UNSIGNED_INT_24_8_EXT:
723464ebd5Sriastradh      component_size = 4;
733464ebd5Sriastradh      break;
743464ebd5Sriastradh   case GL_UNSIGNED_SHORT:
753464ebd5Sriastradh      component_size = 2;
763464ebd5Sriastradh      break;
773464ebd5Sriastradh   case GL_UNSIGNED_BYTE:
783464ebd5Sriastradh      component_size = 1;
793464ebd5Sriastradh      break;
803464ebd5Sriastradh   default:
813464ebd5Sriastradh      component_size = 1;
823464ebd5Sriastradh      assert(0);
833464ebd5Sriastradh   }
843464ebd5Sriastradh
853464ebd5Sriastradh   switch (rb->_BaseFormat) {
863464ebd5Sriastradh   case GL_DEPTH_COMPONENT:
873464ebd5Sriastradh   case GL_DEPTH_STENCIL:
883464ebd5Sriastradh      return component_size;
893464ebd5Sriastradh   default:
903464ebd5Sriastradh      return 4 * component_size;
913464ebd5Sriastradh   }
923464ebd5Sriastradh}
933464ebd5Sriastradh
943464ebd5Sriastradh/* This is commonly used by most of the accessors. */
957117f1b4Smrgstatic void *
963464ebd5Sriastradhget_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
973464ebd5Sriastradh		    GLint x, GLint y)
987117f1b4Smrg{
997117f1b4Smrg   if (!rb->Data)
1007117f1b4Smrg      return NULL;
1013464ebd5Sriastradh
1023464ebd5Sriastradh   return ((char *) rb->Data +
1033464ebd5Sriastradh	   (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format));
1047117f1b4Smrg}
1057117f1b4Smrg
1063464ebd5Sriastradh/* GetRow() implementation for formats where DataType matches the rb->Format.
1073464ebd5Sriastradh */
1083464ebd5Sriastradhstatic void
1093464ebd5Sriastradhget_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
1103464ebd5Sriastradh		GLuint count, GLint x, GLint y, void *values)
1113464ebd5Sriastradh{
1123464ebd5Sriastradh   void *src = rb->GetPointer(ctx, rb, x, y);
1133464ebd5Sriastradh   memcpy(values, src, count * _mesa_get_format_bytes(rb->Format));
1143464ebd5Sriastradh}
1157117f1b4Smrg
1163464ebd5Sriastradh/* Only used for float textures currently, but might also be used for
1173464ebd5Sriastradh * RGBA8888, RGBA16, etc.
1183464ebd5Sriastradh */
1197117f1b4Smrgstatic void
1203464ebd5Sriastradhget_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
1213464ebd5Sriastradh		   GLuint count, const GLint x[], const GLint y[], void *values)
1227117f1b4Smrg{
1233464ebd5Sriastradh   int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
1243464ebd5Sriastradh   GLuint i;
1253464ebd5Sriastradh
1263464ebd5Sriastradh   for (i = 0; i < count; i++) {
1273464ebd5Sriastradh      const void *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1283464ebd5Sriastradh      char *dst = (char *) values + i * format_bytes;
1293464ebd5Sriastradh      memcpy(dst, src, format_bytes);
1303464ebd5Sriastradh   }
1313464ebd5Sriastradh}
1323464ebd5Sriastradh
1333464ebd5Sriastradh/* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and
1343464ebd5Sriastradh * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of
1353464ebd5Sriastradh * storing those initial components of the value per pixel into the
1363464ebd5Sriastradh * destination.
1373464ebd5Sriastradh */
1383464ebd5Sriastradhstatic void
1393464ebd5Sriastradhput_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
1403464ebd5Sriastradh		GLuint count, GLint x, GLint y,
1413464ebd5Sriastradh		const void *values, const GLubyte *mask)
1423464ebd5Sriastradh{
1433464ebd5Sriastradh   void *row = rb->GetPointer(ctx, rb, x, y);
1443464ebd5Sriastradh   int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
1453464ebd5Sriastradh   int datatype_bytes = get_datatype_bytes(rb);
1463464ebd5Sriastradh   unsigned int i;
1473464ebd5Sriastradh
1483464ebd5Sriastradh   if (mask) {
1493464ebd5Sriastradh      for (i = 0; i < count; i++) {
1503464ebd5Sriastradh	 char *dst = (char *) row + i * format_bytes;
1513464ebd5Sriastradh	 const char *src = (const char *) values + i * datatype_bytes;
1523464ebd5Sriastradh
1533464ebd5Sriastradh         if (mask[i]) {
1543464ebd5Sriastradh	    memcpy(dst, src, format_bytes);
1553464ebd5Sriastradh         }
1563464ebd5Sriastradh      }
1573464ebd5Sriastradh   }
1583464ebd5Sriastradh   else {
1593464ebd5Sriastradh      for (i = 0; i < count; i++) {
1603464ebd5Sriastradh	 char *dst = (char *) row + i * format_bytes;
1613464ebd5Sriastradh	 const char *src = (const char *) values + i * datatype_bytes;
1623464ebd5Sriastradh	 memcpy(dst, src, format_bytes);
1633464ebd5Sriastradh      }
1643464ebd5Sriastradh   }
1653464ebd5Sriastradh}
1663464ebd5Sriastradh
1673464ebd5Sriastradhstatic void
1683464ebd5Sriastradhput_mono_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
1693464ebd5Sriastradh		     GLuint count, GLint x, GLint y,
1703464ebd5Sriastradh		     const void *value, const GLubyte *mask)
1713464ebd5Sriastradh{
1723464ebd5Sriastradh   void *row = rb->GetPointer(ctx, rb, x, y);
1733464ebd5Sriastradh   int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
1743464ebd5Sriastradh   unsigned int i;
1753464ebd5Sriastradh
1763464ebd5Sriastradh   if (mask) {
1773464ebd5Sriastradh      for (i = 0; i < count; i++) {
1783464ebd5Sriastradh	 char *dst = (char *) row + i * format_bytes;
1793464ebd5Sriastradh         if (mask[i]) {
1803464ebd5Sriastradh	    memcpy(dst, value, format_bytes);
1813464ebd5Sriastradh         }
1823464ebd5Sriastradh      }
1833464ebd5Sriastradh   }
1843464ebd5Sriastradh   else {
1853464ebd5Sriastradh      for (i = 0; i < count; i++) {
1863464ebd5Sriastradh	 char *dst = (char *) row + i * format_bytes;
1873464ebd5Sriastradh	 memcpy(dst, value, format_bytes);
1883464ebd5Sriastradh      }
1893464ebd5Sriastradh   }
1907117f1b4Smrg}
1917117f1b4Smrg
1927117f1b4Smrg
1937117f1b4Smrgstatic void
1943464ebd5Sriastradhput_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
1953464ebd5Sriastradh		   GLuint count, const GLint x[], const GLint y[],
1963464ebd5Sriastradh		   const void *values, const GLubyte *mask)
1973464ebd5Sriastradh{
1983464ebd5Sriastradh   int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
1993464ebd5Sriastradh   int datatype_bytes = get_datatype_bytes(rb);
2003464ebd5Sriastradh   unsigned int i;
2013464ebd5Sriastradh
2023464ebd5Sriastradh   for (i = 0; i < count; i++) {
2033464ebd5Sriastradh      if (!mask || mask[i]) {
2043464ebd5Sriastradh	 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
2053464ebd5Sriastradh	 const char *src = (const char *) values + i * datatype_bytes;
2063464ebd5Sriastradh	 memcpy(dst, src, format_bytes);
2073464ebd5Sriastradh      }
2083464ebd5Sriastradh   }
2093464ebd5Sriastradh}
2103464ebd5Sriastradh
2113464ebd5Sriastradh
2123464ebd5Sriastradhstatic void
2133464ebd5Sriastradhput_mono_values_generic(struct gl_context *ctx,
2143464ebd5Sriastradh			struct gl_renderbuffer *rb,
2153464ebd5Sriastradh			GLuint count, const GLint x[], const GLint y[],
2163464ebd5Sriastradh			const void *value, const GLubyte *mask)
2173464ebd5Sriastradh{
2183464ebd5Sriastradh   int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
2193464ebd5Sriastradh   unsigned int i;
2203464ebd5Sriastradh
2213464ebd5Sriastradh   for (i = 0; i < count; i++) {
2223464ebd5Sriastradh      if (!mask || mask[i]) {
2233464ebd5Sriastradh	 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
2243464ebd5Sriastradh	 memcpy(dst, value, format_bytes);
2253464ebd5Sriastradh      }
2263464ebd5Sriastradh   }
2273464ebd5Sriastradh}
2283464ebd5Sriastradh
2293464ebd5Sriastradh/**********************************************************************
2303464ebd5Sriastradh * Functions for buffers of 1 X GLubyte values.
2313464ebd5Sriastradh * Typically stencil.
2323464ebd5Sriastradh */
2333464ebd5Sriastradh
2343464ebd5Sriastradhstatic void
2353464ebd5Sriastradhget_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
2367117f1b4Smrg                 const GLint x[], const GLint y[], void *values)
2377117f1b4Smrg{
2387117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
2397117f1b4Smrg   GLuint i;
2407117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
2417117f1b4Smrg   for (i = 0; i < count; i++) {
2423464ebd5Sriastradh      const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
2437117f1b4Smrg      dst[i] = *src;
2447117f1b4Smrg   }
2457117f1b4Smrg}
2467117f1b4Smrg
2477117f1b4Smrg
2487117f1b4Smrgstatic void
2493464ebd5Sriastradhput_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
2507117f1b4Smrg              GLint x, GLint y, const void *values, const GLubyte *mask)
2517117f1b4Smrg{
2527117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
2533464ebd5Sriastradh   GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x;
2547117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
2557117f1b4Smrg   if (mask) {
2567117f1b4Smrg      GLuint i;
2577117f1b4Smrg      for (i = 0; i < count; i++) {
2587117f1b4Smrg         if (mask[i]) {
2597117f1b4Smrg            dst[i] = src[i];
2607117f1b4Smrg         }
2617117f1b4Smrg      }
2627117f1b4Smrg   }
2637117f1b4Smrg   else {
264cdc920a0Smrg      memcpy(dst, values, count * sizeof(GLubyte));
2657117f1b4Smrg   }
2667117f1b4Smrg}
2677117f1b4Smrg
2687117f1b4Smrg
2697117f1b4Smrgstatic void
2703464ebd5Sriastradhput_mono_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
2717117f1b4Smrg                   GLint x, GLint y, const void *value, const GLubyte *mask)
2727117f1b4Smrg{
2737117f1b4Smrg   const GLubyte val = *((const GLubyte *) value);
2743464ebd5Sriastradh   GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x;
2757117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
2767117f1b4Smrg   if (mask) {
2777117f1b4Smrg      GLuint i;
2787117f1b4Smrg      for (i = 0; i < count; i++) {
2797117f1b4Smrg         if (mask[i]) {
2807117f1b4Smrg            dst[i] = val;
2817117f1b4Smrg         }
2827117f1b4Smrg      }
2837117f1b4Smrg   }
2847117f1b4Smrg   else {
2857117f1b4Smrg      GLuint i;
2867117f1b4Smrg      for (i = 0; i < count; i++) {
2877117f1b4Smrg         dst[i] = val;
2887117f1b4Smrg      }
2897117f1b4Smrg   }
2907117f1b4Smrg}
2917117f1b4Smrg
2927117f1b4Smrg
2937117f1b4Smrgstatic void
2943464ebd5Sriastradhput_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
2957117f1b4Smrg                 const GLint x[], const GLint y[],
2967117f1b4Smrg                 const void *values, const GLubyte *mask)
2977117f1b4Smrg{
2987117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
2997117f1b4Smrg   GLuint i;
3007117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
3017117f1b4Smrg   for (i = 0; i < count; i++) {
3027117f1b4Smrg      if (!mask || mask[i]) {
3033464ebd5Sriastradh         GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
3047117f1b4Smrg         *dst = src[i];
3057117f1b4Smrg      }
3067117f1b4Smrg   }
3077117f1b4Smrg}
3087117f1b4Smrg
3097117f1b4Smrg
3107117f1b4Smrgstatic void
3113464ebd5Sriastradhput_mono_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
3127117f1b4Smrg                      const GLint x[], const GLint y[],
3137117f1b4Smrg                      const void *value, const GLubyte *mask)
3147117f1b4Smrg{
3157117f1b4Smrg   const GLubyte val = *((const GLubyte *) value);
3167117f1b4Smrg   GLuint i;
3177117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
3187117f1b4Smrg   for (i = 0; i < count; i++) {
3197117f1b4Smrg      if (!mask || mask[i]) {
3203464ebd5Sriastradh         GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
3217117f1b4Smrg         *dst = val;
3227117f1b4Smrg      }
3237117f1b4Smrg   }
3247117f1b4Smrg}
3257117f1b4Smrg
3267117f1b4Smrg
3277117f1b4Smrg/**********************************************************************
3287117f1b4Smrg * Functions for buffers of 1 X GLushort values.
3297117f1b4Smrg * Typically depth/Z.
3307117f1b4Smrg */
3317117f1b4Smrg
3327117f1b4Smrgstatic void
3333464ebd5Sriastradhget_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
3347117f1b4Smrg                  const GLint x[], const GLint y[], void *values)
3357117f1b4Smrg{
3367117f1b4Smrg   GLushort *dst = (GLushort *) values;
3377117f1b4Smrg   GLuint i;
3387117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
3397117f1b4Smrg   for (i = 0; i < count; i++) {
3403464ebd5Sriastradh      const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
3417117f1b4Smrg      dst[i] = *src;
3427117f1b4Smrg   }
3437117f1b4Smrg}
3447117f1b4Smrg
3457117f1b4Smrg
3467117f1b4Smrgstatic void
3473464ebd5Sriastradhput_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
3487117f1b4Smrg               GLint x, GLint y, const void *values, const GLubyte *mask)
3497117f1b4Smrg{
3507117f1b4Smrg   const GLushort *src = (const GLushort *) values;
3513464ebd5Sriastradh   GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x;
3527117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
3537117f1b4Smrg   if (mask) {
3547117f1b4Smrg      GLuint i;
3557117f1b4Smrg      for (i = 0; i < count; i++) {
3567117f1b4Smrg         if (mask[i]) {
3577117f1b4Smrg            dst[i] = src[i];
3587117f1b4Smrg         }
3597117f1b4Smrg      }
3607117f1b4Smrg   }
3617117f1b4Smrg   else {
362cdc920a0Smrg      memcpy(dst, src, count * sizeof(GLushort));
3637117f1b4Smrg   }
3647117f1b4Smrg}
3657117f1b4Smrg
3667117f1b4Smrg
3677117f1b4Smrgstatic void
3683464ebd5Sriastradhput_mono_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
3697117f1b4Smrg                    GLint x, GLint y, const void *value, const GLubyte *mask)
3707117f1b4Smrg{
3717117f1b4Smrg   const GLushort val = *((const GLushort *) value);
3723464ebd5Sriastradh   GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x;
3737117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
3747117f1b4Smrg   if (mask) {
3757117f1b4Smrg      GLuint i;
3767117f1b4Smrg      for (i = 0; i < count; i++) {
3777117f1b4Smrg         if (mask[i]) {
3787117f1b4Smrg            dst[i] = val;
3797117f1b4Smrg         }
3807117f1b4Smrg      }
3817117f1b4Smrg   }
3827117f1b4Smrg   else {
3837117f1b4Smrg      GLuint i;
3847117f1b4Smrg      for (i = 0; i < count; i++) {
3857117f1b4Smrg         dst[i] = val;
3867117f1b4Smrg      }
3877117f1b4Smrg   }
3887117f1b4Smrg}
3897117f1b4Smrg
3907117f1b4Smrg
3917117f1b4Smrgstatic void
3923464ebd5Sriastradhput_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
3937117f1b4Smrg                  const GLint x[], const GLint y[], const void *values,
3947117f1b4Smrg                  const GLubyte *mask)
3957117f1b4Smrg{
3967117f1b4Smrg   const GLushort *src = (const GLushort *) values;
3977117f1b4Smrg   GLuint i;
3987117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
3997117f1b4Smrg   for (i = 0; i < count; i++) {
4007117f1b4Smrg      if (!mask || mask[i]) {
4013464ebd5Sriastradh         GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
4027117f1b4Smrg         *dst = src[i];
4037117f1b4Smrg      }
4047117f1b4Smrg   }
4057117f1b4Smrg}
4067117f1b4Smrg
4077117f1b4Smrg
4087117f1b4Smrgstatic void
4093464ebd5Sriastradhput_mono_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb,
4107117f1b4Smrg                       GLuint count, const GLint x[], const GLint y[],
4117117f1b4Smrg                       const void *value, const GLubyte *mask)
4127117f1b4Smrg{
4137117f1b4Smrg   const GLushort val = *((const GLushort *) value);
4147117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
4157117f1b4Smrg   if (mask) {
4167117f1b4Smrg      GLuint i;
4177117f1b4Smrg      for (i = 0; i < count; i++) {
4187117f1b4Smrg         if (mask[i]) {
4193464ebd5Sriastradh            GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
4207117f1b4Smrg            *dst = val;
4217117f1b4Smrg         }
4227117f1b4Smrg      }
4237117f1b4Smrg   }
4247117f1b4Smrg   else {
4257117f1b4Smrg      GLuint i;
4267117f1b4Smrg      for (i = 0; i < count; i++) {
4273464ebd5Sriastradh         GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
4287117f1b4Smrg         *dst = val;
4297117f1b4Smrg      }
4307117f1b4Smrg   }
4317117f1b4Smrg}
4327117f1b4Smrg
4337117f1b4Smrg
4347117f1b4Smrg/**********************************************************************
4357117f1b4Smrg * Functions for buffers of 1 X GLuint values.
4367117f1b4Smrg * Typically depth/Z or color index.
4377117f1b4Smrg */
4387117f1b4Smrg
4397117f1b4Smrgstatic void
4403464ebd5Sriastradhget_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
4417117f1b4Smrg                const GLint x[], const GLint y[], void *values)
4427117f1b4Smrg{
4437117f1b4Smrg   GLuint *dst = (GLuint *) values;
4447117f1b4Smrg   GLuint i;
4457117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
4467117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
4477117f1b4Smrg   for (i = 0; i < count; i++) {
4483464ebd5Sriastradh      const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
4497117f1b4Smrg      dst[i] = *src;
4507117f1b4Smrg   }
4517117f1b4Smrg}
4527117f1b4Smrg
4537117f1b4Smrg
4547117f1b4Smrgstatic void
4553464ebd5Sriastradhput_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
4567117f1b4Smrg             GLint x, GLint y, const void *values, const GLubyte *mask)
4577117f1b4Smrg{
4587117f1b4Smrg   const GLuint *src = (const GLuint *) values;
4593464ebd5Sriastradh   GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x;
4607117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
4617117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
4627117f1b4Smrg   if (mask) {
4637117f1b4Smrg      GLuint i;
4647117f1b4Smrg      for (i = 0; i < count; i++) {
4657117f1b4Smrg         if (mask[i]) {
4667117f1b4Smrg            dst[i] = src[i];
4677117f1b4Smrg         }
4687117f1b4Smrg      }
4697117f1b4Smrg   }
4707117f1b4Smrg   else {
471cdc920a0Smrg      memcpy(dst, src, count * sizeof(GLuint));
4727117f1b4Smrg   }
4737117f1b4Smrg}
4747117f1b4Smrg
4757117f1b4Smrg
4767117f1b4Smrgstatic void
4773464ebd5Sriastradhput_mono_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
4787117f1b4Smrg                  GLint x, GLint y, const void *value, const GLubyte *mask)
4797117f1b4Smrg{
4807117f1b4Smrg   const GLuint val = *((const GLuint *) value);
4813464ebd5Sriastradh   GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x;
4827117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
4837117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
4847117f1b4Smrg   if (mask) {
4857117f1b4Smrg      GLuint i;
4867117f1b4Smrg      for (i = 0; i < count; i++) {
4877117f1b4Smrg         if (mask[i]) {
4887117f1b4Smrg            dst[i] = val;
4897117f1b4Smrg         }
4907117f1b4Smrg      }
4917117f1b4Smrg   }
4927117f1b4Smrg   else {
4937117f1b4Smrg      GLuint i;
4947117f1b4Smrg      for (i = 0; i < count; i++) {
4957117f1b4Smrg         dst[i] = val;
4967117f1b4Smrg      }
4977117f1b4Smrg   }
4987117f1b4Smrg}
4997117f1b4Smrg
5007117f1b4Smrg
5017117f1b4Smrgstatic void
5023464ebd5Sriastradhput_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
5037117f1b4Smrg                const GLint x[], const GLint y[], const void *values,
5047117f1b4Smrg                const GLubyte *mask)
5057117f1b4Smrg{
5067117f1b4Smrg   const GLuint *src = (const GLuint *) values;
5077117f1b4Smrg   GLuint i;
5087117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
5097117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
5107117f1b4Smrg   for (i = 0; i < count; i++) {
5117117f1b4Smrg      if (!mask || mask[i]) {
5123464ebd5Sriastradh         GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
5137117f1b4Smrg         *dst = src[i];
5147117f1b4Smrg      }
5157117f1b4Smrg   }
5167117f1b4Smrg}
5177117f1b4Smrg
5187117f1b4Smrg
5197117f1b4Smrgstatic void
5203464ebd5Sriastradhput_mono_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
5217117f1b4Smrg                     const GLint x[], const GLint y[], const void *value,
5227117f1b4Smrg                     const GLubyte *mask)
5237117f1b4Smrg{
5247117f1b4Smrg   const GLuint val = *((const GLuint *) value);
5257117f1b4Smrg   GLuint i;
5267117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_INT ||
5277117f1b4Smrg          rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
5287117f1b4Smrg   for (i = 0; i < count; i++) {
5297117f1b4Smrg      if (!mask || mask[i]) {
5303464ebd5Sriastradh         GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
5317117f1b4Smrg         *dst = val;
5327117f1b4Smrg      }
5337117f1b4Smrg   }
5347117f1b4Smrg}
5357117f1b4Smrg
5367117f1b4Smrg
5377117f1b4Smrg/**********************************************************************
5387117f1b4Smrg * Functions for buffers of 3 X GLubyte (or GLbyte) values.
5397117f1b4Smrg * Typically color buffers.
5407117f1b4Smrg * NOTE: the incoming and outgoing colors are RGBA!  We ignore incoming
5417117f1b4Smrg * alpha values and return 255 for outgoing alpha values.
5427117f1b4Smrg */
5437117f1b4Smrg
5447117f1b4Smrgstatic void *
5453464ebd5Sriastradhget_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
5467117f1b4Smrg                   GLint x, GLint y)
5477117f1b4Smrg{
5484a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGB888);
5497117f1b4Smrg   /* No direct access since this buffer is RGB but caller will be
5507117f1b4Smrg    * treating it as if it were RGBA.
5517117f1b4Smrg    */
5527117f1b4Smrg   return NULL;
5537117f1b4Smrg}
5547117f1b4Smrg
5557117f1b4Smrg
5567117f1b4Smrgstatic void
5573464ebd5Sriastradhget_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
5587117f1b4Smrg               GLint x, GLint y, void *values)
5597117f1b4Smrg{
5603464ebd5Sriastradh   const GLubyte *src = ((const GLubyte *) rb->Data) +
5613464ebd5Sriastradh					   3 * (y * rb->RowStride + x);
5627117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
5637117f1b4Smrg   GLuint i;
5644a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGB888);
5657117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
5667117f1b4Smrg   for (i = 0; i < count; i++) {
5677117f1b4Smrg      dst[i * 4 + 0] = src[i * 3 + 0];
5687117f1b4Smrg      dst[i * 4 + 1] = src[i * 3 + 1];
5697117f1b4Smrg      dst[i * 4 + 2] = src[i * 3 + 2];
5707117f1b4Smrg      dst[i * 4 + 3] = 255;
5717117f1b4Smrg   }
5727117f1b4Smrg}
5737117f1b4Smrg
5747117f1b4Smrg
5757117f1b4Smrgstatic void
5763464ebd5Sriastradhget_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
5777117f1b4Smrg                  const GLint x[], const GLint y[], void *values)
5787117f1b4Smrg{
5797117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
5807117f1b4Smrg   GLuint i;
5814a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGB888);
5827117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
5837117f1b4Smrg   for (i = 0; i < count; i++) {
5847117f1b4Smrg      const GLubyte *src
5853464ebd5Sriastradh         = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
5867117f1b4Smrg      dst[i * 4 + 0] = src[0];
5877117f1b4Smrg      dst[i * 4 + 1] = src[1];
5887117f1b4Smrg      dst[i * 4 + 2] = src[2];
5897117f1b4Smrg      dst[i * 4 + 3] = 255;
5907117f1b4Smrg   }
5917117f1b4Smrg}
5927117f1b4Smrg
5937117f1b4Smrg
5947117f1b4Smrgstatic void
5953464ebd5Sriastradhput_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
5967117f1b4Smrg               GLint x, GLint y, const void *values, const GLubyte *mask)
5977117f1b4Smrg{
5987117f1b4Smrg   /* note: incoming values are RGB+A! */
5997117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
6003464ebd5Sriastradh   GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
6017117f1b4Smrg   GLuint i;
6024a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGB888);
6037117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6047117f1b4Smrg   for (i = 0; i < count; i++) {
6057117f1b4Smrg      if (!mask || mask[i]) {
6067117f1b4Smrg         dst[i * 3 + 0] = src[i * 4 + 0];
6077117f1b4Smrg         dst[i * 3 + 1] = src[i * 4 + 1];
6087117f1b4Smrg         dst[i * 3 + 2] = src[i * 4 + 2];
6097117f1b4Smrg      }
6107117f1b4Smrg   }
6117117f1b4Smrg}
6127117f1b4Smrg
6137117f1b4Smrg
6147117f1b4Smrgstatic void
6153464ebd5Sriastradhput_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
6167117f1b4Smrg                   GLint x, GLint y, const void *values, const GLubyte *mask)
6177117f1b4Smrg{
6187117f1b4Smrg   /* note: incoming values are RGB+A! */
6197117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
6203464ebd5Sriastradh   GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
6217117f1b4Smrg   GLuint i;
6224a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGB888);
6237117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6247117f1b4Smrg   for (i = 0; i < count; i++) {
6257117f1b4Smrg      if (!mask || mask[i]) {
6267117f1b4Smrg         dst[i * 3 + 0] = src[i * 3 + 0];
6277117f1b4Smrg         dst[i * 3 + 1] = src[i * 3 + 1];
6287117f1b4Smrg         dst[i * 3 + 2] = src[i * 3 + 2];
6297117f1b4Smrg      }
6307117f1b4Smrg   }
6317117f1b4Smrg}
6327117f1b4Smrg
6337117f1b4Smrg
6347117f1b4Smrgstatic void
6353464ebd5Sriastradhput_mono_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
6367117f1b4Smrg                    GLint x, GLint y, const void *value, const GLubyte *mask)
6377117f1b4Smrg{
6387117f1b4Smrg   /* note: incoming value is RGB+A! */
6397117f1b4Smrg   const GLubyte val0 = ((const GLubyte *) value)[0];
6407117f1b4Smrg   const GLubyte val1 = ((const GLubyte *) value)[1];
6417117f1b4Smrg   const GLubyte val2 = ((const GLubyte *) value)[2];
6423464ebd5Sriastradh   GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
6434a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGB888);
6447117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6457117f1b4Smrg   if (!mask && val0 == val1 && val1 == val2) {
6467117f1b4Smrg      /* optimized case */
647cdc920a0Smrg      memset(dst, val0, 3 * count);
6487117f1b4Smrg   }
6497117f1b4Smrg   else {
6507117f1b4Smrg      GLuint i;
6517117f1b4Smrg      for (i = 0; i < count; i++) {
6527117f1b4Smrg         if (!mask || mask[i]) {
6537117f1b4Smrg            dst[i * 3 + 0] = val0;
6547117f1b4Smrg            dst[i * 3 + 1] = val1;
6557117f1b4Smrg            dst[i * 3 + 2] = val2;
6567117f1b4Smrg         }
6577117f1b4Smrg      }
6587117f1b4Smrg   }
6597117f1b4Smrg}
6607117f1b4Smrg
6617117f1b4Smrg
6627117f1b4Smrgstatic void
6633464ebd5Sriastradhput_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
6647117f1b4Smrg                  const GLint x[], const GLint y[], const void *values,
6657117f1b4Smrg                  const GLubyte *mask)
6667117f1b4Smrg{
6677117f1b4Smrg   /* note: incoming values are RGB+A! */
6687117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
6697117f1b4Smrg   GLuint i;
6704a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGB888);
6717117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6727117f1b4Smrg   for (i = 0; i < count; i++) {
6737117f1b4Smrg      if (!mask || mask[i]) {
6743464ebd5Sriastradh         GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
6757117f1b4Smrg         dst[0] = src[i * 4 + 0];
6767117f1b4Smrg         dst[1] = src[i * 4 + 1];
6777117f1b4Smrg         dst[2] = src[i * 4 + 2];
6787117f1b4Smrg      }
6797117f1b4Smrg   }
6807117f1b4Smrg}
6817117f1b4Smrg
6827117f1b4Smrg
6837117f1b4Smrgstatic void
6843464ebd5Sriastradhput_mono_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
6857117f1b4Smrg                       GLuint count, const GLint x[], const GLint y[],
6867117f1b4Smrg                       const void *value, const GLubyte *mask)
6877117f1b4Smrg{
6887117f1b4Smrg   /* note: incoming value is RGB+A! */
6897117f1b4Smrg   const GLubyte val0 = ((const GLubyte *) value)[0];
6907117f1b4Smrg   const GLubyte val1 = ((const GLubyte *) value)[1];
6917117f1b4Smrg   const GLubyte val2 = ((const GLubyte *) value)[2];
6927117f1b4Smrg   GLuint i;
6934a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGB888);
6947117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
6957117f1b4Smrg   for (i = 0; i < count; i++) {
6967117f1b4Smrg      if (!mask || mask[i]) {
6973464ebd5Sriastradh         GLubyte *dst = ((GLubyte *) rb->Data) +
6983464ebd5Sriastradh				     3 * (y[i] * rb->RowStride + x[i]);
6997117f1b4Smrg         dst[0] = val0;
7007117f1b4Smrg         dst[1] = val1;
7017117f1b4Smrg         dst[2] = val2;
7027117f1b4Smrg      }
7037117f1b4Smrg   }
7047117f1b4Smrg}
7057117f1b4Smrg
7067117f1b4Smrg
7077117f1b4Smrg/**********************************************************************
7087117f1b4Smrg * Functions for buffers of 4 X GLubyte (or GLbyte) values.
7097117f1b4Smrg * Typically color buffers.
7107117f1b4Smrg */
7117117f1b4Smrg
7127117f1b4Smrgstatic void
7133464ebd5Sriastradhget_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
7147117f1b4Smrg                  const GLint x[], const GLint y[], void *values)
7157117f1b4Smrg{
7167117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
7177117f1b4Smrg   GLuint *dst = (GLuint *) values;
7187117f1b4Smrg   GLuint i;
7197117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
7204a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
7217117f1b4Smrg   for (i = 0; i < count; i++) {
7223464ebd5Sriastradh      const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
7237117f1b4Smrg      dst[i] = *src;
7247117f1b4Smrg   }
7257117f1b4Smrg}
7267117f1b4Smrg
7277117f1b4Smrg
7287117f1b4Smrgstatic void
7293464ebd5Sriastradhput_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
7307117f1b4Smrg               GLint x, GLint y, const void *values, const GLubyte *mask)
7317117f1b4Smrg{
7327117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
7337117f1b4Smrg   const GLuint *src = (const GLuint *) values;
7343464ebd5Sriastradh   GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x);
7357117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
7364a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
7377117f1b4Smrg   if (mask) {
7387117f1b4Smrg      GLuint i;
7397117f1b4Smrg      for (i = 0; i < count; i++) {
7407117f1b4Smrg         if (mask[i]) {
7417117f1b4Smrg            dst[i] = src[i];
7427117f1b4Smrg         }
7437117f1b4Smrg      }
7447117f1b4Smrg   }
7457117f1b4Smrg   else {
746cdc920a0Smrg      memcpy(dst, src, 4 * count * sizeof(GLubyte));
7477117f1b4Smrg   }
7487117f1b4Smrg}
7497117f1b4Smrg
7507117f1b4Smrg
7517117f1b4Smrgstatic void
7523464ebd5Sriastradhput_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
7537117f1b4Smrg                   GLint x, GLint y, const void *values, const GLubyte *mask)
7547117f1b4Smrg{
7557117f1b4Smrg   /* Store RGB values in RGBA buffer */
7567117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
7573464ebd5Sriastradh   GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->RowStride + x);
7587117f1b4Smrg   GLuint i;
7597117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
7604a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
7617117f1b4Smrg   for (i = 0; i < count; i++) {
7627117f1b4Smrg      if (!mask || mask[i]) {
7637117f1b4Smrg         dst[i * 4 + 0] = src[i * 3 + 0];
7647117f1b4Smrg         dst[i * 4 + 1] = src[i * 3 + 1];
7657117f1b4Smrg         dst[i * 4 + 2] = src[i * 3 + 2];
7667117f1b4Smrg         dst[i * 4 + 3] = 0xff;
7677117f1b4Smrg      }
7687117f1b4Smrg   }
7697117f1b4Smrg}
7707117f1b4Smrg
7717117f1b4Smrg
7727117f1b4Smrgstatic void
7733464ebd5Sriastradhput_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
7747117f1b4Smrg                    GLint x, GLint y, const void *value, const GLubyte *mask)
7757117f1b4Smrg{
7767117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
7777117f1b4Smrg   const GLuint val = *((const GLuint *) value);
7783464ebd5Sriastradh   GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x);
7797117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
7804a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
7817117f1b4Smrg   if (!mask && val == 0) {
7827117f1b4Smrg      /* common case */
783cdc920a0Smrg      memset(dst, 0, count * 4 * sizeof(GLubyte));
7847117f1b4Smrg   }
7857117f1b4Smrg   else {
7867117f1b4Smrg      /* general case */
7877117f1b4Smrg      if (mask) {
7887117f1b4Smrg         GLuint i;
7897117f1b4Smrg         for (i = 0; i < count; i++) {
7907117f1b4Smrg            if (mask[i]) {
7917117f1b4Smrg               dst[i] = val;
7927117f1b4Smrg            }
7937117f1b4Smrg         }
7947117f1b4Smrg      }
7957117f1b4Smrg      else {
7967117f1b4Smrg         GLuint i;
7977117f1b4Smrg         for (i = 0; i < count; i++) {
7987117f1b4Smrg            dst[i] = val;
7997117f1b4Smrg         }
8007117f1b4Smrg      }
8017117f1b4Smrg   }
8027117f1b4Smrg}
8037117f1b4Smrg
8047117f1b4Smrg
8057117f1b4Smrgstatic void
8063464ebd5Sriastradhput_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
8077117f1b4Smrg                  const GLint x[], const GLint y[], const void *values,
8087117f1b4Smrg                  const GLubyte *mask)
8097117f1b4Smrg{
8107117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
8117117f1b4Smrg   const GLuint *src = (const GLuint *) values;
8127117f1b4Smrg   GLuint i;
8137117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
8144a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
8157117f1b4Smrg   for (i = 0; i < count; i++) {
8167117f1b4Smrg      if (!mask || mask[i]) {
8173464ebd5Sriastradh         GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
8187117f1b4Smrg         *dst = src[i];
8197117f1b4Smrg      }
8207117f1b4Smrg   }
8217117f1b4Smrg}
8227117f1b4Smrg
8237117f1b4Smrg
8247117f1b4Smrgstatic void
8253464ebd5Sriastradhput_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb,
8267117f1b4Smrg                       GLuint count, const GLint x[], const GLint y[],
8277117f1b4Smrg                       const void *value, const GLubyte *mask)
8287117f1b4Smrg{
8297117f1b4Smrg   /* treat 4*GLubyte as 1*GLuint */
8307117f1b4Smrg   const GLuint val = *((const GLuint *) value);
8317117f1b4Smrg   GLuint i;
8327117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
8334a49301eSmrg   ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
8347117f1b4Smrg   for (i = 0; i < count; i++) {
8357117f1b4Smrg      if (!mask || mask[i]) {
8363464ebd5Sriastradh         GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
8377117f1b4Smrg         *dst = val;
8387117f1b4Smrg      }
8397117f1b4Smrg   }
8407117f1b4Smrg}
8417117f1b4Smrg
8427117f1b4Smrg
8437117f1b4Smrg/**********************************************************************
8447117f1b4Smrg * Functions for buffers of 4 X GLushort (or GLshort) values.
8457117f1b4Smrg * Typically accum buffer.
8467117f1b4Smrg */
8477117f1b4Smrg
8487117f1b4Smrgstatic void
8493464ebd5Sriastradhget_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
8507117f1b4Smrg                   const GLint x[], const GLint y[], void *values)
8517117f1b4Smrg{
8527117f1b4Smrg   GLushort *dst = (GLushort *) values;
8537117f1b4Smrg   GLuint i;
8547117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
8557117f1b4Smrg   for (i = 0; i < count; i++) {
8567117f1b4Smrg      const GLushort *src
8573464ebd5Sriastradh         = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]);
8587117f1b4Smrg      dst[i] = *src;
8597117f1b4Smrg   }
8607117f1b4Smrg}
8617117f1b4Smrg
8627117f1b4Smrg
8637117f1b4Smrgstatic void
8643464ebd5Sriastradhput_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
8657117f1b4Smrg                GLint x, GLint y, const void *values, const GLubyte *mask)
8667117f1b4Smrg{
8677117f1b4Smrg   const GLushort *src = (const GLushort *) values;
8683464ebd5Sriastradh   GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
8697117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
8707117f1b4Smrg   if (mask) {
8717117f1b4Smrg      GLuint i;
8727117f1b4Smrg      for (i = 0; i < count; i++) {
8737117f1b4Smrg         if (mask[i]) {
8747117f1b4Smrg            dst[i * 4 + 0] = src[i * 4 + 0];
8757117f1b4Smrg            dst[i * 4 + 1] = src[i * 4 + 1];
8767117f1b4Smrg            dst[i * 4 + 2] = src[i * 4 + 2];
8777117f1b4Smrg            dst[i * 4 + 3] = src[i * 4 + 3];
8787117f1b4Smrg         }
8797117f1b4Smrg      }
8807117f1b4Smrg   }
8817117f1b4Smrg   else {
882cdc920a0Smrg      memcpy(dst, src, 4 * count * sizeof(GLushort));
8837117f1b4Smrg   }
8847117f1b4Smrg}
8857117f1b4Smrg
8867117f1b4Smrg
8877117f1b4Smrgstatic void
8883464ebd5Sriastradhput_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
8897117f1b4Smrg                    GLint x, GLint y, const void *values, const GLubyte *mask)
8907117f1b4Smrg{
8917117f1b4Smrg   /* Put RGB values in RGBA buffer */
8927117f1b4Smrg   const GLushort *src = (const GLushort *) values;
8933464ebd5Sriastradh   GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
8947117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
8957117f1b4Smrg   if (mask) {
8967117f1b4Smrg      GLuint i;
8977117f1b4Smrg      for (i = 0; i < count; i++) {
8987117f1b4Smrg         if (mask[i]) {
8997117f1b4Smrg            dst[i * 4 + 0] = src[i * 3 + 0];
9007117f1b4Smrg            dst[i * 4 + 1] = src[i * 3 + 1];
9017117f1b4Smrg            dst[i * 4 + 2] = src[i * 3 + 2];
9027117f1b4Smrg            dst[i * 4 + 3] = 0xffff;
9037117f1b4Smrg         }
9047117f1b4Smrg      }
9057117f1b4Smrg   }
9067117f1b4Smrg   else {
907cdc920a0Smrg      memcpy(dst, src, 4 * count * sizeof(GLushort));
9087117f1b4Smrg   }
9097117f1b4Smrg}
9107117f1b4Smrg
9117117f1b4Smrg
9127117f1b4Smrgstatic void
9133464ebd5Sriastradhput_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
9147117f1b4Smrg                     GLint x, GLint y, const void *value, const GLubyte *mask)
9157117f1b4Smrg{
9167117f1b4Smrg   const GLushort val0 = ((const GLushort *) value)[0];
9177117f1b4Smrg   const GLushort val1 = ((const GLushort *) value)[1];
9187117f1b4Smrg   const GLushort val2 = ((const GLushort *) value)[2];
9197117f1b4Smrg   const GLushort val3 = ((const GLushort *) value)[3];
9203464ebd5Sriastradh   GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
9217117f1b4Smrg   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
9227117f1b4Smrg   if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) {
9237117f1b4Smrg      /* common case for clearing accum buffer */
924cdc920a0Smrg      memset(dst, 0, count * 4 * sizeof(GLushort));
9257117f1b4Smrg   }
9267117f1b4Smrg   else {
9277117f1b4Smrg      GLuint i;
9287117f1b4Smrg      for (i = 0; i < count; i++) {
9297117f1b4Smrg         if (!mask || mask[i]) {
9307117f1b4Smrg            dst[i * 4 + 0] = val0;
9317117f1b4Smrg            dst[i * 4 + 1] = val1;
9327117f1b4Smrg            dst[i * 4 + 2] = val2;
9337117f1b4Smrg            dst[i * 4 + 3] = val3;
9347117f1b4Smrg         }
9357117f1b4Smrg      }
9367117f1b4Smrg   }
9377117f1b4Smrg}
9387117f1b4Smrg
9393464ebd5Sriastradh
9403464ebd5Sriastradhstatic void
9413464ebd5Sriastradhput_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
9423464ebd5Sriastradh                   const GLint x[], const GLint y[], const void *values,
9433464ebd5Sriastradh                   const GLubyte *mask)
9443464ebd5Sriastradh{
9453464ebd5Sriastradh   const GLushort *src = (const GLushort *) values;
9463464ebd5Sriastradh   GLuint i;
9473464ebd5Sriastradh   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
9483464ebd5Sriastradh   for (i = 0; i < count; i++) {
9493464ebd5Sriastradh      if (!mask || mask[i]) {
9503464ebd5Sriastradh         GLushort *dst =
9513464ebd5Sriastradh            ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]);
9523464ebd5Sriastradh         dst[0] = src[i * 4 + 0];
9533464ebd5Sriastradh         dst[1] = src[i * 4 + 1];
9543464ebd5Sriastradh         dst[2] = src[i * 4 + 2];
9553464ebd5Sriastradh         dst[3] = src[i * 4 + 3];
9563464ebd5Sriastradh      }
9573464ebd5Sriastradh   }
9583464ebd5Sriastradh}
9593464ebd5Sriastradh
9603464ebd5Sriastradh
9613464ebd5Sriastradhstatic void
9623464ebd5Sriastradhput_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb,
9633464ebd5Sriastradh                        GLuint count, const GLint x[], const GLint y[],
9643464ebd5Sriastradh                        const void *value, const GLubyte *mask)
9653464ebd5Sriastradh{
9663464ebd5Sriastradh   const GLushort val0 = ((const GLushort *) value)[0];
9673464ebd5Sriastradh   const GLushort val1 = ((const GLushort *) value)[1];
9683464ebd5Sriastradh   const GLushort val2 = ((const GLushort *) value)[2];
9693464ebd5Sriastradh   const GLushort val3 = ((const GLushort *) value)[3];
9703464ebd5Sriastradh   GLuint i;
9713464ebd5Sriastradh   ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
9723464ebd5Sriastradh   for (i = 0; i < count; i++) {
9733464ebd5Sriastradh      if (!mask || mask[i]) {
9743464ebd5Sriastradh         GLushort *dst = ((GLushort *) rb->Data) +
9753464ebd5Sriastradh				       4 * (y[i] * rb->RowStride + x[i]);
9763464ebd5Sriastradh         dst[0] = val0;
9773464ebd5Sriastradh         dst[1] = val1;
9783464ebd5Sriastradh         dst[2] = val2;
9793464ebd5Sriastradh         dst[3] = val3;
9803464ebd5Sriastradh      }
9813464ebd5Sriastradh   }
9823464ebd5Sriastradh}
9833464ebd5Sriastradh
9843464ebd5Sriastradh/**********************************************************************
9853464ebd5Sriastradh * Functions for MESA_FORMAT_R8.
9863464ebd5Sriastradh */
9873464ebd5Sriastradhstatic void
9883464ebd5Sriastradhget_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
9893464ebd5Sriastradh	   GLint x, GLint y, void *values)
9903464ebd5Sriastradh{
9913464ebd5Sriastradh   const GLubyte *src = rb->GetPointer(ctx, rb, x, y);
9923464ebd5Sriastradh   GLuint *dst = values;
9933464ebd5Sriastradh   GLuint i;
9943464ebd5Sriastradh
9953464ebd5Sriastradh   for (i = 0; i < count; i++) {
9963464ebd5Sriastradh      dst[i] = 0xff000000 | src[i];
9973464ebd5Sriastradh   }
9983464ebd5Sriastradh}
9993464ebd5Sriastradh
10003464ebd5Sriastradhstatic void
10013464ebd5Sriastradhget_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
10023464ebd5Sriastradh	      const GLint x[], const GLint y[], void *values)
10033464ebd5Sriastradh{
10043464ebd5Sriastradh   GLuint *dst = (GLuint *) values;
10053464ebd5Sriastradh   GLuint i;
10063464ebd5Sriastradh
10073464ebd5Sriastradh   for (i = 0; i < count; i++) {
10083464ebd5Sriastradh      const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]);
10093464ebd5Sriastradh      dst[i] = 0xff000000 | *src;
10103464ebd5Sriastradh   }
10113464ebd5Sriastradh}
10123464ebd5Sriastradh
10133464ebd5Sriastradh/**********************************************************************
10143464ebd5Sriastradh * Functions for MESA_FORMAT_RG88.
10153464ebd5Sriastradh */
10163464ebd5Sriastradhstatic void
10173464ebd5Sriastradhget_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
10183464ebd5Sriastradh	     GLint x, GLint y, void *values)
10193464ebd5Sriastradh{
10203464ebd5Sriastradh   const GLushort *src = rb->GetPointer(ctx, rb, x, y);
10213464ebd5Sriastradh   GLuint *dst = values;
10223464ebd5Sriastradh   GLuint i;
10233464ebd5Sriastradh
10243464ebd5Sriastradh   for (i = 0; i < count; i++) {
10253464ebd5Sriastradh      dst[i] = 0xff000000 | src[i];
10263464ebd5Sriastradh   }
10273464ebd5Sriastradh}
10283464ebd5Sriastradh
10293464ebd5Sriastradhstatic void
10303464ebd5Sriastradhget_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb,
10313464ebd5Sriastradh		GLuint count, const GLint x[], const GLint y[], void *values)
10323464ebd5Sriastradh{
10333464ebd5Sriastradh   GLuint *dst = (GLuint *) values;
10343464ebd5Sriastradh   GLuint i;
10353464ebd5Sriastradh
10363464ebd5Sriastradh   for (i = 0; i < count; i++) {
10373464ebd5Sriastradh      const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
10383464ebd5Sriastradh      dst[i] = 0xff000000 | *src;
10393464ebd5Sriastradh   }
10403464ebd5Sriastradh}
10413464ebd5Sriastradh
10423464ebd5Sriastradh/**********************************************************************
10433464ebd5Sriastradh * Functions for MESA_FORMAT_R16.
10443464ebd5Sriastradh */
10453464ebd5Sriastradhstatic void
10463464ebd5Sriastradhget_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
10473464ebd5Sriastradh	    GLint x, GLint y, void *values)
10483464ebd5Sriastradh{
10493464ebd5Sriastradh   const GLushort *src = rb->GetPointer(ctx, rb, x, y);
10503464ebd5Sriastradh   GLushort *dst = values;
10513464ebd5Sriastradh   GLuint i;
10523464ebd5Sriastradh
10533464ebd5Sriastradh   for (i = 0; i < count; i++) {
10543464ebd5Sriastradh      dst[i * 4 + RCOMP] = src[i];
10553464ebd5Sriastradh      dst[i * 4 + GCOMP] = 0;
10563464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0;
10573464ebd5Sriastradh      dst[i * 4 + ACOMP] = 0xffff;
10583464ebd5Sriastradh   }
10593464ebd5Sriastradh}
10603464ebd5Sriastradh
10613464ebd5Sriastradhstatic void
10623464ebd5Sriastradhget_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
10633464ebd5Sriastradh	       const GLint x[], const GLint y[], void *values)
10643464ebd5Sriastradh{
10653464ebd5Sriastradh   GLushort *dst = values;
10663464ebd5Sriastradh   GLuint i;
10673464ebd5Sriastradh
10683464ebd5Sriastradh   for (i = 0; i < count; i++) {
10693464ebd5Sriastradh      const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
10703464ebd5Sriastradh      dst[i * 4 + RCOMP] = *src;
10713464ebd5Sriastradh      dst[i * 4 + GCOMP] = 0;
10723464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0;
10733464ebd5Sriastradh      dst[i * 4 + ACOMP] = 0xffff;
10743464ebd5Sriastradh   }
10753464ebd5Sriastradh}
10763464ebd5Sriastradh
10773464ebd5Sriastradh/**********************************************************************
10783464ebd5Sriastradh * Functions for MESA_FORMAT_RG1616.
10793464ebd5Sriastradh */
10803464ebd5Sriastradhstatic void
10813464ebd5Sriastradhget_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
10823464ebd5Sriastradh	       GLint x, GLint y, void *values)
10833464ebd5Sriastradh{
10843464ebd5Sriastradh   const GLushort *src = rb->GetPointer(ctx, rb, x, y);
10853464ebd5Sriastradh   GLushort *dst = values;
10863464ebd5Sriastradh   GLuint i;
10873464ebd5Sriastradh
10883464ebd5Sriastradh   for (i = 0; i < count; i++) {
10893464ebd5Sriastradh      dst[i * 4 + RCOMP] = src[i * 2];
10903464ebd5Sriastradh      dst[i * 4 + GCOMP] = src[i * 2 + 1];
10913464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0;
10923464ebd5Sriastradh      dst[i * 4 + ACOMP] = 0xffff;
10933464ebd5Sriastradh   }
10943464ebd5Sriastradh}
10953464ebd5Sriastradh
10963464ebd5Sriastradhstatic void
10973464ebd5Sriastradhget_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb,
10983464ebd5Sriastradh		  GLuint count, const GLint x[], const GLint y[], void *values)
10993464ebd5Sriastradh{
11003464ebd5Sriastradh   GLushort *dst = values;
11013464ebd5Sriastradh   GLuint i;
11023464ebd5Sriastradh
11033464ebd5Sriastradh   for (i = 0; i < count; i++) {
11043464ebd5Sriastradh      const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
11053464ebd5Sriastradh      dst[i * 4 + RCOMP] = src[0];
11063464ebd5Sriastradh      dst[i * 4 + GCOMP] = src[1];
11073464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0;
11083464ebd5Sriastradh      dst[i * 4 + ACOMP] = 0xffff;
11093464ebd5Sriastradh   }
11103464ebd5Sriastradh}
11113464ebd5Sriastradh
11123464ebd5Sriastradh/**********************************************************************
11133464ebd5Sriastradh * Functions for MESA_FORMAT_INTENSITY_FLOAT32.
11143464ebd5Sriastradh */
11153464ebd5Sriastradhstatic void
11163464ebd5Sriastradhget_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
11173464ebd5Sriastradh		  GLuint count, GLint x, GLint y, void *values)
11183464ebd5Sriastradh{
11193464ebd5Sriastradh   const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
11203464ebd5Sriastradh   GLfloat *dst = values;
11213464ebd5Sriastradh   GLuint i;
11223464ebd5Sriastradh
11233464ebd5Sriastradh   for (i = 0; i < count; i++) {
11243464ebd5Sriastradh      dst[i * 4 + RCOMP] =
11253464ebd5Sriastradh      dst[i * 4 + GCOMP] =
11263464ebd5Sriastradh      dst[i * 4 + BCOMP] =
11273464ebd5Sriastradh      dst[i * 4 + ACOMP] = src[i];
11283464ebd5Sriastradh   }
11293464ebd5Sriastradh}
11303464ebd5Sriastradh
11313464ebd5Sriastradhstatic void
11323464ebd5Sriastradhget_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
11333464ebd5Sriastradh		     GLuint count, const GLint x[], const GLint y[],
11343464ebd5Sriastradh		     void *values)
11353464ebd5Sriastradh{
11363464ebd5Sriastradh   GLfloat *dst = values;
11373464ebd5Sriastradh   GLuint i;
11383464ebd5Sriastradh
11393464ebd5Sriastradh   for (i = 0; i < count; i++) {
11403464ebd5Sriastradh      const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
11413464ebd5Sriastradh      dst[i * 4 + RCOMP] =
11423464ebd5Sriastradh      dst[i * 4 + GCOMP] =
11433464ebd5Sriastradh      dst[i * 4 + BCOMP] =
11443464ebd5Sriastradh      dst[i * 4 + ACOMP] = src[0];
11453464ebd5Sriastradh   }
11463464ebd5Sriastradh}
11473464ebd5Sriastradh
11483464ebd5Sriastradh/**********************************************************************
11493464ebd5Sriastradh * Functions for MESA_FORMAT_LUMINANCE_FLOAT32.
11503464ebd5Sriastradh */
11513464ebd5Sriastradhstatic void
11523464ebd5Sriastradhget_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
11533464ebd5Sriastradh		  GLuint count, GLint x, GLint y, void *values)
11543464ebd5Sriastradh{
11553464ebd5Sriastradh   const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
11563464ebd5Sriastradh   GLfloat *dst = values;
11573464ebd5Sriastradh   GLuint i;
11583464ebd5Sriastradh
11593464ebd5Sriastradh   for (i = 0; i < count; i++) {
11603464ebd5Sriastradh      dst[i * 4 + RCOMP] =
11613464ebd5Sriastradh      dst[i * 4 + GCOMP] =
11623464ebd5Sriastradh      dst[i * 4 + BCOMP] = src[i];
11633464ebd5Sriastradh      dst[i * 4 + ACOMP] = 1.0;
11643464ebd5Sriastradh   }
11653464ebd5Sriastradh}
11663464ebd5Sriastradh
11673464ebd5Sriastradhstatic void
11683464ebd5Sriastradhget_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
11693464ebd5Sriastradh		     GLuint count, const GLint x[], const GLint y[],
11703464ebd5Sriastradh		     void *values)
11713464ebd5Sriastradh{
11723464ebd5Sriastradh   GLfloat *dst = values;
11733464ebd5Sriastradh   GLuint i;
11743464ebd5Sriastradh
11753464ebd5Sriastradh   for (i = 0; i < count; i++) {
11763464ebd5Sriastradh      const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
11773464ebd5Sriastradh      dst[i * 4 + RCOMP] =
11783464ebd5Sriastradh      dst[i * 4 + GCOMP] =
11793464ebd5Sriastradh      dst[i * 4 + BCOMP] = src[0];
11803464ebd5Sriastradh      dst[i * 4 + ACOMP] = 1.0;
11813464ebd5Sriastradh   }
11823464ebd5Sriastradh}
11833464ebd5Sriastradh
11843464ebd5Sriastradh/**********************************************************************
11853464ebd5Sriastradh * Functions for MESA_FORMAT_ALPHA_FLOAT32.
11863464ebd5Sriastradh */
11873464ebd5Sriastradhstatic void
11883464ebd5Sriastradhget_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
11893464ebd5Sriastradh		  GLuint count, GLint x, GLint y, void *values)
11903464ebd5Sriastradh{
11913464ebd5Sriastradh   const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
11923464ebd5Sriastradh   GLfloat *dst = values;
11933464ebd5Sriastradh   GLuint i;
11943464ebd5Sriastradh
11953464ebd5Sriastradh   for (i = 0; i < count; i++) {
11963464ebd5Sriastradh      dst[i * 4 + RCOMP] = 0.0;
11973464ebd5Sriastradh      dst[i * 4 + GCOMP] = 0.0;
11983464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0.0;
11993464ebd5Sriastradh      dst[i * 4 + ACOMP] = src[i];
12003464ebd5Sriastradh   }
12013464ebd5Sriastradh}
12023464ebd5Sriastradh
12033464ebd5Sriastradhstatic void
12043464ebd5Sriastradhget_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
12053464ebd5Sriastradh		     GLuint count, const GLint x[], const GLint y[],
12063464ebd5Sriastradh		     void *values)
12073464ebd5Sriastradh{
12083464ebd5Sriastradh   GLfloat *dst = values;
12093464ebd5Sriastradh   GLuint i;
12103464ebd5Sriastradh
12113464ebd5Sriastradh   for (i = 0; i < count; i++) {
12123464ebd5Sriastradh      const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
12133464ebd5Sriastradh      dst[i * 4 + RCOMP] = 0.0;
12143464ebd5Sriastradh      dst[i * 4 + GCOMP] = 0.0;
12153464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0.0;
12163464ebd5Sriastradh      dst[i * 4 + ACOMP] = src[0];
12173464ebd5Sriastradh   }
12183464ebd5Sriastradh}
12193464ebd5Sriastradh
12203464ebd5Sriastradhstatic void
12213464ebd5Sriastradhput_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
12223464ebd5Sriastradh		  GLuint count, GLint x, GLint y,
12233464ebd5Sriastradh		  const void *values, const GLubyte *mask)
12243464ebd5Sriastradh{
12253464ebd5Sriastradh   float *dst = rb->GetPointer(ctx, rb, x, y);
12263464ebd5Sriastradh   const float *src = values;
12273464ebd5Sriastradh   unsigned int i;
12283464ebd5Sriastradh
12293464ebd5Sriastradh   if (mask) {
12303464ebd5Sriastradh      for (i = 0; i < count; i++) {
12313464ebd5Sriastradh         if (mask[i]) {
12323464ebd5Sriastradh	    dst[i] = src[i * 4 + ACOMP];
12333464ebd5Sriastradh         }
12343464ebd5Sriastradh      }
12353464ebd5Sriastradh   }
12363464ebd5Sriastradh   else {
12373464ebd5Sriastradh      for (i = 0; i < count; i++) {
12383464ebd5Sriastradh	 dst[i] = src[i * 4 + ACOMP];
12393464ebd5Sriastradh      }
12403464ebd5Sriastradh   }
12413464ebd5Sriastradh}
12423464ebd5Sriastradh
12433464ebd5Sriastradhstatic void
12443464ebd5Sriastradhput_mono_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
12453464ebd5Sriastradh		       GLuint count, GLint x, GLint y,
12463464ebd5Sriastradh		       const void *value, const GLubyte *mask)
12473464ebd5Sriastradh{
12483464ebd5Sriastradh   float *dst = rb->GetPointer(ctx, rb, x, y);
12493464ebd5Sriastradh   const float *src = value;
12503464ebd5Sriastradh   unsigned int i;
12513464ebd5Sriastradh
12523464ebd5Sriastradh   if (mask) {
12533464ebd5Sriastradh      for (i = 0; i < count; i++) {
12543464ebd5Sriastradh         if (mask[i]) {
12553464ebd5Sriastradh	    dst[i] = src[ACOMP];
12563464ebd5Sriastradh         }
12573464ebd5Sriastradh      }
12583464ebd5Sriastradh   }
12593464ebd5Sriastradh   else {
12603464ebd5Sriastradh      for (i = 0; i < count; i++) {
12613464ebd5Sriastradh	 dst[i] = src[ACOMP];
12623464ebd5Sriastradh      }
12633464ebd5Sriastradh   }
12643464ebd5Sriastradh}
12653464ebd5Sriastradh
12663464ebd5Sriastradhstatic void
12673464ebd5Sriastradhput_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
12683464ebd5Sriastradh		     GLuint count, const GLint x[], const GLint y[],
12693464ebd5Sriastradh		     const void *values, const GLubyte *mask)
12703464ebd5Sriastradh{
12713464ebd5Sriastradh   const float *src = values;
12723464ebd5Sriastradh   unsigned int i;
12733464ebd5Sriastradh
12743464ebd5Sriastradh   for (i = 0; i < count; i++) {
12753464ebd5Sriastradh      if (!mask || mask[i]) {
12763464ebd5Sriastradh	 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
12773464ebd5Sriastradh
12783464ebd5Sriastradh	 *dst = src[i * 4 + ACOMP];
12793464ebd5Sriastradh      }
12803464ebd5Sriastradh   }
12813464ebd5Sriastradh}
12823464ebd5Sriastradh
12837117f1b4Smrgstatic void
12843464ebd5Sriastradhput_mono_values_a_float32(struct gl_context *ctx,
12853464ebd5Sriastradh			  struct gl_renderbuffer *rb,
12863464ebd5Sriastradh			  GLuint count, const GLint x[], const GLint y[],
12873464ebd5Sriastradh			  const void *value, const GLubyte *mask)
12887117f1b4Smrg{
12893464ebd5Sriastradh   const float *src = value;
12903464ebd5Sriastradh   unsigned int i;
12913464ebd5Sriastradh
12927117f1b4Smrg   for (i = 0; i < count; i++) {
12937117f1b4Smrg      if (!mask || mask[i]) {
12943464ebd5Sriastradh	 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
12953464ebd5Sriastradh	 *dst = src[ACOMP];
12967117f1b4Smrg      }
12977117f1b4Smrg   }
12987117f1b4Smrg}
12997117f1b4Smrg
13003464ebd5Sriastradh/**********************************************************************
13013464ebd5Sriastradh * Functions for MESA_FORMAT_R_FLOAT32.
13023464ebd5Sriastradh */
13033464ebd5Sriastradhstatic void
13043464ebd5Sriastradhget_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
13053464ebd5Sriastradh		  GLuint count, GLint x, GLint y, void *values)
13063464ebd5Sriastradh{
13073464ebd5Sriastradh   const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
13083464ebd5Sriastradh   GLfloat *dst = values;
13093464ebd5Sriastradh   GLuint i;
13103464ebd5Sriastradh
13113464ebd5Sriastradh   for (i = 0; i < count; i++) {
13123464ebd5Sriastradh      dst[i * 4 + RCOMP] = src[i];
13133464ebd5Sriastradh      dst[i * 4 + GCOMP] = 0.0;
13143464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0.0;
13153464ebd5Sriastradh      dst[i * 4 + ACOMP] = 1.0;
13163464ebd5Sriastradh   }
13173464ebd5Sriastradh}
13187117f1b4Smrg
13197117f1b4Smrgstatic void
13203464ebd5Sriastradhget_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
13213464ebd5Sriastradh		     GLuint count, const GLint x[], const GLint y[],
13223464ebd5Sriastradh		     void *values)
13237117f1b4Smrg{
13243464ebd5Sriastradh   GLfloat *dst = values;
13257117f1b4Smrg   GLuint i;
13263464ebd5Sriastradh
13277117f1b4Smrg   for (i = 0; i < count; i++) {
13283464ebd5Sriastradh      const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
13293464ebd5Sriastradh      dst[i * 4 + RCOMP] = src[0];
13303464ebd5Sriastradh      dst[i * 4 + GCOMP] = 0.0;
13313464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0.0;
13323464ebd5Sriastradh      dst[i * 4 + ACOMP] = 1.0;
13333464ebd5Sriastradh   }
13343464ebd5Sriastradh}
13353464ebd5Sriastradh
13363464ebd5Sriastradh/**********************************************************************
13373464ebd5Sriastradh * Functions for MESA_FORMAT_RG_FLOAT32.
13383464ebd5Sriastradh */
13393464ebd5Sriastradhstatic void
13403464ebd5Sriastradhget_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
13413464ebd5Sriastradh		   GLuint count, GLint x, GLint y, void *values)
13423464ebd5Sriastradh{
13433464ebd5Sriastradh   const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
13443464ebd5Sriastradh   GLfloat *dst = values;
13453464ebd5Sriastradh   GLuint i;
13463464ebd5Sriastradh
13473464ebd5Sriastradh   for (i = 0; i < count; i++) {
13483464ebd5Sriastradh      dst[i * 4 + RCOMP] = src[i * 2 + 0];
13493464ebd5Sriastradh      dst[i * 4 + GCOMP] = src[i * 2 + 1];
13503464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0.0;
13513464ebd5Sriastradh      dst[i * 4 + ACOMP] = 1.0;
13527117f1b4Smrg   }
13537117f1b4Smrg}
13547117f1b4Smrg
13553464ebd5Sriastradhstatic void
13563464ebd5Sriastradhget_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
13573464ebd5Sriastradh		      GLuint count, const GLint x[], const GLint y[],
13583464ebd5Sriastradh		      void *values)
13593464ebd5Sriastradh{
13603464ebd5Sriastradh   GLfloat *dst = values;
13613464ebd5Sriastradh   GLuint i;
13627117f1b4Smrg
13633464ebd5Sriastradh   for (i = 0; i < count; i++) {
13643464ebd5Sriastradh      const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
13653464ebd5Sriastradh      dst[i * 4 + RCOMP] = src[0];
13663464ebd5Sriastradh      dst[i * 4 + GCOMP] = src[1];
13673464ebd5Sriastradh      dst[i * 4 + BCOMP] = 0.0;
13683464ebd5Sriastradh      dst[i * 4 + ACOMP] = 1.0;
13693464ebd5Sriastradh   }
13703464ebd5Sriastradh}
13717117f1b4Smrg
13727117f1b4Smrg/**
13733464ebd5Sriastradh * This is the default software fallback for gl_renderbuffer's span
13743464ebd5Sriastradh * access functions.
13757117f1b4Smrg *
13763464ebd5Sriastradh * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
13773464ebd5Sriastradh * are packed in the type of rb->Format, and that subsequent rows appear
13783464ebd5Sriastradh * rb->RowStride pixels later.
13797117f1b4Smrg */
13803464ebd5Sriastradhvoid
13813464ebd5Sriastradh_mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb)
13827117f1b4Smrg{
13833464ebd5Sriastradh   rb->GetPointer = get_pointer_generic;
13843464ebd5Sriastradh   rb->GetRow = get_row_generic;
13857117f1b4Smrg
13863464ebd5Sriastradh   switch (rb->Format) {
13873464ebd5Sriastradh   case MESA_FORMAT_RGB888:
13887117f1b4Smrg      rb->DataType = GL_UNSIGNED_BYTE;
13897117f1b4Smrg      rb->GetPointer = get_pointer_ubyte3;
13907117f1b4Smrg      rb->GetRow = get_row_ubyte3;
13917117f1b4Smrg      rb->GetValues = get_values_ubyte3;
13927117f1b4Smrg      rb->PutRow = put_row_ubyte3;
13937117f1b4Smrg      rb->PutRowRGB = put_row_rgb_ubyte3;
13947117f1b4Smrg      rb->PutMonoRow = put_mono_row_ubyte3;
13957117f1b4Smrg      rb->PutValues = put_values_ubyte3;
13967117f1b4Smrg      rb->PutMonoValues = put_mono_values_ubyte3;
13977117f1b4Smrg      break;
13983464ebd5Sriastradh
13993464ebd5Sriastradh   case MESA_FORMAT_RGBA8888:
14007117f1b4Smrg      rb->DataType = GL_UNSIGNED_BYTE;
14017117f1b4Smrg      rb->GetValues = get_values_ubyte4;
14027117f1b4Smrg      rb->PutRow = put_row_ubyte4;
14037117f1b4Smrg      rb->PutRowRGB = put_row_rgb_ubyte4;
14047117f1b4Smrg      rb->PutMonoRow = put_mono_row_ubyte4;
14057117f1b4Smrg      rb->PutValues = put_values_ubyte4;
14067117f1b4Smrg      rb->PutMonoValues = put_mono_values_ubyte4;
14077117f1b4Smrg      break;
14083464ebd5Sriastradh
14093464ebd5Sriastradh   case MESA_FORMAT_R8:
14103464ebd5Sriastradh      rb->DataType = GL_UNSIGNED_BYTE;
14113464ebd5Sriastradh      rb->GetValues = get_values_r8;
14123464ebd5Sriastradh      rb->GetRow = get_row_r8;
14133464ebd5Sriastradh      rb->PutRow = put_row_generic;
14143464ebd5Sriastradh      rb->PutRowRGB = put_row_generic;
14153464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_generic;
14163464ebd5Sriastradh      rb->PutValues = put_values_generic;
14173464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_generic;
14183464ebd5Sriastradh      break;
14193464ebd5Sriastradh
14203464ebd5Sriastradh   case MESA_FORMAT_RG88:
14213464ebd5Sriastradh      rb->DataType = GL_UNSIGNED_BYTE;
14223464ebd5Sriastradh      rb->GetValues = get_values_rg88;
14233464ebd5Sriastradh      rb->GetRow = get_row_rg88;
14243464ebd5Sriastradh      rb->PutRow = put_row_generic;
14253464ebd5Sriastradh      rb->PutRowRGB = put_row_generic;
14263464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_generic;
14273464ebd5Sriastradh      rb->PutValues = put_values_generic;
14283464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_generic;
14293464ebd5Sriastradh      break;
14303464ebd5Sriastradh
14313464ebd5Sriastradh   case MESA_FORMAT_R16:
14323464ebd5Sriastradh      rb->DataType = GL_UNSIGNED_SHORT;
14333464ebd5Sriastradh      rb->GetValues = get_values_r16;
14343464ebd5Sriastradh      rb->GetRow = get_row_r16;
14353464ebd5Sriastradh      rb->PutRow = put_row_generic;
14363464ebd5Sriastradh      rb->PutRowRGB = put_row_generic;
14373464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_generic;
14383464ebd5Sriastradh      rb->PutValues = put_values_generic;
14393464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_generic;
14403464ebd5Sriastradh      break;
14413464ebd5Sriastradh
14423464ebd5Sriastradh   case MESA_FORMAT_RG1616:
14433464ebd5Sriastradh      rb->DataType = GL_UNSIGNED_SHORT;
14443464ebd5Sriastradh      rb->GetValues = get_values_rg1616;
14453464ebd5Sriastradh      rb->GetRow = get_row_rg1616;
14463464ebd5Sriastradh      rb->PutRow = put_row_generic;
14473464ebd5Sriastradh      rb->PutRowRGB = put_row_generic;
14483464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_generic;
14493464ebd5Sriastradh      rb->PutValues = put_values_generic;
14503464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_generic;
14513464ebd5Sriastradh      break;
14523464ebd5Sriastradh
14533464ebd5Sriastradh   case MESA_FORMAT_SIGNED_RGBA_16:
14544a49301eSmrg      rb->DataType = GL_SHORT;
14557117f1b4Smrg      rb->GetValues = get_values_ushort4;
14567117f1b4Smrg      rb->PutRow = put_row_ushort4;
14577117f1b4Smrg      rb->PutRowRGB = put_row_rgb_ushort4;
14587117f1b4Smrg      rb->PutMonoRow = put_mono_row_ushort4;
14597117f1b4Smrg      rb->PutValues = put_values_ushort4;
14607117f1b4Smrg      rb->PutMonoValues = put_mono_values_ushort4;
14617117f1b4Smrg      break;
14623464ebd5Sriastradh
14634a49301eSmrg#if 0
14643464ebd5Sriastradh   case MESA_FORMAT_A8:
14657117f1b4Smrg      rb->DataType = GL_UNSIGNED_BYTE;
14667117f1b4Smrg      rb->GetValues = get_values_alpha8;
14677117f1b4Smrg      rb->PutRow = put_row_alpha8;
14687117f1b4Smrg      rb->PutRowRGB = NULL;
14697117f1b4Smrg      rb->PutMonoRow = put_mono_row_alpha8;
14707117f1b4Smrg      rb->PutValues = put_values_alpha8;
14717117f1b4Smrg      rb->PutMonoValues = put_mono_values_alpha8;
14727117f1b4Smrg      break;
14737117f1b4Smrg#endif
14743464ebd5Sriastradh
14753464ebd5Sriastradh   case MESA_FORMAT_S8:
14767117f1b4Smrg      rb->DataType = GL_UNSIGNED_BYTE;
14777117f1b4Smrg      rb->GetValues = get_values_ubyte;
14787117f1b4Smrg      rb->PutRow = put_row_ubyte;
14797117f1b4Smrg      rb->PutRowRGB = NULL;
14807117f1b4Smrg      rb->PutMonoRow = put_mono_row_ubyte;
14817117f1b4Smrg      rb->PutValues = put_values_ubyte;
14827117f1b4Smrg      rb->PutMonoValues = put_mono_values_ubyte;
14837117f1b4Smrg      break;
14843464ebd5Sriastradh
14853464ebd5Sriastradh   case MESA_FORMAT_Z16:
14867117f1b4Smrg      rb->DataType = GL_UNSIGNED_SHORT;
14877117f1b4Smrg      rb->GetValues = get_values_ushort;
14887117f1b4Smrg      rb->PutRow = put_row_ushort;
14897117f1b4Smrg      rb->PutRowRGB = NULL;
14907117f1b4Smrg      rb->PutMonoRow = put_mono_row_ushort;
14917117f1b4Smrg      rb->PutValues = put_values_ushort;
14927117f1b4Smrg      rb->PutMonoValues = put_mono_values_ushort;
14937117f1b4Smrg      break;
14943464ebd5Sriastradh
14953464ebd5Sriastradh   case MESA_FORMAT_Z32:
14963464ebd5Sriastradh   case MESA_FORMAT_X8_Z24:
14973464ebd5Sriastradh   case MESA_FORMAT_Z24_X8:
14984a49301eSmrg      rb->DataType = GL_UNSIGNED_INT;
14994a49301eSmrg      rb->GetValues = get_values_uint;
15004a49301eSmrg      rb->PutRow = put_row_uint;
15014a49301eSmrg      rb->PutRowRGB = NULL;
15024a49301eSmrg      rb->PutMonoRow = put_mono_row_uint;
15034a49301eSmrg      rb->PutValues = put_values_uint;
15044a49301eSmrg      rb->PutMonoValues = put_mono_values_uint;
15054a49301eSmrg      break;
15063464ebd5Sriastradh
15073464ebd5Sriastradh   case MESA_FORMAT_Z24_S8:
15083464ebd5Sriastradh   case MESA_FORMAT_S8_Z24:
15093464ebd5Sriastradh      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
15107117f1b4Smrg      rb->GetValues = get_values_uint;
15117117f1b4Smrg      rb->PutRow = put_row_uint;
15127117f1b4Smrg      rb->PutRowRGB = NULL;
15137117f1b4Smrg      rb->PutMonoRow = put_mono_row_uint;
15147117f1b4Smrg      rb->PutValues = put_values_uint;
15157117f1b4Smrg      rb->PutMonoValues = put_mono_values_uint;
15163464ebd5Sriastradh      break;
15173464ebd5Sriastradh
15183464ebd5Sriastradh   case MESA_FORMAT_RGBA_FLOAT32:
15193464ebd5Sriastradh      rb->GetRow = get_row_generic;
15203464ebd5Sriastradh      rb->GetValues = get_values_generic;
15213464ebd5Sriastradh      rb->PutRow = put_row_generic;
15223464ebd5Sriastradh      rb->PutRowRGB = NULL;
15233464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_generic;
15243464ebd5Sriastradh      rb->PutValues = put_values_generic;
15253464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_generic;
15263464ebd5Sriastradh      break;
15273464ebd5Sriastradh
15283464ebd5Sriastradh   case MESA_FORMAT_INTENSITY_FLOAT32:
15293464ebd5Sriastradh      rb->GetRow = get_row_i_float32;
15303464ebd5Sriastradh      rb->GetValues = get_values_i_float32;
15313464ebd5Sriastradh      rb->PutRow = put_row_generic;
15323464ebd5Sriastradh      rb->PutRowRGB = NULL;
15333464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_generic;
15343464ebd5Sriastradh      rb->PutValues = put_values_generic;
15353464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_generic;
15363464ebd5Sriastradh      break;
15373464ebd5Sriastradh
15383464ebd5Sriastradh   case MESA_FORMAT_LUMINANCE_FLOAT32:
15393464ebd5Sriastradh      rb->GetRow = get_row_l_float32;
15403464ebd5Sriastradh      rb->GetValues = get_values_l_float32;
15413464ebd5Sriastradh      rb->PutRow = put_row_generic;
15423464ebd5Sriastradh      rb->PutRowRGB = NULL;
15433464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_generic;
15443464ebd5Sriastradh      rb->PutValues = put_values_generic;
15453464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_generic;
15463464ebd5Sriastradh      break;
15473464ebd5Sriastradh
15483464ebd5Sriastradh   case MESA_FORMAT_ALPHA_FLOAT32:
15493464ebd5Sriastradh      rb->GetRow = get_row_a_float32;
15503464ebd5Sriastradh      rb->GetValues = get_values_a_float32;
15513464ebd5Sriastradh      rb->PutRow = put_row_a_float32;
15523464ebd5Sriastradh      rb->PutRowRGB = NULL;
15533464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_a_float32;
15543464ebd5Sriastradh      rb->PutValues = put_values_a_float32;
15553464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_a_float32;
15563464ebd5Sriastradh      break;
15573464ebd5Sriastradh
15583464ebd5Sriastradh   case MESA_FORMAT_RG_FLOAT32:
15593464ebd5Sriastradh      rb->GetRow = get_row_rg_float32;
15603464ebd5Sriastradh      rb->GetValues = get_values_rg_float32;
15613464ebd5Sriastradh      rb->PutRow = put_row_generic;
15623464ebd5Sriastradh      rb->PutRowRGB = NULL;
15633464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_generic;
15643464ebd5Sriastradh      rb->PutValues = put_values_generic;
15653464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_generic;
15663464ebd5Sriastradh      break;
15673464ebd5Sriastradh
15683464ebd5Sriastradh   case MESA_FORMAT_R_FLOAT32:
15693464ebd5Sriastradh      rb->GetRow = get_row_r_float32;
15703464ebd5Sriastradh      rb->GetValues = get_values_r_float32;
15713464ebd5Sriastradh      rb->PutRow = put_row_generic;
15723464ebd5Sriastradh      rb->PutRowRGB = NULL;
15733464ebd5Sriastradh      rb->PutMonoRow = put_mono_row_generic;
15743464ebd5Sriastradh      rb->PutValues = put_values_generic;
15753464ebd5Sriastradh      rb->PutMonoValues = put_mono_values_generic;
15763464ebd5Sriastradh      break;
15773464ebd5Sriastradh
15783464ebd5Sriastradh   default:
15793464ebd5Sriastradh      break;
15803464ebd5Sriastradh   }
15813464ebd5Sriastradh}
15823464ebd5Sriastradh
15833464ebd5Sriastradh/**
15843464ebd5Sriastradh * This is a software fallback for the gl_renderbuffer->AllocStorage
15853464ebd5Sriastradh * function.
15863464ebd5Sriastradh * Device drivers will typically override this function for the buffers
15873464ebd5Sriastradh * which it manages (typically color buffers, Z and stencil).
15883464ebd5Sriastradh * Other buffers (like software accumulation and aux buffers) which the driver
15893464ebd5Sriastradh * doesn't manage can be handled with this function.
15903464ebd5Sriastradh *
15913464ebd5Sriastradh * This one multi-purpose function can allocate stencil, depth, accum, color
15923464ebd5Sriastradh * or color-index buffers!
15933464ebd5Sriastradh *
15943464ebd5Sriastradh * This function also plugs in the appropriate GetPointer, Get/PutRow and
15953464ebd5Sriastradh * Get/PutValues functions.
15963464ebd5Sriastradh */
15973464ebd5SriastradhGLboolean
15983464ebd5Sriastradh_mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
15993464ebd5Sriastradh                                GLenum internalFormat,
16003464ebd5Sriastradh                                GLuint width, GLuint height)
16013464ebd5Sriastradh{
16023464ebd5Sriastradh   switch (internalFormat) {
16033464ebd5Sriastradh   case GL_RGB:
16043464ebd5Sriastradh   case GL_R3_G3_B2:
16053464ebd5Sriastradh   case GL_RGB4:
16063464ebd5Sriastradh   case GL_RGB5:
16073464ebd5Sriastradh   case GL_RGB8:
16083464ebd5Sriastradh   case GL_RGB10:
16093464ebd5Sriastradh   case GL_RGB12:
16103464ebd5Sriastradh   case GL_RGB16:
16113464ebd5Sriastradh      rb->Format = MESA_FORMAT_RGB888;
16123464ebd5Sriastradh      break;
16133464ebd5Sriastradh   case GL_RGBA:
16143464ebd5Sriastradh   case GL_RGBA2:
16153464ebd5Sriastradh   case GL_RGBA4:
16163464ebd5Sriastradh   case GL_RGB5_A1:
16173464ebd5Sriastradh   case GL_RGBA8:
16183464ebd5Sriastradh#if 1
16193464ebd5Sriastradh   case GL_RGB10_A2:
16203464ebd5Sriastradh   case GL_RGBA12:
16213464ebd5Sriastradh#endif
16223464ebd5Sriastradh      rb->Format = MESA_FORMAT_RGBA8888;
16233464ebd5Sriastradh      break;
16243464ebd5Sriastradh   case GL_RGBA16:
16253464ebd5Sriastradh   case GL_RGBA16_SNORM:
16263464ebd5Sriastradh      /* for accum buffer */
16273464ebd5Sriastradh      rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
16283464ebd5Sriastradh      break;
16293464ebd5Sriastradh#if 0
16303464ebd5Sriastradh   case GL_ALPHA8:
16313464ebd5Sriastradh      rb->Format = MESA_FORMAT_A8;
16323464ebd5Sriastradh      break;
16333464ebd5Sriastradh#endif
16343464ebd5Sriastradh   case GL_STENCIL_INDEX:
16353464ebd5Sriastradh   case GL_STENCIL_INDEX1_EXT:
16363464ebd5Sriastradh   case GL_STENCIL_INDEX4_EXT:
16373464ebd5Sriastradh   case GL_STENCIL_INDEX8_EXT:
16383464ebd5Sriastradh   case GL_STENCIL_INDEX16_EXT:
16393464ebd5Sriastradh      rb->Format = MESA_FORMAT_S8;
16403464ebd5Sriastradh      break;
16413464ebd5Sriastradh   case GL_DEPTH_COMPONENT:
16423464ebd5Sriastradh   case GL_DEPTH_COMPONENT16:
16433464ebd5Sriastradh      rb->Format = MESA_FORMAT_Z16;
16443464ebd5Sriastradh      break;
16453464ebd5Sriastradh   case GL_DEPTH_COMPONENT24:
16463464ebd5Sriastradh      rb->Format = MESA_FORMAT_X8_Z24;
16473464ebd5Sriastradh      break;
16483464ebd5Sriastradh   case GL_DEPTH_COMPONENT32:
16494a49301eSmrg      rb->Format = MESA_FORMAT_Z32;
16507117f1b4Smrg      break;
16517117f1b4Smrg   case GL_DEPTH_STENCIL_EXT:
16527117f1b4Smrg   case GL_DEPTH24_STENCIL8_EXT:
16534a49301eSmrg      rb->Format = MESA_FORMAT_Z24_S8;
16547117f1b4Smrg      break;
16557117f1b4Smrg   default:
16563464ebd5Sriastradh      /* unsupported format */
16577117f1b4Smrg      return GL_FALSE;
16587117f1b4Smrg   }
16597117f1b4Smrg
16603464ebd5Sriastradh   _mesa_set_renderbuffer_accessors(rb);
16613464ebd5Sriastradh
16627117f1b4Smrg   ASSERT(rb->DataType);
16637117f1b4Smrg   ASSERT(rb->GetPointer);
16647117f1b4Smrg   ASSERT(rb->GetRow);
16657117f1b4Smrg   ASSERT(rb->GetValues);
16667117f1b4Smrg   ASSERT(rb->PutRow);
16677117f1b4Smrg   ASSERT(rb->PutMonoRow);
16687117f1b4Smrg   ASSERT(rb->PutValues);
16697117f1b4Smrg   ASSERT(rb->PutMonoValues);
16707117f1b4Smrg
16717117f1b4Smrg   /* free old buffer storage */
16727117f1b4Smrg   if (rb->Data) {
1673cdc920a0Smrg      free(rb->Data);
16747117f1b4Smrg      rb->Data = NULL;
16757117f1b4Smrg   }
16767117f1b4Smrg
16773464ebd5Sriastradh   rb->RowStride = width;
16783464ebd5Sriastradh
16797117f1b4Smrg   if (width > 0 && height > 0) {
16807117f1b4Smrg      /* allocate new buffer storage */
16813464ebd5Sriastradh      rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format));
16824a49301eSmrg
16837117f1b4Smrg      if (rb->Data == NULL) {
16847117f1b4Smrg         rb->Width = 0;
16857117f1b4Smrg         rb->Height = 0;
16863464ebd5Sriastradh	 rb->RowStride = 0;
16877117f1b4Smrg         _mesa_error(ctx, GL_OUT_OF_MEMORY,
16887117f1b4Smrg                     "software renderbuffer allocation (%d x %d x %d)",
16893464ebd5Sriastradh                     width, height, _mesa_get_format_bytes(rb->Format));
16907117f1b4Smrg         return GL_FALSE;
16917117f1b4Smrg      }
16927117f1b4Smrg   }
16937117f1b4Smrg
16947117f1b4Smrg   rb->Width = width;
16957117f1b4Smrg   rb->Height = height;
16964a49301eSmrg   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
16973464ebd5Sriastradh
16983464ebd5Sriastradh   if (rb->Name == 0 &&
16993464ebd5Sriastradh       internalFormat == GL_RGBA16_SNORM &&
17003464ebd5Sriastradh       rb->_BaseFormat == 0) {
17013464ebd5Sriastradh      /* NOTE: This is a special case just for accumulation buffers.
17023464ebd5Sriastradh       * This is a very limited use case- there's no snorm texturing or
17033464ebd5Sriastradh       * rendering going on.
17043464ebd5Sriastradh       */
17053464ebd5Sriastradh      rb->_BaseFormat = GL_RGBA;
17063464ebd5Sriastradh   }
17073464ebd5Sriastradh   else {
17083464ebd5Sriastradh      /* the internalFormat should have been error checked long ago */
17093464ebd5Sriastradh      ASSERT(rb->_BaseFormat);
17103464ebd5Sriastradh   }
17117117f1b4Smrg
17127117f1b4Smrg   return GL_TRUE;
17137117f1b4Smrg}
17147117f1b4Smrg
17157117f1b4Smrg
17167117f1b4Smrg
17177117f1b4Smrg/**********************************************************************/
17187117f1b4Smrg/**********************************************************************/
17197117f1b4Smrg/**********************************************************************/
17207117f1b4Smrg
17217117f1b4Smrg
17227117f1b4Smrg/**
17237117f1b4Smrg * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
17247117f1b4Smrg * buffer wrapper around an existing RGB renderbuffer (hw or sw).
17257117f1b4Smrg *
17267117f1b4Smrg * When PutRow is called (for example), we store the alpha values in
17277117f1b4Smrg * this buffer, then pass on the PutRow call to the wrapped RGB
17287117f1b4Smrg * buffer.
17297117f1b4Smrg */
17307117f1b4Smrg
17317117f1b4Smrg
17327117f1b4Smrgstatic GLboolean
17333464ebd5Sriastradhalloc_storage_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb,
17347117f1b4Smrg                     GLenum internalFormat, GLuint width, GLuint height)
17357117f1b4Smrg{
17367117f1b4Smrg   ASSERT(arb != arb->Wrapped);
17374a49301eSmrg   ASSERT(arb->Format == MESA_FORMAT_A8);
17387117f1b4Smrg
17397117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
17407117f1b4Smrg   if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat,
17417117f1b4Smrg                                  width, height)) {
17427117f1b4Smrg      return GL_FALSE;
17437117f1b4Smrg   }
17447117f1b4Smrg
17457117f1b4Smrg   /* next, resize my alpha buffer */
17467117f1b4Smrg   if (arb->Data) {
1747cdc920a0Smrg      free(arb->Data);
17487117f1b4Smrg   }
17497117f1b4Smrg
1750cdc920a0Smrg   arb->Data = malloc(width * height * sizeof(GLubyte));
17517117f1b4Smrg   if (arb->Data == NULL) {
17527117f1b4Smrg      arb->Width = 0;
17537117f1b4Smrg      arb->Height = 0;
17547117f1b4Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation");
17557117f1b4Smrg      return GL_FALSE;
17567117f1b4Smrg   }
17577117f1b4Smrg
17587117f1b4Smrg   arb->Width = width;
17597117f1b4Smrg   arb->Height = height;
17603464ebd5Sriastradh   arb->RowStride = width;
17617117f1b4Smrg
17627117f1b4Smrg   return GL_TRUE;
17637117f1b4Smrg}
17647117f1b4Smrg
17657117f1b4Smrg
17667117f1b4Smrg/**
17677117f1b4Smrg * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
17687117f1b4Smrg */
17697117f1b4Smrgstatic void
17707117f1b4Smrgdelete_renderbuffer_alpha8(struct gl_renderbuffer *arb)
17717117f1b4Smrg{
17727117f1b4Smrg   if (arb->Data) {
1773cdc920a0Smrg      free(arb->Data);
17747117f1b4Smrg   }
17757117f1b4Smrg   ASSERT(arb->Wrapped);
17767117f1b4Smrg   ASSERT(arb != arb->Wrapped);
17777117f1b4Smrg   arb->Wrapped->Delete(arb->Wrapped);
17787117f1b4Smrg   arb->Wrapped = NULL;
1779cdc920a0Smrg   free(arb);
17807117f1b4Smrg}
17817117f1b4Smrg
17827117f1b4Smrg
17837117f1b4Smrgstatic void *
17843464ebd5Sriastradhget_pointer_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb,
17857117f1b4Smrg                   GLint x, GLint y)
17867117f1b4Smrg{
17877117f1b4Smrg   return NULL;   /* don't allow direct access! */
17887117f1b4Smrg}
17897117f1b4Smrg
17907117f1b4Smrg
17917117f1b4Smrgstatic void
17923464ebd5Sriastradhget_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
17937117f1b4Smrg               GLint x, GLint y, void *values)
17947117f1b4Smrg{
17957117f1b4Smrg   /* NOTE: 'values' is RGBA format! */
17963464ebd5Sriastradh   const GLubyte *src = (const GLubyte *) arb->Data + y * arb->RowStride + x;
17977117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
17987117f1b4Smrg   GLuint i;
17997117f1b4Smrg   ASSERT(arb != arb->Wrapped);
18007117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
18017117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
18027117f1b4Smrg   arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values);
18037117f1b4Smrg   /* second, fill in alpha values from this buffer! */
18047117f1b4Smrg   for (i = 0; i < count; i++) {
18057117f1b4Smrg      dst[i * 4 + 3] = src[i];
18067117f1b4Smrg   }
18077117f1b4Smrg}
18087117f1b4Smrg
18097117f1b4Smrg
18107117f1b4Smrgstatic void
18113464ebd5Sriastradhget_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
18127117f1b4Smrg                  const GLint x[], const GLint y[], void *values)
18137117f1b4Smrg{
18147117f1b4Smrg   GLubyte *dst = (GLubyte *) values;
18157117f1b4Smrg   GLuint i;
18167117f1b4Smrg   ASSERT(arb != arb->Wrapped);
18177117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
18187117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
18197117f1b4Smrg   arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values);
18207117f1b4Smrg   /* second, fill in alpha values from this buffer! */
18217117f1b4Smrg   for (i = 0; i < count; i++) {
18223464ebd5Sriastradh      const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i];
18237117f1b4Smrg      dst[i * 4 + 3] = *src;
18247117f1b4Smrg   }
18257117f1b4Smrg}
18267117f1b4Smrg
18277117f1b4Smrg
18287117f1b4Smrgstatic void
18293464ebd5Sriastradhput_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
18307117f1b4Smrg               GLint x, GLint y, const void *values, const GLubyte *mask)
18317117f1b4Smrg{
18327117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
18333464ebd5Sriastradh   GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x;
18347117f1b4Smrg   GLuint i;
18357117f1b4Smrg   ASSERT(arb != arb->Wrapped);
18367117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
18377117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
18387117f1b4Smrg   arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask);
18397117f1b4Smrg   /* second, store alpha in our buffer */
18407117f1b4Smrg   for (i = 0; i < count; i++) {
18417117f1b4Smrg      if (!mask || mask[i]) {
18427117f1b4Smrg         dst[i] = src[i * 4 + 3];
18437117f1b4Smrg      }
18447117f1b4Smrg   }
18457117f1b4Smrg}
18467117f1b4Smrg
18477117f1b4Smrg
18487117f1b4Smrgstatic void
18493464ebd5Sriastradhput_row_rgb_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
18507117f1b4Smrg                   GLint x, GLint y, const void *values, const GLubyte *mask)
18517117f1b4Smrg{
18527117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
18533464ebd5Sriastradh   GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x;
18547117f1b4Smrg   GLuint i;
18557117f1b4Smrg   ASSERT(arb != arb->Wrapped);
18567117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
18577117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
18587117f1b4Smrg   arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask);
18597117f1b4Smrg   /* second, store alpha in our buffer */
18607117f1b4Smrg   for (i = 0; i < count; i++) {
18617117f1b4Smrg      if (!mask || mask[i]) {
18627117f1b4Smrg         dst[i] = src[i * 4 + 3];
18637117f1b4Smrg      }
18647117f1b4Smrg   }
18657117f1b4Smrg}
18667117f1b4Smrg
18677117f1b4Smrg
18687117f1b4Smrgstatic void
18693464ebd5Sriastradhput_mono_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
18707117f1b4Smrg                    GLint x, GLint y, const void *value, const GLubyte *mask)
18717117f1b4Smrg{
18727117f1b4Smrg   const GLubyte val = ((const GLubyte *) value)[3];
18733464ebd5Sriastradh   GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x;
18747117f1b4Smrg   ASSERT(arb != arb->Wrapped);
18757117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
18767117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
18777117f1b4Smrg   arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask);
18787117f1b4Smrg   /* second, store alpha in our buffer */
18797117f1b4Smrg   if (mask) {
18807117f1b4Smrg      GLuint i;
18817117f1b4Smrg      for (i = 0; i < count; i++) {
18827117f1b4Smrg         if (mask[i]) {
18837117f1b4Smrg            dst[i] = val;
18847117f1b4Smrg         }
18857117f1b4Smrg      }
18867117f1b4Smrg   }
18877117f1b4Smrg   else {
1888cdc920a0Smrg      memset(dst, val, count);
18897117f1b4Smrg   }
18907117f1b4Smrg}
18917117f1b4Smrg
18927117f1b4Smrg
18937117f1b4Smrgstatic void
18943464ebd5Sriastradhput_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
18957117f1b4Smrg                  const GLint x[], const GLint y[],
18967117f1b4Smrg                  const void *values, const GLubyte *mask)
18977117f1b4Smrg{
18987117f1b4Smrg   const GLubyte *src = (const GLubyte *) values;
18997117f1b4Smrg   GLuint i;
19007117f1b4Smrg   ASSERT(arb != arb->Wrapped);
19017117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
19027117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
19037117f1b4Smrg   arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask);
19047117f1b4Smrg   /* second, store alpha in our buffer */
19057117f1b4Smrg   for (i = 0; i < count; i++) {
19067117f1b4Smrg      if (!mask || mask[i]) {
19073464ebd5Sriastradh         GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i];
19087117f1b4Smrg         *dst = src[i * 4 + 3];
19097117f1b4Smrg      }
19107117f1b4Smrg   }
19117117f1b4Smrg}
19127117f1b4Smrg
19137117f1b4Smrg
19147117f1b4Smrgstatic void
19153464ebd5Sriastradhput_mono_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb,
19167117f1b4Smrg                       GLuint count, const GLint x[], const GLint y[],
19177117f1b4Smrg                       const void *value, const GLubyte *mask)
19187117f1b4Smrg{
19197117f1b4Smrg   const GLubyte val = ((const GLubyte *) value)[3];
19207117f1b4Smrg   GLuint i;
19217117f1b4Smrg   ASSERT(arb != arb->Wrapped);
19227117f1b4Smrg   ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
19237117f1b4Smrg   /* first, pass the call to the wrapped RGB buffer */
19247117f1b4Smrg   arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask);
19257117f1b4Smrg   /* second, store alpha in our buffer */
19267117f1b4Smrg   for (i = 0; i < count; i++) {
19277117f1b4Smrg      if (!mask || mask[i]) {
19283464ebd5Sriastradh         GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i];
19297117f1b4Smrg         *dst = val;
19307117f1b4Smrg      }
19317117f1b4Smrg   }
19327117f1b4Smrg}
19337117f1b4Smrg
19347117f1b4Smrg
19357117f1b4Smrgstatic void
19367117f1b4Smrgcopy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src)
19377117f1b4Smrg{
19384a49301eSmrg   ASSERT(dst->Format == MESA_FORMAT_A8);
19394a49301eSmrg   ASSERT(src->Format == MESA_FORMAT_A8);
19407117f1b4Smrg   ASSERT(dst->Width == src->Width);
19417117f1b4Smrg   ASSERT(dst->Height == src->Height);
19423464ebd5Sriastradh   ASSERT(dst->RowStride == src->RowStride);
19437117f1b4Smrg
19443464ebd5Sriastradh   memcpy(dst->Data, src->Data, dst->RowStride * dst->Height * sizeof(GLubyte));
19457117f1b4Smrg}
19467117f1b4Smrg
19477117f1b4Smrg
19487117f1b4Smrg/**********************************************************************/
19497117f1b4Smrg/**********************************************************************/
19507117f1b4Smrg/**********************************************************************/
19517117f1b4Smrg
19527117f1b4Smrg
19537117f1b4Smrg/**
19547117f1b4Smrg * Default GetPointer routine.  Always return NULL to indicate that
19557117f1b4Smrg * direct buffer access is not supported.
19567117f1b4Smrg */
19577117f1b4Smrgstatic void *
19583464ebd5Sriastradhnop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
19597117f1b4Smrg{
19607117f1b4Smrg   return NULL;
19617117f1b4Smrg}
19627117f1b4Smrg
19637117f1b4Smrg
19647117f1b4Smrg/**
19657117f1b4Smrg * Initialize the fields of a gl_renderbuffer to default values.
19667117f1b4Smrg */
19677117f1b4Smrgvoid
19687117f1b4Smrg_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
19697117f1b4Smrg{
19707117f1b4Smrg   _glthread_INIT_MUTEX(rb->Mutex);
19717117f1b4Smrg
19727117f1b4Smrg   rb->ClassID = 0;
19737117f1b4Smrg   rb->Name = name;
19747117f1b4Smrg   rb->RefCount = 0;
19757117f1b4Smrg   rb->Delete = _mesa_delete_renderbuffer;
19767117f1b4Smrg
19777117f1b4Smrg   /* The rest of these should be set later by the caller of this function or
19787117f1b4Smrg    * the AllocStorage method:
19797117f1b4Smrg    */
19807117f1b4Smrg   rb->AllocStorage = NULL;
19817117f1b4Smrg
19827117f1b4Smrg   rb->Width = 0;
19837117f1b4Smrg   rb->Height = 0;
19847117f1b4Smrg   rb->InternalFormat = GL_NONE;
19854a49301eSmrg   rb->Format = MESA_FORMAT_NONE;
19864a49301eSmrg
19877117f1b4Smrg   rb->DataType = GL_NONE;
19887117f1b4Smrg   rb->Data = NULL;
19897117f1b4Smrg
19907117f1b4Smrg   /* Point back to ourself so that we don't have to check for Wrapped==NULL
19917117f1b4Smrg    * all over the drivers.
19927117f1b4Smrg    */
19937117f1b4Smrg   rb->Wrapped = rb;
19947117f1b4Smrg
19957117f1b4Smrg   rb->GetPointer = nop_get_pointer;
19967117f1b4Smrg   rb->GetRow = NULL;
19977117f1b4Smrg   rb->GetValues = NULL;
19987117f1b4Smrg   rb->PutRow = NULL;
19997117f1b4Smrg   rb->PutRowRGB = NULL;
20007117f1b4Smrg   rb->PutMonoRow = NULL;
20017117f1b4Smrg   rb->PutValues = NULL;
20027117f1b4Smrg   rb->PutMonoValues = NULL;
20037117f1b4Smrg}
20047117f1b4Smrg
20057117f1b4Smrg
20067117f1b4Smrg/**
20077117f1b4Smrg * Allocate a new gl_renderbuffer object.  This can be used for user-created
20087117f1b4Smrg * renderbuffers or window-system renderbuffers.
20097117f1b4Smrg */
20107117f1b4Smrgstruct gl_renderbuffer *
20113464ebd5Sriastradh_mesa_new_renderbuffer(struct gl_context *ctx, GLuint name)
20127117f1b4Smrg{
20137117f1b4Smrg   struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
20147117f1b4Smrg   if (rb) {
20157117f1b4Smrg      _mesa_init_renderbuffer(rb, name);
20167117f1b4Smrg   }
20177117f1b4Smrg   return rb;
20187117f1b4Smrg}
20197117f1b4Smrg
20207117f1b4Smrg
20217117f1b4Smrg/**
20227117f1b4Smrg * Delete a gl_framebuffer.
20237117f1b4Smrg * This is the default function for renderbuffer->Delete().
20247117f1b4Smrg */
20257117f1b4Smrgvoid
20267117f1b4Smrg_mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
20277117f1b4Smrg{
20287117f1b4Smrg   if (rb->Data) {
2029cdc920a0Smrg      free(rb->Data);
20307117f1b4Smrg   }
2031cdc920a0Smrg   free(rb);
20327117f1b4Smrg}
20337117f1b4Smrg
20347117f1b4Smrg
20357117f1b4Smrg/**
20367117f1b4Smrg * Allocate a software-based renderbuffer.  This is called via the
20377117f1b4Smrg * ctx->Driver.NewRenderbuffer() function when the user creates a new
20387117f1b4Smrg * renderbuffer.
20397117f1b4Smrg * This would not be used for hardware-based renderbuffers.
20407117f1b4Smrg */
20417117f1b4Smrgstruct gl_renderbuffer *
20423464ebd5Sriastradh_mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name)
20437117f1b4Smrg{
20447117f1b4Smrg   struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
20457117f1b4Smrg   if (rb) {
20467117f1b4Smrg      rb->AllocStorage = _mesa_soft_renderbuffer_storage;
20477117f1b4Smrg      /* Normally, one would setup the PutRow, GetRow, etc functions here.
20487117f1b4Smrg       * But we're doing that in the _mesa_soft_renderbuffer_storage() function
20497117f1b4Smrg       * instead.
20507117f1b4Smrg       */
20517117f1b4Smrg   }
20527117f1b4Smrg   return rb;
20537117f1b4Smrg}
20547117f1b4Smrg
20557117f1b4Smrg
20567117f1b4Smrg/**
20577117f1b4Smrg * Add software-based color renderbuffers to the given framebuffer.
20587117f1b4Smrg * This is a helper routine for device drivers when creating a
20597117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
20607117f1b4Smrg * Once this function is called, you can basically forget about this
20617117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
20627117f1b4Smrg * rendering!
20637117f1b4Smrg */
20647117f1b4SmrgGLboolean
20653464ebd5Sriastradh_mesa_add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
20667117f1b4Smrg                              GLuint rgbBits, GLuint alphaBits,
20677117f1b4Smrg                              GLboolean frontLeft, GLboolean backLeft,
20687117f1b4Smrg                              GLboolean frontRight, GLboolean backRight)
20697117f1b4Smrg{
20703464ebd5Sriastradh   gl_buffer_index b;
20717117f1b4Smrg
20727117f1b4Smrg   if (rgbBits > 16 || alphaBits > 16) {
20737117f1b4Smrg      _mesa_problem(ctx,
20747117f1b4Smrg                    "Unsupported bit depth in _mesa_add_color_renderbuffers");
20757117f1b4Smrg      return GL_FALSE;
20767117f1b4Smrg   }
20777117f1b4Smrg
20787117f1b4Smrg   assert(MAX_COLOR_ATTACHMENTS >= 4);
20797117f1b4Smrg
20807117f1b4Smrg   for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
20817117f1b4Smrg      struct gl_renderbuffer *rb;
20827117f1b4Smrg
20837117f1b4Smrg      if (b == BUFFER_FRONT_LEFT && !frontLeft)
20847117f1b4Smrg         continue;
20857117f1b4Smrg      else if (b == BUFFER_BACK_LEFT && !backLeft)
20867117f1b4Smrg         continue;
20877117f1b4Smrg      else if (b == BUFFER_FRONT_RIGHT && !frontRight)
20887117f1b4Smrg         continue;
20897117f1b4Smrg      else if (b == BUFFER_BACK_RIGHT && !backRight)
20907117f1b4Smrg         continue;
20917117f1b4Smrg
20927117f1b4Smrg      assert(fb->Attachment[b].Renderbuffer == NULL);
20937117f1b4Smrg
20947117f1b4Smrg      rb = _mesa_new_renderbuffer(ctx, 0);
20957117f1b4Smrg      if (!rb) {
20967117f1b4Smrg         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
20977117f1b4Smrg         return GL_FALSE;
20987117f1b4Smrg      }
20997117f1b4Smrg
21007117f1b4Smrg      if (rgbBits <= 8) {
21017117f1b4Smrg         if (alphaBits)
21024a49301eSmrg            rb->Format = MESA_FORMAT_RGBA8888;
21037117f1b4Smrg         else
21044a49301eSmrg            rb->Format = MESA_FORMAT_RGB888;
21057117f1b4Smrg      }
21067117f1b4Smrg      else {
21077117f1b4Smrg         assert(rgbBits <= 16);
21084a49301eSmrg         rb->Format = MESA_FORMAT_NONE; /*XXX RGBA16;*/
21097117f1b4Smrg      }
21104a49301eSmrg      rb->InternalFormat = GL_RGBA;
21117117f1b4Smrg
21127117f1b4Smrg      rb->AllocStorage = _mesa_soft_renderbuffer_storage;
21137117f1b4Smrg      _mesa_add_renderbuffer(fb, b, rb);
21147117f1b4Smrg   }
21157117f1b4Smrg
21167117f1b4Smrg   return GL_TRUE;
21177117f1b4Smrg}
21187117f1b4Smrg
21197117f1b4Smrg
21207117f1b4Smrg/**
21217117f1b4Smrg * Add software-based alpha renderbuffers to the given framebuffer.
21227117f1b4Smrg * This is a helper routine for device drivers when creating a
21237117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
21247117f1b4Smrg * Once this function is called, you can basically forget about this
21257117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
21267117f1b4Smrg * rendering!
21277117f1b4Smrg */
21287117f1b4SmrgGLboolean
21293464ebd5Sriastradh_mesa_add_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
21307117f1b4Smrg                              GLuint alphaBits,
21317117f1b4Smrg                              GLboolean frontLeft, GLboolean backLeft,
21327117f1b4Smrg                              GLboolean frontRight, GLboolean backRight)
21337117f1b4Smrg{
21343464ebd5Sriastradh   gl_buffer_index b;
21357117f1b4Smrg
21367117f1b4Smrg   /* for window system framebuffers only! */
21377117f1b4Smrg   assert(fb->Name == 0);
21387117f1b4Smrg
21397117f1b4Smrg   if (alphaBits > 8) {
21407117f1b4Smrg      _mesa_problem(ctx,
21417117f1b4Smrg                    "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
21427117f1b4Smrg      return GL_FALSE;
21437117f1b4Smrg   }
21447117f1b4Smrg
21457117f1b4Smrg   assert(MAX_COLOR_ATTACHMENTS >= 4);
21467117f1b4Smrg
21477117f1b4Smrg   /* Wrap each of the RGB color buffers with an alpha renderbuffer.
21487117f1b4Smrg    */
21497117f1b4Smrg   for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
21507117f1b4Smrg      struct gl_renderbuffer *arb;
21517117f1b4Smrg
21527117f1b4Smrg      if (b == BUFFER_FRONT_LEFT && !frontLeft)
21537117f1b4Smrg         continue;
21547117f1b4Smrg      else if (b == BUFFER_BACK_LEFT && !backLeft)
21557117f1b4Smrg         continue;
21567117f1b4Smrg      else if (b == BUFFER_FRONT_RIGHT && !frontRight)
21577117f1b4Smrg         continue;
21587117f1b4Smrg      else if (b == BUFFER_BACK_RIGHT && !backRight)
21597117f1b4Smrg         continue;
21607117f1b4Smrg
21617117f1b4Smrg      /* the RGB buffer to wrap must already exist!! */
21627117f1b4Smrg      assert(fb->Attachment[b].Renderbuffer);
21637117f1b4Smrg
21647117f1b4Smrg      /* only GLubyte supported for now */
21657117f1b4Smrg      assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
21667117f1b4Smrg
21677117f1b4Smrg      /* allocate alpha renderbuffer */
21687117f1b4Smrg      arb = _mesa_new_renderbuffer(ctx, 0);
21697117f1b4Smrg      if (!arb) {
21707117f1b4Smrg         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
21717117f1b4Smrg         return GL_FALSE;
21727117f1b4Smrg      }
21737117f1b4Smrg
21747117f1b4Smrg      /* wrap the alpha renderbuffer around the RGB renderbuffer */
21757117f1b4Smrg      arb->Wrapped = fb->Attachment[b].Renderbuffer;
21767117f1b4Smrg
21777117f1b4Smrg      /* Set up my alphabuffer fields and plug in my functions.
21787117f1b4Smrg       * The functions will put/get the alpha values from/to RGBA arrays
21797117f1b4Smrg       * and then call the wrapped buffer's functions to handle the RGB
21807117f1b4Smrg       * values.
21817117f1b4Smrg       */
21827117f1b4Smrg      arb->InternalFormat = arb->Wrapped->InternalFormat;
21834a49301eSmrg      arb->Format         = MESA_FORMAT_A8;
21847117f1b4Smrg      arb->DataType       = arb->Wrapped->DataType;
21857117f1b4Smrg      arb->AllocStorage   = alloc_storage_alpha8;
21867117f1b4Smrg      arb->Delete         = delete_renderbuffer_alpha8;
21877117f1b4Smrg      arb->GetPointer     = get_pointer_alpha8;
21887117f1b4Smrg      arb->GetRow         = get_row_alpha8;
21897117f1b4Smrg      arb->GetValues      = get_values_alpha8;
21907117f1b4Smrg      arb->PutRow         = put_row_alpha8;
21917117f1b4Smrg      arb->PutRowRGB      = put_row_rgb_alpha8;
21927117f1b4Smrg      arb->PutMonoRow     = put_mono_row_alpha8;
21937117f1b4Smrg      arb->PutValues      = put_values_alpha8;
21947117f1b4Smrg      arb->PutMonoValues  = put_mono_values_alpha8;
21957117f1b4Smrg
21967117f1b4Smrg      /* clear the pointer to avoid assertion/sanity check failure later */
21977117f1b4Smrg      fb->Attachment[b].Renderbuffer = NULL;
21987117f1b4Smrg
21997117f1b4Smrg      /* plug the alpha renderbuffer into the colorbuffer attachment */
22007117f1b4Smrg      _mesa_add_renderbuffer(fb, b, arb);
22017117f1b4Smrg   }
22027117f1b4Smrg
22037117f1b4Smrg   return GL_TRUE;
22047117f1b4Smrg}
22057117f1b4Smrg
22067117f1b4Smrg
22077117f1b4Smrg/**
22087117f1b4Smrg * For framebuffers that use a software alpha channel wrapper
22097117f1b4Smrg * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
22107117f1b4Smrg * copy the back buffer alpha channel into the front buffer alpha channel.
22117117f1b4Smrg */
22127117f1b4Smrgvoid
22133464ebd5Sriastradh_mesa_copy_soft_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb)
22147117f1b4Smrg{
22157117f1b4Smrg   if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
22167117f1b4Smrg       fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer)
22177117f1b4Smrg      copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer,
22187117f1b4Smrg                         fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
22197117f1b4Smrg
22207117f1b4Smrg
22217117f1b4Smrg   if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
22227117f1b4Smrg       fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer)
22237117f1b4Smrg      copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer,
22247117f1b4Smrg                         fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
22257117f1b4Smrg}
22267117f1b4Smrg
22277117f1b4Smrg
22287117f1b4Smrg/**
22297117f1b4Smrg * Add a software-based depth renderbuffer to the given framebuffer.
22307117f1b4Smrg * This is a helper routine for device drivers when creating a
22317117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
22327117f1b4Smrg * Once this function is called, you can basically forget about this
22337117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
22347117f1b4Smrg * rendering!
22357117f1b4Smrg */
22367117f1b4SmrgGLboolean
22373464ebd5Sriastradh_mesa_add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
22387117f1b4Smrg                             GLuint depthBits)
22397117f1b4Smrg{
22407117f1b4Smrg   struct gl_renderbuffer *rb;
22417117f1b4Smrg
22427117f1b4Smrg   if (depthBits > 32) {
22437117f1b4Smrg      _mesa_problem(ctx,
22447117f1b4Smrg                    "Unsupported depthBits in _mesa_add_depth_renderbuffer");
22457117f1b4Smrg      return GL_FALSE;
22467117f1b4Smrg   }
22477117f1b4Smrg
22487117f1b4Smrg   assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
22497117f1b4Smrg
22507117f1b4Smrg   rb = _mesa_new_renderbuffer(ctx, 0);
22517117f1b4Smrg   if (!rb) {
22527117f1b4Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
22537117f1b4Smrg      return GL_FALSE;
22547117f1b4Smrg   }
22557117f1b4Smrg
22567117f1b4Smrg   if (depthBits <= 16) {
22574a49301eSmrg      rb->Format = MESA_FORMAT_Z16;
22584a49301eSmrg      rb->InternalFormat = GL_DEPTH_COMPONENT16;
22597117f1b4Smrg   }
22607117f1b4Smrg   else if (depthBits <= 24) {
22614a49301eSmrg      rb->Format = MESA_FORMAT_X8_Z24;
22624a49301eSmrg      rb->InternalFormat = GL_DEPTH_COMPONENT24;
22637117f1b4Smrg   }
22647117f1b4Smrg   else {
22654a49301eSmrg      rb->Format = MESA_FORMAT_Z32;
22664a49301eSmrg      rb->InternalFormat = GL_DEPTH_COMPONENT32;
22677117f1b4Smrg   }
22687117f1b4Smrg
22697117f1b4Smrg   rb->AllocStorage = _mesa_soft_renderbuffer_storage;
22707117f1b4Smrg   _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
22717117f1b4Smrg
22727117f1b4Smrg   return GL_TRUE;
22737117f1b4Smrg}
22747117f1b4Smrg
22757117f1b4Smrg
22767117f1b4Smrg/**
22777117f1b4Smrg * Add a software-based stencil renderbuffer to the given framebuffer.
22787117f1b4Smrg * This is a helper routine for device drivers when creating a
22797117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
22807117f1b4Smrg * Once this function is called, you can basically forget about this
22817117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
22827117f1b4Smrg * rendering!
22837117f1b4Smrg */
22847117f1b4SmrgGLboolean
22853464ebd5Sriastradh_mesa_add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
22867117f1b4Smrg                               GLuint stencilBits)
22877117f1b4Smrg{
22887117f1b4Smrg   struct gl_renderbuffer *rb;
22897117f1b4Smrg
22907117f1b4Smrg   if (stencilBits > 16) {
22917117f1b4Smrg      _mesa_problem(ctx,
22927117f1b4Smrg                  "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
22937117f1b4Smrg      return GL_FALSE;
22947117f1b4Smrg   }
22957117f1b4Smrg
22967117f1b4Smrg   assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
22977117f1b4Smrg
22987117f1b4Smrg   rb = _mesa_new_renderbuffer(ctx, 0);
22997117f1b4Smrg   if (!rb) {
23007117f1b4Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
23017117f1b4Smrg      return GL_FALSE;
23027117f1b4Smrg   }
23037117f1b4Smrg
23044a49301eSmrg   assert(stencilBits <= 8);
23054a49301eSmrg   rb->Format = MESA_FORMAT_S8;
23064a49301eSmrg   rb->InternalFormat = GL_STENCIL_INDEX8;
23077117f1b4Smrg
23087117f1b4Smrg   rb->AllocStorage = _mesa_soft_renderbuffer_storage;
23097117f1b4Smrg   _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
23107117f1b4Smrg
23117117f1b4Smrg   return GL_TRUE;
23127117f1b4Smrg}
23137117f1b4Smrg
23147117f1b4Smrg
23157117f1b4Smrg/**
23167117f1b4Smrg * Add a software-based accumulation renderbuffer to the given framebuffer.
23177117f1b4Smrg * This is a helper routine for device drivers when creating a
23187117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
23197117f1b4Smrg * Once this function is called, you can basically forget about this
23207117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
23217117f1b4Smrg * rendering!
23227117f1b4Smrg */
23237117f1b4SmrgGLboolean
23243464ebd5Sriastradh_mesa_add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
23257117f1b4Smrg                             GLuint redBits, GLuint greenBits,
23267117f1b4Smrg                             GLuint blueBits, GLuint alphaBits)
23277117f1b4Smrg{
23287117f1b4Smrg   struct gl_renderbuffer *rb;
23297117f1b4Smrg
23307117f1b4Smrg   if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
23317117f1b4Smrg      _mesa_problem(ctx,
23327117f1b4Smrg                    "Unsupported accumBits in _mesa_add_accum_renderbuffer");
23337117f1b4Smrg      return GL_FALSE;
23347117f1b4Smrg   }
23357117f1b4Smrg
23367117f1b4Smrg   assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
23377117f1b4Smrg
23387117f1b4Smrg   rb = _mesa_new_renderbuffer(ctx, 0);
23397117f1b4Smrg   if (!rb) {
23407117f1b4Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
23417117f1b4Smrg      return GL_FALSE;
23427117f1b4Smrg   }
23437117f1b4Smrg
23444a49301eSmrg   rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
23453464ebd5Sriastradh   rb->InternalFormat = GL_RGBA16_SNORM;
23467117f1b4Smrg   rb->AllocStorage = _mesa_soft_renderbuffer_storage;
23477117f1b4Smrg   _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
23487117f1b4Smrg
23497117f1b4Smrg   return GL_TRUE;
23507117f1b4Smrg}
23517117f1b4Smrg
23527117f1b4Smrg
23537117f1b4Smrg
23547117f1b4Smrg/**
23553464ebd5Sriastradh * Add a software-based aux renderbuffer to the given framebuffer.
23567117f1b4Smrg * This is a helper routine for device drivers when creating a
23577117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer).
23587117f1b4Smrg * Once this function is called, you can basically forget about this
23597117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and
23607117f1b4Smrg * rendering!
23617117f1b4Smrg *
23627117f1b4Smrg * NOTE: color-index aux buffers not supported.
23637117f1b4Smrg */
23647117f1b4SmrgGLboolean
23653464ebd5Sriastradh_mesa_add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
23667117f1b4Smrg                            GLuint colorBits, GLuint numBuffers)
23677117f1b4Smrg{
23687117f1b4Smrg   GLuint i;
23697117f1b4Smrg
23707117f1b4Smrg   if (colorBits > 16) {
23717117f1b4Smrg      _mesa_problem(ctx,
23727117f1b4Smrg                    "Unsupported accumBits in _mesa_add_aux_renderbuffers");
23737117f1b4Smrg      return GL_FALSE;
23747117f1b4Smrg   }
23757117f1b4Smrg
23764a49301eSmrg   assert(numBuffers <= MAX_AUX_BUFFERS);
23777117f1b4Smrg
23787117f1b4Smrg   for (i = 0; i < numBuffers; i++) {
23797117f1b4Smrg      struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
23807117f1b4Smrg
23817117f1b4Smrg      assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
23827117f1b4Smrg
23837117f1b4Smrg      if (!rb) {
23843464ebd5Sriastradh         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer");
23857117f1b4Smrg         return GL_FALSE;
23867117f1b4Smrg      }
23877117f1b4Smrg
23884a49301eSmrg      assert (colorBits <= 8);
23894a49301eSmrg      rb->Format = MESA_FORMAT_RGBA8888;
23904a49301eSmrg      rb->InternalFormat = GL_RGBA;
23917117f1b4Smrg
23927117f1b4Smrg      rb->AllocStorage = _mesa_soft_renderbuffer_storage;
23937117f1b4Smrg      _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
23947117f1b4Smrg   }
23957117f1b4Smrg   return GL_TRUE;
23967117f1b4Smrg}
23977117f1b4Smrg
23987117f1b4Smrg
23997117f1b4Smrg/**
24007117f1b4Smrg * Create/attach software-based renderbuffers to the given framebuffer.
24017117f1b4Smrg * This is a helper routine for device drivers.  Drivers can just as well
24027117f1b4Smrg * call the individual _mesa_add_*_renderbuffer() routines directly.
24037117f1b4Smrg */
24047117f1b4Smrgvoid
24057117f1b4Smrg_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
24067117f1b4Smrg                             GLboolean color,
24077117f1b4Smrg                             GLboolean depth,
24087117f1b4Smrg                             GLboolean stencil,
24097117f1b4Smrg                             GLboolean accum,
24107117f1b4Smrg                             GLboolean alpha,
24117117f1b4Smrg                             GLboolean aux)
24127117f1b4Smrg{
24137117f1b4Smrg   GLboolean frontLeft = GL_TRUE;
24147117f1b4Smrg   GLboolean backLeft = fb->Visual.doubleBufferMode;
24157117f1b4Smrg   GLboolean frontRight = fb->Visual.stereoMode;
24167117f1b4Smrg   GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
24177117f1b4Smrg
24187117f1b4Smrg   if (color) {
2419cdc920a0Smrg      assert(fb->Visual.redBits == fb->Visual.greenBits);
2420cdc920a0Smrg      assert(fb->Visual.redBits == fb->Visual.blueBits);
2421cdc920a0Smrg      _mesa_add_color_renderbuffers(NULL, fb,
2422cdc920a0Smrg				    fb->Visual.redBits,
2423cdc920a0Smrg				    fb->Visual.alphaBits,
2424cdc920a0Smrg				    frontLeft, backLeft,
2425cdc920a0Smrg				    frontRight, backRight);
24267117f1b4Smrg   }
24277117f1b4Smrg
24287117f1b4Smrg   if (depth) {
24297117f1b4Smrg      assert(fb->Visual.depthBits > 0);
24307117f1b4Smrg      _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
24317117f1b4Smrg   }
24327117f1b4Smrg
24337117f1b4Smrg   if (stencil) {
24347117f1b4Smrg      assert(fb->Visual.stencilBits > 0);
24357117f1b4Smrg      _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
24367117f1b4Smrg   }
24377117f1b4Smrg
24387117f1b4Smrg   if (accum) {
24397117f1b4Smrg      assert(fb->Visual.accumRedBits > 0);
24407117f1b4Smrg      assert(fb->Visual.accumGreenBits > 0);
24417117f1b4Smrg      assert(fb->Visual.accumBlueBits > 0);
24427117f1b4Smrg      _mesa_add_accum_renderbuffer(NULL, fb,
24437117f1b4Smrg                                   fb->Visual.accumRedBits,
24447117f1b4Smrg                                   fb->Visual.accumGreenBits,
24457117f1b4Smrg                                   fb->Visual.accumBlueBits,
24467117f1b4Smrg                                   fb->Visual.accumAlphaBits);
24477117f1b4Smrg   }
24487117f1b4Smrg
24497117f1b4Smrg   if (aux) {
24507117f1b4Smrg      assert(fb->Visual.numAuxBuffers > 0);
24517117f1b4Smrg      _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
24527117f1b4Smrg                                  fb->Visual.numAuxBuffers);
24537117f1b4Smrg   }
24547117f1b4Smrg
24557117f1b4Smrg   if (alpha) {
24567117f1b4Smrg      assert(fb->Visual.alphaBits > 0);
24577117f1b4Smrg      _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits,
24587117f1b4Smrg                                    frontLeft, backLeft,
24597117f1b4Smrg                                    frontRight, backRight);
24607117f1b4Smrg   }
24617117f1b4Smrg
24627117f1b4Smrg#if 0
24637117f1b4Smrg   if (multisample) {
24647117f1b4Smrg      /* maybe someday */
24657117f1b4Smrg   }
24667117f1b4Smrg#endif
24677117f1b4Smrg}
24687117f1b4Smrg
24697117f1b4Smrg
24707117f1b4Smrg/**
24717117f1b4Smrg * Attach a renderbuffer to a framebuffer.
24723464ebd5Sriastradh * \param bufferName  one of the BUFFER_x tokens
24737117f1b4Smrg */
24747117f1b4Smrgvoid
24757117f1b4Smrg_mesa_add_renderbuffer(struct gl_framebuffer *fb,
24763464ebd5Sriastradh                       gl_buffer_index bufferName, struct gl_renderbuffer *rb)
24777117f1b4Smrg{
24787117f1b4Smrg   assert(fb);
24797117f1b4Smrg   assert(rb);
24807117f1b4Smrg   assert(bufferName < BUFFER_COUNT);
24817117f1b4Smrg
24827117f1b4Smrg   /* There should be no previous renderbuffer on this attachment point,
24837117f1b4Smrg    * with the exception of depth/stencil since the same renderbuffer may
24847117f1b4Smrg    * be used for both.
24857117f1b4Smrg    */
24867117f1b4Smrg   assert(bufferName == BUFFER_DEPTH ||
24877117f1b4Smrg          bufferName == BUFFER_STENCIL ||
24887117f1b4Smrg          fb->Attachment[bufferName].Renderbuffer == NULL);
24897117f1b4Smrg
24907117f1b4Smrg   /* winsys vs. user-created buffer cross check */
24917117f1b4Smrg   if (fb->Name) {
24927117f1b4Smrg      assert(rb->Name);
24937117f1b4Smrg   }
24947117f1b4Smrg   else {
24957117f1b4Smrg      assert(!rb->Name);
24967117f1b4Smrg   }
24977117f1b4Smrg
24987117f1b4Smrg   fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
24997117f1b4Smrg   fb->Attachment[bufferName].Complete = GL_TRUE;
25007117f1b4Smrg   _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
25017117f1b4Smrg}
25027117f1b4Smrg
25037117f1b4Smrg
25047117f1b4Smrg/**
25057117f1b4Smrg * Remove the named renderbuffer from the given framebuffer.
25063464ebd5Sriastradh * \param bufferName  one of the BUFFER_x tokens
25077117f1b4Smrg */
25087117f1b4Smrgvoid
25093464ebd5Sriastradh_mesa_remove_renderbuffer(struct gl_framebuffer *fb,
25103464ebd5Sriastradh                          gl_buffer_index bufferName)
25117117f1b4Smrg{
25127117f1b4Smrg   struct gl_renderbuffer *rb;
25137117f1b4Smrg
25147117f1b4Smrg   assert(bufferName < BUFFER_COUNT);
25157117f1b4Smrg
25167117f1b4Smrg   rb = fb->Attachment[bufferName].Renderbuffer;
25177117f1b4Smrg   if (!rb)
25187117f1b4Smrg      return;
25197117f1b4Smrg
25207117f1b4Smrg   _mesa_reference_renderbuffer(&rb, NULL);
25217117f1b4Smrg
25227117f1b4Smrg   fb->Attachment[bufferName].Renderbuffer = NULL;
25237117f1b4Smrg}
25247117f1b4Smrg
25257117f1b4Smrg
25267117f1b4Smrg/**
25277117f1b4Smrg * Set *ptr to point to rb.  If *ptr points to another renderbuffer,
25287117f1b4Smrg * dereference that buffer first.  The new renderbuffer's refcount will
25297117f1b4Smrg * be incremented.  The old renderbuffer's refcount will be decremented.
25307117f1b4Smrg */
25317117f1b4Smrgvoid
25327117f1b4Smrg_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
25337117f1b4Smrg                             struct gl_renderbuffer *rb)
25347117f1b4Smrg{
25357117f1b4Smrg   assert(ptr);
25367117f1b4Smrg   if (*ptr == rb) {
25377117f1b4Smrg      /* no change */
25387117f1b4Smrg      return;
25397117f1b4Smrg   }
25407117f1b4Smrg
25417117f1b4Smrg   if (*ptr) {
25427117f1b4Smrg      /* Unreference the old renderbuffer */
25437117f1b4Smrg      GLboolean deleteFlag = GL_FALSE;
25447117f1b4Smrg      struct gl_renderbuffer *oldRb = *ptr;
25457117f1b4Smrg
25467117f1b4Smrg      _glthread_LOCK_MUTEX(oldRb->Mutex);
25477117f1b4Smrg      ASSERT(oldRb->RefCount > 0);
25487117f1b4Smrg      oldRb->RefCount--;
25497117f1b4Smrg      /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
25507117f1b4Smrg      deleteFlag = (oldRb->RefCount == 0);
25517117f1b4Smrg      _glthread_UNLOCK_MUTEX(oldRb->Mutex);
25527117f1b4Smrg
25537117f1b4Smrg      if (deleteFlag) {
25547117f1b4Smrg         oldRb->Delete(oldRb);
25557117f1b4Smrg      }
25567117f1b4Smrg
25577117f1b4Smrg      *ptr = NULL;
25587117f1b4Smrg   }
25597117f1b4Smrg   assert(!*ptr);
25607117f1b4Smrg
25617117f1b4Smrg   if (rb) {
25627117f1b4Smrg      /* reference new renderbuffer */
25637117f1b4Smrg      _glthread_LOCK_MUTEX(rb->Mutex);
25647117f1b4Smrg      rb->RefCount++;
25657117f1b4Smrg      /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
25667117f1b4Smrg      _glthread_UNLOCK_MUTEX(rb->Mutex);
25677117f1b4Smrg      *ptr = rb;
25687117f1b4Smrg   }
25697117f1b4Smrg}
2570