[Mesa-dev] [PATCH] mesa: consolidate texstore functions
Jose Fonseca
jfonseca at vmware.com
Thu Dec 22 08:15:47 PST 2011
Looks good to me.
Jose
----- Original Message -----
> From: Brian Paul <brianp at vmware.com>
>
> The code for storing 1D, 2D and 3D tex images (whole or sub-images)
> was
> all pretty similar. This consolidates those six paths.
>
> v2: rework switch statement to catch unexpected targets
> ---
> src/mesa/main/texstore.c | 484
> +++++++++++++++-------------------------------
> 1 files changed, 153 insertions(+), 331 deletions(-)
>
> diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
> index fb1ad04..86c35d3 100644
> --- a/src/mesa/main/texstore.c
> +++ b/src/mesa/main/texstore.c
> @@ -4565,9 +4565,137 @@ get_read_write_mode(GLenum userFormat,
> gl_format texFormat)
> return GL_MAP_WRITE_BIT;
> }
>
> +
> +/**
> + * Helper function for storing 1D, 2D, 3D whole and subimages into
> texture
> + * memory.
> + * The source of the image data may be user memory or a PBO. In the
> later
> + * case, we'll map the PBO, copy from it, then unmap it.
> + */
> +static void
> +store_texsubimage(struct gl_context *ctx,
> + struct gl_texture_image *texImage,
> + GLint xoffset, GLint yoffset, GLint zoffset,
> + GLint width, GLint height, GLint depth,
> + GLenum format, GLenum type, const GLvoid *pixels,
> + const struct gl_pixelstore_attrib *packing,
> + const char *caller)
> +
> +{
> + const GLbitfield mapMode = get_read_write_mode(format,
> texImage->TexFormat);
> + const GLenum target = texImage->TexObject->Target;
> + GLboolean success = GL_FALSE;
> + GLuint dims, slice, numSlices = 1, sliceOffset = 0;
> + GLint srcImageStride = 0;
> + const GLubyte *src;
> +
> + assert(xoffset + width <= texImage->Width);
> + assert(yoffset + height <= texImage->Height);
> + assert(zoffset + depth <= texImage->Depth);
> +
> + switch (target) {
> + case GL_TEXTURE_1D:
> + dims = 1;
> + break;
> + case GL_TEXTURE_2D_ARRAY:
> + case GL_TEXTURE_3D:
> + dims = 3;
> + break;
> + default:
> + dims = 2;
> + }
> +
> + /* get pointer to src pixels (may be in a pbo which we'll map
> here) */
> + src = (const GLubyte *)
> + _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
> + format, type, pixels, packing,
> caller);
> + if (!src)
> + return;
> +
> + /* compute slice info (and do some sanity checks) */
> + switch (target) {
> + case GL_TEXTURE_2D:
> + case GL_TEXTURE_RECTANGLE:
> + case GL_TEXTURE_CUBE_MAP:
> + /* one image slice, nothing special needs to be done */
> + break;
> + case GL_TEXTURE_1D:
> + assert(height == 1);
> + assert(depth == 1);
> + assert(yoffset == 0);
> + assert(zoffset == 0);
> + break;
> + case GL_TEXTURE_1D_ARRAY:
> + assert(depth == 1);
> + assert(zoffset == 0);
> + numSlices = height;
> + sliceOffset = yoffset;
> + height = 1;
> + yoffset = 0;
> + srcImageStride = _mesa_image_row_stride(packing, width,
> format, type);
> + break;
> + case GL_TEXTURE_2D_ARRAY:
> + numSlices = depth;
> + sliceOffset = zoffset;
> + depth = 1;
> + zoffset = 0;
> + srcImageStride = _mesa_image_image_stride(packing, width,
> height,
> + format, type);
> + break;
> + case GL_TEXTURE_3D:
> + /* we'll store 3D images as a series of slices */
> + numSlices = depth;
> + sliceOffset = zoffset;
> + srcImageStride = _mesa_image_image_stride(packing, width,
> height,
> + format, type);
> + break;
> + default:
> + _mesa_warning(ctx, "Unexpected target 0x%x in
> store_texsubimage()", target);
> + return;
> + }
> +
> + assert(numSlices == 1 || srcImageStride != 0);
> +
> + for (slice = 0; slice < numSlices; slice++) {
> + GLubyte *dstMap;
> + GLint dstRowStride;
> +
> + ctx->Driver.MapTextureImage(ctx, texImage,
> + slice + sliceOffset,
> + xoffset, yoffset, width, height,
> + mapMode, &dstMap, &dstRowStride);
> + if (dstMap) {
> + /* Note: we're only storing a 2D (or 1D) slice at a time
> but we need
> + * to pass the right 'dims' value so that
> GL_UNPACK_SKIP_IMAGES is
> + * used for 3D images.
> + */
> + success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
> + texImage->TexFormat,
> + 0, 0, 0, /* dstX/Y/Zoffset */
> + dstRowStride,
> + &dstMap,
> + width, height, 1, /* w, h, d */
> + format, type, src, packing);
> +
> + ctx->Driver.UnmapTextureImage(ctx, texImage, slice +
> sliceOffset);
> + }
> +
> + src += srcImageStride;
> +
> + if (!success)
> + break;
> + }
> +
> + if (!success)
> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
> +
> + _mesa_unmap_teximage_pbo(ctx, packing);
> +}
> +
> +
> +
> /**
> - * This is the software fallback for Driver.TexImage1D().
> - * \sa _mesa_store_teximage2d()
> + * This is the fallback for Driver.TexImage1D().
> */
> void
> _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint
> level,
> @@ -4578,13 +4706,6 @@ _mesa_store_teximage1d(struct gl_context *ctx,
> GLenum target, GLint level,
> struct gl_texture_object *texObj,
> struct gl_texture_image *texImage)
> {
> - const GLbitfield rwMode = get_read_write_mode(format,
> texImage->TexFormat);
> - GLubyte *dstMap;
> - GLint dstRowStride;
> - GLboolean success;
> -
> - (void) border;
> -
> if (width == 0)
> return;
>
> @@ -4595,47 +4716,14 @@ _mesa_store_teximage1d(struct gl_context
> *ctx, GLenum target, GLint level,
> return;
> }
>
> - pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format,
> type,
> - pixels, packing,
> "glTexImage1D");
> - if (!pixels) {
> - /* Note: we check for a NULL image pointer here, _after_ we
> allocated
> - * memory for the texture. That's what the GL spec calls for.
> - */
> - return;
> - }
> -
> - /* Map dest texture buffer (write to whole region) */
> - ctx->Driver.MapTextureImage(ctx, texImage, 0,
> - 0, 0, width, 1,
> - rwMode,
> - &dstMap, &dstRowStride);
> - if (dstMap) {
> - success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
> - texImage->TexFormat,
> - 0, 0, 0, /* dstX/Y/Zoffset */
> - 0, /* dstRowStride */
> - &dstMap,
> - width, 1, 1,
> - format, type, pixels, packing);
> -
> - ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
> - }
> - else {
> - success = GL_FALSE;
> - }
> -
> - if (!success)
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
> -
> - _mesa_unmap_teximage_pbo(ctx, packing);
> + store_texsubimage(ctx, texImage,
> + 0, 0, 0, width, 1, 1,
> + format, type, pixels, packing, "glTexImage1D");
> }
>
>
> /**
> - * This is the software fallback for Driver.TexImage2D().
> - *
> - * This function is oriented toward storing images in main memory,
> rather
> - * than VRAM. Device driver's can easily plug in their own
> replacement.
> + * This is the fallback for Driver.TexImage2D().
> */
> void
> _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint
> level,
> @@ -4646,13 +4734,6 @@ _mesa_store_teximage2d(struct gl_context *ctx,
> GLenum target, GLint level,
> struct gl_texture_object *texObj,
> struct gl_texture_image *texImage)
> {
> - const GLbitfield rwMode = get_read_write_mode(format,
> texImage->TexFormat);
> - GLubyte *dstMap;
> - GLint dstRowStride;
> - GLboolean success;
> -
> - (void) border;
> -
> if (width == 0 || height == 0)
> return;
>
> @@ -4663,80 +4744,15 @@ _mesa_store_teximage2d(struct gl_context
> *ctx, GLenum target, GLint level,
> return;
> }
>
> - pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1,
> format, type,
> - pixels, packing,
> "glTexImage2D");
> - if (!pixels) {
> - /* Note: we check for a NULL image pointer here, _after_ we
> allocated
> - * memory for the texture. That's what the GL spec calls for.
> - */
> - return;
> - }
> -
> - if (target == GL_TEXTURE_1D_ARRAY) {
> - const GLint srcStride =
> - _mesa_image_row_stride(packing, width, format, type);
> - int y;
> -
> - success = GL_TRUE;
> -
> - for (y = 0; y < height; y++) {
> - /* Map dest texture buffer (write to whole region) */
> - ctx->Driver.MapTextureImage(ctx, texImage, y,
> - 0, 0, width, 1,
> - rwMode,
> - &dstMap, &dstRowStride);
> - if (dstMap) {
> - success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
> - texImage->TexFormat,
> - 0, 0, 0, /* dstX/Y/Zoffset */
> - dstRowStride,
> - &dstMap,
> - width, 1, 1,
> - format, type, pixels, packing);
> - ctx->Driver.UnmapTextureImage(ctx, texImage, y);
> - }
> - else {
> - success = GL_FALSE;
> - }
> -
> - if (!success)
> - break;
> -
> - pixels = (const GLubyte *) pixels + srcStride;
> - }
> - } else {
> - /* Map dest texture buffer (write to whole region) */
> - ctx->Driver.MapTextureImage(ctx, texImage, 0,
> - 0, 0, width, height,
> - rwMode,
> - &dstMap, &dstRowStride);
> - if (dstMap) {
> - success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
> - texImage->TexFormat,
> - 0, 0, 0, /* dstX/Y/Zoffset */
> - dstRowStride,
> - &dstMap,
> - width, height, 1,
> - format, type, pixels, packing);
> -
> - ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
> - }
> - else {
> - success = GL_FALSE;
> - }
> - }
> -
> - if (!success)
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
> -
> - _mesa_unmap_teximage_pbo(ctx, packing);
> + store_texsubimage(ctx, texImage,
> + 0, 0, 0, width, height, 1,
> + format, type, pixels, packing, "glTexImage2D");
> }
>
>
>
> /**
> - * This is the software fallback for Driver.TexImage3D().
> - * \sa _mesa_store_teximage2d()
> + * This is the fallback for Driver.TexImage3D().
> */
> void
> _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint
> level,
> @@ -4747,14 +4763,6 @@ _mesa_store_teximage3d(struct gl_context *ctx,
> GLenum target, GLint level,
> struct gl_texture_object *texObj,
> struct gl_texture_image *texImage)
> {
> - const GLbitfield rwMode = get_read_write_mode(format,
> texImage->TexFormat);
> - GLboolean success = GL_TRUE;
> - GLint slice;
> - GLubyte **sliceMaps;
> - GLint dstRowStride;
> -
> - (void) border;
> -
> if (width == 0 || height == 0 || depth == 0)
> return;
>
> @@ -4765,66 +4773,16 @@ _mesa_store_teximage3d(struct gl_context
> *ctx, GLenum target, GLint level,
> return;
> }
>
> - pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height,
> depth,
> - format, type,
> - pixels, packing,
> "glTexImage3D");
> - if (!pixels) {
> - /* Note: we check for a NULL image pointer here, _after_ we
> allocated
> - * memory for the texture. That's what the GL spec calls for.
> - */
> - return;
> - }
> -
> - if (target == GL_TEXTURE_1D_ARRAY) {
> - depth = height;
> - height = 1;
> - }
> -
> - sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
> -
> - /* Map dest texture buffer slices */
> - for (slice = 0; slice < depth; slice++) {
> - ctx->Driver.MapTextureImage(ctx, texImage, slice,
> - 0, 0, width, height,
> - rwMode,
> - &sliceMaps[slice], &dstRowStride);
> - if (!sliceMaps[slice]) {
> - success = GL_FALSE;
> - break;
> - }
> - }
> -
> - if (success) {
> - success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
> - texImage->TexFormat,
> - 0, 0, 0, /* dstX/Y/Zoffset */
> - dstRowStride,
> - sliceMaps,
> - width, height, depth,
> - format, type, pixels, packing);
> - }
> -
> - /* Unmap dest texture buffer slices */
> - for (slice = 0; slice < depth; slice++) {
> - if (sliceMaps[slice]) {
> - ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
> - }
> - }
> -
> - if (!success)
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
> -
> - _mesa_unmap_teximage_pbo(ctx, packing);
> -
> - free(sliceMaps);
> + store_texsubimage(ctx, texImage,
> + 0, 0, 0, width, height, depth,
> + format, type, pixels, packing, "glTexImage3D");
> }
>
>
>
>
> /*
> - * This is the software fallback for Driver.TexSubImage1D()
> - * and Driver.CopyTexSubImage1D().
> + * This is the fallback for Driver.TexSubImage1D().
> */
> void
> _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target,
> GLint level,
> @@ -4834,49 +4792,15 @@ _mesa_store_texsubimage1d(struct gl_context
> *ctx, GLenum target, GLint level,
> struct gl_texture_object *texObj,
> struct gl_texture_image *texImage)
> {
> - const GLbitfield rwMode = get_read_write_mode(format,
> texImage->TexFormat);
> - GLubyte *dstMap;
> - GLint dstRowStride;
> - GLboolean success;
> -
> - /* get pointer to src pixels (may be in a pbo which we'll map
> here) */
> - pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format,
> type,
> - pixels, packing,
> "glTexSubImage1D");
> - if (!pixels)
> - return;
> -
> - /* Map dest texture buffer */
> - ctx->Driver.MapTextureImage(ctx, texImage, 0,
> - xoffset, 0, width, 1,
> - rwMode,
> - &dstMap, &dstRowStride);
> -
> - if (dstMap) {
> - success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
> - texImage->TexFormat,
> - 0, 0, 0, /* dstX/Y/Zoffset */
> - dstRowStride,
> - &dstMap,
> - width, 1, 1,
> - format, type, pixels, packing);
> -
> - ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
> - }
> - else {
> - success = GL_FALSE;
> - }
> -
> - if (!success)
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
> -
> - _mesa_unmap_teximage_pbo(ctx, packing);
> + store_texsubimage(ctx, texImage,
> + xoffset, 0, 0, width, 1, 1,
> + format, type, pixels, packing,
> "glTexSubImage1D");
> }
>
>
>
> /**
> - * This is the software fallback for Driver.TexSubImage2D()
> - * and Driver.CopyTexSubImage2D().
> + * This is the fallback for Driver.TexSubImage2D().
> */
> void
> _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target,
> GLint level,
> @@ -4887,69 +4811,14 @@ _mesa_store_texsubimage2d(struct gl_context
> *ctx, GLenum target, GLint level,
> struct gl_texture_object *texObj,
> struct gl_texture_image *texImage)
> {
> - const GLbitfield rwMode = get_read_write_mode(format,
> texImage->TexFormat);
> - GLboolean success = GL_FALSE;
> - GLuint slice, numSlices, sliceOffset, srcImageStride;
> - const GLubyte *src;
> -
> - /* get pointer to src pixels (may be in a pbo which we'll map
> here) */
> - src = (const GLubyte *)
> - _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format,
> type,
> - pixels, packing,
> "glTexSubImage2D");
> - if (!src)
> - return;
> -
> - if (target == GL_TEXTURE_1D_ARRAY) {
> - /* map each slice of the 1D array separately */
> - numSlices = height;
> - sliceOffset = yoffset;
> - height = 1;
> - yoffset = 0;
> - srcImageStride = _mesa_image_row_stride(packing, width,
> format, type);
> - }
> - else {
> - /* regular 2D image */
> - numSlices = 1;
> - sliceOffset = 0;
> - srcImageStride = 0;
> - }
> -
> - for (slice = 0; slice < numSlices; slice++) {
> - GLubyte *dstMap;
> - GLint dstRowStride;
> -
> - ctx->Driver.MapTextureImage(ctx, texImage,
> - slice + sliceOffset,
> - xoffset, yoffset, width, height,
> - rwMode, &dstMap, &dstRowStride);
> - if (dstMap) {
> - success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
> - texImage->TexFormat,
> - 0, 0, 0, /* dstX/Y/Zoffset */
> - dstRowStride,
> - &dstMap,
> - width, height, 1, /* w, h, d */
> - format, type, src, packing);
> -
> - ctx->Driver.UnmapTextureImage(ctx, texImage, slice +
> sliceOffset);
> - }
> -
> - src += srcImageStride;
> -
> - if (!success)
> - break;
> - }
> -
> - if (!success)
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
> -
> - _mesa_unmap_teximage_pbo(ctx, packing);
> + store_texsubimage(ctx, texImage,
> + xoffset, yoffset, 0, width, height, 1,
> + format, type, pixels, packing,
> "glTexSubImage2D");
> }
>
>
> /*
> - * This is the software fallback for Driver.TexSubImage3D().
> - * and Driver.CopyTexSubImage3D().
> + * This is the fallback for Driver.TexSubImage3D().
> */
> void
> _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target,
> GLint level,
> @@ -4960,56 +4829,9 @@ _mesa_store_texsubimage3d(struct gl_context
> *ctx, GLenum target, GLint level,
> struct gl_texture_object *texObj,
> struct gl_texture_image *texImage)
> {
> - const GLbitfield rwMode = get_read_write_mode(format,
> texImage->TexFormat);
> - GLboolean success = GL_TRUE;
> - GLint slice;
> - GLubyte **sliceMaps;
> - GLint dstRowStride;
> -
> - /* get pointer to src pixels (may be in a pbo which we'll map
> here) */
> - pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height,
> depth, format,
> - type, pixels, packing,
> - "glTexSubImage3D");
> - if (!pixels)
> - return;
> -
> - sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
> -
> - /* Map dest texture buffer slices */
> - for (slice = 0; slice < depth; slice++) {
> - ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
> - xoffset, yoffset, width, height,
> - rwMode,
> - &sliceMaps[slice], &dstRowStride);
> - if (!sliceMaps[slice]) {
> - success = GL_FALSE;
> - break;
> - }
> - }
> -
> - if (success) {
> - success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
> - texImage->TexFormat,
> - 0, 0, 0,
> - dstRowStride,
> - sliceMaps,
> - width, height, depth,
> - format, type, pixels, packing);
> - }
> -
> - /* Unmap dest texture buffer slices */
> - for (slice = 0; slice < depth; slice++) {
> - if (sliceMaps[slice]) {
> - ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset +
> slice);
> - }
> - }
> -
> - if (!success)
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
> -
> - _mesa_unmap_teximage_pbo(ctx, packing);
> -
> - free(sliceMaps);
> + store_texsubimage(ctx, texImage,
> + xoffset, yoffset, zoffset, width, height,
> depth,
> + format, type, pixels, packing,
> "glTexSubImage3D");
> }
>
>
> --
> 1.7.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
More information about the mesa-dev
mailing list