[Mesa-dev] [PATCH] i965: Transcode RGB ETC1/2 textures to DXT1 or FXT1.

Ian Romanick idr at freedesktop.org
Tue Jan 15 15:49:51 PST 2013


On 01/11/2013 08:54 PM, Eric Anholt wrote:
> The previous solution of transcoding to ARGB8888 gave exact results, but
> below the expected performance.  Given that the user has gone out of
> their way to give us compressed data for performance reasons, try to
> respect their wishes by doing the best compression we can handle.  We
> expect DXT1 compression to be better quality, but it may not always be
> available, in which case FXT1 seems like a reasonable fallback.
>
> This regresses OES_compressed_ETC1_RGB8_texture/miptree (which expects
> exact results, which we no longer provide), but it improves GLBenchmark
> 2.1 offscreen performance by 3.2% +/- 2.1% (n=11/10, throttling
> outliers removed).

There are ETC1 and ETC2 conformance tests.  Do they pass?

> ---
>   src/mesa/drivers/dri/intel/intel_mipmap_tree.c |   44 +++++++++++++++++++-----
>   1 file changed, 35 insertions(+), 9 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
> index 7542219..73411c6 100644
> --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
> +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
> @@ -295,6 +295,7 @@ intel_miptree_create(struct intel_context *intel,
>                        GLuint num_samples,
>                        bool force_y_tiling)
>   {
> +   struct gl_context *ctx = &intel->ctx;
>      struct intel_mipmap_tree *mt;
>      uint32_t tiling = I915_TILING_NONE;
>      GLenum base_format;
> @@ -304,10 +305,11 @@ intel_miptree_create(struct intel_context *intel,
>
>      switch (format) {
>      case MESA_FORMAT_ETC1_RGB8:
> -      format = MESA_FORMAT_RGBX8888_REV;
> -      break;
>      case MESA_FORMAT_ETC2_RGB8:
> -      format = MESA_FORMAT_RGBX8888_REV;
> +      if (ctx->Mesa_DXTn)
> +         format = MESA_FORMAT_RGB_DXT1;
> +      else
> +         format = MESA_FORMAT_RGB_FXT1;
>         break;
>      case MESA_FORMAT_ETC2_SRGB8:
>      case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
> @@ -1299,10 +1301,6 @@ intel_miptree_map_etc(struct intel_context *intel,
>       */
>      assert(mt->wraps_etc);
>
> -   if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
> -      assert(mt->format == MESA_FORMAT_RGBX8888_REV);
> -   }
> -
>      assert(map->mode & GL_MAP_WRITE_BIT);
>      assert(map->mode & GL_MAP_INVALIDATE_RANGE_BIT);
>
> @@ -1319,6 +1317,7 @@ intel_miptree_unmap_etc(struct intel_context *intel,
>                           unsigned int level,
>                           unsigned int slice)
>   {
> +   struct gl_context *ctx = &intel->ctx;
>      uint32_t image_x;
>      uint32_t image_y;
>      intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
> @@ -1330,11 +1329,38 @@ intel_miptree_unmap_etc(struct intel_context *intel,
>                   + image_y * mt->region->pitch * mt->region->cpp
>                   + image_x * mt->region->cpp;
>
> -   if (mt->etc_format == MESA_FORMAT_ETC1_RGB8)
> +   if (mt->format == MESA_FORMAT_RGB_DXT1 ||
> +       mt->format == MESA_FORMAT_RGB_FXT1) {
> +      unsigned int bw, bh;
> +      _mesa_get_format_block_size(mt->etc_format, &bw, &bh);
> +
> +      int rgba_temp_w = ALIGN(map->w, bw);
> +      int rgba_temp_h = ALIGN(map->h, bh);
> +      void *rgba_temp = malloc(_mesa_format_image_size(MESA_FORMAT_RGBA8888,
> +                                                       rgba_temp_w, rgba_temp_h, 1));
> +      int rgba_stride = _mesa_format_row_stride(MESA_FORMAT_RGBA8888,
> +                                                rgba_temp_w);
> +      if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
> +         _mesa_etc1_unpack_rgba8888(rgba_temp, rgba_stride,
> +                                    map->ptr, map->stride,
> +                                    map->w, map->h);
> +      } else {
> +         _mesa_unpack_etc2_format(rgba_temp, rgba_stride,
> +                                  map->ptr, map->stride,
> +                                  map->w, map->h, mt->etc_format);
> +      }
> +      _mesa_texstore(ctx, 2, GL_RGB,
> +                     mt->format,
> +                     mt->region->pitch * mt->region->cpp, &dst,
> +                     map->w, map->h, 1,
> +                     GL_RGBA, GL_UNSIGNED_BYTE, rgba_temp,
> +                     &ctx->DefaultPacking);
> +      free(rgba_temp);
> +   } else if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
>         _mesa_etc1_unpack_rgba8888(dst, mt->region->pitch * mt->region->cpp,
>                                    map->ptr, map->stride,
>                                    map->w, map->h);
> -   else
> +   } else
>         _mesa_unpack_etc2_format(dst, mt->region->pitch * mt->region->cpp,
>                                  map->ptr, map->stride,
>                                  map->w, map->h, mt->etc_format);
>



More information about the mesa-dev mailing list