X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_texture.c;h=e34fd09dcb753f468310695d74e11f2668d30e6d;hb=1975208919a273018a2cda87e765870c5f86d01f;hp=fd801a354b15ba055bec666f8416040e26d54053;hpb=529b7b355d392b1534ccd8ff7b428dc21cbfdc21;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index fd801a354b1..e34fd09dcb7 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -27,9 +27,6 @@ #include "main/mfeatures.h" #include "main/bufferobj.h" -#if FEATURE_convolve -#include "main/convolve.h" -#endif #include "main/enums.h" #include "main/fbobject.h" #include "main/formats.h" @@ -47,11 +44,11 @@ #include "state_tracker/st_debug.h" #include "state_tracker/st_context.h" #include "state_tracker/st_cb_fbo.h" +#include "state_tracker/st_cb_flush.h" #include "state_tracker/st_cb_texture.h" #include "state_tracker/st_format.h" #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" @@ -259,8 +256,9 @@ get_texture_dims(GLenum target) * We use the given st_texture_image as a clue to determine the size of the * mipmap image at level=0. * + * \return GL_TRUE for success, GL_FALSE if out of memory. */ -static void +static GLboolean guess_and_alloc_texture(struct st_context *st, struct st_texture_object *stObj, const struct st_texture_image *stImage) @@ -291,7 +289,8 @@ guess_and_alloc_texture(struct st_context *st, (dims >= 3 && depth == 1) ) { /* we can't determine the image size at level=0 */ stObj->width0 = stObj->height0 = stObj->depth0 = 0; - return; + /* this is not an out of memory error */ + return GL_TRUE; } } @@ -312,10 +311,11 @@ guess_and_alloc_texture(struct st_context *st, * the level=0 mipmap image. */ - /* Guess a reasonable value for lastLevel. This is probably going - * to be wrong fairly often and might mean that we have to look at - * resizable buffers, or require that buffers implement lazy - * pagetable arrangements. + /* Guess a reasonable value for lastLevel. With OpenGL we have no + * idea how many mipmap levels will be in a texture until we start + * to render with it. Make an educated guess here but be prepared + * to re-allocating a texture buffer with space for more (or fewer) + * mipmap levels later. */ if ((stObj->base.MinFilter == GL_NEAREST || stObj->base.MinFilter == GL_LINEAR || @@ -352,7 +352,9 @@ guess_and_alloc_texture(struct st_context *st, depth, bindings); - DBG("%s - success\n", __FUNCTION__); + DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL)); + + return stObj->pt != NULL; } @@ -462,7 +464,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, + tex_xfer = pipe_get_transfer(st_context(ctx)->pipe, src_tex, 0, 0, 0, /* face, level are zero */ PIPE_TRANSFER_WRITE, 0, 0, width, height); /* x, y, w, h */ @@ -528,8 +530,6 @@ st_TexImage(GLcontext * ctx, struct pipe_screen *screen = st->pipe->screen; struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); - GLint postConvWidth, postConvHeight; - GLint texelBytes, sizeInBytes; GLuint dstRowStride = 0; struct gl_pixelstore_attrib unpackNB; enum pipe_transfer_usage transfer_usage = 0; @@ -537,6 +537,12 @@ st_TexImage(GLcontext * ctx, DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); + /* The Mesa/Gallium state tracker does not implement the imaging extensions + * such as convolution. + */ + assert(!ctx->Extensions.ARB_imaging); + assert(!ctx->Extensions.EXT_convolution); + /* switch to "normal" */ if (stObj->surface_based) { _mesa_clear_texture_object(ctx, texObj); @@ -553,39 +559,17 @@ st_TexImage(GLcontext * ctx, texImage->Border = 0; border = 0; } - - postConvWidth = width; - postConvHeight = height; + else { + assert(texImage->Width == width); + assert(texImage->Height == height); + assert(texImage->Depth == depth); + } stImage->face = _mesa_tex_target_to_face(target); stImage->level = level; -#if FEATURE_convolve - if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { - _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, - &postConvHeight); - } -#endif - _mesa_set_fetch_functions(texImage, dims); - if (_mesa_is_format_compressed(texImage->TexFormat)) { - /* must be a compressed format */ - texelBytes = 0; - } - else { - texelBytes = _mesa_get_format_bytes(texImage->TexFormat); - - /* Minimum pitch of 32 bytes */ - if (postConvWidth * texelBytes < 32) { - postConvWidth = 32 / texelBytes; - texImage->RowStride = postConvWidth; - } - - /* we'll set RowStride elsewhere when the texture is a "mapped" state */ - /*assert(texImage->RowStride == postConvWidth);*/ - } - /* Release the reference to a potentially orphaned buffer. * Release any old malloced memory. */ @@ -618,14 +602,12 @@ st_TexImage(GLcontext * ctx, } if (!stObj->pt) { - guess_and_alloc_texture(st, stObj, stImage); - 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); - guess_and_alloc_texture(st, stObj, stImage); - if (!stObj->pt) { + if (!guess_and_alloc_texture(st, stObj, stImage)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); return; } @@ -634,9 +616,13 @@ st_TexImage(GLcontext * ctx, 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, - stImage->face, stImage->level)) { + stImage->face, stImage->level)) { pipe_resource_reference(&stImage->pt, stObj->pt); assert(stImage->pt); @@ -645,9 +631,11 @@ st_TexImage(GLcontext * ctx, if (!stImage->pt) DBG("XXX: Image did not fit into texture - storing in local memory!\n"); - /* st_CopyTexImage calls this function with pixels == NULL, with - * the expectation that the texture will be set up but nothing - * more will be done. This is where those calls return: + /* 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, @@ -660,10 +648,6 @@ st_TexImage(GLcontext * ctx, pixels, unpack, "glTexImage"); } - /* Note: we can't check for pixels==NULL until after we've allocated - * memory for the texture. - */ - /* See if we can do texture compression with a blit/render. */ if (!compressed_src && @@ -682,7 +666,12 @@ st_TexImage(GLcontext * ctx, } } + /* + * Prepare to store the texture data. Either map the gallium texture buffer + * memory or malloc space for it. + */ if (stImage->pt) { + /* Store the image in the gallium texture memory buffer */ if (format == GL_DEPTH_COMPONENT && util_format_is_depth_and_stencil(stImage->pt->format)) transfer_usage = PIPE_TRANSFER_READ_WRITE; @@ -690,28 +679,17 @@ st_TexImage(GLcontext * ctx, transfer_usage = PIPE_TRANSFER_WRITE; texImage->Data = st_texture_image_map(st, stImage, 0, - transfer_usage, 0, 0, - stImage->base.Width, - stImage->base.Height); + transfer_usage, 0, 0, width, height); if(stImage->transfer) dstRowStride = stImage->transfer->stride; } else { /* Allocate regular memory and store the image there temporarily. */ - if (_mesa_is_format_compressed(texImage->TexFormat)) { - sizeInBytes = _mesa_format_image_size(texImage->TexFormat, - texImage->Width, - texImage->Height, - texImage->Depth); - dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width); - assert(dims != 3); - } - else { - dstRowStride = postConvWidth * texelBytes; - sizeInBytes = depth * dstRowStride * postConvHeight; - } + GLuint imageSize = _mesa_format_image_size(texImage->TexFormat, + width, height, depth); + dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width); - texImage->Data = _mesa_align_malloc(sizeInBytes, 16); + texImage->Data = _mesa_align_malloc(imageSize, 16); } if (!texImage->Data) { @@ -719,33 +697,33 @@ st_TexImage(GLcontext * ctx, return; } - if (!pixels) + 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 * texelBytes, dstRowStride); + width, height, depth, width, dstRowStride); - /* Copy data. Would like to know when it's ok for us to eg. use - * the blitter to copy. Or, use the hardware to do the format - * conversion and copy: + /* Copy user texture image into the texture buffer. */ if (compressed_src) { - const GLuint srcImageStride = _mesa_format_row_stride(texImage->TexFormat, width); - if(dstRowStride == srcImageStride) + const GLuint srcRowStride = + _mesa_format_row_stride(texImage->TexFormat, width); + if (dstRowStride == srcRowStride) { memcpy(texImage->Data, pixels, imageSize); - else - { + } + else { char *dst = texImage->Data; 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, srcImageStride); + for (i = 0; i < lines; ++i) { + memcpy(dst, src, srcRowStride); dst += dstRowStride; - src += srcImageStride; + src += srcRowStride; } } } @@ -774,8 +752,7 @@ st_TexImage(GLcontext * ctx, /* map next slice of 3D texture */ texImage->Data = st_texture_image_map(st, stImage, i + 1, transfer_usage, 0, 0, - stImage->base.Width, - stImage->base.Height); + width, height); src += srcImageStride; } } @@ -898,7 +875,7 @@ 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 = st_cond_flush_get_tex_transfer(st_context(ctx), + tex_xfer = pipe_get_transfer(st_context(ctx)->pipe, dst_texture, 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, width, height); @@ -984,11 +961,6 @@ 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. */ - unsigned face = _mesa_tex_target_to_face(target); - - st_teximage_flush_before_map(st, stImage->pt, face, level, - PIPE_TRANSFER_READ); - texImage->Data = st_texture_image_map(st, stImage, 0, PIPE_TRANSFER_READ, 0, 0, stImage->base.Width, @@ -1120,16 +1092,12 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, * from uploading the buffer under us. */ if (stImage->pt) { - unsigned face = _mesa_tex_target_to_face(target); - 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; - st_teximage_flush_before_map(st, stImage->pt, face, level, - transfer_usage); texImage->Data = st_texture_image_map(st, stImage, zoffset, transfer_usage, xoffset, yoffset, @@ -1252,11 +1220,8 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, enum pipe_format pformat; if (stImage->pt) { - unsigned face = _mesa_tex_target_to_face(target); pformat = stImage->pt->format; - st_teximage_flush_before_map(st, stImage->pt, face, level, - PIPE_TRANSFER_WRITE); texImage->Data = st_texture_image_map(st, stImage, 0, PIPE_TRANSFER_WRITE, xoffset, yoffset, @@ -1340,7 +1305,7 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, srcY = strb->Base.Height - srcY - height; } - src_trans = st_cond_flush_get_tex_transfer( st_context(ctx), + src_trans = pipe_get_transfer(st_context(ctx)->pipe, strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, @@ -1354,9 +1319,6 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, else transfer_usage = PIPE_TRANSFER_WRITE; - st_teximage_flush_before_map(st, stImage->pt, 0, 0, - transfer_usage); - texDest = st_texture_image_map(st, stImage, 0, transfer_usage, destX, destY, width, height); @@ -1538,9 +1500,6 @@ st_copy_texsubimage(GLcontext *ctx, struct pipe_surface *dest_surface = NULL; GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); - /* any rendering in progress must flushed before we grab the fb image */ - st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); - /* make sure finalize_textures has been called? */ if (0) st_validate_state(st); @@ -1801,17 +1760,12 @@ copy_image_data_to_texture(struct st_context *st, */ st_texture_image_copy(st->pipe, stObj->pt, dstLevel, /* dest texture, level */ - stImage->pt, /* src texture */ + stImage->pt, stImage->level, /* src texture, level */ stImage->face); pipe_resource_reference(&stImage->pt, NULL); } else if (stImage->base.Data) { - /* More straightforward upload. - */ - st_teximage_flush_before_map(st, stObj->pt, stImage->face, dstLevel, - PIPE_TRANSFER_WRITE); - st_texture_image_data(st, stObj->pt, stImage->face, @@ -1838,8 +1792,7 @@ copy_image_data_to_texture(struct st_context *st, GLboolean st_finalize_texture(GLcontext *ctx, struct pipe_context *pipe, - struct gl_texture_object *tObj, - GLboolean *needFlush) + struct gl_texture_object *tObj) { struct st_context *st = st_context(ctx); struct st_texture_object *stObj = st_texture_object(tObj); @@ -1848,8 +1801,6 @@ st_finalize_texture(GLcontext *ctx, struct st_texture_image *firstImage; enum pipe_format firstImageFormat; - *needFlush = GL_FALSE; - if (stObj->base._Complete) { /* The texture is complete and we know exactly how many mipmap levels * are present/needed. This is conditional because we may be called @@ -1926,7 +1877,7 @@ st_finalize_texture(GLcontext *ctx, */ for (face = 0; face < nr_faces; face++) { GLuint level; - for (level = 0; level <= stObj->lastLevel; level++) { + for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) { struct st_texture_image *stImage = st_texture_image(stObj->base.Image[face][level]); @@ -1934,7 +1885,6 @@ st_finalize_texture(GLcontext *ctx, */ if (stImage && stObj->pt != stImage->pt) { copy_image_data_to_texture(st, stObj, level, stImage); - *needFlush = GL_TRUE; } } }