Looks good to me. Jose
----- Original Message ----- > From: Brian Paul <bri...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev