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 UNCLAMPED_FLOAT_TO_SHORT | ( | us, | |||
f | ) | us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) |
Definition at line 49 of file st_cb_accum.c.
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 }