st_cb_accum.c File Reference

Include dependency graph for st_cb_accum.c:

Go to the source code of this file.

Defines

#define UNCLAMPED_FLOAT_TO_SHORT(us, f)   us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )

Functions

static void acc_get_tile_rgba (struct pipe_context *pipe, struct pipe_surface *acc_ps, uint x, uint y, uint w, uint h, float *p)
 For hardware that supports deep color buffers, we could accelerate most/all the accum operations with blending/texturing.
static void acc_put_tile_rgba (struct pipe_context *pipe, struct pipe_surface *acc_ps, uint x, uint y, uint w, uint h, const float *p)
 Wrapper for pipe_put_tile_rgba().
void st_clear_accum_buffer (GLcontext *ctx, struct gl_renderbuffer *rb)
static void accum_mad (GLcontext *ctx, GLfloat scale, GLfloat bias, GLint xpos, GLint ypos, GLint width, GLint height, struct st_renderbuffer *acc_strb)
 For ADD/MULT.
static void accum_accum (struct pipe_context *pipe, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, struct st_renderbuffer *acc_strb, struct st_renderbuffer *color_strb)
static void accum_load (struct pipe_context *pipe, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, struct st_renderbuffer *acc_strb, struct st_renderbuffer *color_strb)
static void accum_return (GLcontext *ctx, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, struct st_renderbuffer *acc_strb, struct st_renderbuffer *color_strb)
static void st_Accum (GLcontext *ctx, GLenum op, GLfloat value)
void st_init_accum_functions (struct dd_function_table *functions)


Define Documentation

#define UNCLAMPED_FLOAT_TO_SHORT ( us,
 )     us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )

Definition at line 49 of file st_cb_accum.c.


Function Documentation

static void acc_get_tile_rgba ( struct pipe_context pipe,
struct pipe_surface acc_ps,
uint  x,
uint  y,
uint  w,
uint  h,
float *  p 
) [static]

For hardware that supports deep color buffers, we could accelerate most/all the accum operations with blending/texturing.

For now, just use the get/put_tile() functions and do things in software. Wrapper for pipe_get_tile_rgba(). Do format/cpp override to make the tile util function think the surface is 16bit/channel, even if it's not. See also: st_renderbuffer_alloc_storage()

Definition at line 66 of file st_cb_accum.c.

References pipe_surface::block, DEFAULT_ACCUM_PIPE_FORMAT, pipe_surface::format, pipe_format_block::height, pipe_get_tile_rgba(), pipe_format_block::size, and pipe_format_block::width.

00068 {
00069    const enum pipe_format f = acc_ps->format;
00070    const struct pipe_format_block b = acc_ps->block;
00071 
00072    acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT;
00073    acc_ps->block.size = 8;
00074    acc_ps->block.width = 1;
00075    acc_ps->block.height = 1;
00076 
00077    pipe_get_tile_rgba(acc_ps, x, y, w, h, p);
00078 
00079    acc_ps->format = f;
00080    acc_ps->block = b;
00081 }

static void acc_put_tile_rgba ( struct pipe_context pipe,
struct pipe_surface acc_ps,
uint  x,
uint  y,
uint  w,
uint  h,
const float *  p 
) [static]

Wrapper for pipe_put_tile_rgba().

Do format/cpp override to make the tile util function think the surface is 16bit/channel, even if it's not. See also: st_renderbuffer_alloc_storage()

Definition at line 90 of file st_cb_accum.c.

References pipe_surface::block, DEFAULT_ACCUM_PIPE_FORMAT, pipe_surface::format, pipe_format_block::height, pipe_put_tile_rgba(), pipe_format_block::size, and pipe_format_block::width.

00092 {
00093    enum pipe_format f = acc_ps->format;
00094    const struct pipe_format_block b = acc_ps->block;
00095 
00096    acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT;
00097    acc_ps->block.size = 8;
00098    acc_ps->block.width = 1;
00099    acc_ps->block.height = 1;
00100 
00101    pipe_put_tile_rgba(acc_ps, x, y, w, h, p);
00102 
00103    acc_ps->format = f;
00104    acc_ps->block = b;
00105 }

static void accum_accum ( struct pipe_context pipe,
GLfloat  value,
GLint  xpos,
GLint  ypos,
GLint  width,
GLint  height,
struct st_renderbuffer acc_strb,
struct st_renderbuffer color_strb 
) [static]

Definition at line 192 of file st_cb_accum.c.

References acc_get_tile_rgba(), acc_put_tile_rgba(), pipe_screen::get_tex_surface, PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_get_tile_rgba(), pipe_surface_reference(), pipe_context::screen, and st_renderbuffer::texture.

