From: Marek Olšák <marek.ol...@amd.com> in order to support ASTC --- src/mesa/state_tracker/st_cb_texture.c | 41 +++++++++++++++----------- src/mesa/state_tracker/st_texture.h | 13 ++++---- 2 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index b345b2c6d8b..ecd1f4ef339 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -200,23 +200,23 @@ st_FreeTextureImageBuffer(struct gl_context *ctx, DBG("%s\n", __func__); if (stImage->pt) { pipe_resource_reference(&stImage->pt, NULL); } free(stImage->transfer); stImage->transfer = NULL; stImage->num_transfers = 0; - if (stImage->etc_data) { - free(stImage->etc_data); - stImage->etc_data = NULL; + if (stImage->compressed_data) { + free(stImage->compressed_data); + stImage->compressed_data = NULL; } /* if the texture image is being deallocated, the structure of the * texture is changing so we'll likely need a new sampler view. */ st_texture_release_all_sampler_views(st, stObj); } bool st_compressed_format_fallback(struct st_context *st, mesa_format format) @@ -224,36 +224,37 @@ st_compressed_format_fallback(struct st_context *st, mesa_format format) if (format == MESA_FORMAT_ETC1_RGB8) return !st->has_etc1; if (_mesa_is_format_etc2(format)) return !st->has_etc2; return false; } static void -etc_fallback_allocate(struct st_context *st, struct st_texture_image *stImage) +compressed_tex_fallback_allocate(struct st_context *st, + struct st_texture_image *stImage) { struct gl_texture_image *texImage = &stImage->base; if (!st_compressed_format_fallback(st, texImage->TexFormat)) return; - if (stImage->etc_data) - free(stImage->etc_data); + if (stImage->compressed_data) + free(stImage->compressed_data); unsigned data_size = _mesa_format_image_size(texImage->TexFormat, texImage->Width2, texImage->Height2, texImage->Depth2); - stImage->etc_data = + stImage->compressed_data = malloc(data_size * _mesa_num_tex_faces(texImage->TexObject->Target)); } /** called via ctx->Driver.MapTextureImage() */ static void st_MapTextureImage(struct gl_context *ctx, struct gl_texture_image *texImage, GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h, GLbitfield mode, GLubyte **mapOut, GLint *rowStrideOut) @@ -268,36 +269,42 @@ st_MapTextureImage(struct gl_context *ctx, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT)) == 0); const enum pipe_transfer_usage transfer_flags = st_access_flags_to_transfer_flags(mode, false); map = st_texture_image_map(st, stImage, transfer_flags, x, y, slice, w, h, 1, &transfer); if (map) { if (st_compressed_format_fallback(st, texImage->TexFormat)) { - /* ETC isn't supported by all gallium drivers, where it's represented - * by uncompressed formats. We store the compressed data (as it's - * needed for image copies in OES_copy_image), and decompress as - * necessary in Unmap. + /* Some compressed formats don't have to be supported by drivers, + * and st/mesa transparently handles decompression on upload (Unmap), + * so that drivers don't see the compressed formats. * - * Note: all ETC1/ETC2 formats have 4x4 block sizes. + * We store the compressed data (it's needed for glGetCompressedTex- + * Image and image copies in OES_copy_image). */ unsigned z = transfer->box.z; struct st_texture_image_transfer *itransfer = &stImage->transfer[z]; - unsigned bytes = _mesa_get_format_bytes(texImage->TexFormat); + unsigned blk_w, blk_h; + _mesa_get_format_block_size(texImage->TexFormat, &blk_w, &blk_h); + + unsigned y_blocks = DIV_ROUND_UP(texImage->Height2, blk_h); unsigned stride = *rowStrideOut = itransfer->temp_stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width2); + unsigned block_size = _mesa_get_format_bytes(texImage->TexFormat); + *mapOut = itransfer->temp_data = - stImage->etc_data + ((x / 4) * bytes + (y / 4) * stride) + - z * stride * texImage->Height2 / 4; + stImage->compressed_data + + (z * y_blocks + (y / blk_h)) * stride + + (x / blk_w) * block_size; itransfer->map = map; } else { /* supported mapping */ *mapOut = map; *rowStrideOut = transfer->stride; } } else { *mapOut = NULL; @@ -624,21 +631,21 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, GLuint width = texImage->Width; GLuint height = texImage->Height; GLuint depth = texImage->Depth; DBG("%s\n", __func__); assert(!stImage->pt); /* xxx this might be wrong */ stObj->needs_validation = true; - etc_fallback_allocate(st, stImage); + compressed_tex_fallback_allocate(st, stImage); /* Look if the parent texture object has space for this image */ if (stObj->pt && level <= stObj->pt->last_level && st_texture_match_image(st, stObj->pt, texImage)) { /* this image will fit in the existing texture object's memory */ pipe_resource_reference(&stImage->pt, stObj->pt); return GL_TRUE; } @@ -2833,21 +2840,21 @@ st_texture_storage(struct gl_context *ctx, return GL_FALSE; /* Set image resource pointers */ for (level = 0; level < levels; level++) { GLuint face; for (face = 0; face < numFaces; face++) { struct st_texture_image *stImage = st_texture_image(texObj->Image[face][level]); pipe_resource_reference(&stImage->pt, stObj->pt); - etc_fallback_allocate(st, stImage); + compressed_tex_fallback_allocate(st, stImage); } } /* The texture is in a validated state, so no need to check later. */ stObj->needs_validation = false; stObj->validated_first_level = 0; stObj->validated_last_level = levels - 1; return GL_TRUE; } diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 82a5bc7797c..726ab78dad4 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -35,23 +35,23 @@ #include "main/mtypes.h" struct pipe_resource; struct st_texture_image_transfer { struct pipe_transfer *transfer; - /* For ETC fallback. */ - GLubyte *temp_data; /**< Temporary ETC texture storage. */ - unsigned temp_stride; /**< Stride of the ETC texture storage. */ + /* For compressed texture fallback. */ + GLubyte *temp_data; /**< Temporary compressed texture storage. */ + unsigned temp_stride; /**< Stride of the compressed texture storage. */ GLubyte *map; /**< Saved map pointer of the uncompressed transfer. */ }; /** * Container for one context's validated sampler view. */ struct st_sampler_view { struct pipe_sampler_view *view; @@ -83,24 +83,25 @@ struct st_texture_image * Else there is no image data. */ struct pipe_resource *pt; /* List of transfers, allocated on demand. * transfer[layer] is a mapping for that layer. */ struct st_texture_image_transfer *transfer; unsigned num_transfers; - /* For ETC images, keep track of the original data. This is necessary for - * mapping/unmapping, as well as image copies. + /* For compressed images unsupported by the driver. Keep track of + * the original data. This is necessary for mapping/unmapping, + * as well as image copies. */ - GLubyte *etc_data; + GLubyte *compressed_data; }; /** * Subclass of gl_texure_object. */ struct st_texture_object { struct gl_texture_object base; /* The "parent" object */ -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev