[Mesa-dev] [PATCH 22/22] intel: Enable ETC2 support on intel hardware

Anuj Phogat anuj.phogat at gmail.com
Fri Nov 9 23:30:09 PST 2012


Formats supported are:
GL_COMPRESSED_RGB8_ETC2
GL_COMPRESSED_SRGB8_ETC2
GL_COMPRESSED_RGBA8_ETC2_EAC
GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
GL_COMPRESSED_R11_EAC
GL_COMPRESSED_RG11_EAC
GL_COMPRESSED_SIGNED_R11_EAC
GL_COMPRESSED_SIGNED_RG11_EAC
GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2

Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
---
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |   14 +++
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c   |   94 +++++++++++++++++++++-
 src/mesa/drivers/dri/intel/intel_mipmap_tree.h   |   25 ++++--
 3 files changed, 122 insertions(+), 11 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 25ee557..5a2ab04 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -557,6 +557,20 @@ brw_init_surface_formats(struct brw_context *brw)
     * during glCompressedTexImage2D(). See intel_mipmap_tree::wraps_etc1.
     */
    ctx->TextureFormatSupported[MESA_FORMAT_ETC1_RGB8] = true;
+
+   /* On hardware that lacks support for ETC2, we map ETC2 to RGBX
+    * during glCompressedTexImage2D(). See intel_mipmap_tree::wraps_etc2.
+    */
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_RGB8] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SRGB8] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_RGBA8_EAC] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_R11_EAC] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_RG11_EAC] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] = true;
 }
 
 bool
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index cd7299e..b50ff69 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -200,11 +200,48 @@ intel_miptree_create(struct intel_context *intel,
    uint32_t tiling = I915_TILING_NONE;
    GLenum base_format;
    bool wraps_etc1 = false;
+   bool wraps_etc2 = false;
+   gl_format etc2_format;
    GLuint total_width, total_height;
 
-   if (format == MESA_FORMAT_ETC1_RGB8) {
-      format = MESA_FORMAT_RGBX8888_REV;
+   switch(format) {
+   case MESA_FORMAT_ETC1_RGB8:
       wraps_etc1 = true;
+      format = MESA_FORMAT_RGBX8888_REV;
+      break;
+   case MESA_FORMAT_ETC2_RGB8:
+      etc2_format = format;
+      wraps_etc2 = true;
+      format = MESA_FORMAT_RGBX8888_REV;
+      break;
+   case MESA_FORMAT_ETC2_SRGB8:
+   case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
+   case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
+      etc2_format = format;
+      wraps_etc2 = true;
+      format = MESA_FORMAT_SARGB8;
+      break;
+   case MESA_FORMAT_ETC2_RGBA8_EAC:
+   case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
+      etc2_format = format;
+      wraps_etc2 = true;
+      format = MESA_FORMAT_RGBA8888_REV;
+      break;
+   case MESA_FORMAT_ETC2_R11_EAC:
+   case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
+      etc2_format = format;
+      wraps_etc2 = true;
+      format = MESA_FORMAT_R16;
+      break;
+   case MESA_FORMAT_ETC2_RG11_EAC:
+   case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
+      etc2_format = format;
+      wraps_etc2 = true;
+      format = MESA_FORMAT_RG1616;
+      break;
+   default:
+      /* Non ETC1 / ETC2 format */
+      break;
    }
 
    base_format = _mesa_get_format_base_format(format);
@@ -258,6 +295,8 @@ intel_miptree_create(struct intel_context *intel,
    }
 
    mt->wraps_etc1 = wraps_etc1;
+   mt->wraps_etc2 = wraps_etc2;
+   mt->etc2_format = etc2_format;
    mt->region = intel_region_alloc(intel->intelScreen,
 				   tiling,
 				   mt->cpp,
@@ -1267,6 +1306,53 @@ intel_miptree_unmap_s8(struct intel_context *intel,
 }
 
 static void
+intel_miptree_map_etc2(struct intel_context *intel,
+                       struct intel_mipmap_tree *mt,
+                       struct intel_miptree_map *map,
+                       unsigned int level,
+                       unsigned int slice)
+{
+   /* For justification of these invariants,
+    * see intel_mipmap_tree:wraps_etc2.
+    */
+   assert(mt->wraps_etc2);
+
+   /* intel_miptree_map_etc2() can be called from glCompressedTexImage2D
+    * and CompressedTexSubImage2D. Hence the assertions below hold.
+    */
+   assert(map->mode & GL_MAP_WRITE_BIT);
+   assert(map->mode & GL_MAP_INVALIDATE_RANGE_BIT);
+
+   map->stride = _mesa_format_row_stride(mt->etc2_format, map->w);
+   map->buffer = malloc(_mesa_format_image_size(mt->etc2_format,
+                        map->w, map->h, 1));
+   map->ptr = map->buffer;
+}
+
+static void
+intel_miptree_unmap_etc2(struct intel_context *intel,
+                         struct intel_mipmap_tree *mt,
+                         struct intel_miptree_map *map,
+                         unsigned int level,
+                         unsigned int slice)
+{
+   uint32_t image_x;
+   uint32_t image_y;
+   intel_miptree_get_image_offset(mt, level, 0, slice, &image_x, &image_y);
+
+   uint8_t *dst = intel_region_map(intel, mt->region, map->mode)
+                + image_y * mt->region->pitch * mt->region->cpp
+                + image_x * mt->region->cpp;
+
+   _mesa_unpack_etc2_format(dst, mt->region->pitch * mt->region->cpp,
+                            map->ptr, map->stride,
+                            map->w, map->h, mt->etc2_format);
+
+   intel_region_unmap(intel, mt->region);
+   free(map->buffer);
+}
+
+static void
 intel_miptree_map_etc1(struct intel_context *intel,
                        struct intel_mipmap_tree *mt,
                        struct intel_miptree_map *map,
@@ -1539,6 +1625,8 @@ intel_miptree_map_singlesample(struct intel_context *intel,
       intel_miptree_map_s8(intel, mt, map, level, slice);
    } else if (mt->wraps_etc1) {
       intel_miptree_map_etc1(intel, mt, map, level, slice);
+   } else if (mt->wraps_etc2) {
+      intel_miptree_map_etc2(intel, mt, map, level, slice);
    } else if (mt->stencil_mt) {
       intel_miptree_map_depthstencil(intel, mt, map, level, slice);
    } else if (intel->has_llc &&
@@ -1577,6 +1665,8 @@ intel_miptree_unmap_singlesample(struct intel_context *intel,
       intel_miptree_unmap_s8(intel, mt, map, level, slice);
    } else if (mt->wraps_etc1) {
       intel_miptree_unmap_etc1(intel, mt, map, level, slice);
+   } else if (mt->wraps_etc2) {
+      intel_miptree_unmap_etc2(intel, mt, map, level, slice);
    } else if (mt->stencil_mt) {
       intel_miptree_unmap_depthstencil(intel, mt, map, level, slice);
    } else if (map->bo) {
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 0d0e757..2a71584 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -197,11 +197,15 @@ struct intel_mipmap_tree
     * MESA_FORMAT_Z32_FLOAT, otherwise for MESA_FORMAT_S8_Z24 objects it will be
     * MESA_FORMAT_X8_Z24.
     *
-    * For ETC1 textures, this is MESA_FORMAT_RGBX8888_REV if the hardware
-    * lacks support for ETC1. See @ref wraps_etc1.
+    * For ETC1/ETC2 textures, this is one of the uncompressed mesa texture
+    * formats if the hardware lacks support for ETC1/ETC2. See @ref wraps_etc1,
+    * wraps_etc2.
     */
    gl_format format;
 
+   /** This variable stores the value of ETC2 compressed texture format */
+   gl_format etc2_format;
+
    /**
     * The X offset of each image in the miptree must be aligned to this. See
     * the "Alignment Unit Size" section of the BSpec.
@@ -351,16 +355,19 @@ struct intel_mipmap_tree
    struct intel_mipmap_tree *mcs_mt;
 
    /**
-    * \brief The miptree contains RGBX data that was originally ETC1 data.
+    * \brief The miptree contains uncompressed data that was originally
+    * ETC1/ETC2 data.
     *
-    * On hardware that lacks support for ETC1 textures, we do the
-    * following on calls to glCompressedTexImage2D(GL_ETC1_RGB8_OES):
-    *   1. Create a miptree whose format is MESA_FORMAT_RGBX8888_REV with
-    *      the wraps_etc1 flag set.
-    *   2. Translate the ETC1 data into RGBX.
-    *   3. Store the RGBX data into the miptree and discard the ETC1 data.
+    * On hardware that lacks support for ETC1/ETC2 textures, we do the following
+    * on calls to glCompressedTexImage2D() with an ETC1/ETC2 texture format:
+    *   1. Create a miptree whose format is a suitable uncompressed mesa format
+    *      with the wraps_etc1/wraps_etc2 flag set.
+    *   2. Translate the ETC1/ETC2 data into uncompressed mesa format.
+    *   3. Store the uncompressed  data into the miptree and discard the ETC1/ETC2
+    *      data.
     */
    bool wraps_etc1;
+   bool wraps_etc2;
 
    /* These are also refcounted:
     */
-- 
1.7.7.6



More information about the mesa-dev mailing list