diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/main/image.c | 2 | ||||
-rw-r--r-- | src/mesa/main/matrix.c | 10 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_accum.c | 244 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 27 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_fbo.c | 145 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_fbo.h | 13 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_readpixels.c | 13 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_framebuffer.c | 17 | ||||
-rw-r--r-- | src/mesa/swrast/s_context.c | 1 |
9 files changed, 231 insertions, 241 deletions
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index c06031e6cb2..090e5eb3300 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -2874,7 +2874,7 @@ extract_uint_indexes(GLuint n, GLuint indexes[], } else { for (i = 0; i < n; i++) - indexes[i] = s[i] & 0xfff; /* lower 8 bits */ + indexes[i] = s[i] & 0xff; /* lower 8 bits */ } } break; diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c index 39b4967a58e..ebc3cbd59c3 100644 --- a/src/mesa/main/matrix.c +++ b/src/mesa/main/matrix.c @@ -160,11 +160,21 @@ _mesa_MatrixMode( GLenum mode ) ctx->CurrentStack = &ctx->ProjectionMatrixStack; break; case GL_TEXTURE: + /* This error check is disabled because if we're called from + * glPopAttrib() when the active texture unit is >= MaxTextureCoordUnits + * we'll generate an unexpected error. + * From the GL_ARB_vertex_shader spec it sounds like we should instead + * do error checking in other places when we actually try to access + * texture matrices beyond MaxTextureCoordUnits. + */ +#if 0 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMatrixMode(invalid tex unit %d)", ctx->Texture.CurrentUnit); return; } +#endif + ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->TextureMatrixStack)); ctx->CurrentStack = &ctx->TextureMatrixStack[ctx->Texture.CurrentUnit]; break; case GL_COLOR: diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 7f793cf08db..95181578f63 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -48,10 +48,6 @@ #include "util/u_tile.h" -#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ - us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) - - /** * For hardware that supports deep color buffers, we could accelerate * most/all the accum operations with blending/texturing. @@ -59,74 +55,20 @@ */ -/** - * 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() - */ -static void -acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *acc_pt, - uint x, uint y, uint w, uint h, float *p) -{ - const enum pipe_format f = acc_pt->format; - const struct pipe_format_block b = acc_pt->block; - - acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT; - acc_pt->block.size = 8; - acc_pt->block.width = 1; - acc_pt->block.height = 1; - - pipe_get_tile_rgba(acc_pt, x, y, w, h, p); - - acc_pt->format = f; - acc_pt->block = b; -} - - -/** - * 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() - */ -static void -acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *acc_pt, - uint x, uint y, uint w, uint h, const float *p) -{ - enum pipe_format f = acc_pt->format; - const struct pipe_format_block b = acc_pt->block; - - acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT; - acc_pt->block.size = 8; - acc_pt->block.width = 1; - acc_pt->block.height = 1; - - pipe_put_tile_rgba(acc_pt, x, y, w, h, p); - - acc_pt->format = f; - acc_pt->block = b; -} - - - void st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { struct st_renderbuffer *acc_strb = st_renderbuffer(rb); - struct pipe_transfer *acc_pt; - struct pipe_screen *screen = ctx->st->pipe->screen; const GLint xpos = ctx->DrawBuffer->_Xmin; const GLint ypos = ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - xpos; const GLint height = ctx->DrawBuffer->_Ymax - ypos; - GLubyte *map; - - acc_pt = st_cond_flush_get_tex_transfer(st_context(ctx), acc_strb->texture, - 0, 0, 0, - PIPE_TRANSFER_WRITE, xpos, ypos, - width, height); - map = screen->transfer_map(screen, acc_pt); + size_t stride = acc_strb->stride; + GLubyte *data = acc_strb->data; - /* note acc_strb->format might not equal acc_pt->format */ + if(!data) + return; + switch (acc_strb->format) { case PIPE_FORMAT_R16G16B16A16_SNORM: { @@ -136,7 +78,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]); int i, j; for (i = 0; i < height; i++) { - GLshort *dst = (GLshort *) (map + i * acc_pt->stride + xpos * 8); + GLshort *dst = (GLshort *) (data + (ypos + i) * stride + xpos * 8); for (j = 0; j < width; j++) { dst[0] = r; dst[1] = g; @@ -150,9 +92,6 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) default: _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()"); } - - screen->transfer_unmap(screen, acc_pt); - screen->tex_transfer_destroy(acc_pt); } @@ -162,27 +101,18 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, GLint xpos, GLint ypos, GLint width, GLint height, struct st_renderbuffer *acc_strb) { - struct pipe_screen *screen = ctx->st->pipe->screen; - struct pipe_transfer *acc_pt; - GLubyte *map; - - acc_pt = st_cond_flush_get_tex_transfer(st_context(ctx), acc_strb->texture, - 0, 0, 0, - PIPE_TRANSFER_READ_WRITE, - xpos, ypos, - width, height); - map = screen->transfer_map(screen, acc_pt); - - /* note acc_strb->format might not equal acc_pt->format */ + size_t stride = acc_strb->stride; + GLubyte *data = acc_strb->data; + switch (acc_strb->format) { case PIPE_FORMAT_R16G16B16A16_SNORM: { int i, j; for (i = 0; i < height; i++) { - GLshort *acc = (GLshort *) (map + (ypos + i) * acc_pt->stride + xpos * 8); + GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8); for (j = 0; j < width * 4; j++) { - float val = SHORT_TO_FLOAT(acc[j]) * scale + bias; - acc[j] = FLOAT_TO_SHORT(val); + float val = SHORT_TO_FLOAT(*acc) * scale + bias; + *acc++ = FLOAT_TO_SHORT(val); } } } @@ -190,9 +120,6 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, default: _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()"); } - - screen->transfer_unmap(screen, acc_pt); - screen->tex_transfer_destroy(acc_pt); } @@ -204,39 +131,39 @@ accum_accum(struct st_context *st, GLfloat value, { struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_transfer *acc_trans, *color_trans; - GLfloat *colorBuf, *accBuf; - GLint i; - - acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ, xpos, ypos, - width, height); + struct pipe_transfer *color_trans; + size_t stride = acc_strb->stride; + GLubyte *data = acc_strb->data; + GLfloat *buf; color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, xpos, ypos, width, height); - colorBuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); - accBuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(color_trans, 0, 0, width, height, colorBuf); - acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf); + pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf); - for (i = 0; i < 4 * width * height; i++) { - accBuf[i] = accBuf[i] + colorBuf[i] * value; + switch (acc_strb->format) { + case PIPE_FORMAT_R16G16B16A16_SNORM: + { + const GLfloat *color = buf; + int i, j; + for (i = 0; i < height; i++) { + GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8); + for (j = 0; j < width * 4; j++) { + float val = *color++ * value; + *acc++ += FLOAT_TO_SHORT(val); + } + } + } + break; + default: + _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()"); } - screen->tex_transfer_destroy(acc_trans); - acc_trans = st_no_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, xpos, ypos, - width, height); - - acc_put_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf); - - _mesa_free(colorBuf); - _mesa_free(accBuf); - screen->tex_transfer_destroy(acc_trans); + _mesa_free(buf); screen->tex_transfer_destroy(color_trans); } @@ -249,13 +176,10 @@ accum_load(struct st_context *st, GLfloat value, { struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_transfer *acc_trans, *color_trans; + struct pipe_transfer *color_trans; + size_t stride = acc_strb->stride; + GLubyte *data = acc_strb->data; GLfloat *buf; - GLint i; - - acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, xpos, ypos, - width, height); color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture, 0, 0, 0, @@ -266,14 +190,25 @@ accum_load(struct st_context *st, GLfloat value, pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf); - for (i = 0; i < 4 * width * height; i++) { - buf[i] = buf[i] * value; + switch (acc_strb->format) { + case PIPE_FORMAT_R16G16B16A16_SNORM: + { + const GLfloat *color = buf; + int i, j; + for (i = 0; i < height; i++) { + GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8); + for (j = 0; j < width * 4; j++) { + float val = *color++ * value; + *acc++ = FLOAT_TO_SHORT(val); + } + } + } + break; + default: + _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()"); } - acc_put_tile_rgba(pipe, acc_trans, 0, 0, width, height, buf); - _mesa_free(buf); - screen->tex_transfer_destroy(acc_trans); screen->tex_transfer_destroy(color_trans); } @@ -287,48 +222,58 @@ accum_return(GLcontext *ctx, GLfloat value, struct pipe_context *pipe = ctx->st->pipe; struct pipe_screen *screen = pipe->screen; const GLubyte *colormask = ctx->Color.ColorMask; - struct pipe_transfer *acc_trans, *color_trans; - GLfloat *abuf, *cbuf = NULL; - GLint i, ch; - - abuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + enum pipe_transfer_usage usage; + struct pipe_transfer *color_trans; + size_t stride = acc_strb->stride; + const GLubyte *data = acc_strb->data; + GLfloat *buf; - acc_trans = st_cond_flush_get_tex_transfer(st_context(ctx), - acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ, xpos, ypos, - width, height); + buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) + usage = PIPE_TRANSFER_READ_WRITE; + else + usage = PIPE_TRANSFER_WRITE; + color_trans = st_cond_flush_get_tex_transfer(st_context(ctx), color_strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ_WRITE, + usage, xpos, ypos, width, height); - acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, abuf); - - if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) { - cbuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(color_trans, 0, 0, width, height, cbuf); - } + if (usage != PIPE_TRANSFER_WRITE) + pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf); - for (i = 0; i < width * height; i++) { - for (ch = 0; ch < 4; ch++) { - if (colormask[ch]) { - GLfloat val = abuf[i * 4 + ch] * value; - abuf[i * 4 + ch] = CLAMP(val, 0.0f, 1.0f); - } - else { - abuf[i * 4 + ch] = cbuf[i * 4 + ch]; + switch (acc_strb->format) { + case PIPE_FORMAT_R16G16B16A16_SNORM: + { + GLfloat *color = buf; + int i, j, ch; + for (i = 0; i < height; i++) { + const GLshort *acc = (const GLshort *) (data + (ypos + i) * stride + xpos * 8); + for (j = 0; j < width; j++) { + for (ch = 0; ch < 4; ch++) { + if (colormask[ch]) { + GLfloat val = SHORT_TO_FLOAT(*acc * value); + *color = CLAMP(val, 0.0f, 1.0f); + } + else { + /* No change */ + } + ++acc; + ++color; + } + } } } + break; + default: + _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()"); } - pipe_put_tile_rgba(color_trans, 0, 0, width, height, abuf); + pipe_put_tile_rgba(color_trans, 0, 0, width, height, buf); - _mesa_free(abuf); - if (cbuf) - _mesa_free(cbuf); - screen->tex_transfer_destroy(acc_trans); + _mesa_free(buf); screen->tex_transfer_destroy(color_trans); } @@ -347,6 +292,9 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value) const GLint width = ctx->DrawBuffer->_Xmax - xpos; const GLint height = ctx->DrawBuffer->_Ymax - ypos; + if(!acc_strb->data) + return; + /* make sure color bufs aren't cached */ st_flush( st, PIPE_FLUSH_RENDER_CACHE, NULL ); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 89725cfe8dc..04cf673f637 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -630,6 +630,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct st_renderbuffer *strb; + enum pipe_transfer_usage usage; struct pipe_transfer *pt; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; GLint skipPixels; @@ -642,8 +643,14 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, y = ctx->DrawBuffer->Height - y - height; } + if(format != GL_DEPTH_STENCIL && + pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0) + usage = PIPE_TRANSFER_READ_WRITE; + else + usage = PIPE_TRANSFER_WRITE; + pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, x, y, + usage, x, y, width, height); stmap = screen->transfer_map(screen, pt); @@ -694,6 +701,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, case PIPE_FORMAT_S8_UNORM: { ubyte *dest = stmap + spanY * pt->stride + spanX; + assert(usage == PIPE_TRANSFER_WRITE); memcpy(dest, sValues, spanWidth); } break; @@ -701,6 +709,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, if (format == GL_DEPTH_STENCIL) { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; + assert(usage == PIPE_TRANSFER_WRITE); for (k = 0; k < spanWidth; k++) { dest[k] = zValues[k] | (sValues[k] << 24); } @@ -708,6 +717,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, else { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; + assert(usage == PIPE_TRANSFER_READ_WRITE); for (k = 0; k < spanWidth; k++) { dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24); } @@ -717,13 +727,15 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, if (format == GL_DEPTH_STENCIL) { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; + assert(usage == PIPE_TRANSFER_WRITE); for (k = 0; k < spanWidth; k++) { - dest[k] = zValues[k] | (sValues[k] << 24); + dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff); } } else { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; + assert(usage == PIPE_TRANSFER_READ_WRITE); for (k = 0; k < spanWidth; k++) { dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff); } @@ -811,6 +823,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, { struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); struct pipe_screen *screen = ctx->st->pipe->screen; + enum pipe_transfer_usage usage; struct pipe_transfer *ptDraw; ubyte *drawMap; ubyte *buffer; @@ -827,9 +840,14 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); + if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0) + usage = PIPE_TRANSFER_READ_WRITE; + else + usage = PIPE_TRANSFER_WRITE; + ptDraw = st_cond_flush_get_tex_transfer(st_context(ctx), rbDraw->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, dstx, dsty, + usage, dstx, dsty, width, height); assert(ptDraw->block.width == 1); @@ -859,6 +877,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, { uint *dst4 = (uint *) dst; int j; + assert(usage == PIPE_TRANSFER_READ_WRITE); for (j = 0; j < width; j++) { *dst4 = (*dst4 & 0xffffff) | (src[j] << 24); dst4++; @@ -869,6 +888,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, { uint *dst4 = (uint *) dst; int j; + assert(usage == PIPE_TRANSFER_READ_WRITE); for (j = 0; j < width; j++) { *dst4 = (*dst4 & 0xffffff00) | (src[j] & 0xff); dst4++; @@ -876,6 +896,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } break; case PIPE_FORMAT_S8_UNORM: + assert(usage == PIPE_TRANSFER_WRITE); memcpy(dst, src, width); break; default: diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index c249f3b3578..ecdb988033c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -88,93 +88,92 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, { struct pipe_context *pipe = ctx->st->pipe; struct st_renderbuffer *strb = st_renderbuffer(rb); - struct pipe_texture template; - unsigned surface_usage; - - /* Free the old surface and texture - */ - pipe_surface_reference( &strb->surface, NULL ); - pipe_texture_reference( &strb->texture, NULL ); - - /* Setup new texture template. - */ - memset(&template, 0, sizeof(template)); - template.target = PIPE_TEXTURE_2D; - if (strb->format != PIPE_FORMAT_NONE) { - template.format = strb->format; - } - else { - template.format = st_choose_renderbuffer_format(pipe, internalFormat); - } - pf_get_block(template.format, &template.block); - template.width[0] = width; - template.height[0] = height; - template.depth[0] = 1; - template.last_level = 0; - template.nr_samples = rb->NumSamples; - if (pf_is_depth_stencil(template.format)) { - template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; - } - else { - template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_RENDER_TARGET); - } + enum pipe_format format; + if (strb->format != PIPE_FORMAT_NONE) + format = strb->format; + else + format = st_choose_renderbuffer_format(pipe, internalFormat); + /* init renderbuffer fields */ strb->Base.Width = width; strb->Base.Height = height; - init_renderbuffer_bits(strb, template.format); + init_renderbuffer_bits(strb, format); strb->defined = GL_FALSE; /* undefined contents now */ - /* Probably need dedicated flags for surface usage too: - */ - surface_usage = (PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_GPU_WRITE); -#if 0 - PIPE_BUFFER_USAGE_CPU_READ | - PIPE_BUFFER_USAGE_CPU_WRITE); -#endif + if(strb->software) { + struct pipe_format_block block; + size_t size; + + _mesa_free(strb->data); + + assert(strb->format != PIPE_FORMAT_NONE); + pf_get_block(strb->format, &block); + + strb->stride = pf_get_stride(&block, width); + size = pf_get_2d_size(&block, strb->stride, height); + + strb->data = _mesa_malloc(size); + + return strb->data != NULL; + } + else { + struct pipe_texture template; + unsigned surface_usage; + + /* Free the old surface and texture + */ + pipe_surface_reference( &strb->surface, NULL ); + pipe_texture_reference( &strb->texture, NULL ); - strb->texture = pipe->screen->texture_create( pipe->screen, - &template ); + /* Setup new texture template. + */ + memset(&template, 0, sizeof(template)); + template.target = PIPE_TEXTURE_2D; + template.format = format; + pf_get_block(format, &template.block); + template.width[0] = width; + template.height[0] = height; + template.depth[0] = 1; + template.last_level = 0; + template.nr_samples = rb->NumSamples; + if (pf_is_depth_stencil(format)) { + template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + } + else { + template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_RENDER_TARGET); + } - /* Special path for accum buffers. - * - * Try a different surface format. Since accum buffers are s/w - * only for now, the surface pixel format doesn't really matter, - * only that the buffer is large enough. - */ - if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT) - { - /* Actually, just setting this usage value should be sufficient - * to tell the driver to go ahead and allocate the buffer, even - * if HW doesn't support the format. + /* Probably need dedicated flags for surface usage too: */ - template.tex_usage = 0; - surface_usage = (PIPE_BUFFER_USAGE_CPU_READ | + surface_usage = (PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); +#if 0 + PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE); +#endif strb->texture = pipe->screen->texture_create( pipe->screen, &template ); - } + if (!strb->texture) + return FALSE; - if (!strb->texture) - return FALSE; + strb->surface = pipe->screen->get_tex_surface( pipe->screen, + strb->texture, + 0, 0, 0, + surface_usage ); - strb->surface = pipe->screen->get_tex_surface( pipe->screen, - strb->texture, - 0, 0, 0, - surface_usage ); + assert(strb->surface->texture); + assert(strb->surface->format); + assert(strb->surface->width == width); + assert(strb->surface->height == height); - assert(strb->surface->texture); - assert(strb->surface->format); - assert(strb->surface->width == width); - assert(strb->surface->height == height); - - return strb->surface != NULL; + return strb->surface != NULL; + } } @@ -188,6 +187,7 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb) ASSERT(strb); pipe_surface_reference(&strb->surface, NULL); pipe_texture_reference(&strb->texture, NULL); + _mesa_free(strb->data); _mesa_free(strb); } @@ -244,7 +244,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name) * renderbuffer). The window system code determines the format. */ struct gl_renderbuffer * -st_new_renderbuffer_fb(enum pipe_format format, int samples) +st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw) { struct st_renderbuffer *strb; @@ -258,7 +258,8 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples) strb->Base.ClassID = 0x4242; /* just a unique value */ strb->Base.NumSamples = samples; strb->format = format; - + strb->software = sw; + switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_B8G8R8A8_UNORM: @@ -289,7 +290,7 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples) strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT; strb->Base._BaseFormat = GL_STENCIL_INDEX; break; - case DEFAULT_ACCUM_PIPE_FORMAT: /*PIPE_FORMAT_R16G16B16A16_SNORM*/ + case PIPE_FORMAT_R16G16B16A16_SNORM: strb->Base.InternalFormat = GL_RGBA16; strb->Base._BaseFormat = GL_RGBA; break; @@ -536,7 +537,7 @@ check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, samples = back->Base.NumSamples; /* create front renderbuffer */ - front = st_new_renderbuffer_fb(colorFormat, samples); + front = st_new_renderbuffer_fb(colorFormat, samples, FALSE); _mesa_add_renderbuffer(fb, frontIndex, front); /* alloc texture/surface for new front buffer */ diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index fd77d0a95b0..bea6eb89c3e 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -30,10 +30,6 @@ #define ST_CB_FBO_H -#define DEFAULT_ACCUM_PIPE_FORMAT PIPE_FORMAT_R16G16B16A16_SNORM - - - /** * Derived renderbuffer class. Just need to add a pointer to the * pipe surface. @@ -46,6 +42,13 @@ struct st_renderbuffer enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */ GLboolean defined; /**< defined contents? */ + /** + * Used only when hardware accumulation buffers are not supported. + */ + boolean software; + size_t stride; + void *data; + struct st_texture_object *rtt; /**< GL render to texture's texture */ int rtt_level, rtt_face, rtt_slice; @@ -63,7 +66,7 @@ st_renderbuffer(struct gl_renderbuffer *rb) extern struct gl_renderbuffer * -st_new_renderbuffer_fb(enum pipe_format format, int samples); +st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw); extern void st_init_fbo_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 7a4bbf5ce3a..ccf1a0b5634 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -112,7 +112,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, case PIPE_FORMAT_S8Z24_UNORM: if (format == GL_DEPTH_STENCIL) { const uint *src = (uint *) (stmap + srcY * pt->stride); - const GLfloat scale = 1.0 / (0xffffff); + const GLfloat scale = 1.0f / (0xffffff); GLint k; for (k = 0; k < width; k++) { sValues[k] = src[k] >> 24; @@ -130,7 +130,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, case PIPE_FORMAT_Z24S8_UNORM: if (format == GL_DEPTH_STENCIL) { const uint *src = (uint *) (stmap + srcY * pt->stride); - const GLfloat scale = 1.0 / (0xffffff); + const GLfloat scale = 1.0f / (0xffffff); GLint k; for (k = 0; k < width; k++) { sValues[k] = src[k] & 0xff; @@ -445,11 +445,16 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } } else { - /* untested, but simple: */ + /* XXX: unreachable code -- should be before st_read_stencil_pixels */ assert(format == GL_DEPTH_STENCIL_EXT); for (i = 0; i < height; i++) { + GLuint *zshort = (GLuint *)dst; pipe_get_tile_raw(trans, 0, y, width, 1, dst, 0); y += yStep; + /* Reverse into 24/8 */ + for (j = 0; j < width; j++) { + zshort[j] = (zshort[j] << 8) | (zshort[j] >> 24); + } dst += dstStride; } } @@ -472,7 +477,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } } else { - /* untested, but simple: */ + /* XXX: unreachable code -- should be before st_read_stencil_pixels */ assert(format == GL_DEPTH_STENCIL_EXT); for (i = 0; i < height; i++) { pipe_get_tile_raw(trans, 0, y, width, 1, dst, 0); diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index ef800291ccd..7072cbe62c7 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -60,7 +60,7 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->doubleBufferMode) { struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(colorFormat, samples); + = st_new_renderbuffer_fb(colorFormat, samples, FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } else { @@ -69,14 +69,14 @@ st_create_framebuffer( const __GLcontextModes *visual, * See check_create_front_buffers(). */ struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(colorFormat, samples); + = st_new_renderbuffer_fb(colorFormat, samples, FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); } if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) { /* combined depth/stencil buffer */ struct gl_renderbuffer *depthStencilRb - = st_new_renderbuffer_fb(depthFormat, samples); + = st_new_renderbuffer_fb(depthFormat, samples, FALSE); /* note: bind RB to two attachment points */ _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb); @@ -87,34 +87,35 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->depthBits == 32) { /* 32-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat, samples); + = st_new_renderbuffer_fb(depthFormat, samples, FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits == 24) { /* 24-bit depth buffer, ignore stencil bits */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat, samples); + = st_new_renderbuffer_fb(depthFormat, samples, FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits > 0) { /* 16-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat, samples); + = st_new_renderbuffer_fb(depthFormat, samples, FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } if (visual->stencilBits > 0) { /* 8-bit stencil */ struct gl_renderbuffer *stencilRb - = st_new_renderbuffer_fb(stencilFormat, samples); + = st_new_renderbuffer_fb(stencilFormat, samples, FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb); } } if (visual->accumRedBits > 0) { /* 16-bit/channel accum */ + /* TODO: query the pipe screen for accumulation buffer format support */ struct gl_renderbuffer *accumRb - = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT, 0); /* XXX accum isn't multisampled right? */ + = st_new_renderbuffer_fb(PIPE_FORMAT_R16G16B16A16_SNORM, 0, TRUE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb); } diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index f24f4fc59b2..e7c2ace32c7 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -289,6 +289,7 @@ _swrast_update_specular_vertex_add(GLcontext *ctx) #define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ + _NEW_PROGRAM_CONSTANTS | \ _NEW_TEXTURE | \ _NEW_HINT | \ _NEW_POLYGON ) |