00196 {
00197    struct pipe_screen *screen = pipe->screen;
00198    struct pipe_surface *acc_surf, *color_surf;
00199    GLfloat *colorBuf, *accBuf;
00200    GLint i;
00201 
00202    acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
00203                                       (PIPE_BUFFER_USAGE_CPU_WRITE |
00204                                        PIPE_BUFFER_USAGE_CPU_READ));
00205 
00206    color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
00207                                         PIPE_BUFFER_USAGE_CPU_READ);
00208 
00209    colorBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00210    accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00211 
00212    pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, colorBuf);
00213    acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf);
00214 
00215    for (i = 0; i < 4 * width * height; i++) {
00216       accBuf[i] = accBuf[i] + colorBuf[i] * value;
00217    }
00218 
00219    acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf);
00220 
00221    free(colorBuf);
00222    free(accBuf);
00223    pipe_surface_reference(&acc_surf, NULL);
00224    pipe_surface_reference(&color_surf, NULL);
00225 }

static void accum_load ( struct pipe_context pipe,
GLfloat  value,
GLint  xpos,
GLint  ypos,
GLint  width,
GLint  height,
struct st_renderbuffer acc_strb,
struct st_renderbuffer color_strb 
) [static]

Definition at line 229 of file st_cb_accum.c.

References acc_put_tile_rgba(), pipe_screen::get_tex_surface, PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_get_tile_rgba(), pipe_surface_reference(), pipe_context::screen, and st_renderbuffer::texture.

00233 {
00234    struct pipe_screen *screen = pipe->screen;
00235    struct pipe_surface *acc_surf, *color_surf;
00236    GLfloat *buf;
00237    GLint i;
00238 
00239    acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
00240                                       PIPE_BUFFER_USAGE_CPU_WRITE);
00241 
00242    color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
00243                                         PIPE_BUFFER_USAGE_CPU_READ);
00244 
00245    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00246 
00247    pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, buf);
00248 
00249    for (i = 0; i < 4 * width * height; i++) {
00250       buf[i] = buf[i] * value;
00251    }
00252 
00253    acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, buf);
00254 
00255    free(buf);
00256    pipe_surface_reference(&acc_surf, NULL);
00257    pipe_surface_reference(&color_surf, NULL);
00258 }

static void accum_mad ( GLcontext *  ctx,
GLfloat  scale,
GLfloat  bias,
GLint  xpos,
GLint  ypos,
GLint  width,
GLint  height,
struct st_renderbuffer acc_strb 
) [static]

For ADD/MULT.

Definition at line 158 of file st_cb_accum.c.

References st_renderbuffer::format, PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_FORMAT_R16G16B16A16_SNORM, SHORT_TO_FLOAT, pipe_surface::stride, st_renderbuffer::surface, pipe_screen::surface_map, and pipe_screen::surface_unmap.

00161 {
00162    struct pipe_screen *screen = ctx->st->pipe->screen;
00163    struct pipe_surface *acc_ps = acc_strb->surface;
00164    GLubyte *map;
00165 
00166    map = screen->surface_map(screen, acc_ps, 
00167                              PIPE_BUFFER_USAGE_CPU_WRITE);
00168 
00169    /* note acc_strb->format might not equal acc_ps->format */
00170    switch (acc_strb->format) {
00171    case PIPE_FORMAT_R16G16B16A16_SNORM:
00172       {
00173          int i, j;
00174          for (i = 0; i < height; i++) {
00175             GLshort *acc = (GLshort *) (map + (ypos + i) * acc_ps->stride + xpos * 8);
00176             for (j = 0; j < width * 4; j++) {
00177                float val = SHORT_TO_FLOAT(acc[j]) * scale + bias;
00178                acc[j] = FLOAT_TO_SHORT(val);
00179             }
00180          }
00181       }
00182       break;
00183    default:
00184       _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
00185    }
00186 
00187    screen->surface_unmap(screen, acc_ps);
00188 }

static void accum_return ( GLcontext *  ctx,
GLfloat  value,
GLint  xpos,
GLint  ypos,
GLint  width,
GLint  height,
struct st_renderbuffer acc_strb,
struct st_renderbuffer color_strb 
) [static]

Definition at line 262 of file st_cb_accum.c.

References acc_get_tile_rgba(), CLAMP, pipe_screen::get_tex_surface, PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_get_tile_rgba(), pipe_put_tile_rgba(), pipe_surface_reference(), pipe_context::screen, and st_renderbuffer::texture.

00266 {
00267    struct pipe_context *pipe = ctx->st->pipe;
00268    struct pipe_screen *screen = pipe->screen;
00269    const GLubyte *colormask = ctx->Color.ColorMask;
00270    struct pipe_surface *acc_surf, *color_surf;
00271    GLfloat *abuf, *cbuf = NULL;
00272    GLint i, ch;
00273 
00274    abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00275 
00276    acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
00277                                       PIPE_BUFFER_USAGE_CPU_READ);
00278 
00279    color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
00280                                         (PIPE_BUFFER_USAGE_CPU_READ |
00281                                          PIPE_BUFFER_USAGE_CPU_WRITE));
00282 
00283    acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, abuf);
00284 
00285    if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) {
00286       cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
00287       pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, cbuf);
00288    }
00289 
00290    for (i = 0; i < width * height; i++) {
00291       for (ch = 0; ch < 4; ch++) {
00292          if (colormask[ch]) {
00293             GLfloat val = abuf[i * 4 + ch] * value;
00294             abuf[i * 4 + ch] = CLAMP(val, 0.0f, 1.0f);
00295          }
00296          else {
00297             abuf[i * 4 + ch] = cbuf[i * 4 + ch];
00298          }
00299       }
00300    }
00301 
00302    pipe_put_tile_rgba(color_surf, xpos, ypos, width, height, abuf);
00303 
00304    free(abuf);
00305    if (cbuf)
00306       free(cbuf);
00307    pipe_surface_reference(&acc_surf, NULL);
00308    pipe_surface_reference(&color_surf, NULL);
00309 }

