From 55ed2a73653fb2fb9dee36c729c09177df2d5b4e Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 8 Apr 2009 23:29:18 +0200 Subject: st: If the hw supports it do hw conversion of texture uploads --- src/mesa/state_tracker/st_cb_texture.c | 164 ++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 4 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 57c0544ba8..e68c3d87ee 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -110,6 +110,25 @@ compressed_num_bytes(GLuint mesaFormat) } +static GLboolean +is_compressed_mesa_format(const struct gl_texture_format *format) +{ + switch (format->MesaFormat) { + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: + case MESA_FORMAT_SRGB_DXT1: + case MESA_FORMAT_SRGBA_DXT1: + case MESA_FORMAT_SRGBA_DXT3: + case MESA_FORMAT_SRGBA_DXT5: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + /** called via ctx->Driver.NewTextureImage() */ static struct gl_texture_image * st_NewTextureImage(GLcontext * ctx) @@ -378,6 +397,110 @@ strip_texture_border(GLint border, } +/** + * Try to do texture compression via rendering. If the Gallium driver + * can render into a compressed surface this will allow us to do texture + * compression. + * \return GL_TRUE for success, GL_FALSE for failure + */ +static GLboolean +compress_with_blit(GLcontext * ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_image *texImage) +{ + const GLuint dstImageOffsets[1] = {0}; + struct st_texture_image *stImage = st_texture_image(texImage); + struct pipe_screen *screen = ctx->st->pipe->screen; + const GLuint face = _mesa_tex_target_to_face(target); + const struct gl_texture_format *mesa_format; + struct pipe_texture templ; + struct pipe_texture *src_tex; + struct pipe_surface *dst_surface; + struct pipe_transfer *tex_xfer; + void *map; + + + if (!stImage->pt) { + /* XXX: Can this happen? Should we assert? */ + return GL_FALSE; + } + + /* get destination surface (in the compressed texture) */ + dst_surface = screen->get_tex_surface(screen, stImage->pt, + stImage->face, stImage->level, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + if (!dst_surface) { + /* can't render into this format (or other problem) */ + return GL_FALSE; + } + + /* Choose format for the temporary RGBA texture image. + */ + mesa_format = st_ChooseTextureFormat(ctx, GL_RGBA, format, type); + assert(mesa_format); + if (!mesa_format) + return GL_FALSE; + + /* Create the temporary source texture + */ + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.format = st_mesa_format_to_pipe_format(mesa_format->MesaFormat); + pf_get_block(templ.format, &templ.block); + templ.width[0] = width; + templ.height[0] = height; + templ.depth[0] = 1; + templ.last_level = 0; + templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; + src_tex = screen->texture_create(screen, &templ); + + if (!src_tex) + return GL_FALSE; + + /* Put user's tex data into the temporary texture + */ + tex_xfer = screen->get_tex_transfer(screen, src_tex, + face, level, 0, + PIPE_TRANSFER_WRITE, + 0, 0, width, height); /* x, y, w, h */ + map = screen->transfer_map(screen, tex_xfer); + + mesa_format->StoreImage(ctx, 2, GL_RGBA, mesa_format, + map, /* dest ptr */ + 0, 0, 0, /* dest x/y/z offset */ + tex_xfer->stride, /* dest row stride (bytes) */ + dstImageOffsets, /* image offsets (for 3D only) */ + width, height, 1, /* size */ + format, type, /* source format/type */ + pixels, /* source data */ + unpack); /* source data packing */ + + screen->transfer_unmap(screen, tex_xfer); + screen->tex_transfer_destroy(tex_xfer); + + /* copy / compress image */ + util_blit_pixels_tex(ctx->st->blit, + src_tex, /* pipe_texture (src) */ + 0, 0, /* src x0, y0 */ + width, height, /* src x1, y1 */ + dst_surface, /* pipe_surface (dst) */ + xoffset, yoffset, /* dst x0, y0 */ + xoffset + width, /* dst x1 */ + yoffset + height, /* dst y1 */ + 0.0, /* z */ + PIPE_TEX_MIPFILTER_NEAREST); + + pipe_surface_reference(&dst_surface, NULL); + pipe_texture_reference(&src_tex, NULL); + + return GL_TRUE; +} + + /** * Do glTexImage1/2/3D(). */ @@ -392,8 +515,9 @@ st_TexImage(GLcontext * ctx, const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, struct gl_texture_image *texImage, - GLsizei imageSize, GLboolean compressed) + GLsizei imageSize, GLboolean compressed_src) { + struct pipe_screen *screen = ctx->st->pipe->screen; struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); GLint postConvWidth, postConvHeight; @@ -522,7 +646,7 @@ st_TexImage(GLcontext * ctx, * the expectation that the texture will be set up but nothing * more will be done. This is where those calls return: */ - if (compressed) { + if (compressed_src) { pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, unpack, "glCompressedTexImage"); @@ -535,6 +659,21 @@ st_TexImage(GLcontext * ctx, if (!pixels) return; + /* See if we can do texture compression with a blit/render. + */ + if (!compressed_src && + !ctx->Mesa_DXTn && + is_compressed_mesa_format(texImage->TexFormat) && + screen->is_format_supported(screen, + stImage->pt->format, + stImage->pt->target, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { + if (compress_with_blit(ctx, target, level, 0, 0, 0, width, height, depth, + format, type, pixels, unpack, texImage)) { + return; + } + } + if (stImage->pt) { texImage->Data = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_WRITE, 0, 0, @@ -570,7 +709,7 @@ st_TexImage(GLcontext * ctx, * the blitter to copy. Or, use the hardware to do the format * conversion and copy: */ - if (compressed) { + if (compressed_src) { memcpy(texImage->Data, pixels, imageSize); } else { @@ -607,7 +746,7 @@ st_TexImage(GLcontext * ctx, _mesa_unmap_teximage_pbo(ctx, unpack); - if (stImage->pt) { + if (stImage->pt && texImage->Data) { st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } @@ -787,6 +926,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { + struct pipe_screen *screen = ctx->st->pipe->screen; struct st_texture_image *stImage = st_texture_image(texImage); GLuint dstRowStride; const GLuint srcImageStride = @@ -804,6 +944,22 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, if (!pixels) return; + /* See if we can do texture compression with a blit/render. + */ + if (!ctx->Mesa_DXTn && + is_compressed_mesa_format(texImage->TexFormat) && + screen->is_format_supported(screen, + stImage->pt->format, + stImage->pt->target, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { + if (compress_with_blit(ctx, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, packing, texImage)) { + return; + } + } + /* Map buffer if necessary. Need to lock to prevent other contexts * from uploading the buffer under us. */ -- cgit v1.2.3 From 5facd7986ace899673499f396897469720476799 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 14:27:36 -0600 Subject: st: reformatting and clean-ups in texture code --- src/mesa/state_tracker/st_cb_texture.c | 162 ++++++++++++++------------------- 1 file changed, 67 insertions(+), 95 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 8013e69e8e..942f4a5575 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -381,7 +381,7 @@ st_TexImage(GLcontext * ctx, const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, struct gl_texture_image *texImage, - GLsizei imageSize, int compressed) + GLsizei imageSize, GLboolean compressed) { struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); @@ -395,8 +395,7 @@ st_TexImage(GLcontext * ctx, /* gallium does not support texture borders, strip it off */ if (border) { - strip_texture_border(border, &width, &height, &depth, - unpack, &unpackNB); + strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB); unpack = &unpackNB; texImage->Width = width; texImage->Height = height; @@ -516,7 +515,8 @@ st_TexImage(GLcontext * ctx, pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, unpack, "glCompressedTexImage"); - } else { + } + else { pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, format, type, pixels, unpack, "glTexImage"); @@ -565,7 +565,7 @@ st_TexImage(GLcontext * ctx, else { GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height, format, type); - int i; + GLint i; const GLubyte *src = (const GLubyte *) pixels; for (i = 0; i++ < depth;) { @@ -616,9 +616,9 @@ st_TexImage3D(GLcontext * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - st_TexImage(ctx, 3, target, level, - internalFormat, width, height, depth, border, - format, type, pixels, unpack, texObj, texImage, 0, 0); + st_TexImage(ctx, 3, target, level, internalFormat, width, height, depth, + border, format, type, pixels, unpack, texObj, texImage, + 0, GL_FALSE); } @@ -632,9 +632,8 @@ st_TexImage2D(GLcontext * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - st_TexImage(ctx, 2, target, level, - internalFormat, width, height, 1, border, - format, type, pixels, unpack, texObj, texImage, 0, 0); + st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border, + format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); } @@ -648,9 +647,8 @@ st_TexImage1D(GLcontext * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - st_TexImage(ctx, 1, target, level, - internalFormat, width, 1, 1, border, - format, type, pixels, unpack, texObj, texImage, 0, 0); + st_TexImage(ctx, 1, target, level, internalFormat, width, 1, 1, border, + format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); } @@ -662,9 +660,8 @@ st_CompressedTexImage2D(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - st_TexImage(ctx, 2, target, level, - internalFormat, width, height, 1, border, - 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); + st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border, + 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE); } @@ -676,15 +673,14 @@ static void st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels, struct gl_texture_object *texObj, - struct gl_texture_image *texImage, int compressed) + struct gl_texture_image *texImage, GLboolean compressed) { struct st_texture_image *stImage = st_texture_image(texImage); GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width, texImage->Height, format, type); - GLuint depth; - GLuint i; + GLuint depth, i; GLubyte *dest; /* Map */ @@ -719,7 +715,8 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, if (compressed) { _mesa_get_compressed_teximage(ctx, target, level, dest, texObj, texImage); - } else { + } + else { _mesa_get_teximage(ctx, target, level, format, type, dest, texObj, texImage); } @@ -750,8 +747,8 @@ st_GetTexImage(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - st_get_tex_image(ctx, target, level, format, type, pixels, - texObj, texImage, 0); + st_get_tex_image(ctx, target, level, format, type, pixels, texObj, texImage, + GL_FALSE); } @@ -761,17 +758,14 @@ st_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - st_get_tex_image(ctx, target, level, 0, 0, pixels, - (struct gl_texture_object *) texObj, - (struct gl_texture_image *) texImage, 1); + st_get_tex_image(ctx, target, level, 0, 0, pixels, texObj, texImage, + GL_TRUE); } static void -st_TexSubimage(GLcontext * ctx, - GLint dims, - GLenum target, GLint level, +st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint width, GLint height, GLint depth, GLenum format, GLenum type, const void *pixels, @@ -783,7 +777,7 @@ st_TexSubimage(GLcontext * ctx, GLuint dstRowStride; GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, format, type); - int i; + GLint i; const GLubyte *src; DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, @@ -852,73 +846,58 @@ st_TexSubimage(GLcontext * ctx, static void -st_TexSubImage3D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +st_TexSubImage3D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { - st_TexSubimage(ctx, 3, target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, packing, texObj, texImage); + st_TexSubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type, + pixels, packing, texObj, texImage); } static void -st_TexSubImage2D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +st_TexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { - st_TexSubimage(ctx, 2, target, level, - xoffset, yoffset, 0, - width, height, 1, - format, type, pixels, packing, texObj, texImage); + st_TexSubimage(ctx, 2, target, level, xoffset, yoffset, 0, + width, height, 1, format, type, + pixels, packing, texObj, texImage); } static void -st_TexSubImage1D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +st_TexSubImage1D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { - st_TexSubimage(ctx, 1, target, level, - xoffset, 0, 0, - width, 1, 1, + st_TexSubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, format, type, pixels, packing, texObj, texImage); } /** - * Do a CopyTexSubImage operation using a read transfer from the source, a write - * transfer to the destination and get_tile()/put_tile() to access the pixels/texels. + * Do a CopyTexSubImage operation using a read transfer from the source, + * a write transfer to the destination and get_tile()/put_tile() to access + * the pixels/texels. * * Note: srcY=0=TOP of renderbuffer */ static void -fallback_copy_texsubimage(GLcontext *ctx, - GLenum target, - GLint level, +fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, struct st_renderbuffer *strb, struct st_texture_image *stImage, GLenum baseFormat, @@ -980,8 +959,8 @@ fallback_copy_texsubimage(GLcontext *ctx, if (tempSrc && texDest) { const GLint dims = 2; + const GLint dstRowStride = stImage->transfer->stride; struct gl_texture_image *texImage = &stImage->base; - GLint dstRowStride = stImage->transfer->stride; struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { @@ -1095,7 +1074,6 @@ st_copy_texsubimage(GLcontext *ctx, if (src_format == dest_format && !do_flip) { /* use surface_copy() / blit */ - dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face, stImage->level, destZ, @@ -1179,11 +1157,6 @@ st_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, level); -#if 0 - if (border) - goto fail; -#endif - /* Setup or redefine the texture object, texture and texture * image. Don't populate yet. */ @@ -1274,8 +1247,8 @@ calculate_first_last_level(struct st_texture_object *stObj) * and having firstLevel and lastLevel as signed prevents the need for * extra sign checks. */ - int firstLevel; - int lastLevel; + GLint firstLevel; + GLint lastLevel; /* Yes, this looks overly complicated, but it's all needed. */ @@ -1330,15 +1303,15 @@ copy_image_data_to_texture(struct st_context *st, /* More straightforward upload. */ st_texture_image_data(st->pipe, - stObj->pt, - stImage->face, - dstLevel, - stImage->base.Data, - stImage->base.RowStride * - stObj->pt->block.size, - stImage->base.RowStride * - stImage->base.Height * - stObj->pt->block.size); + stObj->pt, + stImage->face, + dstLevel, + stImage->base.Data, + stImage->base.RowStride * + stObj->pt->block.size, + stImage->base.RowStride * + stImage->base.Height * + stObj->pt->block.size); _mesa_align_free(stImage->base.Data); stImage->base.Data = NULL; } @@ -1384,7 +1357,6 @@ st_finalize_texture(GLcontext *ctx, if (firstImage->pt && firstImage->pt != stObj->pt && firstImage->pt->last_level >= stObj->lastLevel) { - pipe_texture_reference(&stObj->pt, firstImage->pt); } -- cgit v1.2.3 From d11d903c1b81000d04f859dcc2da41dae024f146 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 14:32:42 -0600 Subject: st: make loops over 3D texture slices a litte more intuitive --- src/mesa/state_tracker/st_cb_texture.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 942f4a5575..405af024b7 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -568,7 +568,7 @@ st_TexImage(GLcontext * ctx, GLint i; const GLubyte *src = (const GLubyte *) pixels; - for (i = 0; i++ < depth;) { + for (i = 0; i < depth; i++) { if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, texImage->TexFormat, @@ -581,9 +581,11 @@ st_TexImage(GLcontext * ctx, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); } - if (stImage->pt && i < depth) { + if (stImage->pt && i + 1 < depth) { + /* unmap this slice */ st_texture_image_unmap(ctx->st, stImage); - texImage->Data = st_texture_image_map(ctx->st, stImage, i, + /* map next slice of 3D texture */ + texImage->Data = st_texture_image_map(ctx->st, stImage, i + 1, PIPE_TRANSFER_WRITE, 0, 0, stImage->base.Width, stImage->base.Height); @@ -711,7 +713,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, dest = (GLubyte *) pixels; - for (i = 0; i++ < depth;) { + for (i = 0; i < depth; i++) { if (compressed) { _mesa_get_compressed_teximage(ctx, target, level, dest, texObj, texImage); @@ -721,9 +723,11 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, texObj, texImage); } - if (stImage->pt && i < depth) { + if (stImage->pt && i + 1 < depth) { + /* unmap this slice */ st_texture_image_unmap(ctx->st, stImage); - texImage->Data = st_texture_image_map(ctx->st, stImage, i, + /* map next slice of 3D texture */ + texImage->Data = st_texture_image_map(ctx->st, stImage, i + 1, PIPE_TRANSFER_READ, 0, 0, stImage->base.Width, stImage->base.Height); @@ -808,7 +812,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, src = (const GLubyte *) pixels; dstRowStride = stImage->transfer->stride; - for (i = 0; i++ < depth;) { + for (i = 0; i < depth; i++) { if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, texImage->TexFormat, texImage->Data, @@ -820,10 +824,12 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); } - if (stImage->pt && i < depth) { - /* map next slice of 3D texture */ + if (stImage->pt && i + 1 < depth) { + /* unmap this slice */ st_texture_image_unmap(ctx->st, stImage); - texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i, + /* map next slice of 3D texture */ + texImage->Data = st_texture_image_map(ctx->st, stImage, + zoffset + i + 1, PIPE_TRANSFER_WRITE, xoffset, yoffset, width, height); -- cgit v1.2.3 From eaca19edbbe7876079aa33d7f75d93601677081b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 14:35:36 -0600 Subject: st: add const qualifiers, use GL types --- src/mesa/state_tracker/st_cb_texture.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 405af024b7..c9f57510c0 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -88,7 +88,7 @@ gl_target_to_pipe(GLenum target) * Return nominal bytes per texel for a compressed format, 0 for non-compressed * format. */ -static int +static GLuint compressed_num_bytes(GLuint mesaFormat) { switch(mesaFormat) { @@ -563,8 +563,8 @@ st_TexImage(GLcontext * ctx, memcpy(texImage->Data, pixels, imageSize); } else { - GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height, - format, type); + const GLuint srcImageStride = + _mesa_image_image_stride(unpack, width, height, format, type); GLint i; const GLubyte *src = (const GLubyte *) pixels; @@ -678,10 +678,9 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_image *texImage, GLboolean compressed) { struct st_texture_image *stImage = st_texture_image(texImage); - GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, - texImage->Width, - texImage->Height, - format, type); + const GLuint dstImageStride = + _mesa_image_image_stride(&ctx->Pack, texImage->Width, texImage->Height, + format, type); GLuint depth, i; GLubyte *dest; @@ -779,8 +778,8 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, { struct st_texture_image *stImage = st_texture_image(texImage); GLuint dstRowStride; - GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, - format, type); + const GLuint srcImageStride = + _mesa_image_image_stride(packing, width, height, format, type); GLint i; const GLubyte *src; @@ -1106,7 +1105,7 @@ st_copy_texsubimage(GLcontext *ctx, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { /* draw textured quad to do the copy */ - int srcY0, srcY1; + GLint srcY0, srcY1; dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face, stImage->level, @@ -1339,9 +1338,7 @@ st_finalize_texture(GLcontext *ctx, { struct st_texture_object *stObj = st_texture_object(tObj); const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - int comp_byte = 0; - int cpp; - GLuint face; + GLuint comp_byte = 0, cpp, face; struct st_texture_image *firstImage; *needFlush = GL_FALSE; -- cgit v1.2.3 From 1ad2484f03cbe9ae6bd4ebe50d6894e570d65952 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 14:41:49 -0600 Subject: st: consolidate format->usage computation --- src/mesa/state_tracker/st_cb_texture.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index c9f57510c0..197ded70c0 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -226,6 +226,21 @@ logbase2(int n) } +/** + * Return default texture usage bitmask for the given texture format. + */ +static GLuint +default_usage(enum pipe_format fmt) +{ + GLuint usage = PIPE_TEXTURE_USAGE_SAMPLER; + if (pf_is_depth_stencil(fmt)) + usage |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + else + usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; + return usage; +} + + /** * Allocate a pipe_texture object for the given st_texture_object using * the given st_texture_image to guess the mipmap size/levels. @@ -250,7 +265,7 @@ guess_and_alloc_texture(struct st_context *st, GLuint width = stImage->base.Width2; /* size w/out border */ GLuint height = stImage->base.Height2; GLuint depth = stImage->base.Depth2; - GLuint i, comp_byte = 0; + GLuint i, comp_byte = 0, usage; enum pipe_format fmt; DBG("%s\n", __FUNCTION__); @@ -312,6 +327,9 @@ guess_and_alloc_texture(struct st_context *st, comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat); fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat); + + usage = default_usage(fmt); + stObj->pt = st_texture_create(st, gl_target_to_pipe(stObj->base.Target), fmt, @@ -320,10 +338,7 @@ guess_and_alloc_texture(struct st_context *st, height, depth, comp_byte, - ( (pf_is_depth_stencil(fmt) ? - PIPE_TEXTURE_USAGE_DEPTH_STENCIL : - PIPE_TEXTURE_USAGE_RENDER_TARGET) | - PIPE_TEXTURE_USAGE_SAMPLER )); + usage); DBG("%s - success\n", __FUNCTION__); } @@ -1396,6 +1411,8 @@ st_finalize_texture(GLcontext *ctx, if (!stObj->pt) { const enum pipe_format fmt = st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat); + GLuint usage = default_usage(fmt); + stObj->pt = st_texture_create(ctx->st, gl_target_to_pipe(stObj->base.Target), fmt, @@ -1404,10 +1421,7 @@ st_finalize_texture(GLcontext *ctx, firstImage->base.Height2, firstImage->base.Depth2, comp_byte, - ( (pf_is_depth_stencil(fmt) ? - PIPE_TEXTURE_USAGE_DEPTH_STENCIL : - PIPE_TEXTURE_USAGE_RENDER_TARGET) | - PIPE_TEXTURE_USAGE_SAMPLER )); + usage); if (!stObj->pt) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); -- cgit v1.2.3 From f12201567463c7aeb9b76c32f000d577a82e7f92 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 14:48:21 -0600 Subject: st: remove comp_byte parameter to st_texture_create() We can determine if the texture is compressed by checking the format. --- src/mesa/state_tracker/st_atom_pixeltransfer.c | 3 +-- src/mesa/state_tracker/st_cb_bitmap.c | 5 ++--- src/mesa/state_tracker/st_cb_drawpixels.c | 5 ++--- src/mesa/state_tracker/st_cb_texture.c | 12 +++--------- src/mesa/state_tracker/st_texture.c | 3 +-- src/mesa/state_tracker/st_texture.h | 1 - 6 files changed, 9 insertions(+), 20 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 8d0029dde5..e0bbf7f3be 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -125,8 +125,7 @@ create_color_map_texture(GLcontext *ctx) /* create texture for color map/table */ pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, - texSize, texSize, 1, 0, - PIPE_TEXTURE_USAGE_SAMPLER); + texSize, texSize, 1, PIPE_TEXTURE_USAGE_SAMPLER); return pt; } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 2d547dd072..3b2ad00f5c 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -330,7 +330,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, * Create texture to hold bitmap pattern. */ pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, ctx->st->bitmap.tex_format, - 0, width, height, 1, 0, + 0, width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) { _mesa_unmap_bitmap_pbo(ctx, unpack); @@ -579,8 +579,7 @@ reset_cache(struct st_context *st) cache->texture = st_texture_create(st, PIPE_TEXTURE_2D, st->bitmap.tex_format, 0, BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, - 1, 0, - PIPE_TEXTURE_USAGE_SAMPLER); + 1, PIPE_TEXTURE_USAGE_SAMPLER); /* Map the texture transfer. * Subsequent glBitmap calls will write into the texture image. diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index ebb1d1142a..0a4430501f 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -351,8 +351,7 @@ make_texture(struct st_context *st, if (!pixels) return NULL; - pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, - 1, 0, + pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) { _mesa_unmap_drawpix_pbo(ctx, unpack); @@ -951,7 +950,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0, - width, height, 1, 0, + width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) return; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 197ded70c0..bd023e0018 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -265,7 +265,7 @@ guess_and_alloc_texture(struct st_context *st, GLuint width = stImage->base.Width2; /* size w/out border */ GLuint height = stImage->base.Height2; GLuint depth = stImage->base.Depth2; - GLuint i, comp_byte = 0, usage; + GLuint i, usage; enum pipe_format fmt; DBG("%s\n", __FUNCTION__); @@ -323,9 +323,6 @@ guess_and_alloc_texture(struct st_context *st, lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); } - if (stImage->base.IsCompressed) - comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat); - fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat); usage = default_usage(fmt); @@ -337,7 +334,6 @@ guess_and_alloc_texture(struct st_context *st, width, height, depth, - comp_byte, usage); DBG("%s - success\n", __FUNCTION__); @@ -1353,7 +1349,7 @@ st_finalize_texture(GLcontext *ctx, { struct st_texture_object *stObj = st_texture_object(tObj); const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - GLuint comp_byte = 0, cpp, face; + GLuint cpp, face; struct st_texture_image *firstImage; *needFlush = GL_FALSE; @@ -1380,8 +1376,7 @@ st_finalize_texture(GLcontext *ctx, /* FIXME: determine format block instead of cpp */ if (firstImage->base.IsCompressed) { - comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); - cpp = comp_byte; + cpp = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); } else { cpp = firstImage->base.TexFormat->TexelBytes; @@ -1420,7 +1415,6 @@ st_finalize_texture(GLcontext *ctx, firstImage->base.Width2, firstImage->base.Height2, firstImage->base.Depth2, - comp_byte, usage); if (!stObj->pt) { diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 3f90ad502c..12ceac1091 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -78,7 +78,6 @@ st_texture_create(struct st_context *st, GLuint width0, GLuint height0, GLuint depth0, - GLuint compress_byte, GLuint usage ) { struct pipe_texture pt, *newtex; @@ -101,7 +100,7 @@ st_texture_create(struct st_context *st, pt.width[0] = width0; pt.height[0] = height0; pt.depth[0] = depth0; - pt.compressed = compress_byte ? 1 : 0; + pt.compressed = pf_is_compressed(format); pf_get_block(format, &pt.block); pt.tex_usage = usage; diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 28c2f580f6..60c000115e 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -108,7 +108,6 @@ st_texture_create(struct st_context *st, GLuint width0, GLuint height0, GLuint depth0, - GLuint compress_byte, GLuint tex_usage ); -- cgit v1.2.3 From 227aa0070d3b13baaa87270fd1a45fa5904ae3dc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 14:55:32 -0600 Subject: gallium: remove unneeded compressed=0 assignment --- src/mesa/state_tracker/st_cb_fbo.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index f74d0d46d0..92d53da4db 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -111,7 +111,6 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, init_renderbuffer_bits(strb, template.format); template.target = PIPE_TEXTURE_2D; - template.compressed = 0; pf_get_block(template.format, &template.block); template.width[0] = width; template.height[0] = height; -- cgit v1.2.3 From e53d6ab39bf04b2bb39ad23d5990494321ee77ce Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 14:57:41 -0600 Subject: st: rearrange some code to be a little more clear --- src/mesa/state_tracker/st_cb_fbo.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 92d53da4db..1590f275e2 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -96,28 +96,22 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, 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); } - - strb->Base.Width = width; - strb->Base.Height = height; - init_renderbuffer_bits(strb, template.format); - - template.target = PIPE_TEXTURE_2D; 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; } @@ -126,6 +120,10 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, PIPE_TEXTURE_USAGE_RENDER_TARGET); } + /* init renderbuffer fields */ + strb->Base.Width = width; + strb->Base.Height = height; + init_renderbuffer_bits(strb, template.format); /* Probably need dedicated flags for surface usage too: */ -- cgit v1.2.3 From 1f4a7f3a2eafd99906105ff74b26ea3ae0f19030 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 14:58:40 -0600 Subject: st: remove unneeded "is compressed" check The format indicates compressed vs. uncompressed. --- src/mesa/state_tracker/st_texture.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 12ceac1091..fad513a556 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -127,8 +127,7 @@ st_texture_match_image(const struct pipe_texture *pt, /* Check if this image's format matches the established texture's format. */ - if (st_mesa_format_to_pipe_format(image->TexFormat->MesaFormat) != pt->format || - image->IsCompressed != pt->compressed) + if (st_mesa_format_to_pipe_format(image->TexFormat->MesaFormat) != pt->format) return GL_FALSE; /* Test if this image's size matches what's expected in the -- cgit v1.2.3 From 311f77198e171e9ce8ddcce91fd6a894fff1f14f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 15:00:54 -0600 Subject: st: remove another unneeded 'is compressed' comparison --- src/mesa/state_tracker/st_cb_texture.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index bd023e0018..57c0544ba8 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1394,8 +1394,9 @@ st_finalize_texture(GLcontext *ctx, stObj->pt->width[0] != firstImage->base.Width2 || stObj->pt->height[0] != firstImage->base.Height2 || stObj->pt->depth[0] != firstImage->base.Depth2 || - stObj->pt->block.size/stObj->pt->block.width != cpp || /* Nominal bytes per pixel */ - stObj->pt->compressed != firstImage->base.IsCompressed) { + /* Nominal bytes per pixel: */ + stObj->pt->block.size / stObj->pt->block.width != cpp) + { pipe_texture_reference(&stObj->pt, NULL); ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER; } -- cgit v1.2.3 From 88999de8b70d1e170f5bbcadd07132d382c560cf Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 10 Apr 2009 08:05:10 -0600 Subject: gallium: remove pipe_texture::compressed field The format field encodes compressed vs. uncompressed already. We can easily check if a texture is compressed with pf_is_compressed(texture->format). --- src/gallium/drivers/nv04/nv04_transfer.c | 1 - src/gallium/drivers/nv10/nv10_transfer.c | 1 - src/gallium/drivers/nv20/nv20_transfer.c | 1 - src/gallium/drivers/nv30/nv30_transfer.c | 1 - src/gallium/drivers/nv40/nv40_transfer.c | 1 - src/gallium/include/pipe/p_state.h | 1 - src/mesa/state_tracker/st_texture.c | 1 - 7 files changed, 7 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/gallium/drivers/nv04/nv04_transfer.c b/src/gallium/drivers/nv04/nv04_transfer.c index e925a44e29..854b855d64 100644 --- a/src/gallium/drivers/nv04/nv04_transfer.c +++ b/src/gallium/drivers/nv04/nv04_transfer.c @@ -43,7 +43,6 @@ nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; template->last_level = 0; - template->compressed = pt->compressed; template->nr_samples = pt->nr_samples; template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | diff --git a/src/gallium/drivers/nv10/nv10_transfer.c b/src/gallium/drivers/nv10/nv10_transfer.c index 5a99225409..c06b8d34c7 100644 --- a/src/gallium/drivers/nv10/nv10_transfer.c +++ b/src/gallium/drivers/nv10/nv10_transfer.c @@ -43,7 +43,6 @@ nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; template->last_level = 0; - template->compressed = pt->compressed; template->nr_samples = pt->nr_samples; template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | diff --git a/src/gallium/drivers/nv20/nv20_transfer.c b/src/gallium/drivers/nv20/nv20_transfer.c index e5255296aa..5018995596 100644 --- a/src/gallium/drivers/nv20/nv20_transfer.c +++ b/src/gallium/drivers/nv20/nv20_transfer.c @@ -43,7 +43,6 @@ nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; template->last_level = 0; - template->compressed = pt->compressed; template->nr_samples = pt->nr_samples; template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c index 8b915b35bd..2367571878 100644 --- a/src/gallium/drivers/nv30/nv30_transfer.c +++ b/src/gallium/drivers/nv30/nv30_transfer.c @@ -43,7 +43,6 @@ nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; template->last_level = 0; - template->compressed = pt->compressed; template->nr_samples = pt->nr_samples; template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c index 728e8b5674..ce45055fe8 100644 --- a/src/gallium/drivers/nv40/nv40_transfer.c +++ b/src/gallium/drivers/nv40/nv40_transfer.c @@ -43,7 +43,6 @@ nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; template->last_level = 0; - template->compressed = pt->compressed; template->nr_samples = pt->nr_samples; template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 705ae68ec6..4b590bdc90 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -336,7 +336,6 @@ struct pipe_texture unsigned nblocksy[PIPE_MAX_TEXTURE_LEVELS]; /**< allocated height in blocks */ unsigned last_level:8; /**< Index of last mipmap level present/defined */ - unsigned compressed:1; unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */ diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index fad513a556..19eb7e2f69 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -100,7 +100,6 @@ st_texture_create(struct st_context *st, pt.width[0] = width0; pt.height[0] = height0; pt.depth[0] = depth0; - pt.compressed = pf_is_compressed(format); pf_get_block(format, &pt.block); pt.tex_usage = usage; -- cgit v1.2.3 From 1ea7f0fef055245fa18c0fbc3e54a866956c2507 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 14 Apr 2009 21:27:58 +0100 Subject: mesa: Fix gcc assembly enable logic. The i386 symbol is defined on WINDDK. --- src/mesa/state_tracker/st_cb_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 57c0544ba8..1f14b3705d 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -169,7 +169,7 @@ st_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) * than COPY_DWORDS would: * XXX Put this in src/mesa/main/imports.h ??? */ -#if defined(i386) || defined(__i386__) +#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) static INLINE void * __memcpy(void *to, const void *from, size_t n) { -- cgit v1.2.3 From 7db7ff878d3e5a6b345228e6eaee4797bb68b360 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 14 Apr 2009 22:14:30 -0600 Subject: mesa: merge the prog_src_register::NegateBase and NegateAbs fields There's really no need for two negation fields. This came from the GL_NV_fragment_program extension. The new, unified Negate bitfield applies after the absolute value step. --- src/mesa/drivers/dri/i915/i915_fragprog.c | 10 ++--- src/mesa/drivers/dri/i965/brw_vs_constval.c | 2 +- src/mesa/drivers/dri/i965/brw_vs_emit.c | 8 ++-- src/mesa/drivers/dri/i965/brw_wm_fp.c | 13 +++--- src/mesa/drivers/dri/i965/brw_wm_glsl.c | 6 +-- src/mesa/drivers/dri/i965/brw_wm_pass0.c | 2 +- src/mesa/drivers/dri/r200/r200_vertprog.c | 34 ++++++++-------- src/mesa/drivers/dri/r300/r300_fragprog.c | 4 +- src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c | 17 ++++---- src/mesa/drivers/dri/r300/r300_vertprog.c | 49 +++++++++-------------- src/mesa/drivers/dri/r300/r500_fragprog.c | 19 +++++---- src/mesa/drivers/dri/r300/radeon_nqssadce.c | 7 ++-- src/mesa/drivers/dri/r300/radeon_program_alu.c | 20 +++++---- src/mesa/drivers/dri/r300/radeon_program_pair.c | 11 +++-- src/mesa/main/ffvertex_prog.c | 3 +- src/mesa/main/texenvprogram.c | 3 +- src/mesa/shader/arbprogparse.c | 8 ++-- src/mesa/shader/nvfragparse.c | 33 ++++++++------- src/mesa/shader/nvvertparse.c | 10 ++--- src/mesa/shader/prog_execute.c | 27 ++++--------- src/mesa/shader/prog_instruction.h | 32 +++------------ src/mesa/shader/prog_print.c | 20 ++++----- src/mesa/shader/programopt.c | 2 +- src/mesa/shader/slang/slang_emit.c | 2 +- src/mesa/state_tracker/st_cb_bitmap.c | 2 +- src/mesa/state_tracker/st_mesa_to_tgsi.c | 20 ++++----- 26 files changed, 156 insertions(+), 208 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index 52f09a4b1b..a5158de945 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -162,12 +162,12 @@ src_vector(struct i915_fragment_program *p, GET_SWZ(source->Swizzle, 1), GET_SWZ(source->Swizzle, 2), GET_SWZ(source->Swizzle, 3)); - if (source->NegateBase) + if (source->Negate) src = negate(src, - GET_BIT(source->NegateBase, 0), - GET_BIT(source->NegateBase, 1), - GET_BIT(source->NegateBase, 2), - GET_BIT(source->NegateBase, 3)); + GET_BIT(source->Negate, 0), + GET_BIT(source->Negate, 1), + GET_BIT(source->Negate, 2), + GET_BIT(source->Negate, 3)); return src; } diff --git a/src/mesa/drivers/dri/i965/brw_vs_constval.c b/src/mesa/drivers/dri/i965/brw_vs_constval.c index d29eb17f8c..2637344b48 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_constval.c +++ b/src/mesa/drivers/dri/i965/brw_vs_constval.c @@ -96,7 +96,7 @@ static GLubyte get_active( struct tracker *t, struct prog_src_register src ) { GLuint i; - GLubyte active = src.NegateBase; /* NOTE! */ + GLubyte active = src.Negate; /* NOTE! */ if (src.RelAddr) return 0xf; diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 2ee63129bc..42f6a99142 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -899,7 +899,7 @@ static struct brw_reg get_arg( struct brw_vs_compile *c, /* Note this is ok for non-swizzle instructions: */ - reg.negate = src->NegateBase ? 1 : 0; + reg.negate = src->Negate ? 1 : 0; return reg; } @@ -945,7 +945,7 @@ static void emit_swz( struct brw_vs_compile *c, GLuint ones_mask = 0; GLuint src_mask = 0; GLubyte src_swz[4]; - GLboolean need_tmp = (src.NegateBase && + GLboolean need_tmp = (src.Negate && dst.file != BRW_GENERAL_REGISTER_FILE); struct brw_reg tmp = dst; GLuint i; @@ -997,8 +997,8 @@ static void emit_swz( struct brw_vs_compile *c, if (ones_mask) brw_MOV(p, brw_writemask(tmp, ones_mask), brw_imm_f(1)); - if (src.NegateBase) - brw_MOV(p, brw_writemask(tmp, src.NegateBase), negate(tmp)); + if (src.Negate) + brw_MOV(p, brw_writemask(tmp, src.Negate), negate(tmp)); if (need_tmp) { brw_MOV(p, dst, tmp); diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index a7f5f1b9a2..1798d842c7 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -80,9 +80,8 @@ static struct prog_src_register src_reg(GLuint file, GLuint idx) reg.Index = idx; reg.Swizzle = SWIZZLE_NOOP; reg.RelAddr = 0; - reg.NegateBase = 0; + reg.Negate = NEGATE_NONE; reg.Abs = 0; - reg.NegateAbs = 0; return reg; } @@ -569,7 +568,7 @@ static void precalc_dst( struct brw_wm_compile *c, src_undef(), src_undef()); /* Avoid letting negation flag of src0 affect our 1 constant. */ - swz->SrcReg[0].NegateBase &= ~NEGATE_X; + swz->SrcReg[0].Negate &= ~NEGATE_X; } if (dst.WriteMask & WRITEMASK_W) { /* dst.w = mov src1.w @@ -604,7 +603,7 @@ static void precalc_lit( struct brw_wm_compile *c, src_undef(), src_undef()); /* Avoid letting the negation flag of src0 affect our 1 constant. */ - swz->SrcReg[0].NegateBase = 0; + swz->SrcReg[0].Negate = NEGATE_NONE; } if (dst.WriteMask & WRITEMASK_YZ) { @@ -651,7 +650,7 @@ static void precalc_tex( struct brw_wm_compile *c, src0, src_undef(), src_undef()); - out->SrcReg[0].NegateBase = 0; + out->SrcReg[0].Negate = NEGATE_NONE; out->SrcReg[0].Abs = 1; /* tmp0 = MAX(coord.X, coord.Y) */ @@ -1050,14 +1049,14 @@ void brw_wm_pass_fp( struct brw_wm_compile *c ) case OPCODE_ABS: out = emit_insn(c, inst); out->Opcode = OPCODE_MOV; - out->SrcReg[0].NegateBase = 0; + out->SrcReg[0].Negate = NEGATE_NONE; out->SrcReg[0].Abs = 1; break; case OPCODE_SUB: out = emit_insn(c, inst); out->Opcode = OPCODE_ADD; - out->SrcReg[1].NegateBase ^= 0xf; + out->SrcReg[1].Negate ^= NEGATE_XYZW; break; case OPCODE_SCS: diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 49fea2e41a..385efd2dd3 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -340,7 +340,7 @@ get_src_reg_const(struct brw_wm_compile *c, const_reg = stride(const_reg, 0, 1, 0); const_reg.subnr = component * 4; - if (src->NegateBase) + if (src->Negate & (1 << component)) const_reg = negate(const_reg); if (src->Abs) const_reg = brw_abs(const_reg); @@ -377,7 +377,7 @@ static struct brw_reg get_src_reg(struct brw_wm_compile *c, else { /* other type of source register */ return get_reg(c, src->File, src->Index, component, nr, - src->NegateBase, src->Abs); + src->Negate, src->Abs); } } @@ -402,7 +402,7 @@ static struct brw_reg get_src_reg_imm(struct brw_wm_compile *c, const GLfloat *param = c->fp->program.Base.Parameters->ParameterValues[src->Index]; GLfloat value = param[component]; - if (src->NegateBase) + if (src->Negate & (1 << channel)) value = -value; if (src->Abs) value = FABSF(value); diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c index 2debd0678a..92142764f5 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c @@ -322,7 +322,7 @@ static struct brw_wm_ref *get_new_ref( struct brw_wm_compile *c, newref->value->lastuse = newref; } - if (src.NegateBase & (1<hw_reg.negate ^= 1; if (src.Abs) { diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index a2561df579..4ce93b5145 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -290,7 +290,7 @@ static unsigned long t_src(struct r200_vertex_program *vp, struct prog_src_regis t_swizzle(GET_SWZ(src->Swizzle, 2)), t_swizzle(GET_SWZ(src->Swizzle, 3)), t_src_class(src->File), - src->NegateBase) | (src->RelAddr << 4); + src->Negate) | (src->RelAddr << 4); } static unsigned long t_src_scalar(struct r200_vertex_program *vp, struct prog_src_register *src) @@ -302,7 +302,7 @@ static unsigned long t_src_scalar(struct r200_vertex_program *vp, struct prog_sr t_swizzle(GET_SWZ(src->Swizzle, 0)), t_swizzle(GET_SWZ(src->Swizzle, 0)), t_src_class(src->File), - src->NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src->RelAddr << 4); + src->Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src->RelAddr << 4); } static unsigned long t_opcode(enum prog_opcode opcode) @@ -700,7 +700,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte t_swizzle(GET_SWZ(src[1].Swizzle, 0)), SWIZZLE_ZERO, t_src_class(src[0].File), - src[0].NegateBase) | (src[0].RelAddr << 4); + src[0].Negate) | (src[0].RelAddr << 4); o_inst->src1 = UNUSED_SRC_0; o_inst->src2 = UNUSED_SRC_0; } @@ -712,12 +712,12 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte t_swizzle(GET_SWZ(src[0].Swizzle, 0)), SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, t_src_class(src[0].File), - src[0].NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), SWIZZLE_ZERO, SWIZZLE_ZERO, t_swizzle(GET_SWZ(src[1].Swizzle, 0)), SWIZZLE_ZERO, t_src_class(src[1].File), - src[1].NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); + src[1].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); o_inst->src2 = UNUSED_SRC_1; o_inst++; @@ -766,11 +766,11 @@ if ((o_inst - vp->instr) == 31) { o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, t_src_class(src[1].File), - src[1].NegateBase) | (src[1].RelAddr << 4); + src[1].Negate) | (src[1].RelAddr << 4); o_inst->src2 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, t_src_class(src[1].File), - src[1].NegateBase) | (src[1].RelAddr << 4); + src[1].Negate) | (src[1].RelAddr << 4); } else { o_inst->src1 = t_src(vp, &src[1]); @@ -792,7 +792,7 @@ else { t_swizzle(GET_SWZ(src[0].Swizzle, 2)), SWIZZLE_ZERO, t_src_class(src[0].File), - src[0].NegateBase) | (src[0].RelAddr << 4); + src[0].Negate) | (src[0].RelAddr << 4); o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 0)), @@ -800,7 +800,7 @@ else { t_swizzle(GET_SWZ(src[1].Swizzle, 2)), SWIZZLE_ZERO, t_src_class(src[1].File), - src[1].NegateBase) | (src[1].RelAddr << 4); + src[1].Negate) | (src[1].RelAddr << 4); o_inst->src2 = UNUSED_SRC_1; goto next; @@ -815,7 +815,7 @@ else { t_swizzle(GET_SWZ(src[0].Swizzle, 2)), VSF_IN_COMPONENT_ONE, t_src_class(src[0].File), - src[0].NegateBase) | (src[0].RelAddr << 4); + src[0].Negate) | (src[0].RelAddr << 4); o_inst->src1 = t_src(vp, &src[1]); o_inst->src2 = UNUSED_SRC_1; goto next; @@ -831,7 +831,7 @@ else { t_swizzle(GET_SWZ(src[1].Swizzle, 2)), t_swizzle(GET_SWZ(src[1].Swizzle, 3)), t_src_class(src[1].File), - (!src[1].NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); + (!src[1].Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); o_inst->src2 = UNUSED_SRC_1; goto next; @@ -846,7 +846,7 @@ else { t_swizzle(GET_SWZ(src[0].Swizzle, 2)), t_swizzle(GET_SWZ(src[0].Swizzle, 3)), t_src_class(src[0].File), - (!src[0].NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); + (!src[0].Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); o_inst->src2 = UNUSED_SRC_1; goto next; @@ -874,7 +874,7 @@ else { VSF_IN_COMPONENT_W, VSF_IN_CLASS_TMP, /* Not 100% sure about this */ - (!src[0].NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE/*VSF_FLAG_ALL*/); + (!src[0].Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE/*VSF_FLAG_ALL*/); o_inst->src2 = UNUSED_SRC_0; u_temp_i--; @@ -899,7 +899,7 @@ else { t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w t_src_class(src[0].File), - src[0].NegateBase) | (src[0].RelAddr << 4); + src[0].Negate) | (src[0].RelAddr << 4); o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z @@ -907,7 +907,7 @@ else { t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w t_src_class(src[1].File), - src[1].NegateBase) | (src[1].RelAddr << 4); + src[1].Negate) | (src[1].RelAddr << 4); o_inst->src2 = UNUSED_SRC_1; o_inst++; @@ -922,7 +922,7 @@ else { t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w t_src_class(src[1].File), - (!src[1].NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); + (!src[1].Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z @@ -930,7 +930,7 @@ else { t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w t_src_class(src[0].File), - src[0].NegateBase) | (src[0].RelAddr << 4); + src[0].Negate) | (src[0].RelAddr << 4); o_inst->src2 = MAKE_VSF_SOURCE(u_temp_i+1, VSF_IN_COMPONENT_X, diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 32182bb667..873cde4414 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -214,9 +214,9 @@ static GLboolean transform_TEX( * r < tex <=> -tex+r < 0 * r >= tex <=> not (-tex+r < 0 */ if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL) - tgt[1].SrcReg[2].NegateBase = tgt[0].SrcReg[2].NegateBase ^ NEGATE_XYZW; + tgt[1].SrcReg[2].Negate = tgt[0].SrcReg[2].Negate ^ NEGATE_XYZW; else - tgt[1].SrcReg[0].NegateBase = tgt[0].SrcReg[0].NegateBase ^ NEGATE_XYZW; + tgt[1].SrcReg[0].Negate = tgt[0].SrcReg[0].Negate ^ NEGATE_XYZW; tgt[2].Opcode = OPCODE_CMP; tgt[2].DstReg = orig_inst->DstReg; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c b/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c index a86d2bd471..191853ac1f 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c @@ -92,7 +92,7 @@ static const struct swizzle_data* lookup_native_swizzle(GLuint swizzle) GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) { if (reg.Abs) - reg.NegateBase = 0; + reg.Negate = NEGATE_NONE; if (opcode == OPCODE_KIL || opcode == OPCODE_TEX || @@ -100,7 +100,8 @@ GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) opcode == OPCODE_TXP) { int j; - if (reg.Abs || reg.NegateBase != (15*reg.NegateAbs)) + if (reg.Abs || (reg.Negate != NEGATE_XYZW && + reg.Negate != NEGATE_NONE)) return GL_FALSE; for(j = 0; j < 4; ++j) { @@ -121,7 +122,7 @@ GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) if (GET_SWZ(reg.Swizzle, j) != SWIZZLE_NIL) relevant |= 1 << j; - if ((reg.NegateBase & relevant) && (reg.NegateBase & relevant) != relevant) + if ((reg.Negate & relevant) && (reg.Negate & relevant) != relevant) return GL_FALSE; if (!lookup_native_swizzle(reg.Swizzle)) @@ -137,7 +138,7 @@ GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src) { if (src.Abs) - src.NegateBase = 0; + src.Negate = NEGATE_NONE; while(dst.WriteMask) { const struct swizzle_data *best_swizzle = 0; @@ -170,11 +171,11 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, } } - if ((src.NegateBase & best_matchmask) != 0) { - best_matchmask &= src.NegateBase; - rgbnegate = !src.NegateAbs; + if ((src.Negate & best_matchmask) != 0) { + best_matchmask &= src.Negate; + rgbnegate = !src.Negate; } else { - rgbnegate = src.NegateAbs; + rgbnegate = src.Negate; } struct prog_instruction *inst; diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 50806575ce..146daa367c 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -245,7 +245,7 @@ static unsigned long t_src_index(struct r300_vertex_program *vp, static unsigned long t_src(struct r300_vertex_program *vp, struct prog_src_register *src) { - /* src->NegateBase uses the NEGATE_ flags from program_instruction.h, + /* src->Negate uses the NEGATE_ flags from program_instruction.h, * which equal our VSF_FLAGS_ values, so it's safe to just pass it here. */ return PVS_SRC_OPERAND(t_src_index(vp, src), @@ -254,13 +254,13 @@ static unsigned long t_src(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src->Swizzle, 2)), t_swizzle(GET_SWZ(src->Swizzle, 3)), t_src_class(src->File), - src->NegateBase) | (src->RelAddr << 4); + src->Negate) | (src->RelAddr << 4); } static unsigned long t_src_scalar(struct r300_vertex_program *vp, struct prog_src_register *src) { - /* src->NegateBase uses the NEGATE_ flags from program_instruction.h, + /* src->Negate uses the NEGATE_ flags from program_instruction.h, * which equal our VSF_FLAGS_ values, so it's safe to just pass it here. */ return PVS_SRC_OPERAND(t_src_index(vp, src), @@ -269,8 +269,7 @@ static unsigned long t_src_scalar(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src->Swizzle, 0)), t_swizzle(GET_SWZ(src->Swizzle, 0)), t_src_class(src->File), - src-> - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src->Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src->RelAddr << 4); } @@ -307,7 +306,7 @@ static GLuint *r300TranslateOpcodeABS(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 3)), t_src_class(src[0].File), (!src[0]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[3] = 0; @@ -369,8 +368,7 @@ static GLuint *r300TranslateOpcodeDP3(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 2)), SWIZZLE_ZERO, t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), @@ -378,8 +376,7 @@ static GLuint *r300TranslateOpcodeDP3(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[1].Swizzle, 1)), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), SWIZZLE_ZERO, t_src_class(src[1].File), - src[1]. - NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | + src[1].Negate ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | (src[1].RelAddr << 4); inst[3] = __CONST(1, SWIZZLE_ZERO); @@ -422,8 +419,7 @@ static GLuint *r300TranslateOpcodeDPH(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 2)), PVS_SRC_SELECT_FORCE_1, t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = t_src(vp, &src[1]); inst[3] = __CONST(1, SWIZZLE_ZERO); @@ -519,7 +515,7 @@ static GLuint *r300TranslateOpcodeFLR(struct r300_vertex_program *vp, PVS_SRC_SELECT_W, PVS_SRC_REG_TEMPORARY, /* Not 100% sure about this */ (!src[0]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE /*VSF_FLAG_ALL */ ); inst[3] = __CONST(0, SWIZZLE_ZERO); (*u_temp_i)--; @@ -564,8 +560,7 @@ static GLuint *r300TranslateOpcodeLG2(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 0)), t_swizzle(GET_SWZ(src[0].Swizzle, 0)), t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = __CONST(0, SWIZZLE_ZERO); inst[3] = __CONST(0, SWIZZLE_ZERO); @@ -592,24 +587,21 @@ static GLuint *r300TranslateOpcodeLIT(struct r300_vertex_program *vp, PVS_SRC_SELECT_FORCE_0, // Z t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W PVS_SRC_SELECT_FORCE_0, // Z t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X PVS_SRC_SELECT_FORCE_0, // Z t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); return inst; @@ -837,7 +829,7 @@ static GLuint *r300TranslateOpcodeSUB(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[1].Swizzle, 3)), t_src_class(src[1].File), (!src[1]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); inst[3] = 0; #else @@ -857,7 +849,7 @@ static GLuint *r300TranslateOpcodeSUB(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[1].Swizzle, 3)), t_src_class(src[1].File), (!src[1]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); #endif @@ -905,16 +897,14 @@ static GLuint *r300TranslateOpcodeXPD(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // Z t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // X t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // Y t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // W t_src_class(src[1].File), - src[1]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[1].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); inst[3] = __CONST(1, SWIZZLE_ZERO); inst += 4; @@ -931,15 +921,14 @@ static GLuint *r300TranslateOpcodeXPD(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // W t_src_class(src[1].File), (!src[1]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // Z t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[3] = PVS_SRC_OPERAND(*u_temp_i, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.c b/src/mesa/drivers/dri/r300/r500_fragprog.c index 07a2a7b17c..292573de89 100644 --- a/src/mesa/drivers/dri/r300/r500_fragprog.c +++ b/src/mesa/drivers/dri/r300/r500_fragprog.c @@ -156,9 +156,9 @@ static GLboolean transform_TEX( * r < tex <=> -tex+r < 0 * r >= tex <=> not (-tex+r < 0 */ if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL) - tgt[1].SrcReg[2].NegateBase = tgt[0].SrcReg[2].NegateBase ^ NEGATE_XYZW; + tgt[1].SrcReg[2].Negate = tgt[0].SrcReg[2].Negate ^ NEGATE_XYZW; else - tgt[1].SrcReg[0].NegateBase = tgt[0].SrcReg[0].NegateBase ^ NEGATE_XYZW; + tgt[1].SrcReg[0].Negate = tgt[0].SrcReg[0].Negate ^ NEGATE_XYZW; tgt[2].Opcode = OPCODE_CMP; tgt[2].DstReg = orig_inst->DstReg; @@ -314,8 +314,8 @@ static GLboolean is_native_swizzle(GLuint opcode, struct prog_src_register reg) if (reg.Abs) return GL_FALSE; - if (reg.NegateAbs) - reg.NegateBase ^= 15; + if (reg.Negate) + reg.Negate ^= NEGATE_XYZW; if (opcode == OPCODE_KIL) { if (reg.Swizzle != SWIZZLE_NOOP) @@ -324,7 +324,7 @@ static GLboolean is_native_swizzle(GLuint opcode, struct prog_src_register reg) for(i = 0; i < 4; ++i) { GLuint swz = GET_SWZ(reg.Swizzle, i); if (swz == SWIZZLE_NIL) { - reg.NegateBase &= ~(1 << i); + reg.Negate &= ~(1 << i); continue; } if (swz >= 4) @@ -332,15 +332,14 @@ static GLboolean is_native_swizzle(GLuint opcode, struct prog_src_register reg) } } - if (reg.NegateBase) + if (reg.Negate) return GL_FALSE; return GL_TRUE; } else if (opcode == OPCODE_DDX || opcode == OPCODE_DDY) { /* DDX/MDH and DDY/MDV explicitly ignore incoming swizzles; * if it doesn't fit perfectly into a .xyzw case... */ - if (reg.Swizzle == SWIZZLE_NOOP && !reg.Abs - && !reg.NegateBase && !reg.NegateAbs) + if (reg.Swizzle == SWIZZLE_NOOP && !reg.Abs && !reg.Negate) return GL_TRUE; return GL_FALSE; @@ -355,7 +354,7 @@ static GLboolean is_native_swizzle(GLuint opcode, struct prog_src_register reg) if (swz != SWIZZLE_NIL && swz != SWIZZLE_ZERO) relevant |= 1 << i; } - if ((reg.NegateBase & relevant) && ((reg.NegateBase & relevant) != relevant)) + if ((reg.Negate & relevant) && ((reg.Negate & relevant) != relevant)) return GL_FALSE; return GL_TRUE; @@ -379,7 +378,7 @@ static void nqssadce_build_swizzle(struct nqssadce_state *s, GLuint swz = GET_SWZ(src.Swizzle, i); if (swz == SWIZZLE_NIL) continue; - negatebase[GET_BIT(src.NegateBase, i)] |= 1 << i; + negatebase[GET_BIT(src.Negate, i)] |= 1 << i; } _mesa_insert_instructions(s->Program, s->IP, (negatebase[0] ? 1 : 0) + (negatebase[1] ? 1 : 0)); diff --git a/src/mesa/drivers/dri/r300/radeon_nqssadce.c b/src/mesa/drivers/dri/r300/radeon_nqssadce.c index a083c3d243..4a2e1cba40 100644 --- a/src/mesa/drivers/dri/r300/radeon_nqssadce.c +++ b/src/mesa/drivers/dri/r300/radeon_nqssadce.c @@ -61,12 +61,12 @@ static struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_reg struct prog_src_register tmp = srcreg; int i; tmp.Swizzle = 0; - tmp.NegateBase = 0; + tmp.Negate = NEGATE_NONE; for(i = 0; i < 4; ++i) { GLuint swz = GET_SWZ(swizzle, i); if (swz < 4) { tmp.Swizzle |= GET_SWZ(srcreg.Swizzle, swz) << (i*3); - tmp.NegateBase |= GET_BIT(srcreg.NegateBase, swz) << i; + tmp.Negate |= GET_BIT(srcreg.Negate, swz) << i; } else { tmp.Swizzle |= swz << (i*3); } @@ -103,9 +103,8 @@ static struct prog_instruction* track_used_srcreg(struct nqssadce_state* s, inst->SrcReg[src].File = PROGRAM_TEMPORARY; inst->SrcReg[src].Index = dstreg.Index; inst->SrcReg[src].Swizzle = 0; - inst->SrcReg[src].NegateBase = 0; + inst->SrcReg[src].Negate = NEGATE_NONE; inst->SrcReg[src].Abs = 0; - inst->SrcReg[src].NegateAbs = 0; for(i = 0; i < 4; ++i) { if (GET_BIT(sourced, i)) inst->SrcReg[src].Swizzle |= i << (3*i); diff --git a/src/mesa/drivers/dri/r300/radeon_program_alu.c b/src/mesa/drivers/dri/r300/radeon_program_alu.c index 1ef71e74dc..ebc5c913b2 100644 --- a/src/mesa/drivers/dri/r300/radeon_program_alu.c +++ b/src/mesa/drivers/dri/r300/radeon_program_alu.c @@ -89,8 +89,9 @@ static void set_swizzle(struct prog_src_register *SrcReg, int coordinate, int sw static void set_negate_base(struct prog_src_register *SrcReg, int coordinate, int negate) { - SrcReg->NegateBase &= ~(1 << coordinate); - SrcReg->NegateBase |= (negate << coordinate); + /* XXX note sure about this negation logic here */ + SrcReg->Negate &= ~(1 << coordinate); + SrcReg->Negate |= (negate << coordinate); } static struct prog_dst_register dstreg(int file, int index) @@ -156,15 +157,14 @@ static struct prog_src_register absolute(struct prog_src_register reg) { struct prog_src_register newreg = reg; newreg.Abs = 1; - newreg.NegateBase = 0; - newreg.NegateAbs = 0; + newreg.Negate = NEGATE_NONE; return newreg; } static struct prog_src_register negate(struct prog_src_register reg) { struct prog_src_register newreg = reg; - newreg.NegateAbs = !newreg.NegateAbs; + newreg.Negate = newreg.Negate ^ NEGATE_XYZW; return newreg; } @@ -189,8 +189,7 @@ static void transform_ABS(struct radeon_transform_context* t, { struct prog_src_register src = inst->SrcReg[0]; src.Abs = 1; - src.NegateBase = 0; - src.NegateAbs = 0; + src.Negate = NEGATE_NONE; emit1(t->Program, OPCODE_MOV, inst->SaturateMode, inst->DstReg, src); } @@ -198,14 +197,13 @@ static void transform_DPH(struct radeon_transform_context* t, struct prog_instruction* inst) { struct prog_src_register src0 = inst->SrcReg[0]; - if (src0.NegateAbs) { + if (src0.Negate) { if (src0.Abs) { int tempreg = radeonFindFreeTemporary(t); emit1(t->Program, OPCODE_MOV, 0, dstreg(PROGRAM_TEMPORARY, tempreg), src0); src0 = srcreg(src0.File, src0.Index); } else { - src0.NegateAbs = 0; - src0.NegateBase ^= NEGATE_XYZW; + src0.Negate ^= NEGATE_XYZW; } } set_swizzle(&src0, 3, SWIZZLE_ONE); @@ -649,7 +647,7 @@ GLboolean radeonTransformDeriv(struct radeon_transform_context* t, B.Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE); - B.NegateBase = NEGATE_XYZW; + B.Negate = NEGATE_XYZW; emit2(t->Program, inst->Opcode, inst->SaturateMode, inst->DstReg, inst->SrcReg[0], B); diff --git a/src/mesa/drivers/dri/r300/radeon_program_pair.c b/src/mesa/drivers/dri/r300/radeon_program_pair.c index f398404f9f..ecc82ff8a8 100644 --- a/src/mesa/drivers/dri/r300/radeon_program_pair.c +++ b/src/mesa/drivers/dri/r300/radeon_program_pair.c @@ -255,8 +255,7 @@ static void final_rewrite(struct pair_state *s, struct prog_instruction *inst) inst->SrcReg[2] = inst->SrcReg[1]; inst->SrcReg[1].File = PROGRAM_BUILTIN; inst->SrcReg[1].Swizzle = SWIZZLE_1111; - inst->SrcReg[1].NegateBase = 0; - inst->SrcReg[1].NegateAbs = 0; + inst->SrcReg[1].Negate = NEGATE_NONE; inst->Opcode = OPCODE_MAD; break; case OPCODE_CMP: @@ -730,7 +729,7 @@ static GLboolean fill_instruction_into_pair(struct pair_state *s, struct radeon_ srcrgb = GL_TRUE; else if (swz < 4) srcalpha = GL_TRUE; - if (swz != SWIZZLE_NIL && GET_BIT(inst->SrcReg[i].NegateBase, j)) + if (swz != SWIZZLE_NIL && GET_BIT(inst->SrcReg[i].Negate, j)) negatebase = 1; } source = alloc_pair_source(s, pair, inst->SrcReg[i], srcrgb, srcalpha); @@ -739,12 +738,12 @@ static GLboolean fill_instruction_into_pair(struct pair_state *s, struct radeon_ pair->RGB.Arg[i].Source = source; pair->RGB.Arg[i].Swizzle = inst->SrcReg[i].Swizzle & 0x1ff; pair->RGB.Arg[i].Abs = inst->SrcReg[i].Abs; - pair->RGB.Arg[i].Negate = (negatebase & ~pair->RGB.Arg[i].Abs) ^ inst->SrcReg[i].NegateAbs; + pair->RGB.Arg[i].Negate = (negatebase & ~pair->RGB.Arg[i].Abs) ^ inst->SrcReg[i].Negate; } if (pairinst->NeedAlpha) { GLboolean srcrgb = GL_FALSE; GLboolean srcalpha = GL_FALSE; - GLuint negatebase = GET_BIT(inst->SrcReg[i].NegateBase, pairinst->IsTranscendent ? 0 : 3); + GLuint negatebase = GET_BIT(inst->SrcReg[i].Negate, pairinst->IsTranscendent ? 0 : 3); GLuint swz = GET_SWZ(inst->SrcReg[i].Swizzle, pairinst->IsTranscendent ? 0 : 3); if (swz < 3) srcrgb = GL_TRUE; @@ -756,7 +755,7 @@ static GLboolean fill_instruction_into_pair(struct pair_state *s, struct radeon_ pair->Alpha.Arg[i].Source = source; pair->Alpha.Arg[i].Swizzle = swz; pair->Alpha.Arg[i].Abs = inst->SrcReg[i].Abs; - pair->Alpha.Arg[i].Negate = (negatebase & ~pair->RGB.Arg[i].Abs) ^ inst->SrcReg[i].NegateAbs; + pair->Alpha.Arg[i].Negate = (negatebase & ~pair->RGB.Arg[i].Abs) ^ inst->SrcReg[i].Negate; } } diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 03f42704a7..1ce5685af4 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -570,9 +570,8 @@ static void emit_arg( struct prog_src_register *src, src->File = reg.file; src->Index = reg.idx; src->Swizzle = reg.swz; - src->NegateBase = reg.negate ? NEGATE_XYZW : 0; + src->Negate = reg.negate ? NEGATE_XYZW : NEGATE_NONE; src->Abs = 0; - src->NegateAbs = 0; src->RelAddr = 0; /* Check that bitfield sizes aren't exceeded */ ASSERT(src->Index == reg.idx); diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 4a124bf27e..a70d069bd9 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -663,9 +663,8 @@ static void emit_arg( struct prog_src_register *reg, reg->File = ureg.file; reg->Index = ureg.idx; reg->Swizzle = ureg.swz; - reg->NegateBase = ureg.negatebase ? 0xf : 0x0; + reg->Negate = ureg.negatebase ? NEGATE_XYZW : NEGATE_NONE; reg->Abs = ureg.abs; - reg->NegateAbs = ureg.negateabs; } static void emit_dst( struct prog_dst_register *dst, diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 35253daa2e..b47bf360cf 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -2669,7 +2669,7 @@ parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst, reg->File = file; reg->Index = index; reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); - reg->NegateBase = negateMask; + reg->Negate = negateMask; reg->RelAddr = isRelOffset; return 0; } @@ -2703,7 +2703,7 @@ parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst, reg->File = file; reg->Index = index; reg->Swizzle = (swizzle[0] << 0); - reg->NegateBase = negateMask; + reg->Negate = negateMask; reg->RelAddr = isRelOffset; return 0; } @@ -3019,7 +3019,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, parse_extended_swizzle_mask(inst, swizzle, &negateMask); fp->SrcReg[0].File = file; fp->SrcReg[0].Index = index; - fp->SrcReg[0].NegateBase = negateMask; + fp->SrcReg[0].Negate = negateMask; fp->SrcReg[0].Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], @@ -3363,7 +3363,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, parse_extended_swizzle_mask (inst, swizzle, &negateMask); vp->SrcReg[0].File = file; vp->SrcReg[0].Index = index; - vp->SrcReg[0].NegateBase = negateMask; + vp->SrcReg[0].Negate = negateMask; vp->SrcReg[0].Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c index 56b7c29bea..0fd55524ab 100644 --- a/src/mesa/shader/nvfragparse.c +++ b/src/mesa/shader/nvfragparse.c @@ -957,6 +957,7 @@ Parse_VectorSrc(struct parse_state *parseState, GLfloat sign = 1.0F; GLubyte token[100]; GLint idx; + GLuint negateBase, negateAbs; /* * First, take care of +/- and absolute value stuff. @@ -968,21 +969,23 @@ Parse_VectorSrc(struct parse_state *parseState, if (Parse_String(parseState, "|")) { srcReg->Abs = GL_TRUE; - srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE; + negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; if (Parse_String(parseState, "-")) - srcReg->NegateBase = NEGATE_XYZW; + negateBase = NEGATE_XYZW; else if (Parse_String(parseState, "+")) - srcReg->NegateBase = NEGATE_NONE; + negateBase = NEGATE_NONE; else - srcReg->NegateBase = NEGATE_NONE; + negateBase = NEGATE_NONE; } else { srcReg->Abs = GL_FALSE; - srcReg->NegateAbs = GL_FALSE; - srcReg->NegateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; + negateAbs = NEGATE_NONE; + negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; } + srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; + /* This should be the real src vector/register name */ if (!Peek_Token(parseState, token)) RETURN_ERROR; @@ -1083,6 +1086,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState, GLfloat sign = 1.0F; GLboolean needSuffix = GL_TRUE; GLint idx; + GLuint negateBase, negateAbs; /* * First, take care of +/- and absolute value stuff. @@ -1094,21 +1098,23 @@ Parse_ScalarSrcReg(struct parse_state *parseState, if (Parse_String(parseState, "|")) { srcReg->Abs = GL_TRUE; - srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE; + negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; if (Parse_String(parseState, "-")) - srcReg->NegateBase = NEGATE_XYZW; + negateBase = NEGATE_XYZW; else if (Parse_String(parseState, "+")) - srcReg->NegateBase = NEGATE_NONE; + negateBase = NEGATE_NONE; else - srcReg->NegateBase = NEGATE_NONE; + negateBase = NEGATE_NONE; } else { srcReg->Abs = GL_FALSE; - srcReg->NegateAbs = GL_FALSE; - srcReg->NegateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; + negateAbs = NEGATE_NONE; + negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; } + srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; + if (!Peek_Token(parseState, token)) RETURN_ERROR; @@ -1247,9 +1253,8 @@ Parse_PrintInstruction(struct parse_state *parseState, } inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; - inst->SrcReg[0].NegateBase = NEGATE_NONE; inst->SrcReg[0].Abs = GL_FALSE; - inst->SrcReg[0].NegateAbs = GL_FALSE; + inst->SrcReg[0].Negate = NEGATE_NONE; return GL_TRUE; } diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c index 624262395b..f5e2df2670 100644 --- a/src/mesa/shader/nvvertparse.c +++ b/src/mesa/shader/nvvertparse.c @@ -641,12 +641,12 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *sr RETURN_ERROR; if (token[0] == '-') { (void) Parse_String(parseState, "-"); - srcReg->NegateBase = NEGATE_XYZW; + srcReg->Negate = NEGATE_XYZW; if (!Peek_Token(parseState, token)) RETURN_ERROR; } else { - srcReg->NegateBase = NEGATE_NONE; + srcReg->Negate = NEGATE_NONE; } /* Src reg can be R, c[n], c[n +/- offset], or a named vertex attrib */ @@ -734,13 +734,13 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *src if (!Peek_Token(parseState, token)) RETURN_ERROR; if (token[0] == '-') { - srcReg->NegateBase = NEGATE_XYZW; + srcReg->Negate = NEGATE_XYZW; (void) Parse_String(parseState, "-"); /* consume '-' */ if (!Peek_Token(parseState, token)) RETURN_ERROR; } else { - srcReg->NegateBase = NEGATE_NONE; + srcReg->Negate = NEGATE_NONE; } /* Src reg can be R, c[n], c[n +/- offset], or a named vertex attrib */ @@ -1062,7 +1062,7 @@ Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction * RETURN_ERROR; srcReg->RelAddr = GL_FALSE; - srcReg->NegateBase = NEGATE_NONE; + srcReg->Negate = NEGATE_NONE; srcReg->Swizzle = SWIZZLE_NOOP; /* Register can be R, c[n], c[n +/- offset], a named vertex attrib, diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index bdac1d4f8a..68a59350a1 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -212,19 +212,14 @@ fetch_vector4(const struct prog_src_register *source, result[3] = src[GET_SWZ(source->Swizzle, 3)]; } - if (source->NegateBase) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } if (source->Abs) { result[0] = FABSF(result[0]); result[1] = FABSF(result[1]); result[2] = FABSF(result[2]); result[3] = FABSF(result[3]); } - if (source->NegateAbs) { + if (source->Negate) { + ASSERT(source->Negate == NEGATE_XYZW); result[0] = -result[0]; result[1] = -result[1]; result[2] = -result[2]; @@ -259,7 +254,7 @@ fetch_vector4ui(const struct prog_src_register *source, result[3] = src[GET_SWZ(source->Swizzle, 3)]; } - /* Note: no NegateBase, Abs, NegateAbs here */ + /* Note: no Negate or Abs here */ } @@ -299,19 +294,14 @@ fetch_vector4_deriv(GLcontext * ctx, result[2] = deriv[GET_SWZ(source->Swizzle, 2)]; result[3] = deriv[GET_SWZ(source->Swizzle, 3)]; - if (source->NegateBase) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } if (source->Abs) { result[0] = FABSF(result[0]); result[1] = FABSF(result[1]); result[2] = FABSF(result[2]); result[3] = FABSF(result[3]); } - if (source->NegateAbs) { + if (source->Negate) { + ASSERT(source->Negate == NEGATE_XYZW); result[0] = -result[0]; result[1] = -result[1]; result[2] = -result[2]; @@ -336,13 +326,10 @@ fetch_vector1(const struct prog_src_register *source, result[0] = src[GET_SWZ(source->Swizzle, 0)]; - if (source->NegateBase) { - result[0] = -result[0]; - } if (source->Abs) { result[0] = FABSF(result[0]); } - if (source->NegateAbs) { + if (source->Negate) { result[0] = -result[0]; } } @@ -1514,7 +1501,7 @@ _mesa_execute_program(GLcontext * ctx, ASSERT(swz <= 3); result[i] = src[swz]; } - if (source->NegateBase & (1 << i)) + if (source->Negate & (1 << i)) result[i] = -result[i]; } store_vector4(inst, machine, result); diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index 4adce11f95..3109f6cbae 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -261,37 +261,15 @@ struct prog_src_register GLuint Swizzle:12; GLuint RelAddr:1; - /** - * \name Source register "sign" control. - * - * The ARB and NV extensions allow varrying degrees of control over the - * sign of the source vector components. These values allow enough control - * for all flavors of the extensions. - */ - /*@{*/ - /** - * Per-component negation for the SWZ instruction. For non-SWZ - * instructions the only possible values are NEGATE_XYZW and NEGATE_NONE. - * - * \since - * ARB_vertex_program, ARB_fragment_program - */ - GLuint NegateBase:4; - - /** - * Take the component-wise absolute value. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, - * NV_vertex_program2_option. - */ + /** Take the component-wise absolute value */ GLuint Abs:1; /** - * Post-absolute value negation (all components). + * Post-Abs negation. + * This will either be NEGATE_NONE or NEGATE_XYZW, except for the SWZ + * instruction which allows per-component negation. */ - GLuint NegateAbs:1; - /*@}*/ + GLuint Negate:4; }; diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index b832ddb477..d73c619fea 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -325,19 +325,19 @@ reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode, * \param extended if true, also allow 0, 1 values */ const char * -_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) +_mesa_swizzle_string(GLuint swizzle, GLuint negateMask, GLboolean extended) { static const char swz[] = "xyzw01!?"; /* See SWIZZLE_x definitions */ static char s[20]; GLuint i = 0; - if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0) + if (!extended && swizzle == SWIZZLE_NOOP && negateMask == 0) return ""; /* no swizzle/negation */ if (!extended) s[i++] = '.'; - if (negateBase & NEGATE_X) + if (negateMask & NEGATE_X) s[i++] = '-'; s[i++] = swz[GET_SWZ(swizzle, 0)]; @@ -345,7 +345,7 @@ _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) s[i++] = ','; } - if (negateBase & NEGATE_Y) + if (negateMask & NEGATE_Y) s[i++] = '-'; s[i++] = swz[GET_SWZ(swizzle, 1)]; @@ -353,7 +353,7 @@ _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) s[i++] = ','; } - if (negateBase & NEGATE_Z) + if (negateMask & NEGATE_Z) s[i++] = '-'; s[i++] = swz[GET_SWZ(swizzle, 2)]; @@ -361,7 +361,7 @@ _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) s[i++] = ','; } - if (negateBase & NEGATE_W) + if (negateMask & NEGATE_W) s[i++] = '-'; s[i++] = swz[GET_SWZ(swizzle, 3)]; @@ -465,14 +465,14 @@ fprint_src_reg(FILE *f, reg_string((gl_register_file) srcReg->File, srcReg->Index, mode, srcReg->RelAddr, prog), _mesa_swizzle_string(srcReg->Swizzle, - srcReg->NegateBase, GL_FALSE), + srcReg->Negate, GL_FALSE), abs); #if 0 _mesa_fprintf(f, "%s[%d]%s", file_string((gl_register_file) srcReg->File, mode), srcReg->Index, _mesa_swizzle_string(srcReg->Swizzle, - srcReg->NegateBase, GL_FALSE)); + srcReg->Negate, GL_FALSE)); #endif } @@ -566,7 +566,7 @@ _mesa_fprint_instruction_opt(FILE *f, mode), inst->SrcReg[0].Index, _mesa_swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].NegateBase, GL_FALSE)); + inst->SrcReg[0].Negate, GL_FALSE)); } if (inst->Comment) _mesa_fprintf(f, " # %s", inst->Comment); @@ -583,7 +583,7 @@ _mesa_fprint_instruction_opt(FILE *f, mode), inst->SrcReg[0].Index, _mesa_swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].NegateBase, GL_TRUE)); + inst->SrcReg[0].Negate, GL_TRUE)); fprint_comment(f, inst); break; case OPCODE_TEX: diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index e283f8933b..ecd98dc85c 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -241,7 +241,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) inst->DstReg.WriteMask = WRITEMASK_X; inst->SrcReg[0].File = PROGRAM_TEMPORARY; inst->SrcReg[0].Index = fogFactorTemp; - inst->SrcReg[0].NegateBase = NEGATE_XYZW; + inst->SrcReg[0].Negate = NEGATE_XYZW; inst->SrcReg[0].Swizzle = SWIZZLE_XXXX; inst->SaturateMode = SATURATE_ZERO_ONE; inst++; diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 8493c490fb..3f455e0640 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1135,7 +1135,7 @@ emit_negation(slang_emit_info *emitInfo, slang_ir_node *n) n->Children[0]->Store, NULL, NULL); - inst->SrcReg[0].NegateBase = NEGATE_XYZW; + inst->SrcReg[0].Negate = NEGATE_XYZW; return inst; } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 3b2ad00f5c..fa4f4082a7 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -147,7 +147,7 @@ make_bitmap_fragment_program(GLcontext *ctx, GLuint samplerIndex) p->Instructions[ic].SrcReg[0].Swizzle = SWIZZLE_XXXX; p->Instructions[ic].SrcReg[0].Index = 0; - p->Instructions[ic].SrcReg[0].NegateBase = NEGATE_XYZW; + p->Instructions[ic].SrcReg[0].Negate = NEGATE_XYZW; ic++; /* END; */ diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index ffa607dd87..43c9afccc3 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -275,8 +275,8 @@ compile_instruction( /* swizzle (ext swizzle also depends on negation) */ { GLuint swz[4]; - GLboolean extended = (inst->SrcReg[i].NegateBase != NEGATE_NONE && - inst->SrcReg[i].NegateBase != NEGATE_XYZW); + GLboolean extended = (inst->SrcReg[i].Negate != NEGATE_NONE && + inst->SrcReg[i].Negate != NEGATE_XYZW); for( j = 0; j < 4; j++ ) { swz[j] = GET_SWZ( inst->SrcReg[i].Swizzle, j ); if (swz[j] > SWIZZLE_W) @@ -296,20 +296,20 @@ compile_instruction( } } - if( inst->SrcReg[i].NegateBase == NEGATE_XYZW ) { + if( inst->SrcReg[i].Negate == NEGATE_XYZW ) { fullsrc->SrcRegister.Negate = 1; } - else if( inst->SrcReg[i].NegateBase != NEGATE_NONE ) { - if( inst->SrcReg[i].NegateBase & NEGATE_X ) { + else if( inst->SrcReg[i].Negate != NEGATE_NONE ) { + if( inst->SrcReg[i].Negate & NEGATE_X ) { fullsrc->SrcRegisterExtSwz.NegateX = 1; } - if( inst->SrcReg[i].NegateBase & NEGATE_Y ) { + if( inst->SrcReg[i].Negate & NEGATE_Y ) { fullsrc->SrcRegisterExtSwz.NegateY = 1; } - if( inst->SrcReg[i].NegateBase & NEGATE_Z ) { + if( inst->SrcReg[i].Negate & NEGATE_Z ) { fullsrc->SrcRegisterExtSwz.NegateZ = 1; } - if( inst->SrcReg[i].NegateBase & NEGATE_W ) { + if( inst->SrcReg[i].Negate & NEGATE_W ) { fullsrc->SrcRegisterExtSwz.NegateW = 1; } } @@ -318,10 +318,6 @@ compile_instruction( fullsrc->SrcRegisterExtMod.Absolute = 1; } - if( inst->SrcReg[i].NegateAbs ) { - fullsrc->SrcRegisterExtMod.Negate = 1; - } - if( inst->SrcReg[i].RelAddr ) { fullsrc->SrcRegister.Indirect = 1; -- cgit v1.2.3 From af9d202b26f75555b653dbe1c2ebaf6a2cf14d28 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 15 Apr 2009 20:07:48 +0100 Subject: mesa: TGSI translation of multiple render targets. --- src/mesa/state_tracker/st_program.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 6348e83d8a..2795570cf1 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -484,14 +484,14 @@ st_translate_fragment_program(struct st_context *st, /* handled above */ assert(0); break; - case FRAG_RESULT_COLOR: + default: + assert(attr == FRAG_RESULT_COLOR || + (FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX)); fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR; fs_output_semantic_index[fs_num_outputs] = numColors; outputMapping[attr] = fs_num_outputs; numColors++; break; - default: - assert(0); } output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr]; -- cgit v1.2.3 From 9b75627fab5bf2ea90f27ddd31b60c54895f6de6 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 15 Apr 2009 15:53:34 +0200 Subject: gallium: Make sure we flush before some texture / buffer operations. Also implement context member functions to optimize away those flushes whenever possible. Signed-off-by: Thomas Hellstrom --- src/gallium/drivers/cell/ppu/cell_context.c | 25 +++++++++++++++ src/gallium/drivers/failover/fo_context.c | 23 ++++++++++++++ src/gallium/drivers/i915simple/i915_context.c | 26 ++++++++++++++++ src/gallium/drivers/i965simple/brw_context.c | 25 +++++++++++++++ src/gallium/drivers/nv04/nv04_context.c | 27 ++++++++++++++++ src/gallium/drivers/nv10/nv10_context.c | 26 ++++++++++++++++ src/gallium/drivers/nv20/nv20_context.c | 27 ++++++++++++++++ src/gallium/drivers/nv30/nv30_context.c | 26 ++++++++++++++++ src/gallium/drivers/nv40/nv40_context.c | 26 ++++++++++++++++ src/gallium/drivers/nv50/nv50_context.c | 26 ++++++++++++++++ src/gallium/drivers/softpipe/sp_context.c | 18 +++++++++++ src/gallium/drivers/trace/tr_context.c | 44 +++++++++++++++++++++++++++ src/gallium/include/pipe/p_context.h | 29 +++++++++++++++++- src/gallium/include/pipe/p_defines.h | 7 +++++ src/mesa/state_tracker/st_cb_accum.c | 36 +++++++++++++++++++--- src/mesa/state_tracker/st_cb_bufferobjects.c | 16 +++++++++- src/mesa/state_tracker/st_cb_drawpixels.c | 8 +++-- src/mesa/state_tracker/st_cb_readpixels.c | 10 +++++- src/mesa/state_tracker/st_cb_texture.c | 17 +++++++++++ src/mesa/state_tracker/st_gen_mipmap.c | 7 +++++ src/mesa/state_tracker/st_texture.c | 22 +++++++++++++- src/mesa/state_tracker/st_texture.h | 7 ++++- 22 files changed, 466 insertions(+), 12 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 808be589bd..ebb7a7acc4 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -99,6 +99,28 @@ static const struct debug_named_value cell_debug_flags[] = { {NULL, 0} }; +static unsigned int +cell_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +static unsigned int +cell_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} struct pipe_context * cell_create_context(struct pipe_screen *screen, @@ -122,6 +144,9 @@ cell_create_context(struct pipe_screen *screen, cell->pipe.clear = cell_clear; cell->pipe.flush = cell_flush; + cell->pipe.is_texture_referenced = cell_is_texture_referenced; + cell->pipe.is_buffer_referenced = cell_is_buffer_referenced; + #if 0 cell->pipe.begin_query = cell_begin_query; cell->pipe.end_query = cell_end_query; diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index fcad717cf8..37184eac7b 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -105,7 +105,28 @@ static boolean failover_draw_arrays( struct pipe_context *pipe, return failover_draw_elements(pipe, NULL, 0, prim, start, count); } +static unsigned int +failover_is_texture_referenced( struct pipe_context *_pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + struct failover_context *failover = failover_context( _pipe ); + struct pipe_context *pipe = (failover->mode == FO_HW) ? + failover->hw : failover->sw; + + return pipe->is_texture_referenced(pipe, texture, face, level); +} +static unsigned int +failover_is_buffer_referenced( struct pipe_context *_pipe, + struct pipe_buffer *buf) +{ + struct failover_context *failover = failover_context( _pipe ); + struct pipe_context *pipe = (failover->mode == FO_HW) ? + failover->hw : failover->sw; + + return pipe->is_buffer_referenced(pipe, buf); +} struct pipe_context *failover_create( struct pipe_context *hw, struct pipe_context *sw ) @@ -151,6 +172,8 @@ struct pipe_context *failover_create( struct pipe_context *hw, #endif failover->pipe.flush = hw->flush; + failover->pipe.is_texture_referenced = failover_is_texture_referenced; + failover->pipe.is_buffer_referenced = failover_is_buffer_referenced; failover->dirty = 0; diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 3e3a596884..ccf9bb31fb 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -136,6 +136,29 @@ static boolean i915_draw_arrays( struct pipe_context *pipe, } +static unsigned int +i915_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +static unsigned int +i915_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + struct pipe_context *i915_create_context( struct pipe_screen *screen, struct pipe_winsys *pipe_winsys, @@ -160,6 +183,9 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, i915->pipe.draw_elements = i915_draw_elements; i915->pipe.draw_range_elements = i915_draw_range_elements; + i915->pipe.is_texture_referenced = i915_is_texture_referenced; + i915->pipe.is_buffer_referenced = i915_is_buffer_referenced; + /* * Create drawing context and plug our rendering stage into it. */ diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index c74cbf8d73..9b33285bc7 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -73,6 +73,28 @@ static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps, pipe->surface_fill(pipe, ps, x, y, w, h, clearValue); } +static unsigned int +brw_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +static unsigned int +brw_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} struct pipe_context *brw_create(struct pipe_screen *screen, struct brw_winsys *brw_winsys, @@ -94,6 +116,9 @@ struct pipe_context *brw_create(struct pipe_screen *screen, brw->pipe.destroy = brw_destroy; brw->pipe.clear = brw_clear; + brw->pipe.is_texture_referenced = brw_is_texture_referenced; + brw->pipe.is_buffer_referenced = brw_is_buffer_referenced; + brw_init_surface_functions(brw); brw_init_texture_functions(brw); brw_init_state_functions(brw); diff --git a/src/gallium/drivers/nv04/nv04_context.c b/src/gallium/drivers/nv04/nv04_context.c index d6710cd892..17166c9f51 100644 --- a/src/gallium/drivers/nv04/nv04_context.c +++ b/src/gallium/drivers/nv04/nv04_context.c @@ -64,6 +64,30 @@ nv04_init_hwctx(struct nv04_context *nv04) return TRUE; } +static unsigned int +nv04_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +static unsigned int +nv04_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + + struct pipe_context * nv04_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -89,6 +113,9 @@ nv04_create(struct pipe_screen *pscreen, unsigned pctx_id) nv04->pipe.clear = nv04_clear; nv04->pipe.flush = nv04_flush; + nv04->pipe.is_texture_referenced = nv04_is_texture_referenced; + nv04->pipe.is_buffer_referenced = nv04_is_buffer_referenced; + nv04_init_surface_functions(nv04); nv04_init_state_functions(nv04); diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index ef2c0c5d9f..3da8d2f568 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -257,6 +257,29 @@ nv10_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) { } +static unsigned int +nv10_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +static unsigned int +nv10_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + struct pipe_context * nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -282,6 +305,9 @@ nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) nv10->pipe.clear = nv10_clear; nv10->pipe.flush = nv10_flush; + nv10->pipe.is_texture_referenced = nv10_is_texture_referenced; + nv10->pipe.is_buffer_referenced = nv10_is_buffer_referenced; + nv10_init_surface_functions(nv10); nv10_init_state_functions(nv10); diff --git a/src/gallium/drivers/nv20/nv20_context.c b/src/gallium/drivers/nv20/nv20_context.c index 1659aec8fa..cbc41707d5 100644 --- a/src/gallium/drivers/nv20/nv20_context.c +++ b/src/gallium/drivers/nv20/nv20_context.c @@ -380,6 +380,30 @@ nv20_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) { } + +static unsigned int +nv20_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +static unsigned int +nv20_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + struct pipe_context * nv20_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -405,6 +429,9 @@ nv20_create(struct pipe_screen *pscreen, unsigned pctx_id) nv20->pipe.clear = nv20_clear; nv20->pipe.flush = nv20_flush; + nv20->pipe.is_texture_referenced = nv20_is_texture_referenced; + nv20->pipe.is_buffer_referenced = nv20_is_buffer_referenced; + nv20_init_surface_functions(nv20); nv20_init_state_functions(nv20); diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 61654f8756..f827bdc78b 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -31,6 +31,29 @@ nv30_destroy(struct pipe_context *pipe) FREE(nv30); } +static unsigned int +nv30_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +static unsigned int +nv30_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + struct pipe_context * nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -55,6 +78,9 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) nv30->pipe.clear = nv30_clear; nv30->pipe.flush = nv30_flush; + nv30->pipe.is_texture_referenced = nv30_is_texture_referenced; + nv30->pipe.is_buffer_referenced = nv30_is_buffer_referenced; + nv30_init_query_functions(nv30); nv30_init_surface_functions(nv30); nv30_init_state_functions(nv30); diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 5d325f5067..8eba6a43ef 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -31,6 +31,29 @@ nv40_destroy(struct pipe_context *pipe) FREE(nv40); } +static unsigned int +nv40_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +static unsigned int +nv40_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + struct pipe_context * nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -55,6 +78,9 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40->pipe.clear = nv40_clear; nv40->pipe.flush = nv40_flush; + nv40->pipe.is_texture_referenced = nv40_is_texture_referenced; + nv40->pipe.is_buffer_referenced = nv40_is_buffer_referenced; + nv40_init_query_functions(nv40); nv40_init_surface_functions(nv40); nv40_init_state_functions(nv40); diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 565a5da668..a511f655c1 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -51,6 +51,29 @@ nv50_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) { } +static unsigned int +nv50_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +static unsigned int +nv50_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + /** + * FIXME: Optimize. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + struct pipe_context * nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -76,6 +99,9 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) nv50->pipe.flush = nv50_flush; + nv50->pipe.is_texture_referenced = nv50_is_texture_referenced; + nv50->pipe.is_buffer_referenced = nv50_is_buffer_referenced; + nv50_init_surface_functions(nv50); nv50_init_state_functions(nv50); nv50_init_query_functions(nv50); diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 06ace27d14..6ae4d1ad7b 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -121,6 +121,21 @@ static void softpipe_destroy( struct pipe_context *pipe ) FREE( softpipe ); } +static unsigned int +softpipe_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level, + unsigned zslice) +{ + return PIPE_UNREFERENCED; +} + +static unsigned int +softpipe_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + return PIPE_UNREFERENCED; +} struct pipe_context * softpipe_create( struct pipe_screen *screen, @@ -190,6 +205,9 @@ softpipe_create( struct pipe_screen *screen, softpipe->pipe.clear = softpipe_clear; softpipe->pipe.flush = softpipe_flush; + softpipe->pipe.is_texture_referenced = softpipe_is_texture_referenced; + softpipe->pipe.is_buffer_referenced = softpipe_is_buffer_referenced; + softpipe_init_query_funcs( softpipe ); softpipe_init_texture_funcs( softpipe ); diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index d8d5821a1d..556b5e003f 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -1030,6 +1030,48 @@ trace_context_destroy(struct pipe_context *_pipe) FREE(tr_ctx); } +static unsigned int +trace_is_texture_referenced( struct pipe_context *_pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + unsigned int referenced; + + trace_dump_call_begin("pipe_context", "is_texture_referenced"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, texture); + trace_dump_arg(uint, face); + trace_dump_arg(uint, level); + + referenced = pipe->is_texture_referenced(pipe, texture, face, level); + + trace_dump_ret(uint, referenced); + trace_dump_call_end(); + + return referenced; +} + +static unsigned int +trace_is_buffer_referenced( struct pipe_context *_pipe, + struct pipe_buffer *buf) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + unsigned int referenced; + + trace_dump_call_begin("pipe_context", "is_buffer_referenced"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, buf); + + referenced = pipe->is_buffer_referenced(pipe, buf); + + trace_dump_ret(uint, referenced); + trace_dump_call_end(); + + return referenced; +} struct pipe_context * trace_context_create(struct pipe_screen *_screen, @@ -1096,6 +1138,8 @@ trace_context_create(struct pipe_screen *_screen, tr_ctx->base.surface_fill = trace_context_surface_fill; tr_ctx->base.clear = trace_context_clear; tr_ctx->base.flush = trace_context_flush; + tr_ctx->base.is_texture_referenced = trace_is_texture_referenced; + tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced; tr_ctx->pipe = pipe; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index c5c839799e..57e966ac3b 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -42,7 +42,6 @@ struct pipe_state_cache; struct pipe_query; struct pipe_winsys; - /** * Gallium rendering context. Basically: * - state setting functions @@ -231,6 +230,34 @@ struct pipe_context { void (*flush)( struct pipe_context *pipe, unsigned flags, struct pipe_fence_handle **fence ); + + /** + * Check whether a texture is referenced by an unflushed hw command. + * The state-tracker uses this function to optimize away unnecessary + * flushes. It is safe (but wasteful) to always return. + * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE. + * \param pipe The pipe context whose unflushed hw commands will be + * checked. + * \param level mipmap level. + * \param texture texture to check. + * \param face cubemap face. Use 0 for non-cubemap texture. + */ + + unsigned int (*is_texture_referenced) (struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level); + /** + * Check whether a buffer is referenced by an unflushed hw command. + * The state-tracker uses this function to optimize away unnecessary + * flushes. It is safe (but wasteful) to always return + * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE. + * \param pipe The pipe context whose unflushed hw commands will be + * checked. + * \param buf Buffer to check. + */ + + unsigned int (*is_buffer_referenced) (struct pipe_context *pipe, + struct pipe_buffer *buf); }; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 1d2aa10949..82e23c413c 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -312,6 +312,13 @@ enum pipe_transfer_usage { #define PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS 26 +/** + * Referenced query flags. + */ + +#define PIPE_UNREFERENCED 0 +#define PIPE_REFERENCED_FOR_READ (1 << 0) +#define PIPE_REFERENCED_FOR_WRITE (1 << 1) #ifdef __cplusplus } diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 3f9a825a15..1510a1e236 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -40,6 +40,7 @@ #include "st_draw.h" #include "st_public.h" #include "st_format.h" +#include "st_texture.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" @@ -118,6 +119,9 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) const GLint height = ctx->DrawBuffer->_Ymax - ypos; GLubyte *map; + st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0, + PIPE_TRANSFER_WRITE); + acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, PIPE_TRANSFER_WRITE, xpos, ypos, width, height); @@ -163,6 +167,9 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, struct pipe_transfer *acc_pt; GLubyte *map; + st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0, + PIPE_TRANSFER_READ_WRITE); + acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, PIPE_TRANSFER_READ_WRITE, xpos, ypos, width, height); @@ -192,20 +199,27 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, static void -accum_accum(struct pipe_context *pipe, GLfloat value, +accum_accum(struct st_context *st, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, struct st_renderbuffer *acc_strb, struct st_renderbuffer *color_strb) { + struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_transfer *acc_trans, *color_trans; GLfloat *colorBuf, *accBuf; GLint i; + st_teximage_flush_before_map(st, acc_strb->texture, 0, 0, + PIPE_TRANSFER_READ); + acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, xpos, ypos, width, height); + st_teximage_flush_before_map(st, color_strb->texture, 0, 0, + PIPE_TRANSFER_READ); + color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, xpos, ypos, width, height); @@ -235,20 +249,27 @@ accum_accum(struct pipe_context *pipe, GLfloat value, static void -accum_load(struct pipe_context *pipe, GLfloat value, +accum_load(struct st_context *st, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, struct st_renderbuffer *acc_strb, struct st_renderbuffer *color_strb) { + struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_transfer *acc_trans, *color_trans; GLfloat *buf; GLint i; + st_teximage_flush_before_map(st, acc_strb->texture, 0, 0, + PIPE_TRANSFER_WRITE); + acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, PIPE_TRANSFER_WRITE, xpos, ypos, width, height); + st_teximage_flush_before_map(st, color_strb->texture, 0, 0, + PIPE_TRANSFER_READ); + color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, xpos, ypos, width, height); @@ -284,10 +305,16 @@ accum_return(GLcontext *ctx, GLfloat value, abuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0, + PIPE_TRANSFER_READ); + acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, xpos, ypos, width, height); + st_teximage_flush_before_map(ctx->st, color_strb->texture, 0, 0, + PIPE_TRANSFER_READ_WRITE); + color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0, PIPE_TRANSFER_READ_WRITE, xpos, ypos, width, height); @@ -325,7 +352,6 @@ static void st_Accum(GLcontext *ctx, GLenum op, GLfloat value) { struct st_context *st = ctx->st; - struct pipe_context *pipe = st->pipe; struct st_renderbuffer *acc_strb = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); struct st_renderbuffer *color_strb @@ -352,11 +378,11 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value) break; case GL_ACCUM: if (value != 0.0F) { - accum_accum(pipe, value, xpos, ypos, width, height, acc_strb, color_strb); + accum_accum(st, value, xpos, ypos, width, height, acc_strb, color_strb); } break; case GL_LOAD: - accum_load(pipe, value, xpos, ypos, width, height, acc_strb, color_strb); + accum_load(st, value, xpos, ypos, width, height, acc_strb, color_strb); break; case GL_RETURN: accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb); diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 3651e4ae7d..fdb800fbd0 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -32,6 +32,7 @@ #include "st_context.h" #include "st_cb_bufferobjects.h" +#include "st_public.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -103,6 +104,9 @@ st_bufferobj_subdata(GLcontext *ctx, if (offset >= st_obj->size || size > (st_obj->size - offset)) return; + if (pipe->is_buffer_referenced(pipe, st_obj->buffer)) + st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL); + pipe_buffer_write(pipe->screen, st_obj->buffer, offset, size, data); } @@ -123,6 +127,10 @@ st_bufferobj_get_subdata(GLcontext *ctx, if (offset >= st_obj->size || size > (st_obj->size - offset)) return; + if (pipe->is_buffer_referenced(pipe, st_obj->buffer) & + PIPE_REFERENCED_FOR_WRITE) + st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL); + pipe_buffer_read(pipe->screen, st_obj->buffer, offset, size, data); } @@ -171,7 +179,7 @@ st_bufferobj_data(GLcontext *ctx, st_obj->size = size; if (data) - st_bufferobj_subdata(ctx, target, 0, size, data, obj); + pipe_buffer_write(pipe->screen, st_obj->buffer, 0, size, data); } @@ -185,6 +193,7 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); GLuint flags; + unsigned referenced; switch (access) { case GL_WRITE_ONLY: @@ -200,6 +209,11 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, break; } + referenced = pipe->is_buffer_referenced(pipe, st_obj->buffer); + if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) || + (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) + st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL); + obj->Pointer = pipe_buffer_map(pipe->screen, st_obj->buffer, flags); if(obj->Pointer) { obj->Offset = 0; diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 0a4430501f..c67b026413 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -631,8 +631,6 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, GLint skipPixels; ubyte *stmap; - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - strb = st_renderbuffer(ctx->DrawBuffer-> Attachment[BUFFER_STENCIL].Renderbuffer); @@ -640,6 +638,9 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, y = ctx->DrawBuffer->Height - y - height; } + st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, + PIPE_TRANSFER_WRITE); + pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, PIPE_TRANSFER_WRITE, x, y, width, height); @@ -825,6 +826,9 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); + st_teximage_flush_before_map(ctx->st, rbDraw->texture, 0, 0, + PIPE_TRANSFER_WRITE); + ptDraw = screen->get_tex_transfer(screen, rbDraw->texture, 0, 0, 0, PIPE_TRANSFER_WRITE, dstx, dsty, width, height); diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 9ce5f3fe84..519ad6660f 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -42,13 +42,14 @@ #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "util/u_tile.h" + #include "st_context.h" #include "st_cb_bitmap.h" #include "st_cb_readpixels.h" #include "st_cb_fbo.h" #include "st_format.h" #include "st_public.h" - +#include "st_texture.h" /** * Special case for reading stencil buffer. @@ -73,6 +74,10 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, } /* Create a read transfer from the renderbuffer's texture */ + + st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, + PIPE_TRANSFER_READ); + pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, x, y, width, height); @@ -240,6 +245,9 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, y = strb->texture->height[0] - y - height; } + st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, + PIPE_TRANSFER_READ); + trans = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, x, y, width, height); if (!trans) { diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 1f14b3705d..727432d7de 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -700,6 +700,10 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, /* Image is stored in hardware format in a buffer managed by the * kernel. Need to explicitly map and unmap it. */ + + st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level, + PIPE_TRANSFER_READ); + texImage->Data = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_READ, 0, 0, stImage->base.Width, @@ -808,6 +812,8 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, * from uploading the buffer under us. */ if (stImage->pt) { + st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level, + PIPE_TRANSFER_WRITE); texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, PIPE_TRANSFER_WRITE, xoffset, yoffset, @@ -932,6 +938,9 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, srcY = strb->Base.Height - srcY - height; } + st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, + PIPE_TRANSFER_READ); + src_trans = screen->get_tex_transfer( screen, strb->texture, 0, 0, 0, @@ -939,6 +948,9 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, srcX, srcY, width, height); + st_teximage_flush_before_map(ctx->st, stImage->pt, 0, 0, + PIPE_TRANSFER_WRITE); + texDest = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_WRITE, destX, destY, width, height); @@ -1318,6 +1330,11 @@ copy_image_data_to_texture(struct st_context *st, /* More straightforward upload. */ + + st_teximage_flush_before_map(st, stObj->pt, stImage->face, dstLevel, + PIPE_TRANSFER_WRITE); + + st_texture_image_data(st->pipe, stObj->pt, stImage->face, diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 9cc2176d5e..6e9aa5245e 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -123,10 +123,17 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, const ubyte *srcData; ubyte *dstData; + st_teximage_flush_before_map(ctx->st, pt, face, srcLevel, + PIPE_TRANSFER_READ); + srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice, PIPE_TRANSFER_READ, 0, 0, pt->width[srcLevel], pt->height[srcLevel]); + + st_teximage_flush_before_map(ctx->st, pt, face, dstLevel, + PIPE_TRANSFER_WRITE); + dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice, PIPE_TRANSFER_WRITE, 0, 0, pt->width[dstLevel], diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 19eb7e2f69..fcbaeb6989 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -188,8 +188,10 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, GLuint zoffset, enum pipe_transfer_usage usage, GLuint x, GLuint y, GLuint w, GLuint h) { - struct pipe_screen *screen = st->pipe->screen; + struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = pipe->screen; struct pipe_texture *pt = stImage->pt; + DBG("%s \n", __FUNCTION__); stImage->transfer = screen->get_tex_transfer(screen, pt, stImage->face, @@ -265,6 +267,7 @@ st_texture_image_data(struct pipe_context *pipe, struct pipe_transfer *dst_transfer; DBG("%s\n", __FUNCTION__); + for (i = 0; i < depth; i++) { dst_transfer = screen->get_tex_transfer(screen, dst, face, level, i, PIPE_TRANSFER_WRITE, 0, 0, @@ -481,3 +484,20 @@ st_release_teximage(struct st_framebuffer *stfb, uint surfIndex, return 1; } + +void +st_teximage_flush_before_map(struct st_context *st, + struct pipe_texture *pt, + unsigned int face, + unsigned int level, + enum pipe_transfer_usage usage) +{ + struct pipe_context *pipe = st->pipe; + unsigned referenced = + pipe->is_texture_referenced(pipe, pt, face, level); + + if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) || + usage == PIPE_TRANSFER_WRITE || + usage == PIPE_TRANSFER_READ_WRITE)) + st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); +} diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 60c000115e..a392e3d57c 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -170,5 +170,10 @@ st_texture_image_copy(struct pipe_context *pipe, struct pipe_texture *src, GLuint face); - +extern void +st_teximage_flush_before_map(struct st_context *st, + struct pipe_texture *pt, + unsigned int face, + unsigned int level, + enum pipe_transfer_usage usage); #endif -- cgit v1.2.3 From 51b339af2e8b80575a24bb9146f031c9605180bb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 15 Apr 2009 09:37:22 -0600 Subject: st: decompress_with_blit() path for glGetTexImage(). Decompress a texture by rendering a textured quad. --- src/mesa/state_tracker/st_cb_texture.c | 83 +++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index e68c3d87ee..53396c0278 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -55,6 +55,7 @@ #include "pipe/p_inlines.h" #include "util/u_tile.h" #include "util/u_blit.h" +#include "util/u_surface.h" #define DBG if (0) printf @@ -817,6 +818,72 @@ st_CompressedTexImage2D(GLcontext *ctx, GLenum target, GLint level, } + +/** + * glGetTexImage() helper: decompress a compressed texture by rendering + * a textured quad. Store the results in the user's buffer. + * XXX unfinished business: decompress sRGB texture + */ +static void +decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + struct pipe_screen *screen = ctx->st->pipe->screen; + struct st_texture_image *stImage = st_texture_image(texImage); + const GLuint width = texImage->Width; + const GLuint height = texImage->Height; + struct pipe_surface *dst_surface; + struct pipe_texture *dst_texture; + struct pipe_transfer *tex_xfer; + GLuint row; + + /* create temp / dest surface */ + if (!util_create_rgba_surface(screen, width, height, + &dst_texture, &dst_surface)) { + _mesa_problem(ctx, "util_create_rgba_surface() failed " + "in decompress_with_blit()"); + return; + } + + /* blit/render/decompress */ + util_blit_pixels_tex(ctx->st->blit, + stImage->pt, /* pipe_texture (src) */ + 0, 0, /* src x0, y0 */ + width, height, /* src x1, y1 */ + dst_surface, /* pipe_surface (dst) */ + 0, 0, /* dst x0, y0 */ + width, height, /* dst x1, y1 */ + 0.0, /* z */ + PIPE_TEX_MIPFILTER_NEAREST); + + /* map the dst_surface so we can read from it */ + tex_xfer = screen->get_tex_transfer(screen, dst_texture, 0, 0, 0, + PIPE_TRANSFER_READ, + 0, 0, width, height); + + /* copy/pack data into user buffer */ + /* XXX: to do: look for cases where we can just memcpy() */ + for (row = 0; row < height; row++) { + const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ + GLfloat rgba[4 * MAX_WIDTH]; + GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, height, + format, type, row, 0); + + /* get float[4] rgba row from surface */ + pipe_get_tile_rgba(tex_xfer, 0, row, width, 1, rgba); + + _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, + format, type, dest, &ctx->Pack, transferOps); + } + + /* destroy the temp / dest surface */ + util_destroy_rgba_surface(dst_texture, dst_surface); +} + + + /** * Need to map texture image into memory before copying image data, * then unmap it. @@ -825,7 +892,7 @@ static void st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels, struct gl_texture_object *texObj, - struct gl_texture_image *texImage, GLboolean compressed) + struct gl_texture_image *texImage, GLboolean compressed_dst) { struct st_texture_image *stImage = st_texture_image(texImage); const GLuint dstImageStride = @@ -834,6 +901,18 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, GLuint depth, i; GLubyte *dest; + if (stImage->pt && + pf_is_compressed(stImage->pt->format) && + !compressed_dst) { + /* Need to decompress the texture. + * We'll do this by rendering a textured quad. + * Note that we only expect RGBA formats (no Z/depth formats). + */ + decompress_with_blit(ctx, target, level, format, type, pixels, + texObj, texImage); + return; + } + /* Map */ if (stImage->pt) { /* Image is stored in hardware format in a buffer managed by the @@ -863,7 +942,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, dest = (GLubyte *) pixels; for (i = 0; i < depth; i++) { - if (compressed) { + if (compressed_dst) { _mesa_get_compressed_teximage(ctx, target, level, dest, texObj, texImage); } -- cgit v1.2.3 From 66cdbf945a3ee75d7b8cba5135310a7ebec21289 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 15 Apr 2009 09:51:38 -0600 Subject: st: st_equal_formats() function to compare gallium/GL pixel formats --- src/mesa/state_tracker/st_format.c | 20 ++++++++++++++++++++ src/mesa/state_tracker/st_format.h | 4 ++++ 2 files changed, 24 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 9e2d60c926..d507e3e58d 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -716,3 +716,23 @@ st_ChooseTextureFormat(GLcontext *ctx, GLint internalFormat, return translate_gallium_format_to_mesa_format(pFormat); } + + +/** + * Test if a gallium format is equivalent to a GL format/type. + */ +GLboolean +st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type) +{ + switch (pFormat) { + case PIPE_FORMAT_R8G8B8A8_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_BYTE; + case PIPE_FORMAT_B8G8R8A8_UNORM: + return format == GL_BGRA && type == GL_UNSIGNED_BYTE; + case PIPE_FORMAT_R5G6B5_UNORM: + return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5; + /* XXX more combos... */ + default: + return GL_FALSE; + } +} diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 3f5ac3201b..7bbbe2d570 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -76,4 +76,8 @@ st_ChooseTextureFormat(GLcontext * ctx, GLint internalFormat, GLenum format, GLenum type); +extern GLboolean +st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type); + + #endif /* ST_CB_TEXIMAGE_H */ -- cgit v1.2.3 From 7b24e58a0ca571d6230ef5076ea352253b81fe6e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 15 Apr 2009 09:52:04 -0600 Subject: st: check for fast memcpy path in decompress_with_blit() --- src/mesa/state_tracker/st_cb_texture.c | 46 ++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 53396c0278..cf20e029a7 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "main/mfeatures.h" +#include "main/bufferobj.h" #if FEATURE_convolve #include "main/convolve.h" #endif @@ -837,7 +838,6 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, struct pipe_surface *dst_surface; struct pipe_texture *dst_texture; struct pipe_transfer *tex_xfer; - GLuint row; /* create temp / dest surface */ if (!util_create_rgba_surface(screen, width, height, @@ -863,20 +863,40 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, PIPE_TRANSFER_READ, 0, 0, width, height); - /* copy/pack data into user buffer */ - /* XXX: to do: look for cases where we can just memcpy() */ - for (row = 0; row < height; row++) { - const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ - GLfloat rgba[4 * MAX_WIDTH]; - GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, height, - format, type, row, 0); - - /* get float[4] rgba row from surface */ - pipe_get_tile_rgba(tex_xfer, 0, row, width, 1, rgba); + pixels = _mesa_map_readpix_pbo(ctx, &ctx->Pack, pixels); - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, - format, type, dest, &ctx->Pack, transferOps); + /* copy/pack data into user buffer */ + if (st_equal_formats(stImage->pt->format, format, type)) { + /* memcpy */ + const uint bytesPerRow = width * pf_get_size(stImage->pt->format); + ubyte *map = screen->transfer_map(screen, tex_xfer); + GLuint row; + for (row = 0; row < height; row++) { + GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, + height, format, type, row, 0); + memcpy(dest, map, bytesPerRow); + map += tex_xfer->stride; + } + screen->transfer_unmap(screen, tex_xfer); } + else { + /* format translation via floats */ + GLuint row; + for (row = 0; row < height; row++) { + const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ + GLfloat rgba[4 * MAX_WIDTH]; + GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, + height, format, type, row, 0); + + /* get float[4] rgba row from surface */ + pipe_get_tile_rgba(tex_xfer, 0, row, width, 1, rgba); + + _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, + type, dest, &ctx->Pack, transferOps); + } + } + + _mesa_unmap_readpix_pbo(ctx, &ctx->Pack); /* destroy the temp / dest surface */ util_destroy_rgba_surface(dst_texture, dst_surface); -- cgit v1.2.3 From 255c33d733cc4d2d7483d903513fdc9c34c90f0d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 15 Apr 2009 09:54:04 -0600 Subject: st: remove XXX comment --- src/mesa/state_tracker/st_cb_texture.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index cf20e029a7..ad3bb64e47 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -823,7 +823,6 @@ st_CompressedTexImage2D(GLcontext *ctx, GLenum target, GLint level, /** * glGetTexImage() helper: decompress a compressed texture by rendering * a textured quad. Store the results in the user's buffer. - * XXX unfinished business: decompress sRGB texture */ static void decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, -- cgit v1.2.3 From e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 17 Apr 2009 11:47:30 +0200 Subject: gallium: Create OGL state tracker wrappers for various CPU access operations. There are two usage types of buffer CPU accesses: One where we try to use the buffer contents for multiple draw commands in a batch. (batch := sequence of commands that are flushed together), like incrementally adding bitmaps to a bitmap texture that is reallocated on flush. And one where we assume we can safely overwrite the old buffer contexts, like glTexSubImage. In this case we need to make sure all old drawing commands referencing the buffer are flushed before we map the buffer. This is easily forgotten. Add wrappers for the most common of these operations. The first type is prefixed with "st_no_flush" and the second type is prefixed with "st_cond_flush", where "cond" indicates that we attmpt to only flush if there is indeed unflushed draw commands referencing the buffer. Prefixed functions are screen::get_tex_transfer pipe_buffer_write pipe_buffer_read pipe_buffer_map Please use the wrappers whenever possible. Signed-off-by: Thomas Hellstrom --- src/mesa/state_tracker/st_atom_constbuf.c | 8 +- src/mesa/state_tracker/st_atom_pixeltransfer.c | 6 +- src/mesa/state_tracker/st_cb_accum.c | 87 ++++++++---------- src/mesa/state_tracker/st_cb_bitmap.c | 25 ++--- src/mesa/state_tracker/st_cb_bufferobjects.c | 31 ++----- src/mesa/state_tracker/st_cb_clear.c | 9 +- src/mesa/state_tracker/st_cb_drawpixels.c | 42 ++++----- src/mesa/state_tracker/st_cb_readpixels.c | 28 +++--- src/mesa/state_tracker/st_cb_texture.c | 33 ++++--- src/mesa/state_tracker/st_gen_mipmap.c | 27 +++--- src/mesa/state_tracker/st_inlines.h | 122 +++++++++++++++++++++++++ src/mesa/state_tracker/st_texture.c | 18 ++-- src/mesa/state_tracker/st_texture.h | 2 +- 13 files changed, 265 insertions(+), 173 deletions(-) create mode 100644 src/mesa/state_tracker/st_inlines.h (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index fd81ac36d2..ec3605e4d6 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -42,7 +42,7 @@ #include "st_atom.h" #include "st_atom_constbuf.h" #include "st_program.h" - +#include "st_inlines.h" /** * Pass the given program parameters to the graphics pipe as a @@ -86,9 +86,9 @@ void st_upload_constants( struct st_context *st, /* load Mesa constants into the constant buffer */ if (cbuf->buffer) - pipe_buffer_write(pipe->screen, cbuf->buffer, - 0, paramBytes, - params->ParameterValues); + st_no_flush_pipe_buffer_write(st, cbuf->buffer, + 0, paramBytes, + params->ParameterValues); st->pipe->set_constant_buffer(st->pipe, id, 0, cbuf); } diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index e0bbf7f3be..eff3666ca8 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -45,6 +45,7 @@ #include "st_format.h" #include "st_program.h" #include "st_texture.h" +#include "st_inlines.h" #include "pipe/p_screen.h" #include "pipe/p_context.h" @@ -147,8 +148,9 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) uint *dest; uint i, j; - transfer = screen->get_tex_transfer(screen, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, - 0, 0, texSize, texSize); + transfer = st_cond_flush_get_tex_transfer(st_context(ctx), + pt, 0, 0, 0, PIPE_TRANSFER_WRITE, + 0, 0, texSize, texSize); dest = (uint *) screen->transfer_map(screen, transfer); /* Pack four 1D maps into a 2D texture: diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 1510a1e236..7f793cf08d 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -41,6 +41,7 @@ #include "st_public.h" #include "st_format.h" #include "st_texture.h" +#include "st_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" @@ -119,12 +120,10 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) const GLint height = ctx->DrawBuffer->_Ymax - ypos; GLubyte *map; - st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0, - PIPE_TRANSFER_WRITE); - - acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, xpos, ypos, - width, height); + 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); /* note acc_strb->format might not equal acc_pt->format */ @@ -167,12 +166,11 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, struct pipe_transfer *acc_pt; GLubyte *map; - st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0, - PIPE_TRANSFER_READ_WRITE); - - acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ_WRITE, xpos, ypos, - width, height); + 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 */ @@ -210,19 +208,14 @@ accum_accum(struct st_context *st, GLfloat value, GLfloat *colorBuf, *accBuf; GLint i; - st_teximage_flush_before_map(st, acc_strb->texture, 0, 0, - PIPE_TRANSFER_READ); - - acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ, xpos, ypos, - width, height); - - st_teximage_flush_before_map(st, color_strb->texture, 0, 0, - PIPE_TRANSFER_READ); + acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ, xpos, ypos, + width, height); - color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ, xpos, ypos, - width, height); + 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)); @@ -235,9 +228,9 @@ accum_accum(struct st_context *st, GLfloat value, } screen->tex_transfer_destroy(acc_trans); - acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, xpos, ypos, - width, height); + 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); @@ -260,19 +253,14 @@ accum_load(struct st_context *st, GLfloat value, GLfloat *buf; GLint i; - st_teximage_flush_before_map(st, acc_strb->texture, 0, 0, - PIPE_TRANSFER_WRITE); + acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, xpos, ypos, + width, height); - acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, xpos, ypos, - width, height); - - st_teximage_flush_before_map(st, color_strb->texture, 0, 0, - PIPE_TRANSFER_READ); - - color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ, xpos, ypos, - width, height); + color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture, + 0, 0, 0, + PIPE_TRANSFER_READ, xpos, ypos, + width, height); buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); @@ -305,19 +293,16 @@ accum_return(GLcontext *ctx, GLfloat value, abuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); - st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0, - PIPE_TRANSFER_READ); - - acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ, xpos, ypos, - width, height); - - st_teximage_flush_before_map(ctx->st, color_strb->texture, 0, 0, - PIPE_TRANSFER_READ_WRITE); + acc_trans = st_cond_flush_get_tex_transfer(st_context(ctx), + acc_strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ, xpos, ypos, + width, height); - color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ_WRITE, xpos, ypos, - width, height); + color_trans = st_cond_flush_get_tex_transfer(st_context(ctx), + color_strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ_WRITE, + xpos, ypos, + width, height); acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, abuf); diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index fa4f4082a7..31ff1f74c0 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -47,6 +47,8 @@ #include "st_cb_program.h" #include "st_mesa_to_tgsi.h" #include "st_texture.h" +#include "st_inlines.h" + #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" @@ -337,8 +339,9 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, return NULL; } - transfer = screen->get_tex_transfer(screen, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, - 0, 0, width, height); + transfer = st_no_flush_get_tex_transfer(st_context(ctx), pt, 0, 0, 0, + PIPE_TRANSFER_WRITE, + 0, 0, width, height); dest = screen->transfer_map(screen, transfer); @@ -425,11 +428,11 @@ setup_bitmap_vertex_data(struct st_context *st, } /* put vertex data into vbuf */ - pipe_buffer_write(pipe->screen, - st->bitmap.vbuf, - st->bitmap.vbuf_slot * sizeof st->bitmap.vertices, - sizeof st->bitmap.vertices, - st->bitmap.vertices); + st_no_flush_pipe_buffer_write(st, + st->bitmap.vbuf, + st->bitmap.vbuf_slot * sizeof st->bitmap.vertices, + sizeof st->bitmap.vertices, + st->bitmap.vertices); return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices; } @@ -584,10 +587,10 @@ reset_cache(struct st_context *st) /* Map the texture transfer. * Subsequent glBitmap calls will write into the texture image. */ - cache->trans = screen->get_tex_transfer(screen, cache->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, 0, 0, - BITMAP_CACHE_WIDTH, - BITMAP_CACHE_HEIGHT); + cache->trans = st_no_flush_get_tex_transfer(st, cache->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, 0, 0, + BITMAP_CACHE_WIDTH, + BITMAP_CACHE_HEIGHT); cache->buffer = screen->transfer_map(screen, cache->trans); /* init image to all 0xff */ diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index fdb800fbd0..1025265cb9 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -30,9 +30,9 @@ #include "main/mtypes.h" #include "main/bufferobj.h" +#include "st_inlines.h" #include "st_context.h" #include "st_cb_bufferobjects.h" -#include "st_public.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -98,16 +98,13 @@ st_bufferobj_subdata(GLcontext *ctx, GLsizeiptrARB size, const GLvoid * data, struct gl_buffer_object *obj) { - struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); if (offset >= st_obj->size || size > (st_obj->size - offset)) return; - if (pipe->is_buffer_referenced(pipe, st_obj->buffer)) - st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL); - - pipe_buffer_write(pipe->screen, st_obj->buffer, offset, size, data); + st_cond_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, + offset, size, data); } @@ -121,17 +118,13 @@ st_bufferobj_get_subdata(GLcontext *ctx, GLsizeiptrARB size, GLvoid * data, struct gl_buffer_object *obj) { - struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); if (offset >= st_obj->size || size > (st_obj->size - offset)) return; - if (pipe->is_buffer_referenced(pipe, st_obj->buffer) & - PIPE_REFERENCED_FOR_WRITE) - st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL); - - pipe_buffer_read(pipe->screen, st_obj->buffer, offset, size, data); + st_cond_flush_pipe_buffer_read(st_context(ctx), st_obj->buffer, + offset, size, data); } @@ -179,7 +172,8 @@ st_bufferobj_data(GLcontext *ctx, st_obj->size = size; if (data) - pipe_buffer_write(pipe->screen, st_obj->buffer, 0, size, data); + st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0, + size, data); } @@ -190,10 +184,8 @@ static void * st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, struct gl_buffer_object *obj) { - struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); GLuint flags; - unsigned referenced; switch (access) { case GL_WRITE_ONLY: @@ -209,12 +201,9 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, break; } - referenced = pipe->is_buffer_referenced(pipe, st_obj->buffer); - if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) || - (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) - st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL); - - obj->Pointer = pipe_buffer_map(pipe->screen, st_obj->buffer, flags); + obj->Pointer = st_cond_flush_pipe_buffer_map(st_context(ctx), + st_obj->buffer, + flags); if(obj->Pointer) { obj->Offset = 0; obj->Length = obj->Size; diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 5bdc6a1330..880e83108c 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -45,6 +45,7 @@ #include "st_program.h" #include "st_public.h" #include "st_mesa_to_tgsi.h" +#include "st_inlines.h" #include "pipe/p_context.h" #include "pipe/p_inlines.h" @@ -166,10 +167,10 @@ draw_quad(GLcontext *ctx, } /* put vertex data into vbuf */ - pipe_buffer_write(pipe->screen, st->clear.vbuf, - st->clear.vbuf_slot * sizeof(st->clear.vertices), - sizeof(st->clear.vertices), - st->clear.vertices); + st_no_flush_pipe_buffer_write(st, st->clear.vbuf, + st->clear.vbuf_slot * sizeof(st->clear.vertices), + sizeof(st->clear.vertices), + st->clear.vertices); /* draw */ util_draw_vertex_buffer(pipe, diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c67b026413..acc9240b5d 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -53,6 +53,8 @@ #include "st_format.h" #include "st_mesa_to_tgsi.h" #include "st_texture.h" +#include "st_inlines.h" + #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" @@ -368,9 +370,9 @@ make_texture(struct st_context *st, /* we'll do pixel transfer in a fragment shader */ ctx->_ImageTransferState = 0x0; - transfer = screen->get_tex_transfer(screen, pt, 0, 0, 0, - PIPE_TRANSFER_WRITE, 0, 0, - width, height); + transfer = st_no_flush_get_tex_transfer(st, pt, 0, 0, 0, + PIPE_TRANSFER_WRITE, 0, 0, + width, height); /* map texture transfer */ dest = screen->transfer_map(screen, transfer); @@ -490,7 +492,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z, /* allocate/load buffer object with vertex data */ buf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX, sizeof(verts)); - pipe_buffer_write(pipe->screen, buf, 0, sizeof(verts), verts); + st_no_flush_pipe_buffer_write(st, buf, 0, sizeof(verts), verts); util_draw_vertex_buffer(pipe, buf, 0, PIPE_PRIM_QUADS, @@ -638,12 +640,9 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, y = ctx->DrawBuffer->Height - y - height; } - st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, - PIPE_TRANSFER_WRITE); - - pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, x, y, - width, height); + pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, x, y, + width, height); stmap = screen->transfer_map(screen, pt); @@ -826,12 +825,10 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); - st_teximage_flush_before_map(ctx->st, rbDraw->texture, 0, 0, - PIPE_TRANSFER_WRITE); - - ptDraw = screen->get_tex_transfer(screen, rbDraw->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, dstx, dsty, - width, height); + ptDraw = st_cond_flush_get_tex_transfer(st_context(ctx), + rbDraw->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, dstx, dsty, + width, height); assert(ptDraw->block.width == 1); assert(ptDraw->block.height == 1); @@ -907,9 +904,6 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, GLfloat *color; enum pipe_format srcFormat, texFormat; - /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - st_validate_state(st); if (type == GL_STENCIL) { @@ -981,13 +975,13 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, else { /* CPU-based fallback/conversion */ struct pipe_transfer *ptRead = - screen->get_tex_transfer(screen, rbRead->texture, 0, 0, 0, - PIPE_TRANSFER_READ, srcx, srcy, width, - height); + st_cond_flush_get_tex_transfer(st, rbRead->texture, 0, 0, 0, + PIPE_TRANSFER_READ, srcx, srcy, width, + height); struct pipe_transfer *ptTex = - screen->get_tex_transfer(screen, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, - 0, 0, width, height); + st_cond_flush_get_tex_transfer(st, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, + 0, 0, width, height); if (type == GL_COLOR) { /* alternate path using get/put_tile() */ diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 519ad6660f..85adcb785e 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -50,6 +50,7 @@ #include "st_format.h" #include "st_public.h" #include "st_texture.h" +#include "st_inlines.h" /** * Special case for reading stencil buffer. @@ -75,11 +76,10 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /* Create a read transfer from the renderbuffer's texture */ - st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, - PIPE_TRANSFER_READ); - - pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ, x, y, width, height); + pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, + 0, 0, 0, + PIPE_TRANSFER_READ, x, y, + width, height); /* map the stencil buffer */ stmap = screen->transfer_map(screen, pt); @@ -245,11 +245,10 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, y = strb->texture->height[0] - y - height; } - st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, - PIPE_TRANSFER_READ); - - trans = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ, x, y, width, height); + trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, + 0, 0, 0, + PIPE_TRANSFER_READ, x, y, + width, height); if (!trans) { return GL_FALSE; } @@ -358,9 +357,6 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (!dest) return; - /* make sure rendering has completed */ - st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); - if (format == GL_STENCIL_INDEX || format == GL_DEPTH_STENCIL) { st_read_stencil_pixels(ctx, x, y, width, height, @@ -403,8 +399,10 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } /* Create a read transfer from the renderbuffer's texture */ - trans = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, - PIPE_TRANSFER_READ, x, y, width, height); + trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, + 0, 0, 0, + PIPE_TRANSFER_READ, x, y, + width, height); /* determine bottom-to-top vs. top-to-bottom order */ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 98dc6ec74d..94e340b7e9 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -50,6 +50,7 @@ #include "state_tracker/st_public.h" #include "state_tracker/st_texture.h" #include "state_tracker/st_gen_mipmap.h" +#include "state_tracker/st_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -465,10 +466,10 @@ compress_with_blit(GLcontext * ctx, /* Put user's tex data into the temporary texture */ - tex_xfer = screen->get_tex_transfer(screen, src_tex, - face, level, 0, - PIPE_TRANSFER_WRITE, - 0, 0, width, height); /* x, y, w, h */ + tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), src_tex, + face, level, 0, + PIPE_TRANSFER_WRITE, + 0, 0, width, height); /* x, y, w, h */ map = screen->transfer_map(screen, tex_xfer); mesa_format->StoreImage(ctx, 2, GL_RGBA, mesa_format, @@ -858,9 +859,10 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, PIPE_TEX_MIPFILTER_NEAREST); /* map the dst_surface so we can read from it */ - tex_xfer = screen->get_tex_transfer(screen, dst_texture, 0, 0, 0, - PIPE_TRANSFER_READ, - 0, 0, width, height); + tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), + dst_texture, 0, 0, 0, + PIPE_TRANSFER_READ, + 0, 0, width, height); pixels = _mesa_map_readpix_pbo(ctx, &ctx->Pack, pixels); @@ -1192,15 +1194,12 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, srcY = strb->Base.Height - srcY - height; } - st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, - PIPE_TRANSFER_READ); - - src_trans = screen->get_tex_transfer( screen, - strb->texture, - 0, 0, 0, - PIPE_TRANSFER_READ, - srcX, srcY, - width, height); + src_trans = st_cond_flush_get_tex_transfer( st_context(ctx), + strb->texture, + 0, 0, 0, + PIPE_TRANSFER_READ, + srcX, srcY, + width, height); st_teximage_flush_before_map(ctx->st, stImage->pt, 0, 0, PIPE_TRANSFER_WRITE); @@ -1589,7 +1588,7 @@ copy_image_data_to_texture(struct st_context *st, PIPE_TRANSFER_WRITE); - st_texture_image_data(st->pipe, + st_texture_image_data(st, stObj->pt, stImage->face, dstLevel, diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 6e9aa5245e..e159b4c9db 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -47,6 +47,7 @@ #include "st_program.h" #include "st_texture.h" #include "st_cb_texture.h" +#include "st_inlines.h" /** @@ -123,21 +124,17 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, const ubyte *srcData; ubyte *dstData; - st_teximage_flush_before_map(ctx->st, pt, face, srcLevel, - PIPE_TRANSFER_READ); - - srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice, - PIPE_TRANSFER_READ, 0, 0, - pt->width[srcLevel], - pt->height[srcLevel]); - - st_teximage_flush_before_map(ctx->st, pt, face, dstLevel, - PIPE_TRANSFER_WRITE); - - dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice, - PIPE_TRANSFER_WRITE, 0, 0, - pt->width[dstLevel], - pt->height[dstLevel]); + srcTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face, + srcLevel, zslice, + PIPE_TRANSFER_READ, 0, 0, + pt->width[srcLevel], + pt->height[srcLevel]); + + dstTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face, + dstLevel, zslice, + PIPE_TRANSFER_WRITE, 0, 0, + pt->width[dstLevel], + pt->height[dstLevel]); srcData = (ubyte *) screen->transfer_map(screen, srcTrans); dstData = (ubyte *) screen->transfer_map(screen, dstTrans); diff --git a/src/mesa/state_tracker/st_inlines.h b/src/mesa/state_tracker/st_inlines.h new file mode 100644 index 0000000000..0322d5dfa6 --- /dev/null +++ b/src/mesa/state_tracker/st_inlines.h @@ -0,0 +1,122 @@ +#ifndef ST_INLINES_H +#define ST_INLINES_H + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_state.h" + +#include "st_context.h" +#include "st_texture.h" +#include "st_public.h" + +static INLINE struct pipe_transfer * +st_cond_flush_get_tex_transfer(struct st_context *st, + struct pipe_texture *pt, + unsigned int face, + unsigned int level, + unsigned int zslice, + enum pipe_transfer_usage usage, + unsigned int x, unsigned int y, + unsigned int w, unsigned int h) +{ + struct pipe_screen *screen = st->pipe->screen; + + st_teximage_flush_before_map(st, pt, face, level, usage); + return screen->get_tex_transfer(screen, pt, face, level, zslice, usage, + x, y, w, h); +} + +static INLINE struct pipe_transfer * +st_no_flush_get_tex_transfer(struct st_context *st, + struct pipe_texture *pt, + unsigned int face, + unsigned int level, + unsigned int zslice, + enum pipe_transfer_usage usage, + unsigned int x, unsigned int y, + unsigned int w, unsigned int h) +{ + struct pipe_screen *screen = st->pipe->screen; + + return screen->get_tex_transfer(screen, pt, face, level, + zslice, usage, x, y, w, h); +} + +static INLINE void * +st_cond_flush_pipe_buffer_map(struct st_context *st, + struct pipe_buffer *buf, + unsigned int map_flags) +{ + struct pipe_context *pipe = st->pipe; + unsigned int referenced = pipe->is_buffer_referenced(pipe, buf); + + if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) || + (map_flags & PIPE_BUFFER_USAGE_CPU_WRITE))) + st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); + + return pipe_buffer_map(pipe->screen, buf, map_flags); +} + +static INLINE void * +st_no_flush_pipe_buffer_map(struct st_context *st, + struct pipe_buffer *buf, + unsigned int map_flags) +{ + return pipe_buffer_map(st->pipe->screen, buf, map_flags); +} + + +static INLINE void +st_cond_flush_pipe_buffer_write(struct st_context *st, + struct pipe_buffer *buf, + unsigned int offset, + unsigned int size, + const void * data) +{ + struct pipe_context *pipe = st->pipe; + + if (pipe->is_buffer_referenced(pipe, buf)) + st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); + + pipe_buffer_write(pipe->screen, buf, offset, size, data); +} + +static INLINE void +st_no_flush_pipe_buffer_write(struct st_context *st, + struct pipe_buffer *buf, + unsigned int offset, + unsigned int size, + const void * data) +{ + pipe_buffer_write(st->pipe->screen, buf, offset, size, data); +} + +static INLINE void +st_cond_flush_pipe_buffer_read(struct st_context *st, + struct pipe_buffer *buf, + unsigned int offset, + unsigned int size, + void * data) +{ + struct pipe_context *pipe = st->pipe; + + if (pipe->is_buffer_referenced(pipe, buf) & PIPE_REFERENCED_FOR_WRITE) + st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); + + pipe_buffer_read(pipe->screen, buf, offset, size, data); +} + +static INLINE void +st_no_flush_pipe_buffer_read(struct st_context *st, + struct pipe_buffer *buf, + unsigned int offset, + unsigned int size, + void * data) +{ + pipe_buffer_read(st->pipe->screen, buf, offset, size, data); +} + +#endif + diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index fcbaeb6989..10faa633ea 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -30,6 +30,7 @@ #include "st_public.h" #include "st_texture.h" #include "st_cb_fbo.h" +#include "st_inlines.h" #include "main/enums.h" #include "main/teximage.h" #include "main/texstore.h" @@ -194,9 +195,9 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, DBG("%s \n", __FUNCTION__); - stImage->transfer = screen->get_tex_transfer(screen, pt, stImage->face, - stImage->level, zoffset, - usage, x, y, w, h); + stImage->transfer = st_no_flush_get_tex_transfer(st, pt, stImage->face, + stImage->level, zoffset, + usage, x, y, w, h); if (stImage->transfer) return screen->transfer_map(screen, stImage->transfer); @@ -253,13 +254,14 @@ st_surface_data(struct pipe_context *pipe, /* Upload data for a particular image. */ void -st_texture_image_data(struct pipe_context *pipe, +st_texture_image_data(struct st_context *st, struct pipe_texture *dst, GLuint face, GLuint level, void *src, GLuint src_row_stride, GLuint src_image_stride) { + struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; GLuint depth = dst->depth[level]; GLuint i; @@ -269,10 +271,10 @@ st_texture_image_data(struct pipe_context *pipe, DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { - dst_transfer = screen->get_tex_transfer(screen, dst, face, level, i, - PIPE_TRANSFER_WRITE, 0, 0, - dst->width[level], - dst->height[level]); + dst_transfer = st_no_flush_get_tex_transfer(st, dst, face, level, i, + PIPE_TRANSFER_WRITE, 0, 0, + dst->width[level], + dst->height[level]); st_surface_data(pipe, dst_transfer, 0, 0, /* dstx, dsty */ diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index a392e3d57c..b9d447cb56 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -156,7 +156,7 @@ st_texture_texel_offset(const struct pipe_texture * pt, /* Upload an image into a texture */ extern void -st_texture_image_data(struct pipe_context *pipe, +st_texture_image_data(struct st_context *st, struct pipe_texture *dst, GLuint face, GLuint level, void *src, GLuint src_row_pitch, GLuint src_image_pitch); -- cgit v1.2.3 From 439c42ae8b652f4fce59e5157c7e598280959684 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 18 Apr 2009 23:14:58 +0100 Subject: st: Wait to create bitmap transfer until needed --- src/mesa/state_tracker/st_cb_bitmap.c | 38 +++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 31ff1f74c0..8709633557 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -573,8 +573,10 @@ reset_cache(struct st_context *st) cache->ymin = 1000000; cache->ymax = -1000000; - if (cache->trans) + if (cache->trans) { screen->tex_transfer_destroy(cache->trans); + cache->trans = NULL; + } assert(!cache->texture); @@ -584,6 +586,18 @@ reset_cache(struct st_context *st) BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, 1, PIPE_TEXTURE_USAGE_SAMPLER); +} + +static void +create_cache_trans(struct st_context *st) +{ + struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = pipe->screen; + struct bitmap_cache *cache = st->bitmap.cache; + + if (cache->trans) + return; + /* Map the texture transfer. * Subsequent glBitmap calls will write into the texture image. */ @@ -622,11 +636,13 @@ st_flush_bitmap_cache(struct st_context *st) /* The texture transfer has been mapped until now. * So unmap and release the texture transfer before drawing. */ - screen->transfer_unmap(screen, cache->trans); - cache->buffer = NULL; + if (cache->trans) { + screen->transfer_unmap(screen, cache->trans); + cache->buffer = NULL; - screen->tex_transfer_destroy(cache->trans); - cache->trans = NULL; + screen->tex_transfer_destroy(cache->trans); + cache->trans = NULL; + } draw_bitmap_quad(st->ctx, cache->xpos, @@ -711,6 +727,9 @@ accum_bitmap(struct st_context *st, if (y + height > cache->ymax) cache->ymax = y + height; + /* create the transfer if needed */ + create_cache_trans(st); + unpack_bitmap(st, px, py, width, height, unpack, bitmap, cache->buffer, BITMAP_CACHE_WIDTH); @@ -823,8 +842,7 @@ st_destroy_bitmap(struct st_context *st) struct pipe_screen *screen = pipe->screen; struct bitmap_cache *cache = st->bitmap.cache; - screen->transfer_unmap(screen, cache->trans); - screen->tex_transfer_destroy(cache->trans); + if (st->bitmap.vs) { cso_delete_vertex_shader(st->cso_context, st->bitmap.vs); @@ -836,7 +854,11 @@ st_destroy_bitmap(struct st_context *st) st->bitmap.vbuf = NULL; } - if (st->bitmap.cache) { + if (cache) { + if (cache->trans) { + screen->transfer_unmap(screen, cache->trans); + screen->tex_transfer_destroy(cache->trans); + } pipe_texture_reference(&st->bitmap.cache->texture, NULL); _mesa_free(st->bitmap.cache); st->bitmap.cache = NULL; -- cgit v1.2.3 From c76a2444a3db4fef4b7892cfd99aa41681b4eb0a Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Mon, 20 Apr 2009 12:52:56 +0200 Subject: gallium: Fix glDraw/CopyPixels fragment program leak. --- src/mesa/state_tracker/st_cb_drawpixels.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index acc9240b5d..703b465574 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -146,6 +146,8 @@ combined_drawpix_fragment_program(GLcontext *ctx) st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo; st->pixel_xfer.user_prog_sn = st->fp->serialNo; st->pixel_xfer.combined_prog_sn = stfp->serialNo; + /* can't reference new program directly, already have a reference on it */ + st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL); st->pixel_xfer.combined_prog = stfp; } -- cgit v1.2.3 From 53c6467aea129b03cf960a0854c1746ce52a2daa Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 17 Apr 2009 17:11:09 +0100 Subject: st: assert on pipe_buffer_create failure This needs a proper fix to propogate the out-of-memory condition back up to Mesa and the app as a GL error. Until then, at least catch the problem at its source. --- src/mesa/state_tracker/st_cb_bufferobjects.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 1025265cb9..ea9f73ca7b 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -169,6 +169,11 @@ st_bufferobj_data(GLcontext *ctx, st_obj->buffer = pipe_buffer_create( pipe->screen, 32, buffer_usage, size ); + /* We don't seem to have any good way of passing failure to + * allocate up to Mesa?? + */ + assert(st_obj->buffer); + st_obj->size = size; if (data) -- cgit v1.2.3 From 01397a66c77f8ebfe78b90ace59c095194a290cf Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 20 Apr 2009 14:53:08 +0100 Subject: mesa: Handle failure to create a transfer. --- src/mesa/state_tracker/st_cb_texture.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 94e340b7e9..c3e990e077 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -682,7 +682,8 @@ st_TexImage(GLcontext * ctx, PIPE_TRANSFER_WRITE, 0, 0, stImage->base.Width, stImage->base.Height); - dstRowStride = stImage->transfer->stride; + if(stImage->transfer) + dstRowStride = stImage->transfer->stride; } else { /* Allocate regular memory and store the image there temporarily. */ -- cgit v1.2.3 From 25e3a534035e71bb319d2e11906d376734941a21 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 20 Apr 2009 15:03:38 -0600 Subject: st: report GL_OUT_OF_MEMORY instead of asserting --- src/mesa/state_tracker/st_cb_bufferobjects.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index ea9f73ca7b..a94e11fff1 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -169,10 +169,10 @@ st_bufferobj_data(GLcontext *ctx, st_obj->buffer = pipe_buffer_create( pipe->screen, 32, buffer_usage, size ); - /* We don't seem to have any good way of passing failure to - * allocate up to Mesa?? - */ - assert(st_obj->buffer); + if (!st_obj->buffer) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB"); + return; + } st_obj->size = size; -- cgit v1.2.3 From f4f39902fd0241162c06065e521151cd2572a34d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 21 Apr 2009 16:47:30 -0600 Subject: st: do away with dynamic state atom for const buffers Just use the new _NEW_PROGRAM_CONSTANTS flag instead. --- src/mesa/state_tracker/st_atom.c | 23 ++--------------------- src/mesa/state_tracker/st_atom_constbuf.c | 10 ++-------- 2 files changed, 4 insertions(+), 29 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index f79092291b..ff7d388dde 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -37,11 +37,8 @@ -/* This is used to initialize st->atoms[]. We could use this list - * directly except for a single atom, st_update_constants, which has a - * .dirty value which changes according to the parameters of the - * current fragment and vertex programs, and so cannot be a static - * value. +/** + * This is used to initialize st->atoms[]. */ static const struct st_tracked_state *atoms[] = { @@ -67,25 +64,9 @@ static const struct st_tracked_state *atoms[] = void st_init_atoms( struct st_context *st ) { - GLuint i; - st->atoms = _mesa_malloc(sizeof(atoms)); st->nr_atoms = sizeof(atoms)/sizeof(*atoms); memcpy(st->atoms, atoms, sizeof(atoms)); - - /* Patch in a pointer to the dynamic state atom: - */ - for (i = 0; i < st->nr_atoms; i++) { - if (st->atoms[i] == &st_update_vs_constants) { - st->atoms[i] = &st->constants.tracked_state[PIPE_SHADER_VERTEX]; - st->atoms[i][0] = st_update_vs_constants; - } - - if (st->atoms[i] == &st_update_fs_constants) { - st->atoms[i] = &st->constants.tracked_state[PIPE_SHADER_FRAGMENT]; - st->atoms[i][0] = st_update_fs_constants; - } - } } diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index ec3605e4d6..c31b120ed1 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -62,12 +62,6 @@ void st_upload_constants( struct st_context *st, if (params && params->NumParameters) { const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4; - /* Update our own dependency flags. This works because this - * function will also be called whenever the program changes. - */ - st->constants.tracked_state[id].dirty.mesa = - (params->StateFlags | _NEW_PROGRAM); - _mesa_load_state_parameters(st->ctx, params); /* We always need to get a new buffer, to keep the drivers simple and @@ -111,7 +105,7 @@ static void update_vs_constants(struct st_context *st ) const struct st_tracked_state st_update_vs_constants = { "st_update_vs_constants", /* name */ { /* dirty */ - 0, /* set dynamically above */ /* mesa */ + _NEW_PROGRAM_CONSTANTS, ST_NEW_VERTEX_PROGRAM, /* st */ }, update_vs_constants /* update */ @@ -130,7 +124,7 @@ static void update_fs_constants(struct st_context *st ) const struct st_tracked_state st_update_fs_constants = { "st_update_fs_constants", /* name */ { /* dirty */ - 0, /* set dynamically above */ /* mesa */ + _NEW_PROGRAM_CONSTANTS, ST_NEW_FRAGMENT_PROGRAM, /* st */ }, update_fs_constants /* update */ -- cgit v1.2.3 From 3eeefa47d08c91e4d3c14343dd0cab1be4252b8c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 21 Apr 2009 16:50:34 -0600 Subject: st: use the static atoms[] array directly We can simplify this now that we no longer have any dynamic atoms. --- src/mesa/state_tracker/st_atom.c | 23 ++++++++--------------- src/mesa/state_tracker/st_context.h | 5 ----- 2 files changed, 8 insertions(+), 20 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index ff7d388dde..ca15ce1b47 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -64,18 +64,13 @@ static const struct st_tracked_state *atoms[] = void st_init_atoms( struct st_context *st ) { - st->atoms = _mesa_malloc(sizeof(atoms)); - st->nr_atoms = sizeof(atoms)/sizeof(*atoms); - memcpy(st->atoms, atoms, sizeof(atoms)); + /* no-op */ } void st_destroy_atoms( struct st_context *st ) { - if (st->atoms) { - _mesa_free(st->atoms); - st->atoms = NULL; - } + /* no-op */ } @@ -153,8 +148,8 @@ void st_validate_state( struct st_context *st ) memset(&examined, 0, sizeof(examined)); prev = *state; - for (i = 0; i < st->nr_atoms; i++) { - const struct st_tracked_state *atom = st->atoms[i]; + for (i = 0; i < Elements(atoms); i++) { + const struct st_tracked_state *atom = atoms[i]; struct st_state_flags generated; // _mesa_printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st); @@ -166,7 +161,7 @@ void st_validate_state( struct st_context *st ) } if (check_state(state, &atom->dirty)) { - st->atoms[i]->update( st ); + atoms[i]->update( st ); // _mesa_printf("after: %x\n", atom->dirty.mesa); } @@ -184,11 +179,9 @@ void st_validate_state( struct st_context *st ) } else { - const GLuint nr = st->nr_atoms; - - for (i = 0; i < nr; i++) { - if (check_state(state, &st->atoms[i]->dirty)) - st->atoms[i]->update( st ); + for (i = 0; i < Elements(atoms); i++) { + if (check_state(state, &atoms[i]->dirty)) + atoms[i]->update( st ); } } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index ae8c2978bf..f840579a40 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -116,11 +116,6 @@ struct st_context char vendor[100]; char renderer[100]; - /* State to be validated: - */ - struct st_tracked_state **atoms; - GLuint nr_atoms; - struct st_state_flags dirty; GLboolean missing_textures; -- cgit v1.2.3 From c1a3b852807fb160f0cd246c1364b7336b4b947e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 21 Apr 2009 17:00:54 -0600 Subject: st: play it safe for now and check _NEW_PROGRAM for shader const buffer atom When a new program is bound but no constants are updated we still need to update the Gallium const buffer. --- src/mesa/state_tracker/st_atom_constbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index c31b120ed1..77ecd0719e 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -124,7 +124,7 @@ static void update_fs_constants(struct st_context *st ) const struct st_tracked_state st_update_fs_constants = { "st_update_fs_constants", /* name */ { /* dirty */ - _NEW_PROGRAM_CONSTANTS, + (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */ ST_NEW_FRAGMENT_PROGRAM, /* st */ }, update_fs_constants /* update */ -- cgit v1.2.3 From f057f6543da469f231d551cb5728d98df8add4fa Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 20 Apr 2009 20:43:56 +0200 Subject: gallium: Reinstate unconditional flushes. Lost in commit e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687. Signed-off-by: Thomas Hellstrom --- src/mesa/state_tracker/st_cb_drawpixels.c | 2 ++ src/mesa/state_tracker/st_cb_readpixels.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 703b465574..08dc7c930e 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -906,6 +906,8 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, GLfloat *color; enum pipe_format srcFormat, texFormat; + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + st_validate_state(st); if (type == GL_STENCIL) { diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 85adcb785e..7a4bbf5ce3 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -357,6 +357,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (!dest) return; + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + if (format == GL_STENCIL_INDEX || format == GL_DEPTH_STENCIL) { st_read_stencil_pixels(ctx, x, y, width, height, -- cgit v1.2.3 From 7843243deedd66b0c94c8874e732ed7e8c6617ff Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 07:58:25 -0600 Subject: st: also check _NEW_PROGRAM flag for vertex shader constant buffers This is a follow-on to commit c1a3b852807fb160f0cd246c1364b7336b4b947e. Note that (at this time) wherever _NEW_PROGRAM_CONSTANTS is set we're still setting _NEW_PROGRAM so this won't really make any difference (for now). --- src/mesa/state_tracker/st_atom_constbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index 77ecd0719e..3ba7b26928 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -105,7 +105,7 @@ static void update_vs_constants(struct st_context *st ) const struct st_tracked_state st_update_vs_constants = { "st_update_vs_constants", /* name */ { /* dirty */ - _NEW_PROGRAM_CONSTANTS, + (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */ ST_NEW_VERTEX_PROGRAM, /* st */ }, update_vs_constants /* update */ -- cgit v1.2.3 From 984f2bb629bb742c6d11d4c8434a2cb32a5b8b75 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 15:10:36 -0600 Subject: st: comments, license, copyright --- src/mesa/state_tracker/st_inlines.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_inlines.h b/src/mesa/state_tracker/st_inlines.h index 0322d5dfa6..a41cfeb96f 100644 --- a/src/mesa/state_tracker/st_inlines.h +++ b/src/mesa/state_tracker/st_inlines.h @@ -1,3 +1,35 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Functions for checking if buffers/textures are referenced when we need + * to read/write from/to them. Flush when needed. + */ + #ifndef ST_INLINES_H #define ST_INLINES_H -- cgit v1.2.3 From 5ed7764fd6354da8e2be15d6fb724c2d6be9be4a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Apr 2009 14:42:23 +0100 Subject: mesa/st: fix incorrect face, level in compress_with_blit We were incorrectly applying the destination texture face and level when requesting a transfer to the temporary texture, which has only one face and level. This would obviously cause problems uploading to compressed cube and mipmap textures. --- src/mesa/state_tracker/st_cb_texture.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index c3e990e077..aeb75117ec 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -418,7 +418,6 @@ compress_with_blit(GLcontext * ctx, const GLuint dstImageOffsets[1] = {0}; struct st_texture_image *stImage = st_texture_image(texImage); struct pipe_screen *screen = ctx->st->pipe->screen; - const GLuint face = _mesa_tex_target_to_face(target); const struct gl_texture_format *mesa_format; struct pipe_texture templ; struct pipe_texture *src_tex; @@ -467,7 +466,7 @@ compress_with_blit(GLcontext * ctx, /* Put user's tex data into the temporary texture */ tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), src_tex, - face, level, 0, + 0, 0, 0, /* face, level are zero */ PIPE_TRANSFER_WRITE, 0, 0, width, height); /* x, y, w, h */ map = screen->transfer_map(screen, tex_xfer); -- cgit v1.2.3 From 3d2bba0d10d59a9c2d6d09c5dc3fabe148d5e0d7 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 28 Apr 2009 14:12:39 +0200 Subject: st: Add an st_get_current() function. Signed-off-by: Thomas Hellstrom --- src/mesa/state_tracker/st_context.c | 6 ++++++ src/mesa/state_tracker/st_public.h | 2 ++ 2 files changed, 8 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index b27274725f..92a630eff9 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -279,6 +279,12 @@ void st_make_current(struct st_context *st, } } +struct st_context *st_get_current(void) +{ + GET_CURRENT_CONTEXT(ctx); + + return (ctx == NULL) ? NULL : ctx->st; +} void st_copy_context_state(struct st_context *dst, struct st_context *src, diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 030314372f..290b8a974e 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -95,6 +95,8 @@ void st_make_current(struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); +struct st_context *st_get_current(void); + void st_flush( struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence ); void st_finish( struct st_context *st ); -- cgit v1.2.3 From afd16512bc354cf1a7220cb9bf3ce445503c7af4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Apr 2009 18:56:26 +0100 Subject: mesa/st: workaround for crashes in st_copy_texsubimage Proper fix for this hasn't been identified, but avoid crashing. --- src/mesa/state_tracker/st_cb_texture.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index aeb75117ec..b7b791d9a4 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -51,6 +51,7 @@ #include "state_tracker/st_texture.h" #include "state_tracker/st_gen_mipmap.h" #include "state_tracker/st_inlines.h" +#include "state_tracker/st_atom.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -1317,6 +1318,10 @@ st_copy_texsubimage(GLcontext *ctx, /* any rendering in progress must complete before we grab the fb image */ st_finish(ctx->st); + /* make sure finalize_textures has been called? + */ + if (0) st_validate_state(ctx->st); + /* determine if copying depth or color data */ if (texBaseFormat == GL_DEPTH_COMPONENT || texBaseFormat == GL_DEPTH24_STENCIL8) { @@ -1330,6 +1335,11 @@ st_copy_texsubimage(GLcontext *ctx, strb = st_renderbuffer(fb->_ColorReadBuffer); } + if (!strb || !strb->surface || !stImage->pt) { + debug_printf("%s: null strb or stImage\n", __FUNCTION__); + return; + } + assert(strb); assert(strb->surface); assert(stImage->pt); -- cgit v1.2.3 From afc0c59dbd7f89d914763fd78701461f22c00450 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Apr 2009 15:33:44 +0100 Subject: mesa/st: translate VERT_ATTRIB_GENERIC8..15 in st_translate_vertex_program It seems quake4 can hit these attributes sometimes. --- src/mesa/state_tracker/st_program.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 2795570cf1..6ec633c0b4 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -169,6 +169,14 @@ st_translate_vertex_program(struct st_context *st, case VERT_ATTRIB_GENERIC5: case VERT_ATTRIB_GENERIC6: case VERT_ATTRIB_GENERIC7: + case VERT_ATTRIB_GENERIC8: + case VERT_ATTRIB_GENERIC9: + case VERT_ATTRIB_GENERIC10: + case VERT_ATTRIB_GENERIC11: + case VERT_ATTRIB_GENERIC12: + case VERT_ATTRIB_GENERIC13: + case VERT_ATTRIB_GENERIC14: + case VERT_ATTRIB_GENERIC15: assert(attr < VERT_ATTRIB_MAX); vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; vs_input_semantic_index[slot] = num_generic++; -- cgit v1.2.3 From 106f2b031cbb83a54fa2949cb07357ecea68b92a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 28 Apr 2009 14:51:11 +0100 Subject: mesa/st: remove duplicate offset calculation --- src/mesa/state_tracker/st_atom_rasterizer.c | 17 +---------------- src/mesa/state_tracker/st_context.h | 2 -- 2 files changed, 1 insertion(+), 18 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 61687fbc3e..4e70510c0c 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -180,22 +180,7 @@ static void update_raster_state( struct st_context *st ) if (ctx->Polygon.StippleFlag) raster->poly_stipple_enable = 1; - - - /* _NEW_BUFFERS, _NEW_POLYGON - */ - if (raster->fill_cw != PIPE_POLYGON_MODE_FILL || - raster->fill_ccw != PIPE_POLYGON_MODE_FILL) - { - GLfloat mrd = (ctx->DrawBuffer ? - ctx->DrawBuffer->_MRD : - 1.0f); - - raster->offset_units = ctx->Polygon.OffsetFactor * mrd; - raster->offset_scale = (ctx->Polygon.OffsetUnits * mrd * - st->polygon_offset_scale); - } - + /* _NEW_POINT */ raster->point_size = ctx->Point.Size; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index f840579a40..6ffed56d9a 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -120,8 +120,6 @@ struct st_context GLboolean missing_textures; - GLfloat polygon_offset_scale; /* ?? */ - /** Mapping from VERT_RESULT_x to post-transformed vertex slot */ const GLuint *vertex_result_to_slot; -- cgit v1.2.3 From 801a33ae44355b89cebed47e9e48e39545522f6e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 28 Apr 2009 17:50:19 +0100 Subject: mesa/st: protect internal flushes with FLUSH_CURRENT Already doing this for driver.flush() --- src/mesa/state_tracker/st_cb_flush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index 7d7d3823c9..fbaffd154f 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -82,7 +82,7 @@ display_front_buffer(struct st_context *st) void st_flush( struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence ) { - FLUSH_VERTICES(st->ctx, 0); + FLUSH_CURRENT(st->ctx, 0); /* Release any vertex buffers that might potentially be accessed in * successive frames: -- cgit v1.2.3 From cd6734288ddc15a778def9578e128184b3f6bdea Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 10:15:21 -0600 Subject: st: when double buffered, only create front color buffer on demand Before we always created the front color buffer, even if was never used. This can save some memory. --- src/mesa/state_tracker/st_cb_fbo.c | 101 ++++++++++++++++++++++++++++++++ src/mesa/state_tracker/st_framebuffer.c | 16 ++--- 2 files changed, 109 insertions(+), 8 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 1590f275e2..0b88d9bf7e 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -452,6 +452,104 @@ st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) } +/** + * Check if we're drawing into, or read from, a front color buffer. If the + * front buffer is missing, create it now. + * + * The back color buffer must exist since we'll use its format/samples info + * for creating the front buffer. + * + * \param frontIndex either BUFFER_FRONT_LEFT or BUFFER_FRONT_RIGHT + * \param backIndex either BUFFER_BACK_LEFT or BUFFER_BACK_RIGHT + */ +static void +check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, + gl_buffer_index frontIndex, + gl_buffer_index backIndex) +{ + if (fb->Attachment[frontIndex].Renderbuffer == NULL) { + GLboolean create = GL_FALSE; + + /* check if drawing to or reading from front buffer */ + if (fb->_ColorReadBufferIndex == frontIndex) { + create = GL_TRUE; + } + else { + GLuint b; + for (b = 0; b < fb->_NumColorDrawBuffers; b++) { + if (fb->_ColorDrawBufferIndexes[b] == frontIndex) { + create = GL_TRUE; + break; + } + } + } + + if (create) { + struct st_renderbuffer *back; + struct gl_renderbuffer *front; + enum pipe_format colorFormat; + uint samples; + + if (0) + _mesa_debug(ctx, "Allocate new front buffer"); + + /* get back renderbuffer info */ + back = st_renderbuffer(fb->Attachment[backIndex].Renderbuffer); + colorFormat = back->format; + samples = back->Base.NumSamples; + + /* create front renderbuffer */ + front = st_new_renderbuffer_fb(colorFormat, samples); + _mesa_add_renderbuffer(fb, frontIndex, front); + + /* alloc texture/surface for new front buffer */ + front->AllocStorage(ctx, front, front->InternalFormat, + fb->Width, fb->Height); + } + } +} + + +/** + * If front left/right color buffers are missing, create them now. + */ +static void +check_create_front_buffers(GLcontext *ctx, struct gl_framebuffer *fb) +{ + /* check if we need to create the front left buffer now */ + check_create_front_buffer(ctx, fb, BUFFER_FRONT_LEFT, BUFFER_BACK_LEFT); + + if (fb->Visual.stereoMode) { + check_create_front_buffer(ctx, fb, BUFFER_FRONT_RIGHT, BUFFER_BACK_RIGHT); + } + + st_invalidate_state(ctx, _NEW_BUFFERS); +} + + +/** + * Called via glDrawBuffer. + */ +static void +st_DrawBuffers(GLcontext *ctx, GLsizei count, const GLenum *buffers) +{ + (void) count; + (void) buffers; + check_create_front_buffers(ctx, ctx->DrawBuffer); +} + + +/** + * Called via glReadBuffer. + */ +static void +st_ReadBuffer(GLcontext *ctx, GLenum buffer) +{ + (void) buffer; + check_create_front_buffers(ctx, ctx->ReadBuffer); +} + + void st_init_fbo_functions(struct dd_function_table *functions) { functions->NewFramebuffer = st_new_framebuffer; @@ -464,4 +562,7 @@ void st_init_fbo_functions(struct dd_function_table *functions) /* no longer needed by core Mesa, drivers handle resizes... functions->ResizeBuffers = st_resize_buffers; */ + + functions->DrawBuffers = st_DrawBuffers; + functions->ReadBuffer = st_ReadBuffer; } diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index daaad65cca..6ad64739bd 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -58,19 +58,19 @@ st_create_framebuffer( const __GLcontextModes *visual, _mesa_initialize_framebuffer(&stfb->Base, visual); - { - /* fake frontbuffer */ - /* XXX allocation should only happen in the unusual case - it's actually needed */ + if (visual->doubleBufferMode) { struct gl_renderbuffer *rb = st_new_renderbuffer_fb(colorFormat, samples); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } - - if (visual->doubleBufferMode) { + else { + /* Only allocate front buffer right now if we're single buffered. + * If double-buffered, allocate front buffer on demand later. + * See check_create_front_buffers(). + */ struct gl_renderbuffer *rb = st_new_renderbuffer_fb(colorFormat, samples); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); } if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) { -- cgit v1.2.3 From 3534539557350f4a63c6e8b3a48fbc8cacffe199 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 10:50:04 -0600 Subject: set: new st_swapbuffers() which does a true front/back buffer swap The pointers to the front/back renderbuffers are exchanged. This new function isn't actually used yet... --- src/mesa/state_tracker/st_framebuffer.c | 79 +++++++++++++++++++++++++++++++++ src/mesa/state_tracker/st_public.h | 4 ++ 2 files changed, 83 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 6ad64739bd..07ccaa6aab 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -293,6 +293,85 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) } +/** + * Swap the front/back color buffers. Exchange the front/back pointers + * and update some derived state. + * No need to call st_notify_swapbuffers() first. + * This is effectively a no-op for single-buffered framebuffers. + * \param front_left returns pointer to front-left renderbuffer after swap + * \param front_right returns pointer to front-right renderbuffer after swap + */ +void +st_swapbuffers(struct st_framebuffer *stfb, + struct pipe_surface **front_left, + struct pipe_surface **front_right) +{ + struct gl_framebuffer *fb = &stfb->Base; + + GET_CURRENT_CONTEXT(ctx); + + if (ctx && ctx->DrawBuffer == &stfb->Base) { + st_flush( ctx->st, + PIPE_FLUSH_RENDER_CACHE | + PIPE_FLUSH_SWAPBUFFERS | + PIPE_FLUSH_FRAME, + NULL ); + } + + /* swap left buffers */ + if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) { + struct gl_renderbuffer *rbTemp; + rbTemp = fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer = + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer = rbTemp; + if (front_left) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + *front_left = strb->surface; + } + } + else { + /* no front buffer, display the back buffer */ + if (front_left) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + *front_left = strb->surface; + } + } + + /* swap right buffers (for stereo) */ + if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer && + fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer) { + struct gl_renderbuffer *rbTemp; + rbTemp = fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer; + fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer = + fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer; + fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer = rbTemp; + if (front_right) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer); + *front_right = strb->surface; + } + } + else { + /* no front right buffer, display back right buffer (if exists) */ + if (front_right) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); + *front_right = strb ? strb->surface : NULL; + } + } + + /* Update the _ColorDrawBuffers[] array and _ColorReadBuffer pointer */ + _mesa_update_framebuffer(ctx); + + /* Make sure we draw into the new back surface */ + st_invalidate_state(ctx, _NEW_BUFFERS); +} + + void *st_framebuffer_private( struct st_framebuffer *stfb ) { return stfb->Private; diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 290b8a974e..174fbc6394 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -103,6 +103,10 @@ void st_finish( struct st_context *st ); void st_notify_swapbuffers(struct st_framebuffer *stfb); +void st_swapbuffers(struct st_framebuffer *stfb, + struct pipe_surface **front_left, + struct pipe_surface **front_right); + int st_set_teximage(struct pipe_texture *pt, int target); /** Redirect rendering into stfb's surface to a texture image */ -- cgit v1.2.3 From b85b315ebbe25efbd118887bdc87a562d4334fcc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 12:25:42 -0600 Subject: st: added st_renderbuffer::defined flag Indicates whether there's defined image contents, or garbage/don't care. This is set when we draw into a renderbuffer and cleared when we resize/ reallocate a renderbuffer or do a buffer swap (back buffer becomes undefined). We use this to determine whether the front color buffer has been drawn to, and whether to display its contents upon glFlush/Finish(), when the new st_swapbuffers() function is used. --- src/mesa/state_tracker/st_atom_framebuffer.c | 1 + src/mesa/state_tracker/st_cb_fbo.c | 2 ++ src/mesa/state_tracker/st_cb_fbo.h | 1 + src/mesa/state_tracker/st_cb_flush.c | 11 ++++++++++- src/mesa/state_tracker/st_context.h | 3 ++- src/mesa/state_tracker/st_framebuffer.c | 12 ++++++++++++ 6 files changed, 28 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index df0f0931ea..f23186c73d 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -123,6 +123,7 @@ update_framebuffer_state( struct st_context *st ) framebuffer->cbufs[framebuffer->nr_cbufs] = strb->surface; framebuffer->nr_cbufs++; } + strb->defined = GL_TRUE; /* we'll be drawing something */ } } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 0b88d9bf7e..fe9befaa2c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -125,6 +125,8 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, strb->Base.Height = height; init_renderbuffer_bits(strb, template.format); + strb->defined = GL_FALSE; /* undefined contents now */ + /* Probably need dedicated flags for surface usage too: */ surface_usage = (PIPE_BUFFER_USAGE_GPU_READ | diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 44fa9fe9a4..fd77d0a95b 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -44,6 +44,7 @@ struct st_renderbuffer struct pipe_texture *texture; struct pipe_surface *surface; /* temporary view into texture */ enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */ + GLboolean defined; /**< defined contents? */ struct st_texture_object *rtt; /**< GL render to texture's texture */ int rtt_level, rtt_face, rtt_slice; diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index fbaffd154f..8ceeeabcd3 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -47,10 +47,19 @@ #include "util/u_blit.h" +/** Check if we have a front color buffer and if it's been drawn to. */ static INLINE GLboolean is_front_buffer_dirty(struct st_context *st) { - return st->frontbuffer_status == FRONT_STATUS_DIRTY; + if (st->frontbuffer_status == FRONT_STATUS_DIRTY) { + return GL_TRUE; + } + else { + GLframebuffer *fb = st->ctx->DrawBuffer; + struct st_renderbuffer *strb + = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + return strb && strb->defined; + } } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 6ffed56d9a..18adb35e87 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -45,6 +45,7 @@ struct blit_state; struct bitmap_cache; +/** XXX we'd like to get rid of these */ #define FRONT_STATUS_UNDEFINED 0 #define FRONT_STATUS_DIRTY 1 #define FRONT_STATUS_COPY_OF_BACK 2 @@ -111,7 +112,7 @@ struct st_context struct gl_fragment_program *fragment_program; } cb; - GLuint frontbuffer_status; /**< one of FRONT_STATUS_ */ + GLuint frontbuffer_status; /**< one of FRONT_STATUS_ (XXX to be removed) */ char vendor[100]; char renderer[100]; diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 07ccaa6aab..639373fff7 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -331,6 +331,12 @@ st_swapbuffers(struct st_framebuffer *stfb, st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); *front_left = strb->surface; } + /* mark back buffer contents as undefined */ + { + struct st_renderbuffer *back = + st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + back->defined = GL_FALSE; + } } else { /* no front buffer, display the back buffer */ @@ -354,6 +360,12 @@ st_swapbuffers(struct st_framebuffer *stfb, st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer); *front_right = strb->surface; } + /* mark back buffer contents as undefined */ + { + struct st_renderbuffer *back = + st_renderbuffer(fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); + back->defined = GL_FALSE; + } } else { /* no front right buffer, display back right buffer (if exists) */ -- cgit v1.2.3 From 3f52a853f795d7432b181de81da6f0c4cf1cc202 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 12:48:46 -0600 Subject: st: when creating an on-demand front color buffer, init to back buffer image When we create a new front color buffer (user called glDrawBuffer(GL_FRONT)) initialize it to the contents of the back buffer. Any previous call to SwapBuffers() would have done that in effect, so make it reality. --- src/mesa/state_tracker/st_cb_fbo.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index fe9befaa2c..9ae4208a18 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -454,6 +454,31 @@ st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) } +/** + * Copy back color buffer to front color buffer. + */ +static void +copy_back_to_front(struct st_context *st, + struct gl_framebuffer *fb, + gl_buffer_index frontIndex, + gl_buffer_index backIndex) + +{ + struct st_framebuffer *stfb = (struct st_framebuffer *) fb; + struct pipe_surface *surf_front, *surf_back; + + (void) st_get_framebuffer_surface(stfb, frontIndex, &surf_front); + (void) st_get_framebuffer_surface(stfb, backIndex, &surf_back); + + if (surf_front && surf_back) { + st->pipe->surface_copy(st->pipe, + surf_front, 0, 0, /* dest */ + surf_back, 0, 0, /* src */ + fb->Width, fb->Height); + } +} + + /** * Check if we're drawing into, or read from, a front color buffer. If the * front buffer is missing, create it now. @@ -493,7 +518,7 @@ check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, uint samples; if (0) - _mesa_debug(ctx, "Allocate new front buffer"); + _mesa_debug(ctx, "Allocate new front buffer\n"); /* get back renderbuffer info */ back = st_renderbuffer(fb->Attachment[backIndex].Renderbuffer); @@ -507,6 +532,11 @@ check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, /* alloc texture/surface for new front buffer */ front->AllocStorage(ctx, front, front->InternalFormat, fb->Width, fb->Height); + + /* initialize the front color buffer contents by copying + * the back buffer. + */ + copy_back_to_front(ctx->st, fb, frontIndex, backIndex); } } } -- cgit v1.2.3 From 602833b107cdf3d70117dbd0970c7d574fb55f3b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 16:44:04 -0600 Subject: st: if st_swapbuffers() is called for single-buffered visual don't crash Furthermore, return pointer(s) to the front color buffer(s). --- src/mesa/state_tracker/st_framebuffer.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 639373fff7..ef800291cc 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -297,7 +297,10 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) * Swap the front/back color buffers. Exchange the front/back pointers * and update some derived state. * No need to call st_notify_swapbuffers() first. - * This is effectively a no-op for single-buffered framebuffers. + * + * For a single-buffered framebuffer, no swap occurs, but we still return + * the pointer(s) to the front color buffer(s). + * * \param front_left returns pointer to front-left renderbuffer after swap * \param front_right returns pointer to front-right renderbuffer after swap */ @@ -318,6 +321,21 @@ st_swapbuffers(struct st_framebuffer *stfb, NULL ); } + if (!fb->Visual.doubleBufferMode) { + /* single buffer mode - return pointers to front surfaces */ + if (front_left) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + *front_left = strb->surface; + } + if (front_right) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer); + *front_right = strb ? strb->surface : NULL; + } + return; + } + /* swap left buffers */ if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) { -- cgit v1.2.3 From 0a56a4968786bd93d9117af2a0a3bda13ea71c4d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 18:17:34 -0600 Subject: st: create renderbuffer's pipe_surface in st_render_texture() Previously we created the pipe_surface during framebuffer validation. But if we did a glCopyTex[Sub]Image() before anything else we wouldn't yet have the surface. This fixes that. --- src/mesa/state_tracker/st_cb_fbo.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 1590f275e2..e003b6db5c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -343,6 +343,7 @@ st_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att) { + struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb; struct gl_renderbuffer *rb; struct pipe_texture *pt = st_get_texobj_texture(att->Texture); @@ -365,6 +366,8 @@ st_render_texture(GLcontext *ctx, rb->AllocStorage = NULL; /* should not get called */ strb = st_renderbuffer(rb); + assert(strb->Base.RefCount > 0); + /* get the texture for the texture object */ stObj = st_texture_object(att->Texture); @@ -384,7 +387,14 @@ st_render_texture(GLcontext *ctx, pipe_surface_reference(&strb->surface, NULL); - /* the new surface will be created during framebuffer validation */ + /* new surface for rendering into the texture */ + strb->surface = screen->get_tex_surface(screen, + strb->texture, + strb->rtt_face, + strb->rtt_level, + strb->rtt_slice, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); init_renderbuffer_bits(strb, pt->format); -- cgit v1.2.3 From 113403ef51e2ec764db061aabf569d6f1a1a3ef0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 5 May 2009 12:12:28 +0100 Subject: mesa: more complete fix for transform_invarient glitches Add a new flag mvp_with_dp4 in the context, and use that to switch both ffvertex.c and programopt.c vertex transformation code to either DP4 or MUL/MAD implementations. --- src/mesa/main/context.c | 13 ++++ src/mesa/main/context.h | 4 ++ src/mesa/main/ffvertex_prog.c | 16 +++-- src/mesa/main/mtypes.h | 6 ++ src/mesa/shader/programopt.c | 119 +++++++++++++++++++++++++++++++++++- src/mesa/state_tracker/st_context.c | 6 ++ 6 files changed, 153 insertions(+), 11 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 016284de9a..d780f91f04 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1522,4 +1522,17 @@ _mesa_Flush(void) } +/** + * Set mvp_with_dp4 flag. If a driver has a preference for DP4 over + * MUL/MAD, or vice versa, call this function to register that. + * Otherwise we default to MUL/MAD. + */ +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ) +{ + ctx->mvp_with_dp4 = flag; +} + + /*@}*/ diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index ecc1cec779..5b57d88029 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -151,6 +151,10 @@ extern struct _glapi_table * _mesa_get_dispatch(GLcontext *ctx); +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ); + /** \name Miscellaneous */ /*@{*/ diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 82e1c4af66..43325b1352 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -315,12 +315,6 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) */ #define DISASSEM 0 -/* Should be tunable by the driver - do we want to do matrix - * multiplications with DP4's or with MUL/MAD's? SSE works better - * with the latter, drivers may differ. - */ -#define PREFER_DP4 1 - /* Use uregs to represent registers internally, translate to Mesa's * expected formats on emit. @@ -348,6 +342,7 @@ struct tnl_program { const struct state_key *state; struct gl_vertex_program *program; GLint max_inst; /** number of instructions allocated for program */ + GLboolean mvp_with_dp4; GLuint temp_in_use; GLuint temp_reserved; @@ -775,7 +770,7 @@ static struct ureg get_eye_position( struct tnl_program *p ) p->eye_position = reserve_temp(p); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 0, modelview ); @@ -881,7 +876,7 @@ static void build_hpos( struct tnl_program *p ) struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 0, mvp ); emit_matrix_transform_vec4( p, hpos, mvp, pos ); @@ -1574,7 +1569,7 @@ static void build_texture_transform( struct tnl_program *p ) struct ureg in = (!is_undef(out_texgen) ? out_texgen : register_input(p, VERT_ATTRIB_TEX0+i)); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 0, texmat ); emit_matrix_transform_vec4( p, out, texmat, in ); @@ -1708,6 +1703,7 @@ static void build_tnl_program( struct tnl_program *p ) static void create_new_program( const struct state_key *key, struct gl_vertex_program *program, + GLboolean mvp_with_dp4, GLuint max_temps) { struct tnl_program p; @@ -1721,6 +1717,7 @@ create_new_program( const struct state_key *key, p.transformed_normal = undef; p.identity = undef; p.temp_in_use = 0; + p.mvp_with_dp4 = mvp_with_dp4; if (max_temps >= sizeof(int) * 8) p.temp_reserved = 0; @@ -1776,6 +1773,7 @@ _mesa_get_fixed_func_vertex_program(GLcontext *ctx) return NULL; create_new_program( &key, prog, + ctx->mvp_with_dp4, ctx->Const.VertexProgram.MaxTemps ); #if 0 diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index cf71077728..587dc80146 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2980,6 +2980,12 @@ struct __GLcontextRec /** software compression/decompression supported or not */ GLboolean Mesa_DXTn; + /** + * Use dp4 (rather than mul/mad) instructions for position + * transformation? + */ + GLboolean mvp_with_dp4; + /** Core tnl module support */ struct gl_tnl_module TnlModule; diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index ecd98dc85c..f70c75cec8 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -45,8 +45,8 @@ * into a vertex program. * May be used to implement the position_invariant option. */ -void -_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +static void +_mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog) { struct prog_instruction *newInst; const GLuint origLen = vprog->Base.NumInstructions; @@ -113,6 +113,121 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) } +static void +_mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + struct prog_instruction *newInst; + const GLuint origLen = vprog->Base.NumInstructions; + const GLuint newLen = origLen + 4; + GLuint hposTemp; + GLuint i; + + /* + * Setup state references for the modelview/projection matrix. + * XXX we should check if these state vars are already declared. + */ + static const gl_state_index mvpState[4][STATE_LENGTH] = { + { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE }, + }; + GLint mvpRef[4]; + + for (i = 0; i < 4; i++) { + mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters, + mvpState[i]); + } + + /* Alloc storage for new instructions */ + newInst = _mesa_alloc_instructions(newLen); + if (!newInst) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "glProgramString(inserting position_invariant code)"); + return; + } + + /* TEMP hposTemp; */ + hposTemp = vprog->Base.NumTemporaries++; + + /* + * Generated instructions: + * emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); + * emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); + */ + _mesa_init_instructions(newInst, 4); + + newInst[0].Opcode = OPCODE_MUL; + newInst[0].DstReg.File = PROGRAM_TEMPORARY; + newInst[0].DstReg.Index = hposTemp; + newInst[0].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[0].SrcReg[0].File = PROGRAM_INPUT; + newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX; + newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[0].SrcReg[1].Index = mvpRef[0]; + newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP; + + for (i = 1; i <= 2; i++) { + newInst[i].Opcode = OPCODE_MAD; + newInst[i].DstReg.File = PROGRAM_TEMPORARY; + newInst[i].DstReg.Index = hposTemp; + newInst[i].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[i].SrcReg[0].File = PROGRAM_INPUT; + newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i); + newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[i].SrcReg[1].Index = mvpRef[i]; + newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[i].SrcReg[2].Index = hposTemp; + newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP; + } + + newInst[3].Opcode = OPCODE_MAD; + newInst[3].DstReg.File = PROGRAM_OUTPUT; + newInst[3].DstReg.Index = VERT_RESULT_HPOS; + newInst[3].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[3].SrcReg[0].File = PROGRAM_INPUT; + newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW; + newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[3].SrcReg[1].Index = mvpRef[3]; + newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[3].SrcReg[2].Index = hposTemp; + newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP; + + + /* Append original instructions after new instructions */ + _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen); + + /* free old instructions */ + _mesa_free_instructions(vprog->Base.Instructions, origLen); + + /* install new instructions */ + vprog->Base.Instructions = newInst; + vprog->Base.NumInstructions = newLen; + vprog->Base.InputsRead |= VERT_BIT_POS; + vprog->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS); +} + + +void +_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + if (ctx->mvp_with_dp4) + _mesa_insert_mvp_dp4_code( ctx, vprog ); + else + _mesa_insert_mvp_mad_code( ctx, vprog ); +} + + + + + /** * Append extra instructions onto the given fragment program to implement diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 92a630eff9..2a1f21c51c 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -177,6 +177,12 @@ struct st_context *st_create_context(struct pipe_context *pipe, ctx = _mesa_create_context(visual, shareCtx, &funcs, NULL); + /* XXX: need a capability bit in gallium to query if the pipe + * driver prefers DP4 or MUL/MAD for vertex transformation. + */ + if (debug_get_bool_option("MESA_MVP_DP4", FALSE)) + _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + return st_create_context_priv(ctx, pipe); } -- cgit v1.2.3 From 01280cff537544299fe0c5f1a282abde8e69b1f3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 11:46:08 +0100 Subject: mesa/st: cope with non-ibo index data in st_draw_feedback.c Previously only non-indexed or indicies-in-a-vbo cases were handled in this code. This change adds the missing regular indices-in-memory case. --- src/mesa/state_tracker/st_draw_feedback.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index e533afd051..32502a9cda 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -196,13 +196,10 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_vertex_elements(draw, vp->num_inputs, velements); if (ib) { - unsigned indexSize; struct gl_buffer_object *bufobj = ib->obj; - struct st_buffer_object *stobj = st_buffer_object(bufobj); + unsigned indexSize; void *map; - index_buffer_handle = stobj->buffer; - switch (ib->type) { case GL_UNSIGNED_INT: indexSize = 4; @@ -215,9 +212,19 @@ st_feedback_draw_vbo(GLcontext *ctx, return; } - map = pipe_buffer_map(pipe->screen, index_buffer_handle, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer(draw, indexSize, map); + if (bufobj && bufobj->Name) { + struct st_buffer_object *stobj = st_buffer_object(bufobj); + + index_buffer_handle = stobj->buffer; + + map = pipe_buffer_map(pipe->screen, index_buffer_handle, + PIPE_BUFFER_USAGE_CPU_READ); + + draw_set_mapped_element_buffer(draw, indexSize, map); + } + else { + draw_set_mapped_element_buffer(draw, indexSize, (void *) ib->ptr); + } } else { /* no index/element buffer */ @@ -252,7 +259,7 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_mapped_vertex_buffer(draw, i, NULL); } } - if (ib) { + if (index_buffer_handle) { pipe_buffer_unmap(pipe->screen, index_buffer_handle); draw_set_mapped_element_buffer(draw, 0, NULL); } -- cgit v1.2.3 From 6826bad6a75e78729dd472ea26c87787c90ada4c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 19:27:30 +0100 Subject: mesa/st: remove redundant call to st_finish in CopyTexSubImage Rendering should already have been flushed, any synchronization will be done by the driver or memory manager. --- src/mesa/state_tracker/st_cb_texture.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index b7b791d9a4..98f109fc65 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1315,9 +1315,6 @@ st_copy_texsubimage(GLcontext *ctx, GLboolean use_fallback = GL_TRUE; GLboolean matching_base_formats; - /* any rendering in progress must complete before we grab the fb image */ - st_finish(ctx->st); - /* make sure finalize_textures has been called? */ if (0) st_validate_state(ctx->st); -- cgit v1.2.3 From d5c2ad8514ce8064d83febf647c9e726788b7924 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 19:48:06 +0100 Subject: mesa/st: keep surface_copy arguments positive The src/dest x,y, and w,h arguments of the pipe->surface_copy function are unsigned and the drivers aren't expecting negative (or extremly-large unsigned) values as inputs. Trim the requests at the state-tracker level before passing down. --- src/mesa/state_tracker/st_cb_drawpixels.c | 43 ++++++++++++++++++++++++++++--- src/mesa/state_tracker/st_cb_texture.c | 28 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 08dc7c930e..89725cfe8d 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -910,6 +910,34 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, st_validate_state(st); + if (srcx < 0) { + width -= -srcx; + dstx += -srcx; + srcx = 0; + } + + if (srcy < 0) { + height -= -srcy; + dsty += -srcy; + srcy = 0; + } + + if (dstx < 0) { + width -= -dstx; + srcx += -dstx; + dstx = 0; + } + + if (dsty < 0) { + height -= -dsty; + srcy += -dsty; + dsty = 0; + } + + if (width < 0 || height < 0) + return; + + if (type == GL_STENCIL) { /* can't use texturing to do stencil */ copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); @@ -951,15 +979,24 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } } + if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { + srcy = ctx->DrawBuffer->Height - srcy - height; + + if (srcy < 0) { + height -= -srcy; + srcy = 0; + } + + if (height < 0) + return; + } + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0, width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) return; - if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - srcy = ctx->DrawBuffer->Height - srcy - height; - } if (srcFormat == texFormat) { /* copy source framebuffer surface into mipmap/texture */ diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 98f109fc65..b182106fd5 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1337,6 +1337,34 @@ st_copy_texsubimage(GLcontext *ctx, return; } + if (srcX < 0) { + width -= -srcX; + destX += -srcX; + srcX = 0; + } + + if (srcY < 0) { + height -= -srcY; + destY += -srcY; + srcY = 0; + } + + if (destX < 0) { + width -= -destX; + srcX += -destX; + destX = 0; + } + + if (destY < 0) { + height -= -destY; + srcY += -destY; + destY = 0; + } + + if (width < 0 || height < 0) + return; + + assert(strb); assert(strb->surface); assert(stImage->pt); -- cgit v1.2.3 From b6e8256899a9a93c665c34e10efcc918f2fcc095 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 5 May 2009 12:12:28 +0100 Subject: mesa: more complete fix for transform_invarient glitches Add a new flag mvp_with_dp4 in the context, and use that to switch both ffvertex.c and programopt.c vertex transformation code to either DP4 or MUL/MAD implementations. --- src/mesa/main/context.c | 13 ++++ src/mesa/main/context.h | 4 ++ src/mesa/main/ffvertex_prog.c | 16 +++-- src/mesa/main/mtypes.h | 6 ++ src/mesa/shader/programopt.c | 119 +++++++++++++++++++++++++++++++++++- src/mesa/state_tracker/st_context.c | 6 ++ 6 files changed, 153 insertions(+), 11 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 016284de9a..d780f91f04 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1522,4 +1522,17 @@ _mesa_Flush(void) } +/** + * Set mvp_with_dp4 flag. If a driver has a preference for DP4 over + * MUL/MAD, or vice versa, call this function to register that. + * Otherwise we default to MUL/MAD. + */ +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ) +{ + ctx->mvp_with_dp4 = flag; +} + + /*@}*/ diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index ecc1cec779..5b57d88029 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -151,6 +151,10 @@ extern struct _glapi_table * _mesa_get_dispatch(GLcontext *ctx); +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ); + /** \name Miscellaneous */ /*@{*/ diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 82e1c4af66..43325b1352 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -315,12 +315,6 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) */ #define DISASSEM 0 -/* Should be tunable by the driver - do we want to do matrix - * multiplications with DP4's or with MUL/MAD's? SSE works better - * with the latter, drivers may differ. - */ -#define PREFER_DP4 1 - /* Use uregs to represent registers internally, translate to Mesa's * expected formats on emit. @@ -348,6 +342,7 @@ struct tnl_program { const struct state_key *state; struct gl_vertex_program *program; GLint max_inst; /** number of instructions allocated for program */ + GLboolean mvp_with_dp4; GLuint temp_in_use; GLuint temp_reserved; @@ -775,7 +770,7 @@ static struct ureg get_eye_position( struct tnl_program *p ) p->eye_position = reserve_temp(p); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 0, modelview ); @@ -881,7 +876,7 @@ static void build_hpos( struct tnl_program *p ) struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 0, mvp ); emit_matrix_transform_vec4( p, hpos, mvp, pos ); @@ -1574,7 +1569,7 @@ static void build_texture_transform( struct tnl_program *p ) struct ureg in = (!is_undef(out_texgen) ? out_texgen : register_input(p, VERT_ATTRIB_TEX0+i)); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 0, texmat ); emit_matrix_transform_vec4( p, out, texmat, in ); @@ -1708,6 +1703,7 @@ static void build_tnl_program( struct tnl_program *p ) static void create_new_program( const struct state_key *key, struct gl_vertex_program *program, + GLboolean mvp_with_dp4, GLuint max_temps) { struct tnl_program p; @@ -1721,6 +1717,7 @@ create_new_program( const struct state_key *key, p.transformed_normal = undef; p.identity = undef; p.temp_in_use = 0; + p.mvp_with_dp4 = mvp_with_dp4; if (max_temps >= sizeof(int) * 8) p.temp_reserved = 0; @@ -1776,6 +1773,7 @@ _mesa_get_fixed_func_vertex_program(GLcontext *ctx) return NULL; create_new_program( &key, prog, + ctx->mvp_with_dp4, ctx->Const.VertexProgram.MaxTemps ); #if 0 diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 30c7cca3b5..ed6b1062bd 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2977,6 +2977,12 @@ struct __GLcontextRec /** software compression/decompression supported or not */ GLboolean Mesa_DXTn; + /** + * Use dp4 (rather than mul/mad) instructions for position + * transformation? + */ + GLboolean mvp_with_dp4; + /** Core tnl module support */ struct gl_tnl_module TnlModule; diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index ecd98dc85c..f70c75cec8 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -45,8 +45,8 @@ * into a vertex program. * May be used to implement the position_invariant option. */ -void -_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +static void +_mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog) { struct prog_instruction *newInst; const GLuint origLen = vprog->Base.NumInstructions; @@ -113,6 +113,121 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) } +static void +_mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + struct prog_instruction *newInst; + const GLuint origLen = vprog->Base.NumInstructions; + const GLuint newLen = origLen + 4; + GLuint hposTemp; + GLuint i; + + /* + * Setup state references for the modelview/projection matrix. + * XXX we should check if these state vars are already declared. + */ + static const gl_state_index mvpState[4][STATE_LENGTH] = { + { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE }, + }; + GLint mvpRef[4]; + + for (i = 0; i < 4; i++) { + mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters, + mvpState[i]); + } + + /* Alloc storage for new instructions */ + newInst = _mesa_alloc_instructions(newLen); + if (!newInst) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "glProgramString(inserting position_invariant code)"); + return; + } + + /* TEMP hposTemp; */ + hposTemp = vprog->Base.NumTemporaries++; + + /* + * Generated instructions: + * emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); + * emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); + */ + _mesa_init_instructions(newInst, 4); + + newInst[0].Opcode = OPCODE_MUL; + newInst[0].DstReg.File = PROGRAM_TEMPORARY; + newInst[0].DstReg.Index = hposTemp; + newInst[0].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[0].SrcReg[0].File = PROGRAM_INPUT; + newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX; + newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[0].SrcReg[1].Index = mvpRef[0]; + newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP; + + for (i = 1; i <= 2; i++) { + newInst[i].Opcode = OPCODE_MAD; + newInst[i].DstReg.File = PROGRAM_TEMPORARY; + newInst[i].DstReg.Index = hposTemp; + newInst[i].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[i].SrcReg[0].File = PROGRAM_INPUT; + newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i); + newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[i].SrcReg[1].Index = mvpRef[i]; + newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[i].SrcReg[2].Index = hposTemp; + newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP; + } + + newInst[3].Opcode = OPCODE_MAD; + newInst[3].DstReg.File = PROGRAM_OUTPUT; + newInst[3].DstReg.Index = VERT_RESULT_HPOS; + newInst[3].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[3].SrcReg[0].File = PROGRAM_INPUT; + newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW; + newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[3].SrcReg[1].Index = mvpRef[3]; + newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[3].SrcReg[2].Index = hposTemp; + newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP; + + + /* Append original instructions after new instructions */ + _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen); + + /* free old instructions */ + _mesa_free_instructions(vprog->Base.Instructions, origLen); + + /* install new instructions */ + vprog->Base.Instructions = newInst; + vprog->Base.NumInstructions = newLen; + vprog->Base.InputsRead |= VERT_BIT_POS; + vprog->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS); +} + + +void +_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + if (ctx->mvp_with_dp4) + _mesa_insert_mvp_dp4_code( ctx, vprog ); + else + _mesa_insert_mvp_mad_code( ctx, vprog ); +} + + + + + /** * Append extra instructions onto the given fragment program to implement diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 92a630eff9..2a1f21c51c 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -177,6 +177,12 @@ struct st_context *st_create_context(struct pipe_context *pipe, ctx = _mesa_create_context(visual, shareCtx, &funcs, NULL); + /* XXX: need a capability bit in gallium to query if the pipe + * driver prefers DP4 or MUL/MAD for vertex transformation. + */ + if (debug_get_bool_option("MESA_MVP_DP4", FALSE)) + _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + return st_create_context_priv(ctx, pipe); } -- cgit v1.2.3 From 33d2ca7624968fc972c917f15fa947df36916296 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 11:46:08 +0100 Subject: mesa/st: cope with non-ibo index data in st_draw_feedback.c Previously only non-indexed or indicies-in-a-vbo cases were handled in this code. This change adds the missing regular indices-in-memory case. --- src/mesa/state_tracker/st_draw_feedback.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index e533afd051..32502a9cda 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -196,13 +196,10 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_vertex_elements(draw, vp->num_inputs, velements); if (ib) { - unsigned indexSize; struct gl_buffer_object *bufobj = ib->obj; - struct st_buffer_object *stobj = st_buffer_object(bufobj); + unsigned indexSize; void *map; - index_buffer_handle = stobj->buffer; - switch (ib->type) { case GL_UNSIGNED_INT: indexSize = 4; @@ -215,9 +212,19 @@ st_feedback_draw_vbo(GLcontext *ctx, return; } - map = pipe_buffer_map(pipe->screen, index_buffer_handle, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer(draw, indexSize, map); + if (bufobj && bufobj->Name) { + struct st_buffer_object *stobj = st_buffer_object(bufobj); + + index_buffer_handle = stobj->buffer; + + map = pipe_buffer_map(pipe->screen, index_buffer_handle, + PIPE_BUFFER_USAGE_CPU_READ); + + draw_set_mapped_element_buffer(draw, indexSize, map); + } + else { + draw_set_mapped_element_buffer(draw, indexSize, (void *) ib->ptr); + } } else { /* no index/element buffer */ @@ -252,7 +259,7 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_mapped_vertex_buffer(draw, i, NULL); } } - if (ib) { + if (index_buffer_handle) { pipe_buffer_unmap(pipe->screen, index_buffer_handle); draw_set_mapped_element_buffer(draw, 0, NULL); } -- cgit v1.2.3 From 507f4e7a7448fb246febefe8819b7b3ac70a35b4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 19:27:30 +0100 Subject: mesa/st: remove redundant call to st_finish in CopyTexSubImage Rendering should already have been flushed, any synchronization will be done by the driver or memory manager. --- src/mesa/state_tracker/st_cb_texture.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index b7b791d9a4..98f109fc65 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1315,9 +1315,6 @@ st_copy_texsubimage(GLcontext *ctx, GLboolean use_fallback = GL_TRUE; GLboolean matching_base_formats; - /* any rendering in progress must complete before we grab the fb image */ - st_finish(ctx->st); - /* make sure finalize_textures has been called? */ if (0) st_validate_state(ctx->st); -- cgit v1.2.3 From e90beb93a89f77bffce8ab3d54457ea65868e93c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 19:48:06 +0100 Subject: mesa/st: keep surface_copy arguments positive The src/dest x,y, and w,h arguments of the pipe->surface_copy function are unsigned and the drivers aren't expecting negative (or extremly-large unsigned) values as inputs. Trim the requests at the state-tracker level before passing down. --- src/mesa/state_tracker/st_cb_drawpixels.c | 43 ++++++++++++++++++++++++++++--- src/mesa/state_tracker/st_cb_texture.c | 28 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 08dc7c930e..89725cfe8d 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -910,6 +910,34 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, st_validate_state(st); + if (srcx < 0) { + width -= -srcx; + dstx += -srcx; + srcx = 0; + } + + if (srcy < 0) { + height -= -srcy; + dsty += -srcy; + srcy = 0; + } + + if (dstx < 0) { + width -= -dstx; + srcx += -dstx; + dstx = 0; + } + + if (dsty < 0) { + height -= -dsty; + srcy += -dsty; + dsty = 0; + } + + if (width < 0 || height < 0) + return; + + if (type == GL_STENCIL) { /* can't use texturing to do stencil */ copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); @@ -951,15 +979,24 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } } + if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { + srcy = ctx->DrawBuffer->Height - srcy - height; + + if (srcy < 0) { + height -= -srcy; + srcy = 0; + } + + if (height < 0) + return; + } + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0, width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) return; - if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - srcy = ctx->DrawBuffer->Height - srcy - height; - } if (srcFormat == texFormat) { /* copy source framebuffer surface into mipmap/texture */ diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 98f109fc65..b182106fd5 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1337,6 +1337,34 @@ st_copy_texsubimage(GLcontext *ctx, return; } + if (srcX < 0) { + width -= -srcX; + destX += -srcX; + srcX = 0; + } + + if (srcY < 0) { + height -= -srcY; + destY += -srcY; + srcY = 0; + } + + if (destX < 0) { + width -= -destX; + srcX += -destX; + destX = 0; + } + + if (destY < 0) { + height -= -destY; + srcY += -destY; + destY = 0; + } + + if (width < 0 || height < 0) + return; + + assert(strb); assert(strb->surface); assert(stImage->pt); -- cgit v1.2.3 From f104e4d666dfccda6f5ad817693216733ddede44 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 11 May 2009 16:09:39 -0600 Subject: st: do proper refcounting for framebuffer surfaces --- src/mesa/state_tracker/st_atom_framebuffer.c | 16 ++++++++++------ src/mesa/state_tracker/st_context.c | 7 +++++++ 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index df0f0931ea..536293683e 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -98,8 +98,6 @@ update_framebuffer_state( struct st_context *st ) struct st_renderbuffer *strb; GLuint i; - memset(framebuffer, 0, sizeof(*framebuffer)); - framebuffer->width = fb->Width; framebuffer->height = fb->Height; @@ -120,12 +118,19 @@ update_framebuffer_state( struct st_context *st ) } if (strb->surface) { - framebuffer->cbufs[framebuffer->nr_cbufs] = strb->surface; + pipe_surface_reference(&framebuffer->cbufs[framebuffer->nr_cbufs], + strb->surface); framebuffer->nr_cbufs++; } } } + for (i = framebuffer->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) { + pipe_surface_reference(&framebuffer->cbufs[i], NULL); + } + /* + * Depth/Stencil renderbuffer/surface. + */ strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); if (strb) { strb = st_renderbuffer(strb->Base.Wrapped); @@ -133,15 +138,14 @@ update_framebuffer_state( struct st_context *st ) /* rendering to a GL texture, may have to update surface */ update_renderbuffer_surface(st, strb); } - - framebuffer->zsbuf = strb->surface; + pipe_surface_reference(&framebuffer->zsbuf, strb->surface); } else { strb = st_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer); if (strb) { strb = st_renderbuffer(strb->Base.Wrapped); assert(strb->surface); - framebuffer->zsbuf = strb->surface; + pipe_surface_reference(&framebuffer->zsbuf, strb->surface); } } diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 2a1f21c51c..e536029e86 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -233,6 +233,7 @@ void st_destroy_context( struct st_context *st ) struct pipe_context *pipe = st->pipe; struct cso_context *cso = st->cso_context; GLcontext *ctx = st->ctx; + GLuint i; /* need to unbind and destroy CSO objects before anything else */ cso_release_all(st->cso_context); @@ -240,6 +241,12 @@ void st_destroy_context( struct st_context *st ) st_reference_fragprog(st, &st->fp, NULL); st_reference_vertprog(st, &st->vp, NULL); + /* release framebuffer surfaces */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + pipe_surface_reference(&st->state.framebuffer.cbufs[i], NULL); + } + pipe_surface_reference(&st->state.framebuffer.zsbuf, NULL); + _mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache); _vbo_DestroyContext(st->ctx); -- cgit v1.2.3 From a892acef982bd17df81ae16131381a558208c112 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 May 2009 11:15:00 -0600 Subject: st/mesa: enable GL_APPLE_vertex_array_object for gallium drivers --- src/mesa/state_tracker/st_cb_bufferobjects.c | 5 +++++ src/mesa/state_tracker/st_extensions.c | 2 ++ 2 files changed, 7 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index a94e11fff1..f5d802055f 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -28,6 +28,7 @@ #include "main/imports.h" #include "main/mtypes.h" +#include "main/arrayobj.h" #include "main/bufferobj.h" #include "st_inlines.h" @@ -307,4 +308,8 @@ st_init_bufferobject_functions(struct dd_function_table *functions) functions->MapBufferRange = st_bufferobj_map_range; functions->FlushMappedBufferRange = st_bufferobj_flush_mapped_range; functions->UnmapBuffer = st_bufferobj_unmap; + + /* For GL_APPLE_vertex_array_object */ + functions->NewArrayObject = _mesa_new_array_object; + functions->DeleteArrayObject = _mesa_delete_array_object; } diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 8f6be50774..d526dfcf52 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -168,6 +168,8 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE; ctx->Extensions.EXT_texture_lod_bias = GL_TRUE; + ctx->Extensions.APPLE_vertex_array_object = GL_TRUE; + ctx->Extensions.NV_blend_square = GL_TRUE; ctx->Extensions.NV_texgen_reflection = GL_TRUE; -- cgit v1.2.3 From 14e5bff97b20565637d468d97dba434ac4cd2ba1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 18 May 2009 10:12:36 -0600 Subject: st: fix incorrect target parameter to screen->is_format_supported() We were passing a GL texture target instead of a pipe_texture_target enum. --- src/mesa/state_tracker/st_gen_mipmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index e159b4c9db..3a88908022 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -87,7 +87,7 @@ st_render_mipmap(struct st_context *st, assert(target != GL_TEXTURE_3D); /* not done yet */ /* check if we can render in the texture's format */ - if (!screen->is_format_supported(screen, pt->format, target, + if (!screen->is_format_supported(screen, pt->format, pt->target, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { return FALSE; } -- cgit v1.2.3 From 7ce105d2e6885eeac73c59dc14c4cd59a89c1425 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 18 May 2009 10:28:04 -0600 Subject: st/mesa: fix incorrect src/dst stride params to _mesa_generate_mipmap_level() The stride needs to be in texels, not bytes. --- src/mesa/state_tracker/st_gen_mipmap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 3a88908022..dc6d77825f 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -123,6 +123,7 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, struct pipe_transfer *srcTrans, *dstTrans; const ubyte *srcData; ubyte *dstData; + int srcStride, dstStride; srcTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face, srcLevel, zslice, @@ -139,14 +140,17 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, srcData = (ubyte *) screen->transfer_map(screen, srcTrans); dstData = (ubyte *) screen->transfer_map(screen, dstTrans); + srcStride = srcTrans->stride / srcTrans->block.size; + dstStride = dstTrans->stride / dstTrans->block.size; + _mesa_generate_mipmap_level(target, datatype, comps, 0 /*border*/, pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], srcData, - srcTrans->stride, /* stride in bytes */ + srcStride, /* stride in texels */ pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel], dstData, - dstTrans->stride); /* stride in bytes */ + dstStride); /* stride in texels */ screen->transfer_unmap(screen, srcTrans); screen->transfer_unmap(screen, dstTrans); -- cgit v1.2.3 From 0c75cb5afe81b0de9d006f9f9b75fdc9a15038d0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 12 May 2009 19:51:44 -0600 Subject: st: reformatting, comments, var renaming --- src/mesa/state_tracker/st_atom_constbuf.c | 48 +++++++++++++++++++------------ 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index 3ba7b26928..5d4d8eee02 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -24,11 +24,12 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ - /* - * Authors: - * Keith Whitwell - * Brian Paul - */ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ #include "main/imports.h" #include "shader/prog_parameter.h" @@ -44,19 +45,21 @@ #include "st_program.h" #include "st_inlines.h" + /** * Pass the given program parameters to the graphics pipe as a * constant buffer. - * \param id either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT + * \param shader_type either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT */ void st_upload_constants( struct st_context *st, struct gl_program_parameter_list *params, - unsigned id) + unsigned shader_type) { struct pipe_context *pipe = st->pipe; - struct pipe_constant_buffer *cbuf = &st->state.constants[id]; + struct pipe_constant_buffer *cbuf = &st->state.constants[shader_type]; - assert(id == PIPE_SHADER_VERTEX || id == PIPE_SHADER_FRAGMENT); + assert(shader_type == PIPE_SHADER_VERTEX || + shader_type == PIPE_SHADER_FRAGMENT); /* update constants */ if (params && params->NumParameters) { @@ -68,13 +71,14 @@ void st_upload_constants( struct st_context *st, * avoid gratuitous rendering synchronization. */ pipe_buffer_reference(&cbuf->buffer, NULL ); - cbuf->buffer = pipe_buffer_create(pipe->screen, 16, PIPE_BUFFER_USAGE_CONSTANT, + cbuf->buffer = pipe_buffer_create(pipe->screen, 16, + PIPE_BUFFER_USAGE_CONSTANT, paramBytes ); - if (0) - { - printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n", - __FUNCTION__, id, params->NumParameters, params->StateFlags); + if (0) { + debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n", + __FUNCTION__, shader_type, params->NumParameters, + params->StateFlags); _mesa_print_parameter_list(params); } @@ -84,15 +88,16 @@ void st_upload_constants( struct st_context *st, 0, paramBytes, params->ParameterValues); - st->pipe->set_constant_buffer(st->pipe, id, 0, cbuf); + st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf); } else { - st->constants.tracked_state[id].dirty.mesa = 0; - // st->pipe->set_constant_buffer(st->pipe, id, 0, NULL); + st->constants.tracked_state[shader_type].dirty.mesa = 0x0; } } -/* Vertex shader: + +/** + * Vertex shader: */ static void update_vs_constants(struct st_context *st ) { @@ -102,6 +107,7 @@ static void update_vs_constants(struct st_context *st ) st_upload_constants( st, params, PIPE_SHADER_VERTEX ); } + const struct st_tracked_state st_update_vs_constants = { "st_update_vs_constants", /* name */ { /* dirty */ @@ -111,7 +117,10 @@ const struct st_tracked_state st_update_vs_constants = { update_vs_constants /* update */ }; -/* Fragment shader: + + +/** + * Fragment shader: */ static void update_fs_constants(struct st_context *st ) { @@ -121,6 +130,7 @@ static void update_fs_constants(struct st_context *st ) st_upload_constants( st, params, PIPE_SHADER_FRAGMENT ); } + const struct st_tracked_state st_update_fs_constants = { "st_update_fs_constants", /* name */ { /* dirty */ -- cgit v1.2.3 From 5b27b4ad37bd992d2d3a6fd9d407277113544f30 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 21 May 2009 08:15:22 -0600 Subject: st: add support for GL_EXT_vertex_array_bgra --- src/mesa/state_tracker/st_draw.c | 13 ++++++++++++- src/mesa/state_tracker/st_draw.h | 3 ++- src/mesa/state_tracker/st_draw_feedback.c | 1 + src/mesa/state_tracker/st_extensions.c | 1 + 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 225541a30b..8e036223c6 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -159,12 +159,21 @@ static GLuint fixed_types[4] = { * Return a PIPE_FORMAT_x for the given GL datatype and size. */ GLuint -st_pipe_vertex_format(GLenum type, GLuint size, GLboolean normalized) +st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, + GLboolean normalized) { assert((type >= GL_BYTE && type <= GL_DOUBLE) || type == GL_FIXED); assert(size >= 1); assert(size <= 4); + assert(format == GL_RGBA || format == GL_BGRA); + + if (format == GL_BGRA) { + /* this is an odd-ball case */ + assert(type == GL_UNSIGNED_BYTE); + assert(normalized); + return PIPE_FORMAT_B8G8R8A8_UNORM; + } if (normalized) { switch (type) { @@ -392,6 +401,7 @@ setup_interleaved_attribs(GLcontext *ctx, velements[attr].src_format = st_pipe_vertex_format(arrays[mesaAttr]->Type, arrays[mesaAttr]->Size, + arrays[mesaAttr]->Format, arrays[mesaAttr]->Normalized); assert(velements[attr].src_format); } @@ -479,6 +489,7 @@ setup_non_interleaved_attribs(GLcontext *ctx, velements[attr].src_format = st_pipe_vertex_format(arrays[mesaAttr]->Type, arrays[mesaAttr]->Size, + arrays[mesaAttr]->Format, arrays[mesaAttr]->Normalized); assert(velements[attr].src_format); } diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h index da04fce8e2..dcfe7e1536 100644 --- a/src/mesa/state_tracker/st_draw.h +++ b/src/mesa/state_tracker/st_draw.h @@ -62,7 +62,8 @@ st_feedback_draw_vbo(GLcontext *ctx, /* Internal function: */ extern GLuint -st_pipe_vertex_format(GLenum type, GLuint size, GLboolean normalized); +st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, + GLboolean normalized); /** diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 32502a9cda..2712c131c0 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -178,6 +178,7 @@ st_feedback_draw_vbo(GLcontext *ctx, velements[attr].src_format = st_pipe_vertex_format(arrays[mesaAttr]->Type, arrays[mesaAttr]->Size, + arrays[mesaAttr]->Format, arrays[mesaAttr]->Normalized); assert(velements[attr].src_format); diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index d526dfcf52..efa88c2481 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -167,6 +167,7 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.EXT_texture_env_combine = GL_TRUE; ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE; ctx->Extensions.EXT_texture_lod_bias = GL_TRUE; + ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE; ctx->Extensions.APPLE_vertex_array_object = GL_TRUE; -- cgit v1.2.3 From 842b4cd3cdb313751647e229a9aa3f0001e03d15 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 May 2009 14:32:45 -0600 Subject: mesa: use Elements() for loop limit --- src/mesa/state_tracker/st_cb_rasterpos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index 7dd2352739..7a9c50b3fc 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -194,7 +194,7 @@ new_draw_rastpos_stage(GLcontext *ctx, struct draw_context *draw) rs->stage.destroy = rastpos_destroy; rs->ctx = ctx; - for (i = 0; i < VERT_ATTRIB_MAX; i++) { + for (i = 0; i < Elements(rs->array); i++) { rs->array[i].Size = 4; rs->array[i].Type = GL_FLOAT; rs->array[i].Stride = 0; -- cgit v1.2.3 From c13bd7488593263f2c45c136b63114ce8b4602fb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 27 May 2009 19:24:09 -0600 Subject: st/mesa: init Format field of vertex arrays for feedback mode Fixes segfault in glRasterPos() --- src/mesa/state_tracker/st_cb_rasterpos.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index 7a9c50b3fc..3bcccd0df4 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -197,6 +197,7 @@ new_draw_rastpos_stage(GLcontext *ctx, struct draw_context *draw) for (i = 0; i < Elements(rs->array); i++) { rs->array[i].Size = 4; rs->array[i].Type = GL_FLOAT; + rs->array[i].Format = GL_RGBA; rs->array[i].Stride = 0; rs->array[i].StrideB = 0; rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i]; -- cgit v1.2.3 From 8aef306c342a973f31b384a71d7a22ade9153a99 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 30 May 2009 12:41:14 -0700 Subject: mesa: Check/propagate return value on st_make_current. Prevents segmentation fault when trying to set the viewport/scissor after a context/drawable visual mismatch. --- src/mesa/state_tracker/st_context.c | 13 ++++++++----- src/mesa/state_tracker/st_public.h | 6 +++--- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index e536029e86..92ddffc014 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -263,9 +263,10 @@ void st_destroy_context( struct st_context *st ) } -void st_make_current(struct st_context *st, - struct st_framebuffer *draw, - struct st_framebuffer *read) +GLboolean +st_make_current(struct st_context *st, + struct st_framebuffer *draw, + struct st_framebuffer *read) { /* Call this periodically to detect when the user has begun using * GL rendering from multiple threads. @@ -274,7 +275,8 @@ void st_make_current(struct st_context *st, if (st) { GLboolean firstTime = st->ctx->FirstTimeCurrent; - _mesa_make_current(st->ctx, &draw->Base, &read->Base); + if(!_mesa_make_current(st->ctx, &draw->Base, &read->Base)) + return GL_FALSE; /* Need to initialize viewport here since draw->Base->Width/Height * will still be zero at this point. * This could be improved, but would require rather extensive work @@ -286,9 +288,10 @@ void st_make_current(struct st_context *st, _mesa_set_scissor(st->ctx, 0, 0, w, h); } + return GL_TRUE; } else { - _mesa_make_current(NULL, NULL, NULL); + return _mesa_make_current(NULL, NULL, NULL); } } diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 290b8a974e..c411687bb6 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -91,9 +91,9 @@ void *st_framebuffer_private( struct st_framebuffer *stfb ); void st_unreference_framebuffer( struct st_framebuffer *stfb ); -void st_make_current(struct st_context *st, - struct st_framebuffer *draw, - struct st_framebuffer *read); +GLboolean st_make_current(struct st_context *st, + struct st_framebuffer *draw, + struct st_framebuffer *read); struct st_context *st_get_current(void); -- cgit v1.2.3 From 0e8a5a84742adf6e99236f246c77325fad174204 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 1 Jun 2009 14:59:11 -0600 Subject: st/mesa: fix incorrect sprite origin when drawing to FBO/texture Need to take the draw buffer's up/down orientation into consideration when setting the sprite_coord_mode field. Fixes inverted sprites when drawing into an FBO. --- src/mesa/state_tracker/st_atom_rasterizer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 4e70510c0c..5c7206409c 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -192,7 +192,8 @@ static void update_raster_state( struct st_context *st ) raster->point_sprite = ctx->Point.PointSprite; for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (ctx->Point.CoordReplace[i]) { - if (ctx->Point.SpriteOrigin == GL_UPPER_LEFT) + if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^ + (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM)) raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_UPPER_LEFT; else raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_LOWER_LEFT; -- cgit v1.2.3 From f989390af6f827d1ea36560381340148811836f3 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 13 May 2009 22:35:06 +0200 Subject: st/gl: Fix mip gen for compressed textures --- src/mesa/state_tracker/st_cb_texture.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index b182106fd5..aaed155925 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -673,7 +673,7 @@ st_TexImage(GLcontext * ctx, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { if (compress_with_blit(ctx, target, level, 0, 0, 0, width, height, depth, format, type, pixels, unpack, texImage)) { - return; + goto done; } } @@ -750,6 +750,7 @@ st_TexImage(GLcontext * ctx, _mesa_unmap_teximage_pbo(ctx, unpack); +done: if (stImage->pt && texImage->Data) { st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; @@ -1061,7 +1062,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, packing, texImage)) { - return; + goto done; } } @@ -1110,16 +1111,17 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, } } - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); +done: if (stImage->pt) { st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } + + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + ctx->Driver.GenerateMipmap(ctx, target, texObj); + } } -- cgit v1.2.3 From 503632557e8904b775e1b6f3f84eb41bda3af122 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 14 May 2009 10:26:56 +0100 Subject: mesa/st: restore flush to copy_texsubimage (was previously finish) Need a flush here even though the original finish was overkill. --- src/mesa/state_tracker/st_cb_texture.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index aaed155925..14b78d1253 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1317,6 +1317,9 @@ st_copy_texsubimage(GLcontext *ctx, GLboolean use_fallback = GL_TRUE; GLboolean matching_base_formats; + /* any rendering in progress must flushed before we grab the fb image */ + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + /* make sure finalize_textures has been called? */ if (0) st_validate_state(ctx->st); -- cgit v1.2.3 From dd174ea2155ded567494448ffc5de7e022eabc5a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 2 Jun 2009 21:24:28 -0600 Subject: st/mesa: implement/enable GL_ARB_copy_buffer extension --- src/mesa/state_tracker/st_cb_bufferobjects.c | 38 ++++++++++++++++++++++++++++ src/mesa/state_tracker/st_extensions.c | 1 + 2 files changed, 39 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index f5d802055f..340fbd9aba 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -296,6 +296,43 @@ st_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) } +/** + * Called via glCopyBufferSubData(). + */ +static void +st_copy_buffer_subdata(GLcontext *ctx, + struct gl_buffer_object *src, + struct gl_buffer_object *dst, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size) +{ + struct pipe_context *pipe = st_context(ctx)->pipe; + struct st_buffer_object *srcObj = st_buffer_object(src); + struct st_buffer_object *dstObj = st_buffer_object(dst); + ubyte *srcPtr, *dstPtr; + + /* buffer should not already be mapped */ + assert(!src->Pointer); + assert(!dst->Pointer); + + srcPtr = (ubyte *) pipe_buffer_map_range(pipe->screen, + srcObj->buffer, + readOffset, size, + PIPE_BUFFER_USAGE_CPU_READ); + + dstPtr = (ubyte *) pipe_buffer_map_range(pipe->screen, + dstObj->buffer, + writeOffset, size, + PIPE_BUFFER_USAGE_CPU_WRITE); + + if (srcPtr && dstPtr) + _mesa_memcpy(dstPtr + writeOffset, srcPtr + readOffset, size); + + pipe_buffer_unmap(pipe->screen, srcObj->buffer); + pipe_buffer_unmap(pipe->screen, dstObj->buffer); +} + + void st_init_bufferobject_functions(struct dd_function_table *functions) { @@ -308,6 +345,7 @@ st_init_bufferobject_functions(struct dd_function_table *functions) functions->MapBufferRange = st_bufferobj_map_range; functions->FlushMappedBufferRange = st_bufferobj_flush_mapped_range; functions->UnmapBuffer = st_bufferobj_unmap; + functions->CopyBufferSubData = st_copy_buffer_subdata; /* For GL_APPLE_vertex_array_object */ functions->NewArrayObject = _mesa_new_array_object; diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index efa88c2481..8ed1211db6 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -138,6 +138,7 @@ void st_init_extensions(struct st_context *st) /* * Extensions that are supported by all Gallium drivers: */ + ctx->Extensions.ARB_copy_buffer = GL_TRUE; ctx->Extensions.ARB_multisample = GL_TRUE; ctx->Extensions.ARB_fragment_program = GL_TRUE; ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */ -- cgit v1.2.3 From 54576130a88fe93a64367f882cd680e37f0ec0ac Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 2 Jun 2009 21:46:17 -0600 Subject: st/mesa: minor clean-ups, reformatting, etc --- src/mesa/state_tracker/st_cb_bufferobjects.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 340fbd9aba..f140641d7e 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -26,6 +26,11 @@ **************************************************************************/ +/** + * Functions for pixel buffer objects and vertex/element buffer objects. + */ + + #include "main/imports.h" #include "main/mtypes.h" #include "main/arrayobj.h" @@ -40,14 +45,6 @@ #include "pipe/p_inlines.h" - -/* Pixel buffers and Vertex/index buffers are handled through these - * mesa callbacks. Framebuffer/Renderbuffer objects are - * created/managed elsewhere. - */ - - - /** * There is some duplication between mesa's bufferobjects and our * bufmgr buffers. Both have an integer handle and a hashtable to @@ -191,7 +188,7 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, struct gl_buffer_object *obj) { struct st_buffer_object *st_obj = st_buffer_object(obj); - GLuint flags; + uint flags; switch (access) { case GL_WRITE_ONLY: @@ -210,7 +207,7 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, obj->Pointer = st_cond_flush_pipe_buffer_map(st_context(ctx), st_obj->buffer, flags); - if(obj->Pointer) { + if (obj->Pointer) { obj->Offset = 0; obj->Length = obj->Size; } @@ -218,7 +215,6 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, } - /** * Called via glMapBufferRange(). */ @@ -229,7 +225,7 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target, { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); - GLuint flags = 0; + uint flags = 0x0; char *map; if (access & GL_MAP_WRITE_BIT) @@ -249,8 +245,9 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target, assert(offset < obj->Size); assert(offset + length <= obj->Size); - map = obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags); - if(obj->Pointer) { + map = obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, + offset, length, flags); + if (obj->Pointer) { obj->Offset = 0; obj->Length = obj->Size; map += offset; -- cgit v1.2.3 From d37795c45334010c70b2e1c23fca0e49ff607a6e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 4 Jun 2009 13:10:19 -0600 Subject: st/mesa: increase ST_MAX_SHADER_TOKENS to 8k --- src/mesa/state_tracker/st_program.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 6ec633c0b4..34926101ed 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -49,7 +49,7 @@ #include "cso_cache/cso_context.h" -#define ST_MAX_SHADER_TOKENS 4096 +#define ST_MAX_SHADER_TOKENS (8 * 1024) #define TGSI_DEBUG 0 -- cgit v1.2.3 From 42678dba941b5a734e6aa03b530653d9c5341a70 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 8 Jun 2009 16:27:59 +0100 Subject: mesa: Allocate tokens from the heap. The recent increase ST_MAX_SHADER_TOKENS to 8K causes stack overflows on windows. Failure to allocate is not being propagated to the caller. This is not a regression since the previous _mesa_malloc result wasn't being checked as well. Unfortunately it is not easy to fix, as the callers of these functions do not have failure propagation mechanism either, and so on. So leaving a just fixme note for now. --- src/mesa/state_tracker/st_program.c | 40 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 34926101ed..06030f6cd8 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -55,20 +55,6 @@ #define TGSI_DEBUG 0 -/** XXX we should use the version of this from u_memory.h but including - * that header causes symbol collisions. - */ -static INLINE void * -mem_dup(const void *src, uint size) -{ - void *dup = _mesa_malloc(size); - if (dup) - _mesa_memcpy(dup, src, size); - return dup; -} - - - /** * Translate a Mesa vertex shader into a TGSI shader. * \param outputMapping to map vertex program output registers (VERT_RESULT_x) @@ -84,7 +70,7 @@ st_translate_vertex_program(struct st_context *st, const ubyte *outputSemanticIndex) { struct pipe_context *pipe = st->pipe; - struct tgsi_token tokens[ST_MAX_SHADER_TOKENS]; + struct tgsi_token *tokens; GLuint defaultOutputMapping[VERT_RESULT_MAX]; struct pipe_shader_state vs; GLuint attr, i; @@ -102,6 +88,13 @@ st_translate_vertex_program(struct st_context *st, GLbitfield input_flags[MAX_PROGRAM_INPUTS]; GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; + tokens = (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens); + if(!tokens) { + /* FIXME: propagate error to the caller */ + assert(0); + return; + } + memset(&vs, 0, sizeof(vs)); memset(input_flags, 0, sizeof(input_flags)); memset(output_flags, 0, sizeof(output_flags)); @@ -347,7 +340,9 @@ st_translate_vertex_program(struct st_context *st, assert(num_tokens < ST_MAX_SHADER_TOKENS); vs.tokens = (struct tgsi_token *) - mem_dup(tokens, num_tokens * sizeof(tokens[0])); + _mesa_realloc(tokens, + ST_MAX_SHADER_TOKENS * sizeof *tokens, + num_tokens * sizeof *tokens); stvp->num_inputs = vs_num_inputs; stvp->state = vs; /* struct copy */ @@ -375,7 +370,7 @@ st_translate_fragment_program(struct st_context *st, const GLuint inputMapping[]) { struct pipe_context *pipe = st->pipe; - struct tgsi_token tokens[ST_MAX_SHADER_TOKENS]; + struct tgsi_token *tokens; GLuint outputMapping[FRAG_RESULT_MAX]; GLuint defaultInputMapping[FRAG_ATTRIB_MAX]; struct pipe_shader_state fs; @@ -395,6 +390,13 @@ st_translate_fragment_program(struct st_context *st, GLbitfield input_flags[MAX_PROGRAM_INPUTS]; GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; + tokens = (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens); + if(!tokens) { + /* FIXME: propagate error to the caller */ + assert(0); + return; + } + memset(&fs, 0, sizeof(fs)); memset(input_flags, 0, sizeof(input_flags)); memset(output_flags, 0, sizeof(output_flags)); @@ -536,7 +538,9 @@ st_translate_fragment_program(struct st_context *st, assert(num_tokens < ST_MAX_SHADER_TOKENS); fs.tokens = (struct tgsi_token *) - mem_dup(tokens, num_tokens * sizeof(tokens[0])); + _mesa_realloc(tokens, + ST_MAX_SHADER_TOKENS * sizeof *tokens, + num_tokens * sizeof *tokens); stfp->state = fs; /* struct copy */ stfp->driver_shader = pipe->create_fs_state(pipe, &fs); -- cgit v1.2.3 From b6753adbc71a2d13e8ec095251f62cb267429de7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 8 Jun 2009 10:44:48 -0600 Subject: st/mesa: remove invalid assertion It's legal for ARB_vertex_program programs to not write to result.position. The results are undefined in that case. This assertion was causing us to abort/exit though. --- src/mesa/state_tracker/st_program.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 06030f6cd8..72ca852458 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -290,9 +290,6 @@ st_translate_vertex_program(struct st_context *st, } } - assert(vs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - - if (outputMapping) { /* find max output slot referenced to compute vs_num_outputs */ GLuint maxSlot = 0; -- cgit v1.2.3 From 34bb024cf2d02d5d5cb672ead05fa131bdff6dd8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 8 Jun 2009 16:11:17 -0600 Subject: st/mesa: fix incorrect bufObj Length assignment, remove unneeded assertion --- src/mesa/state_tracker/st_cb_bufferobjects.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index a94e11fff1..fbe6aa25de 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -251,7 +251,7 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target, map = obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags); if(obj->Pointer) { obj->Offset = 0; - obj->Length = obj->Size; + obj->Length = length; map += offset; } @@ -270,7 +270,6 @@ st_bufferobj_flush_mapped_range(GLcontext *ctx, GLenum target, /* Subrange is relative to mapped range */ assert(offset >= 0); assert(length >= 0); - assert(offset < obj->Length); assert(offset + length <= obj->Length); pipe_buffer_flush_mapped_range(pipe->screen, st_obj->buffer, -- cgit v1.2.3 From 76a1017e978f8e51114d765c8c98ff25da13042b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 9 Jun 2009 18:32:18 +0100 Subject: mesa/st: fix tracking of mapped buffer ranges In st_bufferobj_map_range(), set obj->Offset consistently with its usage elsewhere. --- src/mesa/state_tracker/st_cb_bufferobjects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index fbe6aa25de..19a0e67362 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -250,7 +250,7 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target, map = obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags); if(obj->Pointer) { - obj->Offset = 0; + obj->Offset = offset; obj->Length = length; map += offset; } -- cgit v1.2.3 From 52411a1951da10bebc439a30c02c7ca99bc27c9c Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 10 Jun 2009 15:39:02 +0100 Subject: mesa: Pure software accum buffer. The existing implementation was already implemented on software, but relied on the pipe driver to always support the R16G16B16A16_SNORM format. This patch eliminates that, without prejudice against a future hardware-only implementation. It also avoids some of the short <-> float conversions, and only does a read transfer of the color buffer on GL_RETURN if absolutely necessary. --- src/mesa/state_tracker/st_cb_accum.c | 244 +++++++++++++------------------- src/mesa/state_tracker/st_cb_fbo.c | 147 +++++++++---------- src/mesa/state_tracker/st_cb_fbo.h | 13 +- src/mesa/state_tracker/st_framebuffer.c | 17 +-- 4 files changed, 187 insertions(+), 234 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 7f793cf08d..95181578f6 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_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index e003b6db5c..21ddf2fc7a 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -88,91 +88,90 @@ 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); - - /* 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 - - strb->texture = pipe->screen->texture_create( pipe->screen, - &template ); + init_renderbuffer_bits(strb, format); + + 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 ); - /* 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. + /* 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); + } + + /* 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; + } } @@ -186,6 +185,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); } @@ -242,7 +242,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; @@ -256,7 +256,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: @@ -287,7 +288,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; diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 44fa9fe9a4..9a199550d9 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. @@ -45,6 +41,13 @@ struct st_renderbuffer struct pipe_surface *surface; /* temporary view into texture */ enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */ + /** + * 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; @@ -62,7 +65,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_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index daaad65cca..331575660d 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -63,20 +63,20 @@ st_create_framebuffer( const __GLcontextModes *visual, /* XXX allocation should only happen in the unusual case it's actually needed */ 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 (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); } 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); } -- cgit v1.2.3 From 978bca8b2a7869e875fc205f29751d31178d2281 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 10 Jun 2009 15:39:34 +0100 Subject: mesa: Single precision constants. --- src/mesa/state_tracker/st_cb_readpixels.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 7a4bbf5ce3..86baf3ddef 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; -- cgit v1.2.3 From 0a4fcabe4451af6472245e2630f8c8834aa9d351 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 10 Jun 2009 19:58:54 +0100 Subject: mesa: Fix draw_stencil_pixels for PIPE_FORMAT_Z24S8_UNORM. Reversed component order. This fixes glean depthStencil test failures for PIPE_FORMAT_Z24S8_UNORM visuals. --- src/mesa/state_tracker/st_cb_drawpixels.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 89725cfe8d..d92d29e961 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -718,7 +718,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; for (k = 0; k < spanWidth; k++) { - dest[k] = zValues[k] | (sValues[k] << 24); + dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff); } } else { -- cgit v1.2.3 From 337f559cd2d98a858719cb963450fef2256e83f7 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 10 Jun 2009 21:29:25 +0100 Subject: mesa: Reverse s8z24 into z24s8 as required by EXT_packed_depth_stencil. Actually, after spotting this problem, I realized this is unreachable code. However don't bother to enable this fast path now, given the normal path is working just fine. --- src/mesa/state_tracker/st_cb_readpixels.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 86baf3ddef..ccf1a0b563 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -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); -- cgit v1.2.3 From 96aca15c9d5b6f03fc9b407f02d6966fffeb4f5d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 11 Jun 2009 11:47:20 +0100 Subject: meas: Use a read/write transfer when writing stencil component, but not touching the depth component. --- src/mesa/state_tracker/st_cb_drawpixels.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index d92d29e961..588daf79b2 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,6 +727,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] << 8) | (sValues[k] & 0xff); } @@ -724,6 +735,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] & 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( ptDraw->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: -- cgit v1.2.3 From 48d816b8fff5d01b8c35bd2f933220e41d976e4c Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 11 Jun 2009 12:23:09 +0100 Subject: mesa: Take the format from the right structure. --- src/mesa/state_tracker/st_cb_drawpixels.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 588daf79b2..b674e6b74a 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -840,7 +840,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); - if(pf_get_component_bits( ptDraw->format, PIPE_FORMAT_COMP_Z ) != 0) + if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0) usage = PIPE_TRANSFER_READ_WRITE; else usage = PIPE_TRANSFER_WRITE; -- cgit v1.2.3 From 41cf68153568d4e75ff3cda627293d101f8a8003 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 11 Jun 2009 15:37:53 +0100 Subject: mesa: Only do read write when we don't have a depth value to write --- src/mesa/state_tracker/st_cb_drawpixels.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index b674e6b74a..04cf673f63 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -643,7 +643,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, y = ctx->DrawBuffer->Height - y - height; } - if(format == GL_DEPTH_STENCIL && + if(format != GL_DEPTH_STENCIL && pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0) usage = PIPE_TRANSFER_READ_WRITE; else -- cgit v1.2.3 From bb0b954f1265bd6e50ef1fdade7917863477fa8c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 11 Jun 2009 10:40:19 -0600 Subject: st/mesa: fix typo s/BFC0/BFC1/ --- src/mesa/state_tracker/st_atom_shader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index fc1ff5be04..cb869c98a3 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -237,8 +237,8 @@ find_translated_vp(struct st_context *st, } if (emitBFC1) { xvp->output_to_slot[VERT_RESULT_BFC1] = numVpOuts++; - xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR; - xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 1; + xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR; + xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1; } /* Unneeded vertex program outputs will go to this slot. -- cgit v1.2.3 From 862c7b8cd34ff5606465b97b09fd5fafda50c33b Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 11 Jun 2009 18:50:36 +0100 Subject: mesa: Remove dead code. --- src/mesa/state_tracker/st_cb_drawpixels.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 04cf673f63..2027b713ce 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -769,7 +769,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, struct st_vertex_program *stvp; struct st_context *st = ctx->st; struct pipe_surface *ps; - GLuint bufferFormat; const GLfloat *color; if (format == GL_STENCIL_INDEX || @@ -797,8 +796,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, color = NULL; } - bufferFormat = ps->format; - /* draw with textured quad */ { struct pipe_texture *pt -- cgit v1.2.3 From 7cafd49c936ba9727c3077af8c84afe81b6fa0b4 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 11 Jun 2009 18:52:17 +0100 Subject: mesa: Use PIPE_TEXTURE_USAGE_DEPTH_STENCIL for any depth or stencil format. --- src/mesa/state_tracker/st_format.c | 14 +++++++++----- src/mesa/state_tracker/st_format.h | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index d507e3e58d..b243c249e3 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -392,7 +392,7 @@ default_depth_format(struct pipe_screen *screen, * or PIPE_TEXTURE_USAGE_SAMPLER */ enum pipe_format -st_choose_format(struct pipe_context *pipe, GLint internalFormat, +st_choose_format(struct pipe_context *pipe, GLenum internalFormat, enum pipe_texture_target target, unsigned tex_usage) { struct pipe_screen *screen = pipe->screen; @@ -594,9 +594,13 @@ st_choose_format(struct pipe_context *pipe, GLint internalFormat, static GLboolean -is_stencil_format(GLenum format) +is_depth_or_stencil_format(GLenum internalFormat) { - switch (format) { + switch (internalFormat) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: case GL_STENCIL_INDEX: case GL_STENCIL_INDEX1_EXT: case GL_STENCIL_INDEX4_EXT: @@ -614,10 +618,10 @@ is_stencil_format(GLenum format) * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces. */ enum pipe_format -st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat) +st_choose_renderbuffer_format(struct pipe_context *pipe, GLenum internalFormat) { uint usage; - if (is_stencil_format(internalFormat)) + if (is_depth_or_stencil_format(internalFormat)) usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; else usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 7bbbe2d570..9d9e02fe9b 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -64,11 +64,11 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat); extern enum pipe_format -st_choose_format(struct pipe_context *pipe, GLint internalFormat, +st_choose_format(struct pipe_context *pipe, GLenum internalFormat, enum pipe_texture_target target, unsigned tex_usage); extern enum pipe_format -st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat); +st_choose_renderbuffer_format(struct pipe_context *pipe, GLenum internalFormat); extern const struct gl_texture_format * -- cgit v1.2.3 From de413b1ba9f30771bceacdbc160192d964a1ca63 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 11 Jun 2009 18:53:47 +0100 Subject: mesa: Use new pf_is_depth_and_stencil inline. --- src/mesa/state_tracker/st_cb_clear.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 880e83108c..668acbccb8 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -103,20 +103,6 @@ st_destroy_clear(struct st_context *st) } -static GLboolean -is_depth_stencil_format(enum pipe_format pipeFormat) -{ - switch (pipeFormat) { - case PIPE_FORMAT_S8Z24_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - - /** * Draw a screen-aligned quadrilateral. * Coords are window coords with y=0=bottom. These will be passed @@ -331,7 +317,7 @@ static INLINE GLboolean check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) { const struct st_renderbuffer *strb = st_renderbuffer(rb); - const GLboolean isDS = is_depth_stencil_format(strb->surface->format); + const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format); if (ctx->Scissor.Enabled) return TRUE; @@ -351,7 +337,7 @@ static INLINE GLboolean check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) { const struct st_renderbuffer *strb = st_renderbuffer(rb); - const GLboolean isDS = is_depth_stencil_format(strb->surface->format); + const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format); const GLuint stencilMax = (1 << rb->StencilBits) - 1; const GLboolean maskStencil = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; -- cgit v1.2.3 From 3754c4135cb29e23bd81d573af458742e9a624b2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 11 Jun 2009 14:55:25 -0600 Subject: mesa: rework vertex shader output / fragment shader input attribute matching Before, if a vertex shader's outputs didn't exactly match a fragment shader's inputs we could wind up with invalid TGSI shader declarations. For example: Before patch: DCL OUT[0], POSITION DCL OUT[1], COLOR[1] DCL OUT[2], GENERIC[0] DCL OUT[3], GENERIC[0] <- note duplicate [0] DCL OUT[4], GENERIC[2] After patch: DCL OUT[0], POSITION DCL OUT[1], COLOR[1] DCL OUT[2], GENERIC[0] DCL OUT[3], GENERIC[1] DCL OUT[4], GENERIC[2] --- src/mesa/state_tracker/st_atom_shader.c | 53 ++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index cb869c98a3..ee649be885 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -175,11 +175,12 @@ find_translated_vp(struct st_context *st, /* See if we need to translate vertex program to TGSI form */ if (xvp->serialNo != stvp->serialNo) { - GLuint outAttr, dummySlot; + GLuint outAttr; const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten; GLuint numVpOuts = 0; GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE; - GLint maxGeneric; + GLbitfield usedGenerics = 0x0; + GLbitfield usedOutputSlots = 0x0; /* Compute mapping of vertex program outputs to slots, which depends * on the fragment program's input->slot mapping. @@ -192,10 +193,12 @@ find_translated_vp(struct st_context *st, if (outAttr == VERT_RESULT_HPOS) { /* always put xformed position into slot zero */ - xvp->output_to_slot[VERT_RESULT_HPOS] = 0; + GLuint slot = 0; + xvp->output_to_slot[VERT_RESULT_HPOS] = slot; xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION; xvp->output_to_semantic_index[outAttr] = 0; numVpOuts++; + usedOutputSlots |= (1 << slot); } else if (outputsWritten & (1 << outAttr)) { /* see if the frag prog wants this vert output */ @@ -209,6 +212,12 @@ find_translated_vp(struct st_context *st, xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot]; xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot]; numVpOuts++; + usedOutputSlots |= (1 << vpOutSlot); + } + else { +#if 0 /*debug*/ + printf("VP output %d not used by FP\n", outAttr); +#endif } } else if (outAttr == VERT_RESULT_PSIZ) @@ -226,45 +235,49 @@ find_translated_vp(struct st_context *st, /* must do these last */ if (emitPntSize) { - xvp->output_to_slot[VERT_RESULT_PSIZ] = numVpOuts++; + GLuint slot = numVpOuts++; + xvp->output_to_slot[VERT_RESULT_PSIZ] = slot; xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE; xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0; + usedOutputSlots |= (1 << slot); } if (emitBFC0) { - xvp->output_to_slot[VERT_RESULT_BFC0] = numVpOuts++; + GLuint slot = numVpOuts++; + xvp->output_to_slot[VERT_RESULT_BFC0] = slot; xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR; xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0; + usedOutputSlots |= (1 << slot); } if (emitBFC1) { - xvp->output_to_slot[VERT_RESULT_BFC1] = numVpOuts++; + GLuint slot = numVpOuts++; + xvp->output_to_slot[VERT_RESULT_BFC1] = slot; xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR; xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1; + usedOutputSlots |= (1 << slot); } - /* Unneeded vertex program outputs will go to this slot. - * We could use this info to do dead code elimination in the - * vertex program. - */ - dummySlot = numVpOuts; - - /* find max GENERIC slot index */ - maxGeneric = -1; + /* build usedGenerics mask */ + usedGenerics = 0x0; for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) { - maxGeneric = MAX2(maxGeneric, - xvp->output_to_semantic_index[outAttr]); + usedGenerics |= (1 << xvp->output_to_semantic_index[outAttr]); } } - /* Map vert program outputs that aren't used to the dummy slot - * (and an unused generic attribute slot). + /* For each vertex program output that doesn't match up to a fragment + * program input, map the vertex program output to a free slot and + * free generic attribute. */ for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { if (outputsWritten & (1 << outAttr)) { if (xvp->output_to_slot[outAttr] == UNUSED) { - xvp->output_to_slot[outAttr] = dummySlot; + GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1; + GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1; + usedGenerics |= (1 << freeGeneric); + usedOutputSlots |= (1 << freeSlot); + xvp->output_to_slot[outAttr] = freeSlot; xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC; - xvp->output_to_semantic_index[outAttr] = maxGeneric + 1; + xvp->output_to_semantic_index[outAttr] = freeGeneric; } } -- cgit v1.2.3