[Mesa-dev] [PATCH 4/7] st/mesa: generalize code for the compressed texture map/unmap fallback

Marek Olšák maraeo at gmail.com
Mon Jul 23 23:52:04 UTC 2018


From: Marek Olšák <marek.olsak at 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



More information about the mesa-dev mailing list