static void st_Accum ( GLcontext *  ctx,
GLenum  op,
GLfloat  value 
) [static]

Definition at line 313 of file st_cb_accum.c.

References accum_accum(), accum_load(), accum_mad(), accum_return(), assert, st_context::pipe, PIPE_FLUSH_RENDER_CACHE, st_flush(), and st_renderbuffer().

00314 {
00315    struct st_context *st = ctx->st;
00316    struct pipe_context *pipe = st->pipe;
00317    struct st_renderbuffer *acc_strb
00318      = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
00319    struct st_renderbuffer *color_strb
00320       = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
00321 
00322    const GLint xpos = ctx->DrawBuffer->_Xmin;
00323    const GLint ypos = ctx->DrawBuffer->_Ymin;
00324    const GLint width = ctx->DrawBuffer->_Xmax - xpos;
00325    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
00326 
00327    /* make sure color bufs aren't cached */
00328    st_flush( st, PIPE_FLUSH_RENDER_CACHE, NULL );
00329 
00330    switch (op) {
00331    case GL_ADD:
00332       if (value != 0.0F) {
00333          accum_mad(ctx, 1.0, value, xpos, ypos, width, height, acc_strb);
00334       }
00335       break;
00336    case GL_MULT:
00337       if (value != 1.0F) {
00338          accum_mad(ctx, value, 0.0, xpos, ypos, width, height, acc_strb);
00339       }
00340       break;
00341    case GL_ACCUM:
00342       if (value != 0.0F) {
00343          accum_accum(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
00344       }
00345       break;
00346    case GL_LOAD:
00347       accum_load(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
00348       break;
00349    case GL_RETURN:
00350       accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb);
00351       break;
00352    default:
00353       assert(0);
00354    }
00355 }

void st_clear_accum_buffer ( GLcontext *  ctx,
struct gl_renderbuffer *  rb 
)

Definition at line 110 of file st_cb_accum.c.

References acc_put_tile_rgba(), st_renderbuffer::format, pipe_screen::get_tex_surface, pipe_surface::height, PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_FORMAT_R16G16B16A16_SNORM, pipe_surface_map(), pipe_surface_reference(), pipe_surface_unmap(), st_renderbuffer(), pipe_surface::stride, st_renderbuffer::surface, pipe_screen::surface_map, pipe_screen::surface_unmap, st_renderbuffer::texture, and pipe_surface::width.

00111 {
00112    struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
00113    struct pipe_surface *acc_ps;
00114    struct pipe_screen *screen = ctx->st->pipe->screen;
00115    const GLint xpos = ctx->DrawBuffer->_Xmin;
00116    const GLint ypos = ctx->DrawBuffer->_Ymin;
00117    const GLint width = ctx->DrawBuffer->_Xmax - xpos;
00118    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
00119    GLubyte *map;
00120 
00121    acc_ps = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
00122                                     PIPE_BUFFER_USAGE_CPU_WRITE);
00123    map = screen->surface_map(screen, acc_ps,
00124                              PIPE_BUFFER_USAGE_CPU_WRITE);
00125 
00126    /* note acc_strb->format might not equal acc_ps->format */
00127    switch (acc_strb->format) {
00128    case PIPE_FORMAT_R16G16B16A16_SNORM:
00129       {
00130          GLshort r = FLOAT_TO_SHORT(ctx->Accum.ClearColor[0]);
00131          GLshort g = FLOAT_TO_SHORT(ctx->Accum.ClearColor[1]);
00132          GLshort b = FLOAT_TO_SHORT(ctx->Accum.ClearColor[2]);
00133          GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
00134          int i, j;
00135          for (i = 0; i < height; i++) {
00136             GLshort *dst = (GLshort *) (map + (ypos + i) * acc_ps->stride + xpos * 8);
00137             for (j = 0; j < width; j++) {
00138                dst[0] = r;
00139                dst[1] = g;
00140                dst[2] = b;
00141                dst[3] = a;
00142                dst += 4;
00143             }
00144          }
00145       }
00146       break;
00147    default:
00148       _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
00149    }
00150 
00151    screen->surface_unmap(screen, acc_ps);
00152    pipe_surface_reference(&acc_ps, NULL);
00153 }

void st_init_accum_functions ( struct dd_function_table *  functions  ) 

Definition at line 359 of file st_cb_accum.c.

References st_Accum().

00360 {
00361    functions->Accum = st_Accum;
00362 }


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