<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 9, 2014 at 4:07 AM, Iago Toral Quiroga <span dir="ltr"><<a href="mailto:itoral@igalia.com" target="_blank">itoral@igalia.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Notice that _mesa_format_convert does not handle byte-swapping scenarios,<br>
GL_COLOR_INDEX or MESA_FORMAT_YCBCR(_REV), so these must be handled<br>
separately.<br>
<br>
Also, remove all the code that goes unused after using _mesa_format_convert.<br>
---<br>
src/mesa/main/texstore.c | 684 +++++------------------------------------------<br>
1 file changed, 71 insertions(+), 613 deletions(-)<br>
<br>
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c<br>
index de9f4df..999a009 100644<br>
--- a/src/mesa/main/texstore.c<br>
+++ b/src/mesa/main/texstore.c<br>
@@ -221,116 +221,6 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,<br>
<br>
<br>
/**<br>
- * Make temporary image with uint pixel values. Used for unsigned<br>
- * integer-valued textures.<br>
- */<br>
-static GLuint *<br>
-make_temp_uint_image(struct gl_context *ctx, GLuint dims,<br>
- GLenum logicalBaseFormat,<br>
- GLenum textureBaseFormat,<br>
- GLint srcWidth, GLint srcHeight, GLint srcDepth,<br>
- GLenum srcFormat, GLenum srcType,<br>
- const GLvoid *srcAddr,<br>
- const struct gl_pixelstore_attrib *srcPacking)<br>
-{<br>
- GLuint *tempImage;<br>
- const GLint components = _mesa_components_in_format(logicalBaseFormat);<br>
- const GLint srcStride =<br>
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);<br>
- GLuint *dst;<br>
- GLint img, row;<br>
-<br>
- ASSERT(dims >= 1 && dims <= 3);<br>
-<br>
- ASSERT(logicalBaseFormat == GL_RGBA ||<br>
- logicalBaseFormat == GL_RGB ||<br>
- logicalBaseFormat == GL_RG ||<br>
- logicalBaseFormat == GL_RED ||<br>
- logicalBaseFormat == GL_LUMINANCE_ALPHA ||<br>
- logicalBaseFormat == GL_LUMINANCE ||<br>
- logicalBaseFormat == GL_INTENSITY ||<br>
- logicalBaseFormat == GL_ALPHA);<br>
-<br>
- ASSERT(textureBaseFormat == GL_RGBA ||<br>
- textureBaseFormat == GL_RGB ||<br>
- textureBaseFormat == GL_RG ||<br>
- textureBaseFormat == GL_RED ||<br>
- textureBaseFormat == GL_LUMINANCE_ALPHA ||<br>
- textureBaseFormat == GL_LUMINANCE ||<br>
- textureBaseFormat == GL_INTENSITY ||<br>
- textureBaseFormat == GL_ALPHA);<br>
-<br>
- tempImage = malloc(srcWidth * srcHeight * srcDepth<br>
- * components * sizeof(GLuint));<br>
- if (!tempImage)<br>
- return NULL;<br>
-<br>
- dst = tempImage;<br>
- for (img = 0; img < srcDepth; img++) {<br>
- const GLubyte *src<br>
- = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,<br>
- srcWidth, srcHeight,<br>
- srcFormat, srcType,<br>
- img, 0, 0);<br>
- for (row = 0; row < srcHeight; row++) {<br>
- _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,<br>
- dst, srcFormat, srcType, src,<br>
- srcPacking);<br>
- dst += srcWidth * components;<br>
- src += srcStride;<br>
- }<br>
- }<br>
-<br>
- if (logicalBaseFormat != textureBaseFormat) {<br>
- /* more work */<br>
- GLint texComponents = _mesa_components_in_format(textureBaseFormat);<br>
- GLint logComponents = _mesa_components_in_format(logicalBaseFormat);<br>
- GLuint *newImage;<br>
- GLint i, n;<br>
- GLubyte map[6];<br>
-<br>
- /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */<br>
- ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||<br>
- textureBaseFormat == GL_LUMINANCE_ALPHA);<br>
-<br>
- /* The actual texture format should have at least as many components<br>
- * as the logical texture format.<br>
- */<br>
- ASSERT(texComponents >= logComponents);<br>
-<br>
- newImage = malloc(srcWidth * srcHeight * srcDepth<br>
- * texComponents * sizeof(GLuint));<br>
- if (!newImage) {<br>
- free(tempImage);<br>
- return NULL;<br>
- }<br>
-<br>
- _mesa_compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);<br>
-<br>
- n = srcWidth * srcHeight * srcDepth;<br>
- for (i = 0; i < n; i++) {<br>
- GLint k;<br>
- for (k = 0; k < texComponents; k++) {<br>
- GLint j = map[k];<br>
- if (j == ZERO)<br>
- newImage[i * texComponents + k] = 0;<br>
- else if (j == ONE)<br>
- newImage[i * texComponents + k] = 1;<br>
- else<br>
- newImage[i * texComponents + k] = tempImage[i * logComponents + j];<br>
- }<br>
- }<br>
-<br>
- free(tempImage);<br>
- tempImage = newImage;<br>
- }<br>
-<br>
- return tempImage;<br>
-}<br>
-<br>
-<br>
-<br>
-/**<br>
* Make a temporary (color) texture image with GLubyte components.<br>
* Apply all needed pixel unpacking and pixel transfer operations.<br>
* Note that there are both logicalBaseFormat and textureBaseFormat parameters.<br>
@@ -518,46 +408,6 @@ memcpy_texture(struct gl_context *ctx,<br>
<br>
<br>
/**<br>
- * General-case function for storing a color texture images with<br>
- * components that can be represented with ubytes. Example destination<br>
- * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.<br>
- */<br>
-static GLboolean<br>
-store_ubyte_texture(TEXSTORE_PARAMS)<br>
-{<br>
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);<br>
- GLubyte *tempImage, *src;<br>
- GLint img;<br>
-<br>
- tempImage = _mesa_make_temp_ubyte_image(ctx, dims,<br>
- baseInternalFormat,<br>
- GL_RGBA,<br>
- srcWidth, srcHeight, srcDepth,<br>
- srcFormat, srcType, srcAddr,<br>
- srcPacking);<br>
- if (!tempImage)<br>
- return GL_FALSE;<br>
-<br>
- /* This way we will use the RGB versions of the packing functions and it<br>
- * will work for both RGB and sRGB textures*/<br>
- dstFormat = _mesa_get_srgb_format_linear(dstFormat);<br>
-<br>
- src = tempImage;<br>
- for (img = 0; img < srcDepth; img++) {<br>
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,<br>
- src, srcRowStride,<br>
- dstSlices[img], dstRowStride);<br>
- src += srcHeight * srcRowStride;<br>
- }<br>
- free(tempImage);<br>
-<br>
- return GL_TRUE;<br>
-}<br>
-<br>
-<br>
-<br>
-<br>
-/**<br>
* Store a 32-bit integer or float depth component texture image.<br>
*/<br>
static GLboolean<br>
@@ -690,56 +540,6 @@ _mesa_texstore_z16(TEXSTORE_PARAMS)<br>
<br>
<br>
/**<br>
- * Store an rgb565 or rgb565_rev texture image.<br>
- */<br>
-static GLboolean<br>
-_mesa_texstore_rgb565(TEXSTORE_PARAMS)<br>
-{<br>
- ASSERT(dstFormat == MESA_FORMAT_B5G6R5_UNORM ||<br>
- dstFormat == MESA_FORMAT_R5G6B5_UNORM);<br>
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);<br>
-<br>
- if (!ctx->_ImageTransferState &&<br>
- !srcPacking->SwapBytes &&<br>
- baseInternalFormat == GL_RGB &&<br>
- srcFormat == GL_RGB &&<br>
- srcType == GL_UNSIGNED_BYTE &&<br>
- dims == 2) {<br>
- /* do optimized tex store */<br>
- const GLint srcRowStride =<br>
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);<br>
- const GLubyte *src = (const GLubyte *)<br>
- _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,<br>
- srcFormat, srcType, 0, 0, 0);<br>
- GLubyte *dst = dstSlices[0];<br>
- GLint row, col;<br>
- for (row = 0; row < srcHeight; row++) {<br>
- const GLubyte *srcUB = (const GLubyte *) src;<br>
- GLushort *dstUS = (GLushort *) dst;<br>
- /* check for byteswapped format */<br>
- if (dstFormat == MESA_FORMAT_B5G6R5_UNORM) {<br>
- for (col = 0; col < srcWidth; col++) {<br>
- dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );<br>
- srcUB += 3;<br>
- }<br>
- }<br>
- else {<br>
- for (col = 0; col < srcWidth; col++) {<br>
- dstUS[col] = PACK_COLOR_565( srcUB[2], srcUB[1], srcUB[0] );<br>
- srcUB += 3;<br>
- }<br>
- }<br>
- dst += dstRowStride;<br>
- src += srcRowStride;<br>
- }<br>
- return GL_TRUE;<br>
- } else {<br>
- return GL_FALSE;<br>
- }<br>
-}<br>
-<br>
-<br>
-/**<br>
* Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.<br>
*/<br>
static GLboolean<br>
@@ -1047,119 +847,6 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)<br>
}<br>
<br>
static GLboolean<br>
-_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)<br>
-{<br>
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);<br>
-<br>
- ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UINT);<br>
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);<br>
-<br>
- {<br>
- /* general path */<br>
- const GLuint *tempImage = make_temp_uint_image(ctx, dims,<br>
- baseInternalFormat,<br>
- baseFormat,<br>
- srcWidth, srcHeight,<br>
- srcDepth, srcFormat,<br>
- srcType, srcAddr,<br>
- srcPacking);<br>
- const GLuint *src = tempImage;<br>
- GLint img, row, col;<br>
- GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);<br>
- if (!tempImage)<br>
- return GL_FALSE;<br>
- for (img = 0; img < srcDepth; img++) {<br>
- GLubyte *dstRow = dstSlices[img];<br>
-<br>
- for (row = 0; row < srcHeight; row++) {<br>
- GLuint *dstUI = (GLuint *) dstRow;<br>
- if (is_unsigned) {<br>
- for (col = 0; col < srcWidth; col++) {<br>
- GLushort a,r,g,b;<br>
- r = MIN2(src[RCOMP], 0x3ff);<br>
- g = MIN2(src[GCOMP], 0x3ff);<br>
- b = MIN2(src[BCOMP], 0x3ff);<br>
- a = MIN2(src[ACOMP], 0x003);<br>
- dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);<br>
- src += 4;<br>
- }<br>
- } else {<br>
- for (col = 0; col < srcWidth; col++) {<br>
- GLushort a,r,g,b;<br>
- r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);<br>
- g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);<br>
- b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);<br>
- a = CLAMP((GLint) src[ACOMP], 0, 0x003);<br>
- dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);<br>
- src += 4;<br>
- }<br>
- }<br>
- dstRow += dstRowStride;<br>
- }<br>
- }<br>
- free((void *) tempImage);<br>
- }<br>
- return GL_TRUE;<br>
-}<br>
-<br>
-static GLboolean<br>
-_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)<br>
-{<br>
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);<br>
-<br>
- ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UINT);<br>
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);<br>
-<br>
- {<br>
- /* general path */<br>
- const GLuint *tempImage = make_temp_uint_image(ctx, dims,<br>
- baseInternalFormat,<br>
- baseFormat,<br>
- srcWidth, srcHeight,<br>
- srcDepth, srcFormat,<br>
- srcType, srcAddr,<br>
- srcPacking);<br>
- const GLuint *src = tempImage;<br>
- GLint img, row, col;<br>
- GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);<br>
- if (!tempImage)<br>
- return GL_FALSE;<br>
- for (img = 0; img < srcDepth; img++) {<br>
- GLubyte *dstRow = dstSlices[img];<br>
-<br>
- for (row = 0; row < srcHeight; row++) {<br>
- GLuint *dstUI = (GLuint *) dstRow;<br>
- if (is_unsigned) {<br>
- for (col = 0; col < srcWidth; col++) {<br>
- GLushort a,r,g,b;<br>
- r = MIN2(src[RCOMP], 0x3ff);<br>
- g = MIN2(src[GCOMP], 0x3ff);<br>
- b = MIN2(src[BCOMP], 0x3ff);<br>
- a = MIN2(src[ACOMP], 0x003);<br>
- dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);<br>
- src += 4;<br>
- }<br>
- } else {<br>
- for (col = 0; col < srcWidth; col++) {<br>
- GLushort a,r,g,b;<br>
- r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);<br>
- g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);<br>
- b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);<br>
- a = CLAMP((GLint) src[ACOMP], 0, 0x003);<br>
- dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);<br>
- src += 4;<br>
- }<br>
- }<br>
- dstRow += dstRowStride;<br>
- }<br>
- }<br>
- free((void *) tempImage);<br>
- }<br>
- return GL_TRUE;<br>
-}<br>
-<br>
-<br>
-static GLboolean<br>
texstore_depth_stencil(TEXSTORE_PARAMS)<br>
{<br>
static StoreTexImageFunc table[MESA_FORMAT_COUNT];<br>
@@ -1248,329 +935,100 @@ texstore_compressed(TEXSTORE_PARAMS)<br>
srcFormat, srcType, srcAddr, srcPacking);<br>
}<br>
<br>
-static void<br>
-invert_swizzle(uint8_t dst[4], const uint8_t src[4])<br>
-{<br>
- int i, j;<br>
-<br>
- dst[0] = MESA_FORMAT_SWIZZLE_NONE;<br>
- dst[1] = MESA_FORMAT_SWIZZLE_NONE;<br>
- dst[2] = MESA_FORMAT_SWIZZLE_NONE;<br>
- dst[3] = MESA_FORMAT_SWIZZLE_NONE;<br>
-<br>
- for (i = 0; i < 4; ++i)<br>
- for (j = 0; j < 4; ++j)<br>
- if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE)<br>
- dst[i] = j;<br>
-}<br>
-<br>
-/** Store a texture by per-channel conversions and swizzling.<br>
- *<br>
- * This function attempts to perform a texstore operation by doing simple<br>
- * per-channel conversions and swizzling. This covers a huge chunk of the<br>
- * texture storage operations that anyone cares about. If this function is<br>
- * incapable of performing the operation, it bails and returns GL_FALSE.<br>
- */<br>
static GLboolean<br>
-texstore_swizzle(TEXSTORE_PARAMS)<br>
+texstore_rgba(TEXSTORE_PARAMS)<br>
{<br>
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,<br>
- srcFormat, srcType);<br>
- const GLint srcImageStride = _mesa_image_image_stride(srcPacking,<br>
- srcWidth, srcHeight, srcFormat, srcType);<br>
- const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dims,<br>
- srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);<br>
- const int src_components = _mesa_components_in_format(srcFormat);<br>
-<br>
- GLubyte swizzle[4], rgba2base[6], base2src[6], rgba2dst[4], dst2rgba[4];<br>
- const GLubyte *swap;<br>
- GLenum dst_type;<br>
- int dst_components;<br>
- bool is_array, normalized, need_swap;<br>
- GLint i, img, row;<br>
- const GLubyte *src_row;<br>
- GLubyte *dst_row;<br>
-<br>
- is_array = _mesa_format_to_array(dstFormat, &dst_type, &dst_components,<br>
- rgba2dst, &normalized);<br>
-<br>
- if (!is_array)<br>
- return GL_FALSE;<br>
-<br>
- if (srcFormat == GL_COLOR_INDEX)<br>
- return GL_FALSE;<br>
-<br>
- if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat))<br>
- return GL_FALSE;<br>
-<br>
- switch (srcType) {<br>
- case GL_FLOAT:<br>
- case GL_UNSIGNED_BYTE:<br>
- case GL_BYTE:<br>
- case GL_UNSIGNED_SHORT:<br>
- case GL_SHORT:<br>
- case GL_UNSIGNED_INT:<br>
- case GL_INT:<br>
- /* If wa have to swap bytes in a multi-byte datatype, that means<br>
- * we're not doing an array conversion anymore */<br>
- if (srcPacking->SwapBytes)<br>
- return GL_FALSE;<br>
- need_swap = false;<br>
- break;<br>
- case GL_UNSIGNED_INT_8_8_8_8:<br>
- need_swap = srcPacking->SwapBytes;<br>
- if (_mesa_little_endian())<br>
- need_swap = !need_swap;<br>
- srcType = GL_UNSIGNED_BYTE;<br>
- break;<br>
- case GL_UNSIGNED_INT_8_8_8_8_REV:<br>
- need_swap = srcPacking->SwapBytes;<br>
- if (!_mesa_little_endian())<br>
- need_swap = !need_swap;<br>
- srcType = GL_UNSIGNED_BYTE;<br>
- break;<br>
- default:<br>
- return GL_FALSE;<br>
- }<br>
- swap = need_swap ? map_3210 : map_identity;<br>
-<br>
- _mesa_compute_component_mapping(srcFormat, baseInternalFormat, base2src);<br>
- _mesa_compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);<br>
- invert_swizzle(dst2rgba, rgba2dst);<br>
-<br>
- for (i = 0; i < 4; i++) {<br>
- if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE)<br>
- swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;<br>
- else<br>
- swizzle[i] = swap[base2src[rgba2base[dst2rgba[i]]]];<br>
- }<br>
-<br>
- /* Is it normalized? */<br>
- normalized |= !_mesa_is_enum_format_integer(srcFormat);<br>
-<br>
- for (img = 0; img < srcDepth; img++) {<br>
- if (dstRowStride == srcWidth * dst_components &&<br>
- srcRowStride == srcWidth * src_components) {<br>
- _mesa_swizzle_and_convert(dstSlices[img], dst_type, dst_components,<br>
- srcImage, srcType, src_components,<br>
- swizzle, normalized, srcWidth * srcHeight);<br>
- } else {<br>
- src_row = srcImage;<br>
- dst_row = dstSlices[img];<br>
- for (row = 0; row < srcHeight; row++) {<br>
- _mesa_swizzle_and_convert(dst_row, dst_type, dst_components,<br>
- src_row, srcType, src_components,<br>
- swizzle, normalized, srcWidth);<br>
- dst_row += dstRowStride;<br>
- src_row += srcRowStride;<br>
- }<br>
- }<br>
- srcImage += srcImageStride;<br>
+ void *tempImage = NULL;<br>
+ int srcRowStride, img;<br>
+ GLubyte *src;<br>
+ uint32_t srcMesaFormat;<br>
+ uint8_t rebaseSwizzle[4];<br>
+ bool needRebase;<br>
+<br>
+ /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case<br>
+ * and _mesa_format_convert does not support it. In this case the we only<br>
+ * allow conversions between YCBCR formats and it is mostly a memcpy.<br>
+ */<br>
+ if (dstFormat == MESA_FORMAT_YCBCR || dstFormat == MESA_FORMAT_YCBCR_REV) {<br>
+ return _mesa_texstore_ycbcr(ctx, dims, baseInternalFormat,<br>
+ dstFormat, dstRowStride, dstSlices,<br>
+ srcWidth, srcHeight, srcDepth,<br>
+ srcFormat, srcType, srcAddr,<br>
+ srcPacking);<br>
}<br>
<br>
- return GL_TRUE;<br>
-}<br>
-<br>
-<br>
-/** Stores a texture by converting float and then to the texture format<br>
- *<br>
- * This function performs a texstore operation by converting to float,<br>
- * applying pixel transfer ops, and then converting to the texture's<br>
- * internal format using pixel store functions. This function will work<br>
- * for any rgb or srgb textore format.<br>
- */<br>
-static GLboolean<br>
-texstore_via_float(TEXSTORE_PARAMS)<br>
-{<br>
- GLuint i, img, row;<br>
- const GLint src_stride =<br>
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);<br>
- float *tmp_row;<br>
- bool need_convert;<br>
- uint8_t *src_row, *dst_row, map[4], rgba2base[6], base2rgba[6];<br>
-<br>
- tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row));<br>
- if (!tmp_row)<br>
- return GL_FALSE;<br>
-<br>
- /* The GL spec (4.0, compatibility profile) only specifies srgb<br>
- * conversion as something that is done in the sampler during the<br>
- * filtering process before the colors are handed to the shader.<br>
- * Furthermore, the flowchart (Figure 3.7 in the 4.0 compatibility spec)<br>
- * does not list RGB <-> sRGB conversions anywhere. Therefore, we just<br>
- * treat sRGB formats the same as RGB formats for the purposes of<br>
- * texture upload and transfer ops.<br>
+ /* We have to deal with GL_COLOR_INDEX manually because<br>
+ * _mesa_format_convert does not handle this format. So what we do here is<br>
+ * convert it to RGBA ubyte first and then convert from that to dst as usual.<br>
*/<br>
- dstFormat = _mesa_get_srgb_format_linear(dstFormat);<br>
-<br>
- need_convert = false;<br>
- if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) {<br>
- _mesa_compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba);<br>
- _mesa_compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);<br>
- for (i = 0; i < 4; ++i) {<br>
- map[i] = base2rgba[rgba2base[i]];<br>
- if (map[i] != i)<br>
- need_convert = true;<br>
- }<br>
- }<br>
+ if (srcFormat == GL_COLOR_INDEX) {<br>
+ /* Notice that this will already handle byte swapping if necessary */<br>
+ tempImage = _mesa_make_temp_ubyte_image(ctx, dims,<br>
+ baseInternalFormat,<br>
+ GL_RGBA,<br>
+ srcWidth, srcHeight, srcDepth,<br>
+ srcFormat, srcType, srcAddr,<br>
+ srcPacking);<br>
+ if (!tempImage)<br>
+ return GL_FALSE;<br>
<br>
- for (img = 0; img < srcDepth; img++) {<br>
- dst_row = dstSlices[img];<br>
- src_row = _mesa_image_address(dims, srcPacking, srcAddr,<br>
- srcWidth, srcHeight,<br>
- srcFormat, srcType,<br>
- img, 0, 0);<br>
- for (row = 0; row < srcHeight; row++) {<br>
- _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, tmp_row,<br>
- srcFormat, srcType, src_row,<br>
- srcPacking, ctx->_ImageTransferState);<br>
- if (need_convert)<br>
- _mesa_swizzle_and_convert(tmp_row, GL_FLOAT, 4,<br>
- tmp_row, GL_FLOAT, 4,<br>
- map, false, srcWidth);<br>
- _mesa_pack_float_rgba_row(dstFormat, srcWidth,<br>
- (const GLfloat (*)[4])tmp_row,<br>
- dst_row);<br>
- dst_row += dstRowStride;<br>
- src_row += src_stride;<br>
+ /* Now we only have to adjust our src info for a conversion from<br>
+ * the RGBA ubyte and then we continue as usual.<br>
+ */<br>
+ srcAddr = tempImage;<br>
+ srcFormat = GL_RGBA;<br>
+ srcType = GL_UNSIGNED_BYTE;<br>
+ } else if (srcPacking->SwapBytes) {<br>
+ /* We have to handle byte-swapping scenarios before calling<br>
+ * _mesa_format_convert<br>
+ */<br>
+ GLint swapSize = _mesa_sizeof_packed_type(srcType);<br>
+ if (swapSize == 2 || swapSize == 4) {<br>
+ int components = _mesa_components_in_format(srcFormat);<br>
+ int elementCount = srcWidth * srcHeight * components;<br>
+ tempImage = malloc(elementCount * swapSize);<br>
+ if (!tempImage)<br>
+ return GL_FALSE;<br>
+ if (swapSize == 2)<br>
+ _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, elementCount);<br>
+ else<br>
+ _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, elementCount);<br>
+ srcAddr = tempImage;<br>
}<br>
}<br>
<br>
- free(tmp_row);<br>
-<br>
- return GL_TRUE;<br>
-}<br>
-<br>
-/** Stores an integer rgba texture<br>
- *<br>
- * This function performs an integer texture storage operation by unpacking<br>
- * the texture to 32-bit integers, and repacking it into the internal<br>
- * format of the texture. This will work for any integer rgb texture<br>
- * storage operation.<br>
- */<br>
-static GLboolean<br>
-texstore_rgba_integer(TEXSTORE_PARAMS)<br>
-{<br>
- GLuint i, img, row, *tmp_row;<br>
- GLenum dst_type, tmp_type;<br>
- const GLint src_stride =<br>
+ srcRowStride =<br>
_mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);<br>
- int num_dst_components;<br>
- bool is_array, normalized;<br>
- uint8_t *src_row, *dst_row;<br>
- uint8_t swizzle[4], rgba2base[6], base2rgba[6], rgba2dst[4], dst2rgba[4];<br>
-<br>
- tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row));<br>
- if (!tmp_row)<br>
- return GL_FALSE;<br>
-<br>
- is_array = _mesa_format_to_array(dstFormat, &dst_type, &num_dst_components,<br>
- rgba2dst, &normalized);<br>
-<br>
- assert(is_array && !normalized);<br>
<br>
- if (!is_array) {<br>
- free(tmp_row);<br>
- return GL_FALSE;<br>
- }<br>
-<br>
- invert_swizzle(dst2rgba, rgba2dst);<br>
- _mesa_compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba);<br>
- _mesa_compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);<br>
+ src = (GLubyte *)<br>
+ _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,<br>
+ srcFormat, srcType, 0, 0, 0);<br>
<br>
- for (i = 0; i < 4; ++i) {<br>
- if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE)<br>
- swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;<br>
- else<br>
- swizzle[i] = base2rgba[rgba2base[dst2rgba[i]]];<br>
- }<br>
+ srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType);<br>
+ dstFormat = _mesa_get_srgb_format_linear(dstFormat);<br>
<br>
- if (_mesa_is_type_unsigned(srcType)) {<br>
- tmp_type = GL_UNSIGNED_INT;<br>
+ if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) {<br>
+ needRebase =<br>
+ _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat,<br>
+ rebaseSwizzle);<br>
} else {<br>
- tmp_type = GL_INT;<br>
+ needRebase = false;<br>
}<br>
<br>
for (img = 0; img < srcDepth; img++) {<br>
- dst_row = dstSlices[img];<br>
- src_row = _mesa_image_address(dims, srcPacking, srcAddr,<br>
- srcWidth, srcHeight,<br>
- srcFormat, srcType,<br>
- img, 0, 0);<br>
- for (row = 0; row < srcHeight; row++) {<br>
- _mesa_unpack_color_span_uint(ctx, srcWidth, GL_RGBA, tmp_row,<br>
- srcFormat, srcType, src_row, srcPacking);<br>
- _mesa_swizzle_and_convert(dst_row, dst_type, num_dst_components,<br>
- tmp_row, tmp_type, 4,<br>
- swizzle, false, srcWidth);<br>
- dst_row += dstRowStride;<br>
- src_row += src_stride;<br>
- }<br>
+ _mesa_format_convert(dstSlices[img], dstFormat, dstRowStride,<br>
+ src, srcMesaFormat, srcRowStride,<br>
+ srcWidth, srcHeight,<br>
+ needRebase ? rebaseSwizzle : NULL);<br>
+ src += srcHeight * srcRowStride;<br>
}<br>
<br>
- free(tmp_row);<br>
+ if (tempImage)<br>
+ free(tempImage);<br></blockquote><div><br></div><div>Don't need the if check here. Otherwise,<br></div><div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
return GL_TRUE;<br>
}<br>
<br>
-static GLboolean<br>
-texstore_rgba(TEXSTORE_PARAMS)<br>
-{<br>
- static StoreTexImageFunc table[MESA_FORMAT_COUNT];<br>
- static GLboolean initialized = GL_FALSE;<br>
-<br>
- if (!initialized) {<br>
- memset(table, 0, sizeof table);<br>
-<br>
- table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565;<br>
- table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565;<br>
- table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;<br>
- table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;<br>
-<br>
- table[MESA_FORMAT_B10G10R10A2_UINT] = _mesa_texstore_argb2101010_uint;<br>
- table[MESA_FORMAT_R10G10B10A2_UINT] = _mesa_texstore_abgr2101010_uint;<br>
-<br>
- initialized = GL_TRUE;<br>
- }<br>
-<br>
- if (table[dstFormat] && table[dstFormat](ctx, dims, baseInternalFormat,<br>
- dstFormat, dstRowStride, dstSlices,<br>
- srcWidth, srcHeight, srcDepth,<br>
- srcFormat, srcType, srcAddr,<br>
- srcPacking)) {<br>
- return GL_TRUE;<br>
- }<br>
-<br>
- if (texstore_swizzle(ctx, dims, baseInternalFormat,<br>
- dstFormat,<br>
- dstRowStride, dstSlices,<br>
- srcWidth, srcHeight, srcDepth,<br>
- srcFormat, srcType, srcAddr, srcPacking)) {<br>
- return GL_TRUE;<br>
- }<br>
-<br>
- if (_mesa_is_format_integer(dstFormat)) {<br>
- return texstore_rgba_integer(ctx, dims, baseInternalFormat,<br>
- dstFormat, dstRowStride, dstSlices,<br>
- srcWidth, srcHeight, srcDepth,<br>
- srcFormat, srcType, srcAddr,<br>
- srcPacking);<br>
- } else if (_mesa_get_format_max_bits(dstFormat) <= 8 &&<br>
- !_mesa_is_format_signed(dstFormat)) {<br>
- return store_ubyte_texture(ctx, dims, baseInternalFormat,<br>
- dstFormat,<br>
- dstRowStride, dstSlices,<br>
- srcWidth, srcHeight, srcDepth,<br>
- srcFormat, srcType, srcAddr, srcPacking);<br>
- } else {<br>
- return texstore_via_float(ctx, dims, baseInternalFormat,<br>
- dstFormat, dstRowStride, dstSlices,<br>
- srcWidth, srcHeight, srcDepth,<br>
- srcFormat, srcType, srcAddr,<br>
- srcPacking);<br>
- }<br>
-}<br>
-<br>
GLboolean<br>
_mesa_texstore_needs_transfer_ops(struct gl_context *ctx,<br>
GLenum baseInternalFormat,<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.9.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div></div></div>