Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28.  /*
  29.   * Authors:
  30.   *   Brian Paul
  31.   */
  32.  
  33. #include "main/imports.h"
  34. #include "main/image.h"
  35. #include "main/macros.h"
  36.  
  37. #include "st_debug.h"
  38. #include "st_context.h"
  39. #include "st_cb_accum.h"
  40. #include "st_cb_fbo.h"
  41. #include "st_texture.h"
  42. #include "pipe/p_context.h"
  43. #include "pipe/p_defines.h"
  44. #include "util/u_inlines.h"
  45. #include "util/u_tile.h"
  46.  
  47.  
  48. #if FEATURE_accum
  49.  
  50. /**
  51.  * For hardware that supports deep color buffers, we could accelerate
  52.  * most/all the accum operations with blending/texturing.
  53.  * For now, just use the get/put_tile() functions and do things in software.
  54.  */
  55.  
  56.  
  57. void
  58. st_clear_accum_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
  59. {
  60.    struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
  61.    const GLint xpos = ctx->DrawBuffer->_Xmin;
  62.    const GLint ypos = ctx->DrawBuffer->_Ymin;
  63.    const GLint width = ctx->DrawBuffer->_Xmax - xpos;
  64.    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
  65.    size_t stride = acc_strb->stride;
  66.    GLubyte *data = acc_strb->data;
  67.  
  68.    if(!data)
  69.       return;
  70.    
  71.    switch (acc_strb->format) {
  72.    case PIPE_FORMAT_R16G16B16A16_SNORM:
  73.       {
  74.          GLshort r = FLOAT_TO_SHORT(ctx->Accum.ClearColor[0]);
  75.          GLshort g = FLOAT_TO_SHORT(ctx->Accum.ClearColor[1]);
  76.          GLshort b = FLOAT_TO_SHORT(ctx->Accum.ClearColor[2]);
  77.          GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
  78.          int i, j;
  79.          for (i = 0; i < height; i++) {
  80.             GLshort *dst = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
  81.             for (j = 0; j < width; j++) {
  82.                dst[0] = r;
  83.                dst[1] = g;
  84.                dst[2] = b;
  85.                dst[3] = a;
  86.                dst += 4;
  87.             }
  88.          }
  89.       }
  90.       break;
  91.    default:
  92.       _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
  93.    }
  94. }
  95.  
  96.  
  97. /** For ADD/MULT */
  98. static void
  99. accum_mad(struct gl_context *ctx, GLfloat scale, GLfloat bias,
  100.           GLint xpos, GLint ypos, GLint width, GLint height,
  101.           struct st_renderbuffer *acc_strb)
  102. {
  103.    size_t stride = acc_strb->stride;
  104.    GLubyte *data = acc_strb->data;
  105.  
  106.    switch (acc_strb->format) {
  107.    case PIPE_FORMAT_R16G16B16A16_SNORM:
  108.       {
  109.          int i, j;
  110.          for (i = 0; i < height; i++) {
  111.             GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
  112.             for (j = 0; j < width * 4; j++) {
  113.                float val = SHORT_TO_FLOAT(*acc) * scale + bias;
  114.                *acc++ = FLOAT_TO_SHORT(val);
  115.             }
  116.          }
  117.       }
  118.       break;
  119.    default:
  120.       _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
  121.    }
  122. }
  123.  
  124.  
  125. static void
  126. accum_accum(struct st_context *st, GLfloat value,
  127.             GLint xpos, GLint ypos, GLint width, GLint height,
  128.             struct st_renderbuffer *acc_strb,
  129.             struct st_renderbuffer *color_strb)
  130. {
  131.    struct pipe_context *pipe = st->pipe;
  132.    struct pipe_transfer *color_trans;
  133.    size_t stride = acc_strb->stride;
  134.    GLubyte *data = acc_strb->data;
  135.    GLfloat *buf;
  136.  
  137.    if (ST_DEBUG & DEBUG_FALLBACK)
  138.       debug_printf("%s: fallback processing\n", __FUNCTION__);
  139.  
  140.    color_trans = pipe_get_transfer(st->pipe,
  141.                                    color_strb->texture,
  142.                                    0, 0,
  143.                                    PIPE_TRANSFER_READ, xpos, ypos,
  144.                                    width, height);
  145.  
  146.    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
  147.  
  148.    pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
  149.  
  150.    switch (acc_strb->format) {
  151.    case PIPE_FORMAT_R16G16B16A16_SNORM:
  152.       {
  153.          const GLfloat *color = buf;
  154.          int i, j;
  155.          for (i = 0; i < height; i++) {
  156.             GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
  157.             for (j = 0; j < width * 4; j++) {
  158.                float val = *color++ * value;
  159.                *acc++ += FLOAT_TO_SHORT(val);
  160.             }
  161.          }
  162.       }
  163.       break;
  164.    default:
  165.       _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
  166.    }
  167.  
  168.    free(buf);
  169.    pipe->transfer_destroy(pipe, color_trans);
  170. }
  171.  
  172.  
  173. static void
  174. accum_load(struct st_context *st, GLfloat value,
  175.            GLint xpos, GLint ypos, GLint width, GLint height,
  176.            struct st_renderbuffer *acc_strb,
  177.            struct st_renderbuffer *color_strb)
  178. {
  179.    struct pipe_context *pipe = st->pipe;
  180.    struct pipe_transfer *color_trans;
  181.    size_t stride = acc_strb->stride;
  182.    GLubyte *data = acc_strb->data;
  183.    GLfloat *buf;
  184.  
  185.  
  186.    if (ST_DEBUG & DEBUG_FALLBACK)
  187.       debug_printf("%s: fallback processing\n", __FUNCTION__);
  188.  
  189.    color_trans = pipe_get_transfer(st->pipe, color_strb->texture,
  190.                                    0, 0,
  191.                                    PIPE_TRANSFER_READ, xpos, ypos,
  192.                                    width, height);
  193.  
  194.    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
  195.  
  196.    pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
  197.  
  198.    switch (acc_strb->format) {
  199.    case PIPE_FORMAT_R16G16B16A16_SNORM:
  200.       {
  201.          const GLfloat *color = buf;
  202.          int i, j;
  203.          for (i = 0; i < height; i++) {
  204.             GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
  205.             for (j = 0; j < width * 4; j++) {
  206.                float val = *color++ * value;
  207.                *acc++ = FLOAT_TO_SHORT(val);
  208.             }
  209.          }
  210.       }
  211.       break;
  212.    default:
  213.       _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
  214.    }
  215.  
  216.    free(buf);
  217.    pipe->transfer_destroy(pipe, color_trans);
  218. }
  219.  
  220.  
  221. static void
  222. accum_return(struct gl_context *ctx, GLfloat value,
  223.              GLint xpos, GLint ypos, GLint width, GLint height,
  224.              struct st_renderbuffer *acc_strb,
  225.              struct st_renderbuffer *color_strb)
  226. {
  227.    struct pipe_context *pipe = st_context(ctx)->pipe;
  228.    const GLubyte *colormask = ctx->Color.ColorMask[0];
  229.    enum pipe_transfer_usage usage;
  230.    struct pipe_transfer *color_trans;
  231.    size_t stride = acc_strb->stride;
  232.    const GLubyte *data = acc_strb->data;
  233.    GLfloat *buf;
  234.  
  235.    if (ST_DEBUG & DEBUG_FALLBACK)
  236.       debug_printf("%s: fallback processing\n", __FUNCTION__);
  237.  
  238.    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
  239.  
  240.    if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3])
  241.       usage = PIPE_TRANSFER_READ_WRITE;
  242.    else
  243.       usage = PIPE_TRANSFER_WRITE;
  244.  
  245.    color_trans = pipe_get_transfer(st_context(ctx)->pipe,
  246.                                    color_strb->texture, 0, 0,
  247.                                    usage,
  248.                                    xpos, ypos,
  249.                                    width, height);
  250.  
  251.    if (usage & PIPE_TRANSFER_READ)
  252.       pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
  253.  
  254.    switch (acc_strb->format) {
  255.    case PIPE_FORMAT_R16G16B16A16_SNORM:
  256.       {
  257.          GLfloat *color = buf;
  258.          int i, j, ch;
  259.          for (i = 0; i < height; i++) {
  260.             const GLshort *acc = (const GLshort *) (data + (ypos + i) * stride + xpos * 8);
  261.             for (j = 0; j < width; j++) {
  262.                for (ch = 0; ch < 4; ch++) {
  263.                   if (colormask[ch]) {
  264.                      GLfloat val = SHORT_TO_FLOAT(*acc * value);
  265.                      *color = CLAMP(val, 0.0f, 1.0f);
  266.                   }
  267.                   else {
  268.                      /* No change */
  269.                   }
  270.                   ++acc;
  271.                   ++color;
  272.                }
  273.             }
  274.          }
  275.       }
  276.       break;
  277.    default:
  278.       _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
  279.    }
  280.  
  281.    pipe_put_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
  282.  
  283.    free(buf);
  284.    pipe->transfer_destroy(pipe, color_trans);
  285. }
  286.  
  287.  
  288. static void
  289. st_Accum(struct gl_context *ctx, GLenum op, GLfloat value)
  290. {
  291.    struct st_context *st = st_context(ctx);
  292.    struct st_renderbuffer *acc_strb
  293.      = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
  294.    struct st_renderbuffer *color_strb
  295.       = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
  296.  
  297.    const GLint xpos = ctx->DrawBuffer->_Xmin;
  298.    const GLint ypos = ctx->DrawBuffer->_Ymin;
  299.    const GLint width = ctx->DrawBuffer->_Xmax - xpos;
  300.    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
  301.  
  302.    if(!acc_strb->data)
  303.       return;
  304.    
  305.    switch (op) {
  306.    case GL_ADD:
  307.       if (value != 0.0F) {
  308.          accum_mad(ctx, 1.0, value, xpos, ypos, width, height, acc_strb);
  309.       }
  310.       break;
  311.    case GL_MULT:
  312.       if (value != 1.0F) {
  313.          accum_mad(ctx, value, 0.0, xpos, ypos, width, height, acc_strb);
  314.       }
  315.       break;
  316.    case GL_ACCUM:
  317.       if (value != 0.0F) {
  318.          accum_accum(st, value, xpos, ypos, width, height, acc_strb, color_strb);
  319.       }
  320.       break;
  321.    case GL_LOAD:
  322.       accum_load(st, value, xpos, ypos, width, height, acc_strb, color_strb);
  323.       break;
  324.    case GL_RETURN:
  325.       accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb);
  326.       break;
  327.    default:
  328.       assert(0);
  329.    }
  330. }
  331.  
  332.  
  333.  
  334. void st_init_accum_functions(struct dd_function_table *functions)
  335. {
  336.    functions->Accum = st_Accum;
  337. }
  338.  
  339. #endif /* FEATURE_accum */
  340.