Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  6.5
  4.  *
  5.  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. /**
  27.  * Functions for allocating/managing renderbuffers.
  28.  * Also, routines for reading/writing software-based renderbuffer data as
  29.  * ubytes, ushorts, uints, etc.
  30.  *
  31.  * The 'alpha8' renderbuffer is interesting.  It's used to add a software-based
  32.  * alpha channel to RGB renderbuffers.  This is done by wrapping the RGB
  33.  * renderbuffer with the alpha renderbuffer.  We can do this because of the
  34.  * OO-nature of renderbuffers.
  35.  *
  36.  * Down the road we'll use this for run-time support of 8, 16 and 32-bit
  37.  * color channels.  For example, Mesa may use 32-bit/float color channels
  38.  * internally (swrast) and use wrapper renderbuffers to convert 32-bit
  39.  * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
  40.  */
  41.  
  42.  
  43. #include "glheader.h"
  44. #include "imports.h"
  45. #include "context.h"
  46. #include "fbobject.h"
  47. #include "formats.h"
  48. #include "mtypes.h"
  49. #include "renderbuffer.h"
  50.  
  51.  
  52. /*
  53.  * Routines for get/put values in common buffer formats follow.
  54.  * Someday add support for arbitrary row stride to make them more
  55.  * flexible.
  56.  */
  57.  
  58. /**********************************************************************
  59.  * Functions for buffers of 1 X GLubyte values.
  60.  * Typically stencil.
  61.  */
  62.  
  63. static void *
  64. get_pointer_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb,
  65.                   GLint x, GLint y)
  66. {
  67.    if (!rb->Data)
  68.       return NULL;
  69.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  70.    /* Can't assert rb->Format since these funcs may be used for serveral
  71.     * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
  72.     */
  73.    return (GLubyte *) rb->Data + y * rb->Width + x;
  74. }
  75.  
  76.  
  77. static void
  78. get_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  79.               GLint x, GLint y, void *values)
  80. {
  81.    const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x;
  82.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  83.    memcpy(values, src, count * sizeof(GLubyte));
  84. }
  85.  
  86.  
  87. static void
  88. get_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  89.                  const GLint x[], const GLint y[], void *values)
  90. {
  91.    GLubyte *dst = (GLubyte *) values;
  92.    GLuint i;
  93.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  94.    for (i = 0; i < count; i++) {
  95.       const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
  96.       dst[i] = *src;
  97.    }
  98. }
  99.  
  100.  
  101. static void
  102. put_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  103.               GLint x, GLint y, const void *values, const GLubyte *mask)
  104. {
  105.    const GLubyte *src = (const GLubyte *) values;
  106.    GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
  107.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  108.    if (mask) {
  109.       GLuint i;
  110.       for (i = 0; i < count; i++) {
  111.          if (mask[i]) {
  112.             dst[i] = src[i];
  113.          }
  114.       }
  115.    }
  116.    else {
  117.       memcpy(dst, values, count * sizeof(GLubyte));
  118.    }
  119. }
  120.  
  121.  
  122. static void
  123. put_mono_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  124.                    GLint x, GLint y, const void *value, const GLubyte *mask)
  125. {
  126.    const GLubyte val = *((const GLubyte *) value);
  127.    GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
  128.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  129.    if (mask) {
  130.       GLuint i;
  131.       for (i = 0; i < count; i++) {
  132.          if (mask[i]) {
  133.             dst[i] = val;
  134.          }
  135.       }
  136.    }
  137.    else {
  138.       GLuint i;
  139.       for (i = 0; i < count; i++) {
  140.          dst[i] = val;
  141.       }
  142.    }
  143. }
  144.  
  145.  
  146. static void
  147. put_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  148.                  const GLint x[], const GLint y[],
  149.                  const void *values, const GLubyte *mask)
  150. {
  151.    const GLubyte *src = (const GLubyte *) values;
  152.    GLuint i;
  153.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  154.    for (i = 0; i < count; i++) {
  155.       if (!mask || mask[i]) {
  156.          GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
  157.          *dst = src[i];
  158.       }
  159.    }
  160. }
  161.  
  162.  
  163. static void
  164. put_mono_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  165.                       const GLint x[], const GLint y[],
  166.                       const void *value, const GLubyte *mask)
  167. {
  168.    const GLubyte val = *((const GLubyte *) value);
  169.    GLuint i;
  170.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  171.    for (i = 0; i < count; i++) {
  172.       if (!mask || mask[i]) {
  173.          GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
  174.          *dst = val;
  175.       }
  176.    }
  177. }
  178.  
  179.  
  180. /**********************************************************************
  181.  * Functions for buffers of 1 X GLushort values.
  182.  * Typically depth/Z.
  183.  */
  184.  
  185. static void *
  186. get_pointer_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb,
  187.                    GLint x, GLint y)
  188. {
  189.    if (!rb->Data)
  190.       return NULL;
  191.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
  192.    ASSERT(rb->Width > 0);
  193.    return (GLushort *) rb->Data + y * rb->Width + x;
  194. }
  195.  
  196.  
  197. static void
  198. get_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  199.                GLint x, GLint y, void *values)
  200. {
  201.    const void *src = rb->GetPointer(ctx, rb, x, y);
  202.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
  203.    memcpy(values, src, count * sizeof(GLushort));
  204. }
  205.  
  206.  
  207. static void
  208. get_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  209.                   const GLint x[], const GLint y[], void *values)
  210. {
  211.    GLushort *dst = (GLushort *) values;
  212.    GLuint i;
  213.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
  214.    for (i = 0; i < count; i++) {
  215.       const GLushort *src = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
  216.       dst[i] = *src;
  217.    }
  218. }
  219.  
  220.  
  221. static void
  222. put_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  223.                GLint x, GLint y, const void *values, const GLubyte *mask)
  224. {
  225.    const GLushort *src = (const GLushort *) values;
  226.    GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
  227.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
  228.    if (mask) {
  229.       GLuint i;
  230.       for (i = 0; i < count; i++) {
  231.          if (mask[i]) {
  232.             dst[i] = src[i];
  233.          }
  234.       }
  235.    }
  236.    else {
  237.       memcpy(dst, src, count * sizeof(GLushort));
  238.    }
  239. }
  240.  
  241.  
  242. static void
  243. put_mono_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  244.                     GLint x, GLint y, const void *value, const GLubyte *mask)
  245. {
  246.    const GLushort val = *((const GLushort *) value);
  247.    GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
  248.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
  249.    if (mask) {
  250.       GLuint i;
  251.       for (i = 0; i < count; i++) {
  252.          if (mask[i]) {
  253.             dst[i] = val;
  254.          }
  255.       }
  256.    }
  257.    else {
  258.       GLuint i;
  259.       for (i = 0; i < count; i++) {
  260.          dst[i] = val;
  261.       }
  262.    }
  263. }
  264.  
  265.  
  266. static void
  267. put_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  268.                   const GLint x[], const GLint y[], const void *values,
  269.                   const GLubyte *mask)
  270. {
  271.    const GLushort *src = (const GLushort *) values;
  272.    GLuint i;
  273.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
  274.    for (i = 0; i < count; i++) {
  275.       if (!mask || mask[i]) {
  276.          GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
  277.          *dst = src[i];
  278.       }
  279.    }
  280. }
  281.  
  282.  
  283. static void
  284. put_mono_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb,
  285.                        GLuint count, const GLint x[], const GLint y[],
  286.                        const void *value, const GLubyte *mask)
  287. {
  288.    const GLushort val = *((const GLushort *) value);
  289.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
  290.    if (mask) {
  291.       GLuint i;
  292.       for (i = 0; i < count; i++) {
  293.          if (mask[i]) {
  294.             GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
  295.             *dst = val;
  296.          }
  297.       }
  298.    }
  299.    else {
  300.       GLuint i;
  301.       for (i = 0; i < count; i++) {
  302.          GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
  303.          *dst = val;
  304.       }
  305.    }
  306. }
  307.  
  308.  
  309. /**********************************************************************
  310.  * Functions for buffers of 1 X GLuint values.
  311.  * Typically depth/Z or color index.
  312.  */
  313.  
  314. static void *
  315. get_pointer_uint(struct gl_context *ctx, struct gl_renderbuffer *rb,
  316.                  GLint x, GLint y)
  317. {
  318.    if (!rb->Data)
  319.       return NULL;
  320.    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
  321.           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
  322.    return (GLuint *) rb->Data + y * rb->Width + x;
  323. }
  324.  
  325.  
  326. static void
  327. get_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  328.              GLint x, GLint y, void *values)
  329. {
  330.    const void *src = rb->GetPointer(ctx, rb, x, y);
  331.    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
  332.           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
  333.    memcpy(values, src, count * sizeof(GLuint));
  334. }
  335.  
  336.  
  337. static void
  338. get_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  339.                 const GLint x[], const GLint y[], void *values)
  340. {
  341.    GLuint *dst = (GLuint *) values;
  342.    GLuint i;
  343.    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
  344.           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
  345.    for (i = 0; i < count; i++) {
  346.       const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
  347.       dst[i] = *src;
  348.    }
  349. }
  350.  
  351.  
  352. static void
  353. put_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  354.              GLint x, GLint y, const void *values, const GLubyte *mask)
  355. {
  356.    const GLuint *src = (const GLuint *) values;
  357.    GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
  358.    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
  359.           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
  360.    if (mask) {
  361.       GLuint i;
  362.       for (i = 0; i < count; i++) {
  363.          if (mask[i]) {
  364.             dst[i] = src[i];
  365.          }
  366.       }
  367.    }
  368.    else {
  369.       memcpy(dst, src, count * sizeof(GLuint));
  370.    }
  371. }
  372.  
  373.  
  374. static void
  375. put_mono_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  376.                   GLint x, GLint y, const void *value, const GLubyte *mask)
  377. {
  378.    const GLuint val = *((const GLuint *) value);
  379.    GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
  380.    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
  381.           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
  382.    if (mask) {
  383.       GLuint i;
  384.       for (i = 0; i < count; i++) {
  385.          if (mask[i]) {
  386.             dst[i] = val;
  387.          }
  388.       }
  389.    }
  390.    else {
  391.       GLuint i;
  392.       for (i = 0; i < count; i++) {
  393.          dst[i] = val;
  394.       }
  395.    }
  396. }
  397.  
  398.  
  399. static void
  400. put_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  401.                 const GLint x[], const GLint y[], const void *values,
  402.                 const GLubyte *mask)
  403. {
  404.    const GLuint *src = (const GLuint *) values;
  405.    GLuint i;
  406.    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
  407.           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
  408.    for (i = 0; i < count; i++) {
  409.       if (!mask || mask[i]) {
  410.          GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
  411.          *dst = src[i];
  412.       }
  413.    }
  414. }
  415.  
  416.  
  417. static void
  418. put_mono_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  419.                      const GLint x[], const GLint y[], const void *value,
  420.                      const GLubyte *mask)
  421. {
  422.    const GLuint val = *((const GLuint *) value);
  423.    GLuint i;
  424.    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
  425.           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
  426.    for (i = 0; i < count; i++) {
  427.       if (!mask || mask[i]) {
  428.          GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
  429.          *dst = val;
  430.       }
  431.    }
  432. }
  433.  
  434.  
  435. /**********************************************************************
  436.  * Functions for buffers of 3 X GLubyte (or GLbyte) values.
  437.  * Typically color buffers.
  438.  * NOTE: the incoming and outgoing colors are RGBA!  We ignore incoming
  439.  * alpha values and return 255 for outgoing alpha values.
  440.  */
  441.  
  442. static void *
  443. get_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
  444.                    GLint x, GLint y)
  445. {
  446.    ASSERT(rb->Format == MESA_FORMAT_RGB888);
  447.    /* No direct access since this buffer is RGB but caller will be
  448.     * treating it as if it were RGBA.
  449.     */
  450.    return NULL;
  451. }
  452.  
  453.  
  454. static void
  455. get_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  456.                GLint x, GLint y, void *values)
  457. {
  458.    const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x);
  459.    GLubyte *dst = (GLubyte *) values;
  460.    GLuint i;
  461.    ASSERT(rb->Format == MESA_FORMAT_RGB888);
  462.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  463.    for (i = 0; i < count; i++) {
  464.       dst[i * 4 + 0] = src[i * 3 + 0];
  465.       dst[i * 4 + 1] = src[i * 3 + 1];
  466.       dst[i * 4 + 2] = src[i * 3 + 2];
  467.       dst[i * 4 + 3] = 255;
  468.    }
  469. }
  470.  
  471.  
  472. static void
  473. get_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  474.                   const GLint x[], const GLint y[], void *values)
  475. {
  476.    GLubyte *dst = (GLubyte *) values;
  477.    GLuint i;
  478.    ASSERT(rb->Format == MESA_FORMAT_RGB888);
  479.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  480.    for (i = 0; i < count; i++) {
  481.       const GLubyte *src
  482.          = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
  483.       dst[i * 4 + 0] = src[0];
  484.       dst[i * 4 + 1] = src[1];
  485.       dst[i * 4 + 2] = src[2];
  486.       dst[i * 4 + 3] = 255;
  487.    }
  488. }
  489.  
  490.  
  491. static void
  492. put_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  493.                GLint x, GLint y, const void *values, const GLubyte *mask)
  494. {
  495.    /* note: incoming values are RGB+A! */
  496.    const GLubyte *src = (const GLubyte *) values;
  497.    GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
  498.    GLuint i;
  499.    ASSERT(rb->Format == MESA_FORMAT_RGB888);
  500.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  501.    for (i = 0; i < count; i++) {
  502.       if (!mask || mask[i]) {
  503.          dst[i * 3 + 0] = src[i * 4 + 0];
  504.          dst[i * 3 + 1] = src[i * 4 + 1];
  505.          dst[i * 3 + 2] = src[i * 4 + 2];
  506.       }
  507.    }
  508. }
  509.  
  510.  
  511. static void
  512. put_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  513.                    GLint x, GLint y, const void *values, const GLubyte *mask)
  514. {
  515.    /* note: incoming values are RGB+A! */
  516.    const GLubyte *src = (const GLubyte *) values;
  517.    GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
  518.    GLuint i;
  519.    ASSERT(rb->Format == MESA_FORMAT_RGB888);
  520.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  521.    for (i = 0; i < count; i++) {
  522.       if (!mask || mask[i]) {
  523.          dst[i * 3 + 0] = src[i * 3 + 0];
  524.          dst[i * 3 + 1] = src[i * 3 + 1];
  525.          dst[i * 3 + 2] = src[i * 3 + 2];
  526.       }
  527.    }
  528. }
  529.  
  530.  
  531. static void
  532. put_mono_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  533.                     GLint x, GLint y, const void *value, const GLubyte *mask)
  534. {
  535.    /* note: incoming value is RGB+A! */
  536.    const GLubyte val0 = ((const GLubyte *) value)[0];
  537.    const GLubyte val1 = ((const GLubyte *) value)[1];
  538.    const GLubyte val2 = ((const GLubyte *) value)[2];
  539.    GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
  540.    ASSERT(rb->Format == MESA_FORMAT_RGB888);
  541.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  542.    if (!mask && val0 == val1 && val1 == val2) {
  543.       /* optimized case */
  544.       memset(dst, val0, 3 * count);
  545.    }
  546.    else {
  547.       GLuint i;
  548.       for (i = 0; i < count; i++) {
  549.          if (!mask || mask[i]) {
  550.             dst[i * 3 + 0] = val0;
  551.             dst[i * 3 + 1] = val1;
  552.             dst[i * 3 + 2] = val2;
  553.          }
  554.       }
  555.    }
  556. }
  557.  
  558.  
  559. static void
  560. put_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  561.                   const GLint x[], const GLint y[], const void *values,
  562.                   const GLubyte *mask)
  563. {
  564.    /* note: incoming values are RGB+A! */
  565.    const GLubyte *src = (const GLubyte *) values;
  566.    GLuint i;
  567.    ASSERT(rb->Format == MESA_FORMAT_RGB888);
  568.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  569.    for (i = 0; i < count; i++) {
  570.       if (!mask || mask[i]) {
  571.          GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
  572.          dst[0] = src[i * 4 + 0];
  573.          dst[1] = src[i * 4 + 1];
  574.          dst[2] = src[i * 4 + 2];
  575.       }
  576.    }
  577. }
  578.  
  579.  
  580. static void
  581. put_mono_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
  582.                        GLuint count, const GLint x[], const GLint y[],
  583.                        const void *value, const GLubyte *mask)
  584. {
  585.    /* note: incoming value is RGB+A! */
  586.    const GLubyte val0 = ((const GLubyte *) value)[0];
  587.    const GLubyte val1 = ((const GLubyte *) value)[1];
  588.    const GLubyte val2 = ((const GLubyte *) value)[2];
  589.    GLuint i;
  590.    ASSERT(rb->Format == MESA_FORMAT_RGB888);
  591.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  592.    for (i = 0; i < count; i++) {
  593.       if (!mask || mask[i]) {
  594.          GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
  595.          dst[0] = val0;
  596.          dst[1] = val1;
  597.          dst[2] = val2;
  598.       }
  599.    }
  600. }
  601.  
  602.  
  603. /**********************************************************************
  604.  * Functions for buffers of 4 X GLubyte (or GLbyte) values.
  605.  * Typically color buffers.
  606.  */
  607.  
  608. static void *
  609. get_pointer_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb,
  610.                    GLint x, GLint y)
  611. {
  612.    if (!rb->Data)
  613.       return NULL;
  614.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  615.    ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
  616.    return (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
  617. }
  618.  
  619.  
  620. static void
  621. get_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  622.                GLint x, GLint y, void *values)
  623. {
  624.    const GLubyte *src = (const GLubyte *) rb->Data + 4 * (y * rb->Width + x);
  625.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  626.    ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
  627.    memcpy(values, src, 4 * count * sizeof(GLubyte));
  628. }
  629.  
  630.  
  631. static void
  632. get_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  633.                   const GLint x[], const GLint y[], void *values)
  634. {
  635.    /* treat 4*GLubyte as 1*GLuint */
  636.    GLuint *dst = (GLuint *) values;
  637.    GLuint i;
  638.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  639.    ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
  640.    for (i = 0; i < count; i++) {
  641.       const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
  642.       dst[i] = *src;
  643.    }
  644. }
  645.  
  646.  
  647. static void
  648. put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  649.                GLint x, GLint y, const void *values, const GLubyte *mask)
  650. {
  651.    /* treat 4*GLubyte as 1*GLuint */
  652.    const GLuint *src = (const GLuint *) values;
  653.    GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
  654.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  655.    ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
  656.    if (mask) {
  657.       GLuint i;
  658.       for (i = 0; i < count; i++) {
  659.          if (mask[i]) {
  660.             dst[i] = src[i];
  661.          }
  662.       }
  663.    }
  664.    else {
  665.       memcpy(dst, src, 4 * count * sizeof(GLubyte));
  666.    }
  667. }
  668.  
  669.  
  670. static void
  671. put_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  672.                    GLint x, GLint y, const void *values, const GLubyte *mask)
  673. {
  674.    /* Store RGB values in RGBA buffer */
  675.    const GLubyte *src = (const GLubyte *) values;
  676.    GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
  677.    GLuint i;
  678.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  679.    ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
  680.    for (i = 0; i < count; i++) {
  681.       if (!mask || mask[i]) {
  682.          dst[i * 4 + 0] = src[i * 3 + 0];
  683.          dst[i * 4 + 1] = src[i * 3 + 1];
  684.          dst[i * 4 + 2] = src[i * 3 + 2];
  685.          dst[i * 4 + 3] = 0xff;
  686.       }
  687.    }
  688. }
  689.  
  690.  
  691. static void
  692. put_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  693.                     GLint x, GLint y, const void *value, const GLubyte *mask)
  694. {
  695.    /* treat 4*GLubyte as 1*GLuint */
  696.    const GLuint val = *((const GLuint *) value);
  697.    GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
  698.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  699.    ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
  700.    if (!mask && val == 0) {
  701.       /* common case */
  702.       memset(dst, 0, count * 4 * sizeof(GLubyte));
  703.    }
  704.    else {
  705.       /* general case */
  706.       if (mask) {
  707.          GLuint i;
  708.          for (i = 0; i < count; i++) {
  709.             if (mask[i]) {
  710.                dst[i] = val;
  711.             }
  712.          }
  713.       }
  714.       else {
  715.          GLuint i;
  716.          for (i = 0; i < count; i++) {
  717.             dst[i] = val;
  718.          }
  719.       }
  720.    }
  721. }
  722.  
  723.  
  724. static void
  725. put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  726.                   const GLint x[], const GLint y[], const void *values,
  727.                   const GLubyte *mask)
  728. {
  729.    /* treat 4*GLubyte as 1*GLuint */
  730.    const GLuint *src = (const GLuint *) values;
  731.    GLuint i;
  732.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  733.    ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
  734.    for (i = 0; i < count; i++) {
  735.       if (!mask || mask[i]) {
  736.          GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
  737.          *dst = src[i];
  738.       }
  739.    }
  740. }
  741.  
  742.  
  743. static void
  744. put_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb,
  745.                        GLuint count, const GLint x[], const GLint y[],
  746.                        const void *value, const GLubyte *mask)
  747. {
  748.    /* treat 4*GLubyte as 1*GLuint */
  749.    const GLuint val = *((const GLuint *) value);
  750.    GLuint i;
  751.    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  752.    ASSERT(rb->Format == MESA_FORMAT_RGBA8888);
  753.    for (i = 0; i < count; i++) {
  754.       if (!mask || mask[i]) {
  755.          GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
  756.          *dst = val;
  757.       }
  758.    }
  759. }
  760.  
  761.  
  762. /**********************************************************************
  763.  * Functions for buffers of 4 X GLushort (or GLshort) values.
  764.  * Typically accum buffer.
  765.  */
  766.  
  767. static void *
  768. get_pointer_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb,
  769.                     GLint x, GLint y)
  770. {
  771.    if (!rb->Data)
  772.       return NULL;
  773.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
  774.    return (GLushort *) rb->Data + 4 * (y * rb->Width + x);
  775. }
  776.  
  777.  
  778. static void
  779. get_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  780.                 GLint x, GLint y, void *values)
  781. {
  782.    const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x);
  783.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
  784.    memcpy(values, src, 4 * count * sizeof(GLshort));
  785. }
  786.  
  787.  
  788. static void
  789. get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  790.                    const GLint x[], const GLint y[], void *values)
  791. {
  792.    GLushort *dst = (GLushort *) values;
  793.    GLuint i;
  794.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
  795.    for (i = 0; i < count; i++) {
  796.       const GLushort *src
  797.          = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
  798.       dst[i] = *src;
  799.    }
  800. }
  801.  
  802.  
  803. static void
  804. put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  805.                 GLint x, GLint y, const void *values, const GLubyte *mask)
  806. {
  807.    const GLushort *src = (const GLushort *) values;
  808.    GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
  809.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
  810.    if (mask) {
  811.       GLuint i;
  812.       for (i = 0; i < count; i++) {
  813.          if (mask[i]) {
  814.             dst[i * 4 + 0] = src[i * 4 + 0];
  815.             dst[i * 4 + 1] = src[i * 4 + 1];
  816.             dst[i * 4 + 2] = src[i * 4 + 2];
  817.             dst[i * 4 + 3] = src[i * 4 + 3];
  818.          }
  819.       }
  820.    }
  821.    else {
  822.       memcpy(dst, src, 4 * count * sizeof(GLushort));
  823.    }
  824. }
  825.  
  826.  
  827. static void
  828. put_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  829.                     GLint x, GLint y, const void *values, const GLubyte *mask)
  830. {
  831.    /* Put RGB values in RGBA buffer */
  832.    const GLushort *src = (const GLushort *) values;
  833.    GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
  834.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
  835.    if (mask) {
  836.       GLuint i;
  837.       for (i = 0; i < count; i++) {
  838.          if (mask[i]) {
  839.             dst[i * 4 + 0] = src[i * 3 + 0];
  840.             dst[i * 4 + 1] = src[i * 3 + 1];
  841.             dst[i * 4 + 2] = src[i * 3 + 2];
  842.             dst[i * 4 + 3] = 0xffff;
  843.          }
  844.       }
  845.    }
  846.    else {
  847.       memcpy(dst, src, 4 * count * sizeof(GLushort));
  848.    }
  849. }
  850.  
  851.  
  852. static void
  853. put_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  854.                      GLint x, GLint y, const void *value, const GLubyte *mask)
  855. {
  856.    const GLushort val0 = ((const GLushort *) value)[0];
  857.    const GLushort val1 = ((const GLushort *) value)[1];
  858.    const GLushort val2 = ((const GLushort *) value)[2];
  859.    const GLushort val3 = ((const GLushort *) value)[3];
  860.    GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
  861.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
  862.    if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) {
  863.       /* common case for clearing accum buffer */
  864.       memset(dst, 0, count * 4 * sizeof(GLushort));
  865.    }
  866.    else {
  867.       GLuint i;
  868.       for (i = 0; i < count; i++) {
  869.          if (!mask || mask[i]) {
  870.             dst[i * 4 + 0] = val0;
  871.             dst[i * 4 + 1] = val1;
  872.             dst[i * 4 + 2] = val2;
  873.             dst[i * 4 + 3] = val3;
  874.          }
  875.       }
  876.    }
  877. }
  878.  
  879.  
  880. static void
  881. put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
  882.                    const GLint x[], const GLint y[], const void *values,
  883.                    const GLubyte *mask)
  884. {
  885.    const GLushort *src = (const GLushort *) values;
  886.    GLuint i;
  887.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
  888.    for (i = 0; i < count; i++) {
  889.       if (!mask || mask[i]) {
  890.          GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
  891.          dst[0] = src[i * 4 + 0];
  892.          dst[1] = src[i * 4 + 1];
  893.          dst[2] = src[i * 4 + 2];
  894.          dst[3] = src[i * 4 + 3];
  895.       }
  896.    }
  897. }
  898.  
  899.  
  900. static void
  901. put_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb,
  902.                         GLuint count, const GLint x[], const GLint y[],
  903.                         const void *value, const GLubyte *mask)
  904. {
  905.    const GLushort val0 = ((const GLushort *) value)[0];
  906.    const GLushort val1 = ((const GLushort *) value)[1];
  907.    const GLushort val2 = ((const GLushort *) value)[2];
  908.    const GLushort val3 = ((const GLushort *) value)[3];
  909.    GLuint i;
  910.    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
  911.    for (i = 0; i < count; i++) {
  912.       if (!mask || mask[i]) {
  913.          GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
  914.          dst[0] = val0;
  915.          dst[1] = val1;
  916.          dst[2] = val2;
  917.          dst[3] = val3;
  918.       }
  919.    }
  920. }
  921.  
  922.  
  923.  
  924. /**
  925.  * This is a software fallback for the gl_renderbuffer->AllocStorage
  926.  * function.
  927.  * Device drivers will typically override this function for the buffers
  928.  * which it manages (typically color buffers, Z and stencil).
  929.  * Other buffers (like software accumulation and aux buffers) which the driver
  930.  * doesn't manage can be handled with this function.
  931.  *
  932.  * This one multi-purpose function can allocate stencil, depth, accum, color
  933.  * or color-index buffers!
  934.  *
  935.  * This function also plugs in the appropriate GetPointer, Get/PutRow and
  936.  * Get/PutValues functions.
  937.  */
  938. GLboolean
  939. _mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
  940.                                 GLenum internalFormat,
  941.                                 GLuint width, GLuint height)
  942. {
  943.    GLuint pixelSize;
  944.  
  945.    switch (internalFormat) {
  946.    case GL_RGB:
  947.    case GL_R3_G3_B2:
  948.    case GL_RGB4:
  949.    case GL_RGB5:
  950.    case GL_RGB8:
  951.    case GL_RGB10:
  952.    case GL_RGB12:
  953.    case GL_RGB16:
  954.       rb->Format = MESA_FORMAT_RGB888;
  955.       rb->DataType = GL_UNSIGNED_BYTE;
  956.       rb->GetPointer = get_pointer_ubyte3;
  957.       rb->GetRow = get_row_ubyte3;
  958.       rb->GetValues = get_values_ubyte3;
  959.       rb->PutRow = put_row_ubyte3;
  960.       rb->PutRowRGB = put_row_rgb_ubyte3;
  961.       rb->PutMonoRow = put_mono_row_ubyte3;
  962.       rb->PutValues = put_values_ubyte3;
  963.       rb->PutMonoValues = put_mono_values_ubyte3;
  964.       pixelSize = 3 * sizeof(GLubyte);
  965.       break;
  966.    case GL_RGBA:
  967.    case GL_RGBA2:
  968.    case GL_RGBA4:
  969.    case GL_RGB5_A1:
  970.    case GL_RGBA8:
  971. #if 1
  972.    case GL_RGB10_A2:
  973.    case GL_RGBA12:
  974. #endif
  975.       rb->Format = MESA_FORMAT_RGBA8888;
  976.       rb->DataType = GL_UNSIGNED_BYTE;
  977.       rb->GetPointer = get_pointer_ubyte4;
  978.       rb->GetRow = get_row_ubyte4;
  979.       rb->GetValues = get_values_ubyte4;
  980.       rb->PutRow = put_row_ubyte4;
  981.       rb->PutRowRGB = put_row_rgb_ubyte4;
  982.       rb->PutMonoRow = put_mono_row_ubyte4;
  983.       rb->PutValues = put_values_ubyte4;
  984.       rb->PutMonoValues = put_mono_values_ubyte4;
  985.       pixelSize = 4 * sizeof(GLubyte);
  986.       break;
  987.    case GL_RGBA16:
  988.    case GL_RGBA16_SNORM:
  989.       /* for accum buffer */
  990.       rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
  991.       rb->DataType = GL_SHORT;
  992.       rb->GetPointer = get_pointer_ushort4;
  993.       rb->GetRow = get_row_ushort4;
  994.       rb->GetValues = get_values_ushort4;
  995.       rb->PutRow = put_row_ushort4;
  996.       rb->PutRowRGB = put_row_rgb_ushort4;
  997.       rb->PutMonoRow = put_mono_row_ushort4;
  998.       rb->PutValues = put_values_ushort4;
  999.       rb->PutMonoValues = put_mono_values_ushort4;
  1000.       pixelSize = 4 * sizeof(GLushort);
  1001.       break;
  1002. #if 0
  1003.    case GL_ALPHA8:
  1004.       rb->Format = MESA_FORMAT_A8;
  1005.       rb->DataType = GL_UNSIGNED_BYTE;
  1006.       rb->GetPointer = get_pointer_alpha8;
  1007.       rb->GetRow = get_row_alpha8;
  1008.       rb->GetValues = get_values_alpha8;
  1009.       rb->PutRow = put_row_alpha8;
  1010.       rb->PutRowRGB = NULL;
  1011.       rb->PutMonoRow = put_mono_row_alpha8;
  1012.       rb->PutValues = put_values_alpha8;
  1013.       rb->PutMonoValues = put_mono_values_alpha8;
  1014.       pixelSize = sizeof(GLubyte);
  1015.       break;
  1016. #endif
  1017.    case GL_STENCIL_INDEX:
  1018.    case GL_STENCIL_INDEX1_EXT:
  1019.    case GL_STENCIL_INDEX4_EXT:
  1020.    case GL_STENCIL_INDEX8_EXT:
  1021.    case GL_STENCIL_INDEX16_EXT:
  1022.       rb->Format = MESA_FORMAT_S8;
  1023.       rb->DataType = GL_UNSIGNED_BYTE;
  1024.       rb->GetPointer = get_pointer_ubyte;
  1025.       rb->GetRow = get_row_ubyte;
  1026.       rb->GetValues = get_values_ubyte;
  1027.       rb->PutRow = put_row_ubyte;
  1028.       rb->PutRowRGB = NULL;
  1029.       rb->PutMonoRow = put_mono_row_ubyte;
  1030.       rb->PutValues = put_values_ubyte;
  1031.       rb->PutMonoValues = put_mono_values_ubyte;
  1032.       pixelSize = sizeof(GLubyte);
  1033.       break;
  1034.    case GL_DEPTH_COMPONENT:
  1035.    case GL_DEPTH_COMPONENT16:
  1036.       rb->Format = MESA_FORMAT_Z16;
  1037.       rb->DataType = GL_UNSIGNED_SHORT;
  1038.       rb->GetPointer = get_pointer_ushort;
  1039.       rb->GetRow = get_row_ushort;
  1040.       rb->GetValues = get_values_ushort;
  1041.       rb->PutRow = put_row_ushort;
  1042.       rb->PutRowRGB = NULL;
  1043.       rb->PutMonoRow = put_mono_row_ushort;
  1044.       rb->PutValues = put_values_ushort;
  1045.       rb->PutMonoValues = put_mono_values_ushort;
  1046.       pixelSize = sizeof(GLushort);
  1047.       break;
  1048.    case GL_DEPTH_COMPONENT24:
  1049.       rb->DataType = GL_UNSIGNED_INT;
  1050.       rb->GetPointer = get_pointer_uint;
  1051.       rb->GetRow = get_row_uint;
  1052.       rb->GetValues = get_values_uint;
  1053.       rb->PutRow = put_row_uint;
  1054.       rb->PutRowRGB = NULL;
  1055.       rb->PutMonoRow = put_mono_row_uint;
  1056.       rb->PutValues = put_values_uint;
  1057.       rb->PutMonoValues = put_mono_values_uint;
  1058.       rb->Format = MESA_FORMAT_X8_Z24;
  1059.       pixelSize = sizeof(GLuint);
  1060.       break;
  1061.    case GL_DEPTH_COMPONENT32:
  1062.       rb->DataType = GL_UNSIGNED_INT;
  1063.       rb->GetPointer = get_pointer_uint;
  1064.       rb->GetRow = get_row_uint;
  1065.       rb->GetValues = get_values_uint;
  1066.       rb->PutRow = put_row_uint;
  1067.       rb->PutRowRGB = NULL;
  1068.       rb->PutMonoRow = put_mono_row_uint;
  1069.       rb->PutValues = put_values_uint;
  1070.       rb->PutMonoValues = put_mono_values_uint;
  1071.       rb->Format = MESA_FORMAT_Z32;
  1072.       pixelSize = sizeof(GLuint);
  1073.       break;
  1074.    case GL_DEPTH_STENCIL_EXT:
  1075.    case GL_DEPTH24_STENCIL8_EXT:
  1076.       rb->Format = MESA_FORMAT_Z24_S8;
  1077.       rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
  1078.       rb->GetPointer = get_pointer_uint;
  1079.       rb->GetRow = get_row_uint;
  1080.       rb->GetValues = get_values_uint;
  1081.       rb->PutRow = put_row_uint;
  1082.       rb->PutRowRGB = NULL;
  1083.       rb->PutMonoRow = put_mono_row_uint;
  1084.       rb->PutValues = put_values_uint;
  1085.       rb->PutMonoValues = put_mono_values_uint;
  1086.       pixelSize = sizeof(GLuint);
  1087.       break;
  1088.    default:
  1089.       _mesa_problem(ctx, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
  1090.       return GL_FALSE;
  1091.    }
  1092.  
  1093.    ASSERT(rb->DataType);
  1094.    ASSERT(rb->GetPointer);
  1095.    ASSERT(rb->GetRow);
  1096.    ASSERT(rb->GetValues);
  1097.    ASSERT(rb->PutRow);
  1098.    ASSERT(rb->PutMonoRow);
  1099.    ASSERT(rb->PutValues);
  1100.    ASSERT(rb->PutMonoValues);
  1101.  
  1102.    /* free old buffer storage */
  1103.    if (rb->Data) {
  1104.       free(rb->Data);
  1105.       rb->Data = NULL;
  1106.    }
  1107.  
  1108.    if (width > 0 && height > 0) {
  1109.       /* allocate new buffer storage */
  1110.       rb->Data = malloc(width * height * pixelSize);
  1111.  
  1112.       if (rb->Data == NULL) {
  1113.          rb->Width = 0;
  1114.          rb->Height = 0;
  1115.          _mesa_error(ctx, GL_OUT_OF_MEMORY,
  1116.                      "software renderbuffer allocation (%d x %d x %d)",
  1117.                      width, height, pixelSize);
  1118.          return GL_FALSE;
  1119.       }
  1120.    }
  1121.  
  1122.    rb->Width = width;
  1123.    rb->Height = height;
  1124.    rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
  1125.    ASSERT(rb->_BaseFormat);
  1126.  
  1127.    return GL_TRUE;
  1128. }
  1129.  
  1130.  
  1131.  
  1132. /**********************************************************************/
  1133. /**********************************************************************/
  1134. /**********************************************************************/
  1135.  
  1136.  
  1137. /**
  1138.  * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
  1139.  * buffer wrapper around an existing RGB renderbuffer (hw or sw).
  1140.  *
  1141.  * When PutRow is called (for example), we store the alpha values in
  1142.  * this buffer, then pass on the PutRow call to the wrapped RGB
  1143.  * buffer.
  1144.  */
  1145.  
  1146.  
  1147. static GLboolean
  1148. alloc_storage_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb,
  1149.                      GLenum internalFormat, GLuint width, GLuint height)
  1150. {
  1151.    ASSERT(arb != arb->Wrapped);
  1152.    ASSERT(arb->Format == MESA_FORMAT_A8);
  1153.  
  1154.    /* first, pass the call to the wrapped RGB buffer */
  1155.    if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat,
  1156.                                   width, height)) {
  1157.       return GL_FALSE;
  1158.    }
  1159.  
  1160.    /* next, resize my alpha buffer */
  1161.    if (arb->Data) {
  1162.       free(arb->Data);
  1163.    }
  1164.  
  1165.    arb->Data = malloc(width * height * sizeof(GLubyte));
  1166.    if (arb->Data == NULL) {
  1167.       arb->Width = 0;
  1168.       arb->Height = 0;
  1169.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation");
  1170.       return GL_FALSE;
  1171.    }
  1172.  
  1173.    arb->Width = width;
  1174.    arb->Height = height;
  1175.  
  1176.    return GL_TRUE;
  1177. }
  1178.  
  1179.  
  1180. /**
  1181.  * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
  1182.  */
  1183. static void
  1184. delete_renderbuffer_alpha8(struct gl_renderbuffer *arb)
  1185. {
  1186.    if (arb->Data) {
  1187.       free(arb->Data);
  1188.    }
  1189.    ASSERT(arb->Wrapped);
  1190.    ASSERT(arb != arb->Wrapped);
  1191.    arb->Wrapped->Delete(arb->Wrapped);
  1192.    arb->Wrapped = NULL;
  1193.    free(arb);
  1194. }
  1195.  
  1196.  
  1197. static void *
  1198. get_pointer_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb,
  1199.                    GLint x, GLint y)
  1200. {
  1201.    return NULL;   /* don't allow direct access! */
  1202. }
  1203.  
  1204.  
  1205. static void
  1206. get_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
  1207.                GLint x, GLint y, void *values)
  1208. {
  1209.    /* NOTE: 'values' is RGBA format! */
  1210.    const GLubyte *src = (const GLubyte *) arb->Data + y * arb->Width + x;
  1211.    GLubyte *dst = (GLubyte *) values;
  1212.    GLuint i;
  1213.    ASSERT(arb != arb->Wrapped);
  1214.    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
  1215.    /* first, pass the call to the wrapped RGB buffer */
  1216.    arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values);
  1217.    /* second, fill in alpha values from this buffer! */
  1218.    for (i = 0; i < count; i++) {
  1219.       dst[i * 4 + 3] = src[i];
  1220.    }
  1221. }
  1222.  
  1223.  
  1224. static void
  1225. get_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
  1226.                   const GLint x[], const GLint y[], void *values)
  1227. {
  1228.    GLubyte *dst = (GLubyte *) values;
  1229.    GLuint i;
  1230.    ASSERT(arb != arb->Wrapped);
  1231.    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
  1232.    /* first, pass the call to the wrapped RGB buffer */
  1233.    arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values);
  1234.    /* second, fill in alpha values from this buffer! */
  1235.    for (i = 0; i < count; i++) {
  1236.       const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
  1237.       dst[i * 4 + 3] = *src;
  1238.    }
  1239. }
  1240.  
  1241.  
  1242. static void
  1243. put_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
  1244.                GLint x, GLint y, const void *values, const GLubyte *mask)
  1245. {
  1246.    const GLubyte *src = (const GLubyte *) values;
  1247.    GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
  1248.    GLuint i;
  1249.    ASSERT(arb != arb->Wrapped);
  1250.    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
  1251.    /* first, pass the call to the wrapped RGB buffer */
  1252.    arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask);
  1253.    /* second, store alpha in our buffer */
  1254.    for (i = 0; i < count; i++) {
  1255.       if (!mask || mask[i]) {
  1256.          dst[i] = src[i * 4 + 3];
  1257.       }
  1258.    }
  1259. }
  1260.  
  1261.  
  1262. static void
  1263. put_row_rgb_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
  1264.                    GLint x, GLint y, const void *values, const GLubyte *mask)
  1265. {
  1266.    const GLubyte *src = (const GLubyte *) values;
  1267.    GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
  1268.    GLuint i;
  1269.    ASSERT(arb != arb->Wrapped);
  1270.    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
  1271.    /* first, pass the call to the wrapped RGB buffer */
  1272.    arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask);
  1273.    /* second, store alpha in our buffer */
  1274.    for (i = 0; i < count; i++) {
  1275.       if (!mask || mask[i]) {
  1276.          dst[i] = src[i * 4 + 3];
  1277.       }
  1278.    }
  1279. }
  1280.  
  1281.  
  1282. static void
  1283. put_mono_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
  1284.                     GLint x, GLint y, const void *value, const GLubyte *mask)
  1285. {
  1286.    const GLubyte val = ((const GLubyte *) value)[3];
  1287.    GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
  1288.    ASSERT(arb != arb->Wrapped);
  1289.    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
  1290.    /* first, pass the call to the wrapped RGB buffer */
  1291.    arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask);
  1292.    /* second, store alpha in our buffer */
  1293.    if (mask) {
  1294.       GLuint i;
  1295.       for (i = 0; i < count; i++) {
  1296.          if (mask[i]) {
  1297.             dst[i] = val;
  1298.          }
  1299.       }
  1300.    }
  1301.    else {
  1302.       memset(dst, val, count);
  1303.    }
  1304. }
  1305.  
  1306.  
  1307. static void
  1308. put_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count,
  1309.                   const GLint x[], const GLint y[],
  1310.                   const void *values, const GLubyte *mask)
  1311. {
  1312.    const GLubyte *src = (const GLubyte *) values;
  1313.    GLuint i;
  1314.    ASSERT(arb != arb->Wrapped);
  1315.    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
  1316.    /* first, pass the call to the wrapped RGB buffer */
  1317.    arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask);
  1318.    /* second, store alpha in our buffer */
  1319.    for (i = 0; i < count; i++) {
  1320.       if (!mask || mask[i]) {
  1321.          GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
  1322.          *dst = src[i * 4 + 3];
  1323.       }
  1324.    }
  1325. }
  1326.  
  1327.  
  1328. static void
  1329. put_mono_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb,
  1330.                        GLuint count, const GLint x[], const GLint y[],
  1331.                        const void *value, const GLubyte *mask)
  1332. {
  1333.    const GLubyte val = ((const GLubyte *) value)[3];
  1334.    GLuint i;
  1335.    ASSERT(arb != arb->Wrapped);
  1336.    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
  1337.    /* first, pass the call to the wrapped RGB buffer */
  1338.    arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask);
  1339.    /* second, store alpha in our buffer */
  1340.    for (i = 0; i < count; i++) {
  1341.       if (!mask || mask[i]) {
  1342.          GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
  1343.          *dst = val;
  1344.       }
  1345.    }
  1346. }
  1347.  
  1348.  
  1349. static void
  1350. copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src)
  1351. {
  1352.    ASSERT(dst->Format == MESA_FORMAT_A8);
  1353.    ASSERT(src->Format == MESA_FORMAT_A8);
  1354.    ASSERT(dst->Width == src->Width);
  1355.    ASSERT(dst->Height == src->Height);
  1356.  
  1357.    memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte));
  1358. }
  1359.  
  1360.  
  1361. /**********************************************************************/
  1362. /**********************************************************************/
  1363. /**********************************************************************/
  1364.  
  1365.  
  1366. /**
  1367.  * Default GetPointer routine.  Always return NULL to indicate that
  1368.  * direct buffer access is not supported.
  1369.  */
  1370. static void *
  1371. nop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
  1372. {
  1373.    return NULL;
  1374. }
  1375.  
  1376.  
  1377. /**
  1378.  * Initialize the fields of a gl_renderbuffer to default values.
  1379.  */
  1380. void
  1381. _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
  1382. {
  1383.    _glthread_INIT_MUTEX(rb->Mutex);
  1384.  
  1385.    rb->Magic = RB_MAGIC;
  1386.    rb->ClassID = 0;
  1387.    rb->Name = name;
  1388.    rb->RefCount = 0;
  1389.    rb->Delete = _mesa_delete_renderbuffer;
  1390.  
  1391.    /* The rest of these should be set later by the caller of this function or
  1392.     * the AllocStorage method:
  1393.     */
  1394.    rb->AllocStorage = NULL;
  1395.  
  1396.    rb->Width = 0;
  1397.    rb->Height = 0;
  1398.    rb->InternalFormat = GL_NONE;
  1399.    rb->Format = MESA_FORMAT_NONE;
  1400.  
  1401.    rb->DataType = GL_NONE;
  1402.    rb->Data = NULL;
  1403.  
  1404.    /* Point back to ourself so that we don't have to check for Wrapped==NULL
  1405.     * all over the drivers.
  1406.     */
  1407.    rb->Wrapped = rb;
  1408.  
  1409.    rb->GetPointer = nop_get_pointer;
  1410.    rb->GetRow = NULL;
  1411.    rb->GetValues = NULL;
  1412.    rb->PutRow = NULL;
  1413.    rb->PutRowRGB = NULL;
  1414.    rb->PutMonoRow = NULL;
  1415.    rb->PutValues = NULL;
  1416.    rb->PutMonoValues = NULL;
  1417. }
  1418.  
  1419.  
  1420. /**
  1421.  * Allocate a new gl_renderbuffer object.  This can be used for user-created
  1422.  * renderbuffers or window-system renderbuffers.
  1423.  */
  1424. struct gl_renderbuffer *
  1425. _mesa_new_renderbuffer(struct gl_context *ctx, GLuint name)
  1426. {
  1427.    struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
  1428.    if (rb) {
  1429.       _mesa_init_renderbuffer(rb, name);
  1430.    }
  1431.    return rb;
  1432. }
  1433.  
  1434.  
  1435. /**
  1436.  * Delete a gl_framebuffer.
  1437.  * This is the default function for renderbuffer->Delete().
  1438.  */
  1439. void
  1440. _mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
  1441. {
  1442.    if (rb->Data) {
  1443.       free(rb->Data);
  1444.    }
  1445.    free(rb);
  1446. }
  1447.  
  1448.  
  1449. /**
  1450.  * Allocate a software-based renderbuffer.  This is called via the
  1451.  * ctx->Driver.NewRenderbuffer() function when the user creates a new
  1452.  * renderbuffer.
  1453.  * This would not be used for hardware-based renderbuffers.
  1454.  */
  1455. struct gl_renderbuffer *
  1456. _mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name)
  1457. {
  1458.    struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
  1459.    if (rb) {
  1460.       rb->AllocStorage = _mesa_soft_renderbuffer_storage;
  1461.       /* Normally, one would setup the PutRow, GetRow, etc functions here.
  1462.        * But we're doing that in the _mesa_soft_renderbuffer_storage() function
  1463.        * instead.
  1464.        */
  1465.    }
  1466.    return rb;
  1467. }
  1468.  
  1469.  
  1470. /**
  1471.  * Add software-based color renderbuffers to the given framebuffer.
  1472.  * This is a helper routine for device drivers when creating a
  1473.  * window system framebuffer (not a user-created render/framebuffer).
  1474.  * Once this function is called, you can basically forget about this
  1475.  * renderbuffer; core Mesa will handle all the buffer management and
  1476.  * rendering!
  1477.  */
  1478. GLboolean
  1479. _mesa_add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
  1480.                               GLuint rgbBits, GLuint alphaBits,
  1481.                               GLboolean frontLeft, GLboolean backLeft,
  1482.                               GLboolean frontRight, GLboolean backRight)
  1483. {
  1484.    GLuint b;
  1485.  
  1486.    if (rgbBits > 16 || alphaBits > 16) {
  1487.       _mesa_problem(ctx,
  1488.                     "Unsupported bit depth in _mesa_add_color_renderbuffers");
  1489.       return GL_FALSE;
  1490.    }
  1491.  
  1492.    assert(MAX_COLOR_ATTACHMENTS >= 4);
  1493.  
  1494.    for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
  1495.       struct gl_renderbuffer *rb;
  1496.  
  1497.       if (b == BUFFER_FRONT_LEFT && !frontLeft)
  1498.          continue;
  1499.       else if (b == BUFFER_BACK_LEFT && !backLeft)
  1500.          continue;
  1501.       else if (b == BUFFER_FRONT_RIGHT && !frontRight)
  1502.          continue;
  1503.       else if (b == BUFFER_BACK_RIGHT && !backRight)
  1504.          continue;
  1505.  
  1506.       assert(fb->Attachment[b].Renderbuffer == NULL);
  1507.  
  1508.       rb = _mesa_new_renderbuffer(ctx, 0);
  1509.       if (!rb) {
  1510.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
  1511.          return GL_FALSE;
  1512.       }
  1513.  
  1514.       if (rgbBits <= 8) {
  1515.          if (alphaBits)
  1516.             rb->Format = MESA_FORMAT_RGBA8888;
  1517.          else
  1518.             rb->Format = MESA_FORMAT_RGB888;
  1519.       }
  1520.       else {
  1521.          assert(rgbBits <= 16);
  1522.          rb->Format = MESA_FORMAT_NONE; /*XXX RGBA16;*/
  1523.       }
  1524.       rb->InternalFormat = GL_RGBA;
  1525.  
  1526.       rb->AllocStorage = _mesa_soft_renderbuffer_storage;
  1527.       _mesa_add_renderbuffer(fb, b, rb);
  1528.    }
  1529.  
  1530.    return GL_TRUE;
  1531. }
  1532.  
  1533.  
  1534. /**
  1535.  * Add software-based alpha renderbuffers to the given framebuffer.
  1536.  * This is a helper routine for device drivers when creating a
  1537.  * window system framebuffer (not a user-created render/framebuffer).
  1538.  * Once this function is called, you can basically forget about this
  1539.  * renderbuffer; core Mesa will handle all the buffer management and
  1540.  * rendering!
  1541.  */
  1542. GLboolean
  1543. _mesa_add_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
  1544.                               GLuint alphaBits,
  1545.                               GLboolean frontLeft, GLboolean backLeft,
  1546.                               GLboolean frontRight, GLboolean backRight)
  1547. {
  1548.    GLuint b;
  1549.  
  1550.    /* for window system framebuffers only! */
  1551.    assert(fb->Name == 0);
  1552.  
  1553.    if (alphaBits > 8) {
  1554.       _mesa_problem(ctx,
  1555.                     "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
  1556.       return GL_FALSE;
  1557.    }
  1558.  
  1559.    assert(MAX_COLOR_ATTACHMENTS >= 4);
  1560.  
  1561.    /* Wrap each of the RGB color buffers with an alpha renderbuffer.
  1562.     */
  1563.    for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
  1564.       struct gl_renderbuffer *arb;
  1565.  
  1566.       if (b == BUFFER_FRONT_LEFT && !frontLeft)
  1567.          continue;
  1568.       else if (b == BUFFER_BACK_LEFT && !backLeft)
  1569.          continue;
  1570.       else if (b == BUFFER_FRONT_RIGHT && !frontRight)
  1571.          continue;
  1572.       else if (b == BUFFER_BACK_RIGHT && !backRight)
  1573.          continue;
  1574.  
  1575.       /* the RGB buffer to wrap must already exist!! */
  1576.       assert(fb->Attachment[b].Renderbuffer);
  1577.  
  1578.       /* only GLubyte supported for now */
  1579.       assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
  1580.  
  1581.       /* allocate alpha renderbuffer */
  1582.       arb = _mesa_new_renderbuffer(ctx, 0);
  1583.       if (!arb) {
  1584.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
  1585.          return GL_FALSE;
  1586.       }
  1587.  
  1588.       /* wrap the alpha renderbuffer around the RGB renderbuffer */
  1589.       arb->Wrapped = fb->Attachment[b].Renderbuffer;
  1590.  
  1591.       /* Set up my alphabuffer fields and plug in my functions.
  1592.        * The functions will put/get the alpha values from/to RGBA arrays
  1593.        * and then call the wrapped buffer's functions to handle the RGB
  1594.        * values.
  1595.        */
  1596.       arb->InternalFormat = arb->Wrapped->InternalFormat;
  1597.       arb->Format         = MESA_FORMAT_A8;
  1598.       arb->DataType       = arb->Wrapped->DataType;
  1599.       arb->AllocStorage   = alloc_storage_alpha8;
  1600.       arb->Delete         = delete_renderbuffer_alpha8;
  1601.       arb->GetPointer     = get_pointer_alpha8;
  1602.       arb->GetRow         = get_row_alpha8;
  1603.       arb->GetValues      = get_values_alpha8;
  1604.       arb->PutRow         = put_row_alpha8;
  1605.       arb->PutRowRGB      = put_row_rgb_alpha8;
  1606.       arb->PutMonoRow     = put_mono_row_alpha8;
  1607.       arb->PutValues      = put_values_alpha8;
  1608.       arb->PutMonoValues  = put_mono_values_alpha8;
  1609.  
  1610.       /* clear the pointer to avoid assertion/sanity check failure later */
  1611.       fb->Attachment[b].Renderbuffer = NULL;
  1612.  
  1613.       /* plug the alpha renderbuffer into the colorbuffer attachment */
  1614.       _mesa_add_renderbuffer(fb, b, arb);
  1615.    }
  1616.  
  1617.    return GL_TRUE;
  1618. }
  1619.  
  1620.  
  1621. /**
  1622.  * For framebuffers that use a software alpha channel wrapper
  1623.  * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
  1624.  * copy the back buffer alpha channel into the front buffer alpha channel.
  1625.  */
  1626. void
  1627. _mesa_copy_soft_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb)
  1628. {
  1629.    if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
  1630.        fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer)
  1631.       copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer,
  1632.                          fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
  1633.  
  1634.  
  1635.    if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
  1636.        fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer)
  1637.       copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer,
  1638.                          fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
  1639. }
  1640.  
  1641.  
  1642. /**
  1643.  * Add a software-based depth renderbuffer to the given framebuffer.
  1644.  * This is a helper routine for device drivers when creating a
  1645.  * window system framebuffer (not a user-created render/framebuffer).
  1646.  * Once this function is called, you can basically forget about this
  1647.  * renderbuffer; core Mesa will handle all the buffer management and
  1648.  * rendering!
  1649.  */
  1650. GLboolean
  1651. _mesa_add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
  1652.                              GLuint depthBits)
  1653. {
  1654.    struct gl_renderbuffer *rb;
  1655.  
  1656.    if (depthBits > 32) {
  1657.       _mesa_problem(ctx,
  1658.                     "Unsupported depthBits in _mesa_add_depth_renderbuffer");
  1659.       return GL_FALSE;
  1660.    }
  1661.  
  1662.    assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
  1663.  
  1664.    rb = _mesa_new_renderbuffer(ctx, 0);
  1665.    if (!rb) {
  1666.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
  1667.       return GL_FALSE;
  1668.    }
  1669.  
  1670.    if (depthBits <= 16) {
  1671.       rb->Format = MESA_FORMAT_Z16;
  1672.       rb->InternalFormat = GL_DEPTH_COMPONENT16;
  1673.    }
  1674.    else if (depthBits <= 24) {
  1675.       rb->Format = MESA_FORMAT_X8_Z24;
  1676.       rb->InternalFormat = GL_DEPTH_COMPONENT24;
  1677.    }
  1678.    else {
  1679.       rb->Format = MESA_FORMAT_Z32;
  1680.       rb->InternalFormat = GL_DEPTH_COMPONENT32;
  1681.    }
  1682.  
  1683.    rb->AllocStorage = _mesa_soft_renderbuffer_storage;
  1684.    _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
  1685.  
  1686.    return GL_TRUE;
  1687. }
  1688.  
  1689.  
  1690. /**
  1691.  * Add a software-based stencil renderbuffer to the given framebuffer.
  1692.  * This is a helper routine for device drivers when creating a
  1693.  * window system framebuffer (not a user-created render/framebuffer).
  1694.  * Once this function is called, you can basically forget about this
  1695.  * renderbuffer; core Mesa will handle all the buffer management and
  1696.  * rendering!
  1697.  */
  1698. GLboolean
  1699. _mesa_add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
  1700.                                GLuint stencilBits)
  1701. {
  1702.    struct gl_renderbuffer *rb;
  1703.  
  1704.    if (stencilBits > 16) {
  1705.       _mesa_problem(ctx,
  1706.                   "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
  1707.       return GL_FALSE;
  1708.    }
  1709.  
  1710.    assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
  1711.  
  1712.    rb = _mesa_new_renderbuffer(ctx, 0);
  1713.    if (!rb) {
  1714.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
  1715.       return GL_FALSE;
  1716.    }
  1717.  
  1718.    assert(stencilBits <= 8);
  1719.    rb->Format = MESA_FORMAT_S8;
  1720.    rb->InternalFormat = GL_STENCIL_INDEX8;
  1721.  
  1722.    rb->AllocStorage = _mesa_soft_renderbuffer_storage;
  1723.    _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
  1724.  
  1725.    return GL_TRUE;
  1726. }
  1727.  
  1728.  
  1729. /**
  1730.  * Add a software-based accumulation renderbuffer to the given framebuffer.
  1731.  * This is a helper routine for device drivers when creating a
  1732.  * window system framebuffer (not a user-created render/framebuffer).
  1733.  * Once this function is called, you can basically forget about this
  1734.  * renderbuffer; core Mesa will handle all the buffer management and
  1735.  * rendering!
  1736.  */
  1737. GLboolean
  1738. _mesa_add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
  1739.                              GLuint redBits, GLuint greenBits,
  1740.                              GLuint blueBits, GLuint alphaBits)
  1741. {
  1742.    struct gl_renderbuffer *rb;
  1743.  
  1744.    if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
  1745.       _mesa_problem(ctx,
  1746.                     "Unsupported accumBits in _mesa_add_accum_renderbuffer");
  1747.       return GL_FALSE;
  1748.    }
  1749.  
  1750.    assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
  1751.  
  1752.    rb = _mesa_new_renderbuffer(ctx, 0);
  1753.    if (!rb) {
  1754.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
  1755.       return GL_FALSE;
  1756.    }
  1757.  
  1758.    rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
  1759.    rb->InternalFormat = GL_RGBA16_SNORM;
  1760.    rb->AllocStorage = _mesa_soft_renderbuffer_storage;
  1761.    _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
  1762.  
  1763.    return GL_TRUE;
  1764. }
  1765.  
  1766.  
  1767.  
  1768. /**
  1769.  * Add a software-based aux renderbuffer to the given framebuffer.
  1770.  * This is a helper routine for device drivers when creating a
  1771.  * window system framebuffer (not a user-created render/framebuffer).
  1772.  * Once this function is called, you can basically forget about this
  1773.  * renderbuffer; core Mesa will handle all the buffer management and
  1774.  * rendering!
  1775.  *
  1776.  * NOTE: color-index aux buffers not supported.
  1777.  */
  1778. GLboolean
  1779. _mesa_add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
  1780.                             GLuint colorBits, GLuint numBuffers)
  1781. {
  1782.    GLuint i;
  1783.  
  1784.    if (colorBits > 16) {
  1785.       _mesa_problem(ctx,
  1786.                     "Unsupported accumBits in _mesa_add_aux_renderbuffers");
  1787.       return GL_FALSE;
  1788.    }
  1789.  
  1790.    assert(numBuffers <= MAX_AUX_BUFFERS);
  1791.  
  1792.    for (i = 0; i < numBuffers; i++) {
  1793.       struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
  1794.  
  1795.       assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
  1796.  
  1797.       if (!rb) {
  1798.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer");
  1799.          return GL_FALSE;
  1800.       }
  1801.  
  1802.       assert (colorBits <= 8);
  1803.       rb->Format = MESA_FORMAT_RGBA8888;
  1804.       rb->InternalFormat = GL_RGBA;
  1805.  
  1806.       rb->AllocStorage = _mesa_soft_renderbuffer_storage;
  1807.       _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
  1808.    }
  1809.    return GL_TRUE;
  1810. }
  1811.  
  1812.  
  1813. /**
  1814.  * Create/attach software-based renderbuffers to the given framebuffer.
  1815.  * This is a helper routine for device drivers.  Drivers can just as well
  1816.  * call the individual _mesa_add_*_renderbuffer() routines directly.
  1817.  */
  1818. void
  1819. _mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
  1820.                              GLboolean color,
  1821.                              GLboolean depth,
  1822.                              GLboolean stencil,
  1823.                              GLboolean accum,
  1824.                              GLboolean alpha,
  1825.                              GLboolean aux)
  1826. {
  1827.    GLboolean frontLeft = GL_TRUE;
  1828.    GLboolean backLeft = fb->Visual.doubleBufferMode;
  1829.    GLboolean frontRight = fb->Visual.stereoMode;
  1830.    GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
  1831.  
  1832.    if (color) {
  1833.       assert(fb->Visual.redBits == fb->Visual.greenBits);
  1834.       assert(fb->Visual.redBits == fb->Visual.blueBits);
  1835.       _mesa_add_color_renderbuffers(NULL, fb,
  1836.                                     fb->Visual.redBits,
  1837.                                     fb->Visual.alphaBits,
  1838.                                     frontLeft, backLeft,
  1839.                                     frontRight, backRight);
  1840.    }
  1841.  
  1842.    if (depth) {
  1843.       assert(fb->Visual.depthBits > 0);
  1844.       _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
  1845.    }
  1846.  
  1847.    if (stencil) {
  1848.       assert(fb->Visual.stencilBits > 0);
  1849.       _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
  1850.    }
  1851.  
  1852.    if (accum) {
  1853.       assert(fb->Visual.accumRedBits > 0);
  1854.       assert(fb->Visual.accumGreenBits > 0);
  1855.       assert(fb->Visual.accumBlueBits > 0);
  1856.       _mesa_add_accum_renderbuffer(NULL, fb,
  1857.                                    fb->Visual.accumRedBits,
  1858.                                    fb->Visual.accumGreenBits,
  1859.                                    fb->Visual.accumBlueBits,
  1860.                                    fb->Visual.accumAlphaBits);
  1861.    }
  1862.  
  1863.    if (aux) {
  1864.       assert(fb->Visual.numAuxBuffers > 0);
  1865.       _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
  1866.                                   fb->Visual.numAuxBuffers);
  1867.    }
  1868.  
  1869.    if (alpha) {
  1870.       assert(fb->Visual.alphaBits > 0);
  1871.       _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits,
  1872.                                     frontLeft, backLeft,
  1873.                                     frontRight, backRight);
  1874.    }
  1875.  
  1876. #if 0
  1877.    if (multisample) {
  1878.       /* maybe someday */
  1879.    }
  1880. #endif
  1881. }
  1882.  
  1883.  
  1884. /**
  1885.  * Attach a renderbuffer to a framebuffer.
  1886.  */
  1887. void
  1888. _mesa_add_renderbuffer(struct gl_framebuffer *fb,
  1889.                        GLuint bufferName, struct gl_renderbuffer *rb)
  1890. {
  1891.    assert(fb);
  1892.    assert(rb);
  1893.    assert(bufferName < BUFFER_COUNT);
  1894.  
  1895.    /* There should be no previous renderbuffer on this attachment point,
  1896.     * with the exception of depth/stencil since the same renderbuffer may
  1897.     * be used for both.
  1898.     */
  1899.    assert(bufferName == BUFFER_DEPTH ||
  1900.           bufferName == BUFFER_STENCIL ||
  1901.           fb->Attachment[bufferName].Renderbuffer == NULL);
  1902.  
  1903.    /* winsys vs. user-created buffer cross check */
  1904.    if (fb->Name) {
  1905.       assert(rb->Name);
  1906.    }
  1907.    else {
  1908.       assert(!rb->Name);
  1909.    }
  1910.  
  1911.    fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
  1912.    fb->Attachment[bufferName].Complete = GL_TRUE;
  1913.    _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
  1914. }
  1915.  
  1916.  
  1917. /**
  1918.  * Remove the named renderbuffer from the given framebuffer.
  1919.  */
  1920. void
  1921. _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName)
  1922. {
  1923.    struct gl_renderbuffer *rb;
  1924.  
  1925.    assert(bufferName < BUFFER_COUNT);
  1926.  
  1927.    rb = fb->Attachment[bufferName].Renderbuffer;
  1928.    if (!rb)
  1929.       return;
  1930.  
  1931.    _mesa_reference_renderbuffer(&rb, NULL);
  1932.  
  1933.    fb->Attachment[bufferName].Renderbuffer = NULL;
  1934. }
  1935.  
  1936.  
  1937. /**
  1938.  * Set *ptr to point to rb.  If *ptr points to another renderbuffer,
  1939.  * dereference that buffer first.  The new renderbuffer's refcount will
  1940.  * be incremented.  The old renderbuffer's refcount will be decremented.
  1941.  */
  1942. void
  1943. _mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
  1944.                              struct gl_renderbuffer *rb)
  1945. {
  1946.    assert(ptr);
  1947.    if (*ptr == rb) {
  1948.       /* no change */
  1949.       return;
  1950.    }
  1951.  
  1952.    if (*ptr) {
  1953.       /* Unreference the old renderbuffer */
  1954.       GLboolean deleteFlag = GL_FALSE;
  1955.       struct gl_renderbuffer *oldRb = *ptr;
  1956.  
  1957.       assert(oldRb->Magic == RB_MAGIC);
  1958.       _glthread_LOCK_MUTEX(oldRb->Mutex);
  1959.       assert(oldRb->Magic == RB_MAGIC);
  1960.       ASSERT(oldRb->RefCount > 0);
  1961.       oldRb->RefCount--;
  1962.       /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
  1963.       deleteFlag = (oldRb->RefCount == 0);
  1964.       _glthread_UNLOCK_MUTEX(oldRb->Mutex);
  1965.  
  1966.       if (deleteFlag) {
  1967.          oldRb->Magic = 0; /* now invalid memory! */
  1968.          oldRb->Delete(oldRb);
  1969.       }
  1970.  
  1971.       *ptr = NULL;
  1972.    }
  1973.    assert(!*ptr);
  1974.  
  1975.    if (rb) {
  1976.       assert(rb->Magic == RB_MAGIC);
  1977.       /* reference new renderbuffer */
  1978.       _glthread_LOCK_MUTEX(rb->Mutex);
  1979.       rb->RefCount++;
  1980.       /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
  1981.       _glthread_UNLOCK_MUTEX(rb->Mutex);
  1982.       *ptr = rb;
  1983.    }
  1984. }
  1985.  
  1986.  
  1987. /**
  1988.  * Create a new combined depth/stencil renderbuffer for implementing
  1989.  * the GL_EXT_packed_depth_stencil extension.
  1990.  * \return new depth/stencil renderbuffer
  1991.  */
  1992. struct gl_renderbuffer *
  1993. _mesa_new_depthstencil_renderbuffer(struct gl_context *ctx, GLuint name)
  1994. {
  1995.    struct gl_renderbuffer *dsrb;
  1996.  
  1997.    dsrb = _mesa_new_renderbuffer(ctx, name);
  1998.    if (!dsrb)
  1999.       return NULL;
  2000.  
  2001.    /* init fields not covered by _mesa_new_renderbuffer() */
  2002.    dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT;
  2003.    dsrb->Format = MESA_FORMAT_Z24_S8;
  2004.    dsrb->AllocStorage = _mesa_soft_renderbuffer_storage;
  2005.  
  2006.    return dsrb;
  2007. }
  2008.