From 5d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60ab Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 4 Jan 2012 13:30:35 -0700 Subject: [PATCH] st/mesa: remove st_TexImage(), use core Mesa code instead The core Mesa code does the equivalent memory allocation, image mapping, storing and unmapping. We just need to call prep_teximage() first to handle the 'surface_based' stuff. The other change is to always use the level=0 mipmap image when accessing individual mipmap level images that are stored in resources/buffers. Apparently, we were always using malloc'd memory for individual mipmap images, not resource buffers, before. Signed-off-by: Brian Paul --- src/mesa/state_tracker/st_cb_texture.c | 272 +++---------------------- src/mesa/state_tracker/st_texture.c | 11 +- 2 files changed, 41 insertions(+), 242 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index a6d30ece28d..82717ece25e 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -415,8 +415,6 @@ guess_and_alloc_texture(struct st_context *st, * Called via ctx->Driver.AllocTextureImageBuffer(). * If the texture object/buffer already has space for the indicated image, * we're done. Otherwise, allocate memory for the new texture image. - * XXX This function and st_TexImage() have some duplicated code. That - * can be cleaned up in the future. */ static GLboolean st_AllocTextureImageBuffer(struct gl_context *ctx, @@ -471,7 +469,10 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, } else { /* Create a new, temporary texture/resource/buffer to hold this - * one texture image. + * one texture image. Note that when we later access this image + * (either for mapping or copying) we'll want to always specify + * mipmap level=0, even if the image represents some other mipmap + * level. */ enum pipe_format format = st_mesa_format_to_pipe_format(texImage->TexFormat); @@ -531,227 +532,6 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, } -/** - * Do glTexImage1/2/3D(). - */ -static void -st_TexImage(struct gl_context * ctx, - GLint dims, - struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *unpack, - GLsizei imageSize, GLboolean compressed_src) -{ - struct st_context *st = st_context(ctx); - struct gl_texture_object *texObj = texImage->TexObject; - struct st_texture_object *stObj = st_texture_object(texObj); - struct st_texture_image *stImage = st_texture_image(texImage); - const GLenum target = texObj->Target; - const GLuint level = texImage->Level; - GLuint dstRowStride = 0; - enum pipe_transfer_usage transfer_usage = 0; - GLubyte *dstMap; - - DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); - - prep_teximage(ctx, texImage, internalFormat, width, height, depth, border, - format, type); - - assert(texImage->Width == width); - assert(texImage->Height == height); - assert(texImage->Depth == depth); - - /* Release the reference to a potentially orphaned buffer. - * Release any old malloced memory. - */ - if (stImage->pt) { - pipe_resource_reference(&stImage->pt, NULL); - assert(!stImage->TexData); - } - else if (stImage->TexData) { - _mesa_align_free(stImage->TexData); - } - - /* - * See if the new image is somehow incompatible with the existing - * mipmap. If so, free the old mipmap. - */ - if (stObj->pt) { - if (level > (GLint) stObj->pt->last_level || - !st_texture_match_image(stObj->pt, &stImage->base)) { - DBG("release it\n"); - pipe_resource_reference(&stObj->pt, NULL); - assert(!stObj->pt); - pipe_sampler_view_reference(&stObj->sampler_view, NULL); - } - } - - if (width == 0 || height == 0 || depth == 0) { - /* stop after freeing old image */ - return; - } - - if (!stObj->pt) { - if (!guess_and_alloc_texture(st, stObj, stImage)) { - /* Probably out of memory. - * Try flushing any pending rendering, then retry. - */ - st_finish(st); - if (!guess_and_alloc_texture(st, stObj, stImage)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - return; - } - } - } - - assert(!stImage->pt); - - /* Check if this texture image can live inside the texture object's buffer. - * If so, store the image there. Otherwise the image will temporarily live - * in its own buffer. - */ - if (stObj->pt && - st_texture_match_image(stObj->pt, &stImage->base)) { - - pipe_resource_reference(&stImage->pt, stObj->pt); - assert(stImage->pt); - } - - if (!stImage->pt) - DBG("XXX: Image did not fit into texture - storing in local memory!\n"); - - /* Pixel data may come from regular user memory or a PBO. For the later, - * do bounds checking and map the PBO to read pixels data from it. - * - * XXX we should try to use a GPU-accelerated path to copy the image data - * from the PBO to the texture. - */ - if (compressed_src) { - pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, - unpack, - "glCompressedTexImage"); - } - else { - pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, - format, type, - pixels, unpack, "glTexImage"); - } - - /* for a 1D array upload the image as a series of layer with height = 1 */ - if (target == GL_TEXTURE_1D_ARRAY) { - depth = height; - height = 1; - } - - /* - * Prepare to store the texture data. Either map the gallium texture buffer - * memory or malloc space for it. - */ - if (stImage->pt) { - if (!pixels) { - /* We've allocated texture resource, but have no pixel data - all done. */ - goto done; - } - - /* Store the image in the gallium transfer object */ - if (format == GL_DEPTH_COMPONENT && - util_format_is_depth_and_stencil(stImage->pt->format)) - transfer_usage = PIPE_TRANSFER_READ_WRITE; - else - transfer_usage = PIPE_TRANSFER_WRITE; - - dstMap = st_texture_image_map(st, stImage, 0, - transfer_usage, 0, 0, width, height); - if(stImage->transfer) - dstRowStride = stImage->transfer->stride; - } - else { - /* Allocate regular memory and store the image there temporarily. */ - GLuint imageSize = _mesa_format_image_size(texImage->TexFormat, - width, height, depth); - dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width); - - stImage->TexData = _mesa_align_malloc(imageSize, 16); - dstMap = stImage->TexData; - } - - if (!dstMap) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - return; - } - - if (!pixels) { - /* We've allocated texture memory, but have no pixel data - all done. */ - goto done; - } - - DBG("Upload image %dx%dx%d row_len %x pitch %x\n", - width, height, depth, width, dstRowStride); - - /* Copy user texture image into the mapped texture buffer. - */ - if (compressed_src) { - const GLuint srcRowStride = - _mesa_format_row_stride(texImage->TexFormat, width); - if (dstRowStride == srcRowStride) { - memcpy(dstMap, pixels, imageSize); - } - else { - GLubyte *dst = dstMap; - const char *src = pixels; - GLuint i, bw, bh, lines; - _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); - lines = (height + bh - 1) / bh; - - for (i = 0; i < lines; ++i) { - memcpy(dst, src, srcRowStride); - dst += dstRowStride; - src += srcRowStride; - } - } - } - else { - const GLuint srcImageStride = - _mesa_image_image_stride(unpack, width, height, format, type); - GLint i; - const GLubyte *src = (const GLubyte *) pixels; - - for (i = 0; i < depth; i++) { - if (!_mesa_texstore(ctx, dims, - texImage->_BaseFormat, - texImage->TexFormat, - dstRowStride, - (GLubyte **) &dstMap, /* dstSlice */ - width, height, 1, - format, type, src, unpack)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - } - - if (stImage->pt && i + 1 < depth) { - /* unmap this slice */ - st_texture_image_unmap(st, stImage); - /* map next slice of 3D texture */ - dstMap = st_texture_image_map(st, stImage, i + 1, - transfer_usage, 0, 0, - width, height); - src += srcImageStride; - } - } - } - -done: - _mesa_unmap_teximage_pbo(ctx, unpack); - - if (stImage->pt && stImage->transfer) { - st_texture_image_unmap(st, stImage); - } -} - - static void st_TexImage3D(struct gl_context * ctx, struct gl_texture_image *texImage, @@ -761,8 +541,10 @@ st_TexImage3D(struct gl_context * ctx, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack) { - st_TexImage(ctx, 3, texImage, internalFormat, width, height, depth, border, - format, type, pixels, unpack, 0, GL_FALSE); + prep_teximage(ctx, texImage, internalFormat, width, height, depth, border, + format, type); + _mesa_store_teximage3d(ctx, texImage, internalFormat, width, height, depth, + border, format, type, pixels, unpack); } @@ -774,8 +556,10 @@ st_TexImage2D(struct gl_context * ctx, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack) { - st_TexImage(ctx, 2, texImage, internalFormat, width, height, 1, border, - format, type, pixels, unpack, 0, GL_FALSE); + prep_teximage(ctx, texImage, internalFormat, width, height, 1, border, + format, type); + _mesa_store_teximage2d(ctx, texImage, internalFormat, width, height, + border, format, type, pixels, unpack); } @@ -787,8 +571,10 @@ st_TexImage1D(struct gl_context * ctx, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack) { - st_TexImage(ctx, 1, texImage, internalFormat, width, 1, 1, border, - format, type, pixels, unpack, 0, GL_FALSE); + prep_teximage(ctx, texImage, internalFormat, width, 1, 1, border, + format, type); + _mesa_store_teximage1d(ctx, texImage, internalFormat, width, + border, format, type, pixels, unpack); } @@ -799,8 +585,10 @@ st_CompressedTexImage2D(struct gl_context *ctx, GLint width, GLint height, GLint border, GLsizei imageSize, const GLvoid *data) { - st_TexImage(ctx, 2, texImage, internalFormat, width, height, 1, border, - 0, 0, data, &ctx->Unpack, imageSize, GL_TRUE); + prep_teximage(ctx, texImage, internalFormat, width, 1, 1, border, + GL_NONE, GL_NONE); + _mesa_store_compressed_teximage2d(ctx, texImage, internalFormat, width, + height, border, imageSize, data); } @@ -1451,9 +1239,15 @@ copy_image_data_to_texture(struct st_context *st, if (stImage->pt) { /* Copy potentially with the blitter: */ + GLuint src_level; + if (stImage->pt != stObj->pt) + src_level = 0; + else + src_level = stImage->base.Level; + st_texture_image_copy(st->pipe, stObj->pt, dstLevel, /* dest texture, level */ - stImage->pt, stImage->base.Level, /* src texture, level */ + stImage->pt, src_level, /* src texture, level */ stImage->base.Face); pipe_resource_reference(&stImage->pt, NULL); @@ -1650,13 +1444,11 @@ st_get_default_texture(struct st_context *st) 16, 16, 1, 0, /* w, h, d, border */ GL_RGBA, MESA_FORMAT_RGBA8888); - st_TexImage(st->ctx, 2, - texImg, - GL_RGBA, /* level, intformat */ - 16, 16, 1, 0, /* w, h, d, border */ - GL_RGBA, GL_UNSIGNED_BYTE, pixels, - &st->ctx->DefaultPacking, - 0, GL_FALSE); + _mesa_store_teximage2d(st->ctx, texImg, + GL_RGBA, /* level, intformat */ + 16, 16, 1, /* w, h, d, border */ + GL_RGBA, GL_UNSIGNED_BYTE, pixels, + &st->ctx->DefaultPacking); texObj->Sampler.MinFilter = GL_NEAREST; texObj->Sampler.MagFilter = GL_NEAREST; diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 3323bbbbe4c..132d7a81c63 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -215,12 +215,19 @@ 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 st_texture_object *stObj = + st_texture_object(stImage->base.TexObject); struct pipe_context *pipe = st->pipe; - struct pipe_resource *pt = stImage->pt; + GLuint level; DBG("%s \n", __FUNCTION__); - stImage->transfer = pipe_get_transfer(st->pipe, pt, stImage->base.Level, + if (stObj->pt != stImage->pt) + level = 0; + else + level = stImage->base.Level; + + stImage->transfer = pipe_get_transfer(st->pipe, stImage->pt, level, stImage->base.Face + zoffset, usage, x, y, w, h); -- 2.30.2