acc2.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028  /*
00029   * Authors:
00030   *   Brian Paul
00031   */
00032 
00033 #include "main/imports.h"
00034 #include "main/image.h"
00035 #include "main/macros.h"
00036 
00037 #include "st_context.h"
00038 #include "st_cb_accum.h"
00039 #include "st_cb_fbo.h"
00040 #include "st_draw.h"
00041 #include "st_format.h"
00042 #include "pipe/p_context.h"
00043 #include "pipe/p_defines.h"
00044 #include "pipe/p_inlines.h"
00045 #include "util/p_tile.h"
00046 
00047 
00048 #define UNCLAMPED_FLOAT_TO_SHORT(us, f)  \
00049    us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
00050 
00051 
00059 static void
00060 acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps,
00061                   uint x, uint y, uint w, uint h, float *p)
00062 {
00063    const enum pipe_format f = acc_ps->format;
00064    const int cpp = acc_ps->cpp;
00065 
00066    acc_ps->format = PIPE_FORMAT_R16G16B16A16_SNORM;
00067    acc_ps->cpp = 8;
00068 
00069    pipe_get_tile_rgba(pipe, acc_ps, x, y, w, h, p);
00070 
00071    acc_ps->format = f;
00072    acc_ps->cpp = cpp;
00073 }
00074 
00075 
00076 static void
00077 acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps,
00078                   uint x, uint y, uint w, uint h, const float *p)
00079 {
00080    enum pipe_format f = acc_ps->format;
00081    const int cpp = acc_ps->cpp;
00082 
00083    acc_ps->format = PIPE_FORMAT_R16G16B16A16_SNORM;
00084    acc_ps->cpp = 8;
00085 
00086    pipe_put_tile_rgba(pipe, acc_ps, x, y, w, h, p);
00087 
00088    acc_ps->format = f;
00089    acc_ps->cpp = cpp;
00090 }
00091 
00092 
00093 
00094 void
00095 st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
00096 {
00097    struct pipe_context *pipe = ctx->st->pipe;
00098    struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
00099    struct pipe_surface *acc_ps = acc_strb->surface;
00100    const GLint xpos = ctx->DrawBuffer->_Xmin;
00101    const GLint ypos = ctx->DrawBuffer->_Ymin;
00102    const GLint width = ctx->DrawBuffer->_Xmax - xpos;
00103    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
00104    const GLfloat r = ctx->Accum.ClearColor[0];
00105    const GLfloat g = ctx->Accum.ClearColor[1];
00106    const GLfloat b = ctx->Accum.ClearColor[2];
00107    const GLfloat a = ctx->Accum.ClearColor[3];
00108    GLfloat *accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00109    int i;
00110 
00111 #if 1
00112    GLvoid *map;
00113 
00114    map = pipe_surface_map(acc_ps);
00115    switch (acc_strb->format) {
00116    case PIPE_FORMAT_R16G16B16A16_SNORM:
00117       {
00118          GLshort r = FLOAT_TO_SHORT(ctx->Accum.ClearColor[0]);
00119          GLshort g = FLOAT_TO_SHORT(ctx->Accum.ClearColor[1]);
00120          GLshort b = FLOAT_TO_SHORT(ctx->Accum.ClearColor[2]);
00121          GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
00122          int i, j;
00123          for (i = 0; i < height; i++) {
00124             GLshort *dst = ((GLshort *) map
00125                             + ((ypos + i) * acc_ps->pitch + xpos) * 4);
00126             for (j = 0; j < width; j++) {
00127                dst[0] = r;
00128                dst[1] = g;
00129                dst[2] = b;
00130                dst[3] = a;
00131                dst += 4;
00132             }
00133          }
00134       }
00135       break;
00136    default:
00137       _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
00138    }
00139 
00140    pipe_surface_unmap(acc_ps);
00141 
00142 #else
00143    for (i = 0; i < width * height; i++) {
00144       accBuf[i*4+0] = r;
00145       accBuf[i*4+1] = g;
00146       accBuf[i*4+2] = b;
00147       accBuf[i*4+3] = a;
00148    }
00149 
00150    acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
00151 #endif
00152 }
00153 
00154 
00156 static void
00157 accum_mad(struct pipe_context *pipe, GLfloat scale, GLfloat bias,
00158           GLint xpos, GLint ypos, GLint width, GLint height,
00159           struct pipe_surface *acc_ps)
00160 {
00161    GLfloat *accBuf;
00162    GLint i;
00163 
00164    accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00165 
00166    pipe_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
00167 
00168    for (i = 0; i < 4 * width * height; i++) {
00169       accBuf[i] = accBuf[i] * scale + bias;
00170    }
00171 
00172    pipe_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
00173 
00174    free(accBuf);
00175 }
00176 
00177 
00178 static void
00179 accum_accum(struct pipe_context *pipe, GLfloat value,
00180             GLint xpos, GLint ypos, GLint width, GLint height,
00181             struct pipe_surface *acc_ps,
00182             struct pipe_surface *color_ps)
00183 {
00184    GLfloat *colorBuf, *accBuf;
00185    GLint i;
00186 
00187    colorBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00188    accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00189 
00190    pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, colorBuf);
00191    acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
00192 
00193    for (i = 0; i < 4 * width * height; i++) {
00194       accBuf[i] = accBuf[i] + colorBuf[i] * value;
00195    }
00196 
00197    acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
00198 
00199    free(colorBuf);
00200    free(accBuf);
00201 }
00202 
00203 
00204 static void
00205 accum_load(struct pipe_context *pipe, GLfloat value,
00206            GLint xpos, GLint ypos, GLint width, GLint height,
00207            struct pipe_surface *acc_ps,
00208            struct pipe_surface *color_ps)
00209 {
00210    GLfloat *buf;
00211    GLint i;
00212 
00213    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00214 
00215    pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, buf);
00216 
00217    for (i = 0; i < 4 * width * height; i++) {
00218       buf[i] = buf[i] * value;
00219    }
00220 
00221    acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf);
00222 
00223    free(buf);
00224 }
00225 
00226 
00227 static void
00228 accum_return(GLcontext *ctx, GLfloat value,
00229              GLint xpos, GLint ypos, GLint width, GLint height,
00230              struct pipe_surface *acc_ps,
00231              struct pipe_surface *color_ps)
00232 {
00233    struct pipe_context *pipe = ctx->st->pipe;
00234    const GLubyte *colormask = ctx->Color.ColorMask;
00235    GLfloat *abuf, *cbuf = NULL;
00236    GLint i, ch;
00237 
00238    abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00239 
00240    acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf);
00241 
00242    if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) {
00243       cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00244       pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, cbuf);
00245    }
00246 
00247    for (i = 0; i < width * height; i++) {
00248       for (ch = 0; ch < 4; ch++) {
00249          if (colormask[ch]) {
00250             GLfloat val = abuf[i * 4 + ch] * value;
00251             abuf[i * 4 + ch] = CLAMP(val, 0.0, 1.0);
00252          }
00253          else {
00254             abuf[i * 4 + ch] = cbuf[i * 4 + ch];
00255          }
00256       }
00257    }
00258 
00259    pipe_put_tile_rgba(pipe, color_ps, xpos, ypos, width, height, abuf);
00260 
00261    free(abuf);
00262    if (cbuf)
00263       free(cbuf);
00264 }
00265 
00266 
00267 static void
00268 st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
00269 {
00270    struct st_context *st = ctx->st;
00271    struct pipe_context *pipe = st->pipe;
00272    struct st_renderbuffer *acc_strb
00273      = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
00274    struct st_renderbuffer *color_strb
00275       = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
00276    struct pipe_surface *acc_ps = acc_strb->surface;
00277    struct pipe_surface *color_ps = color_strb->surface;
00278 
00279    const GLint xpos = ctx->DrawBuffer->_Xmin;
00280    const GLint ypos = ctx->DrawBuffer->_Ymin;
00281    const GLint width = ctx->DrawBuffer->_Xmax - xpos;
00282    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
00283 
00284    /* make sure color bufs aren't cached */
00285    pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
00286 
00287    switch (op) {
00288    case GL_ADD:
00289       if (value != 0.0F) {
00290          accum_mad(pipe, 1.0, value, xpos, ypos, width, height, acc_ps);
00291       }
00292       break;
00293    case GL_MULT:
00294       if (value != 1.0F) {
00295          accum_mad(pipe, value, 0.0, xpos, ypos, width, height, acc_ps);
00296       }
00297       break;
00298    case GL_ACCUM:
00299       if (value != 0.0F) {
00300          accum_accum(pipe, value, xpos, ypos, width, height, acc_ps, color_ps);
00301       }
00302       break;
00303    case GL_LOAD:
00304       accum_load(pipe, value, xpos, ypos, width, height, acc_ps, color_ps);
00305       break;
00306    case GL_RETURN:
00307       accum_return(ctx, value, xpos, ypos, width, height, acc_ps, color_ps);
00308       break;
00309    default:
00310       assert(0);
00311    }
00312 }
00313 
00314 
00315 
00316 void st_init_accum_functions(struct dd_function_table *functions)
00317 {
00318    functions->Accum = st_Accum;
00319 }

Generated on Tue Sep 29 06:25:18 2009 for Gallium3D by  doxygen 1.5.4