Module: Mesa
Branch: master
Commit: 0bbae3139ef4cdbfbcf5818ec7ee0f3804b02e90
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=0bbae3139ef4cdbfbcf5818ec7ee0f3804b02e90

Author: Marek Olšák <[email protected]>
Date:   Wed Feb 24 13:11:07 2021 -0500

st/mesa: add a driconf option to transcode ETC2 to DXTC

for performance analysis

Reviewed-by: Pierre-Eric Pelloux-Prayer <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9357>

---

 .../auxiliary/pipe-loader/driinfo_gallium.h        |  1 +
 src/gallium/frontends/dri/dri_screen.c             |  2 +
 src/gallium/include/frontend/api.h                 |  1 +
 src/mesa/state_tracker/st_cb_texture.c             | 84 ++++++++++++++++------
 src/mesa/state_tracker/st_context.c                |  4 ++
 src/mesa/state_tracker/st_context.h                |  1 +
 src/mesa/state_tracker/st_format.c                 | 17 +++--
 src/util/driconf.h                                 |  3 +
 8 files changed, 86 insertions(+), 27 deletions(-)

diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h 
b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
index 4fd080494f1..9c5cdfba5f0 100644
--- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
+++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
@@ -33,6 +33,7 @@ DRI_CONF_SECTION_DEBUG
    DRI_CONF_ALLOW_INCORRECT_PRIMITIVE_ID(false)
    DRI_CONF_FORCE_COMPAT_PROFILE(false)
    DRI_CONF_FORCE_GL_NAMES_REUSE(false)
+   DRI_CONF_TRANSCODE_ETC(false)
    DRI_CONF_FORCE_GL_VENDOR()
    DRI_CONF_OVERRIDE_VRAM_SIZE()
    DRI_CONF_GLX_EXTENSION_OVERRIDE()
diff --git a/src/gallium/frontends/dri/dri_screen.c 
b/src/gallium/frontends/dri/dri_screen.c
index d3938117a41..3f614f8677d 100644
--- a/src/gallium/frontends/dri/dri_screen.c
+++ b/src/gallium/frontends/dri/dri_screen.c
@@ -103,6 +103,8 @@ dri_fill_st_options(struct dri_screen *screen)
       driQueryOptionb(optionCache, "ignore_map_unsynchronized");
    options->force_gl_names_reuse =
       driQueryOptionb(optionCache, "force_gl_names_reuse");
+   options->transcode_etc =
+      driQueryOptionb(optionCache, "transcode_etc");
 
    char *vendor_str = driQueryOptionstr(optionCache, "force_gl_vendor");
    /* not an empty string */
diff --git a/src/gallium/include/frontend/api.h 
b/src/gallium/include/frontend/api.h
index 3d05123455f..e271033754e 100644
--- a/src/gallium/include/frontend/api.h
+++ b/src/gallium/include/frontend/api.h
@@ -245,6 +245,7 @@ struct st_config_options
    bool ignore_map_unsynchronized;
    bool force_integer_tex_nearest;
    bool force_gl_names_reuse;
+   bool transcode_etc;
    char *force_gl_vendor;
    unsigned char config_options_sha1[20];
 };
diff --git a/src/mesa/state_tracker/st_cb_texture.c 
b/src/mesa/state_tracker/st_cb_texture.c
index 463944061f7..6b269196167 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -382,28 +382,72 @@ st_UnmapTextureImage(struct gl_context *ctx,
       assert(z == transfer->box.z);
 
       if (transfer->usage & PIPE_MAP_WRITE) {
-         if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) {
-            _mesa_etc1_unpack_rgba8888(itransfer->map, transfer->stride,
-                                       itransfer->temp_data,
-                                       itransfer->temp_stride,
+         if (util_format_is_compressed(stImage->pt->format)) {
+            /* Transcode into a different compressed format. */
+            unsigned size =
+               _mesa_format_image_size(PIPE_FORMAT_R8G8B8A8_UNORM,
                                        transfer->box.width,
-                                       transfer->box.height);
-         } else if (_mesa_is_format_etc2(texImage->TexFormat)) {
-            bool bgra = stImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB;
-            _mesa_unpack_etc2_format(itransfer->map, transfer->stride,
-                                     itransfer->temp_data,
-                                     itransfer->temp_stride,
-                                     transfer->box.width, transfer->box.height,
-                                     texImage->TexFormat,
-                                     bgra);
-         } else if (_mesa_is_format_astc_2d(texImage->TexFormat)) {
-            _mesa_unpack_astc_2d_ldr(itransfer->map, transfer->stride,
-                                     itransfer->temp_data,
-                                     itransfer->temp_stride,
-                                     transfer->box.width, transfer->box.height,
-                                     texImage->TexFormat);
+                                       transfer->box.height, 1);
+            void *tmp = malloc(size);
+
+            /* Decompress to tmp. */
+            if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) {
+               _mesa_etc1_unpack_rgba8888(tmp, transfer->box.width * 4,
+                                          itransfer->temp_data,
+                                          itransfer->temp_stride,
+                                          transfer->box.width,
+                                          transfer->box.height);
+            } else if (_mesa_is_format_etc2(texImage->TexFormat)) {
+               bool bgra = stImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB;
+
+               _mesa_unpack_etc2_format(tmp, transfer->box.width * 4,
+                                        itransfer->temp_data,
+                                        itransfer->temp_stride,
+                                        transfer->box.width,
+                                        transfer->box.height,
+                                        texImage->TexFormat,
+                                        bgra);
+            } else {
+               /* TODO: We could transcode ASTC too. */
+               unreachable("unexpected format for a compressed format 
fallback");
+            }
+
+            /* Compress it to the target format. */
+            struct gl_pixelstore_attrib pack = {0};
+            pack.Alignment = 4;
+
+            _mesa_texstore(ctx, 2, GL_RGBA, stImage->pt->format,
+                           transfer->stride, &itransfer->map,
+                           transfer->box.width,
+                           transfer->box.height, 1, GL_RGBA,
+                           GL_UNSIGNED_BYTE, tmp, &pack);
+            free(tmp);
          } else {
-            unreachable("unexpected format for a compressed format fallback");
+            /* Decompress into an uncompressed format. */
+            if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) {
+               _mesa_etc1_unpack_rgba8888(itransfer->map, transfer->stride,
+                                          itransfer->temp_data,
+                                          itransfer->temp_stride,
+                                          transfer->box.width,
+                                          transfer->box.height);
+            } else if (_mesa_is_format_etc2(texImage->TexFormat)) {
+               bool bgra = stImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB;
+
+               _mesa_unpack_etc2_format(itransfer->map, transfer->stride,
+                                        itransfer->temp_data,
+                                        itransfer->temp_stride,
+                                        transfer->box.width, 
transfer->box.height,
+                                        texImage->TexFormat,
+                                        bgra);
+            } else if (_mesa_is_format_astc_2d(texImage->TexFormat)) {
+               _mesa_unpack_astc_2d_ldr(itransfer->map, transfer->stride,
+                                        itransfer->temp_data,
+                                        itransfer->temp_stride,
+                                        transfer->box.width, 
transfer->box.height,
+                                        texImage->TexFormat);
+            } else {
+               unreachable("unexpected format for a compressed format 
fallback");
+            }
          }
       }
 
diff --git a/src/mesa/state_tracker/st_context.c 
b/src/mesa/state_tracker/st_context.c
index 3acbc75d1db..07dad53ef70 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -677,6 +677,10 @@ st_create_context_priv(struct gl_context *ctx, struct 
pipe_context *pipe,
    st->has_etc2 = screen->is_format_supported(screen, PIPE_FORMAT_ETC2_RGB8,
                                               PIPE_TEXTURE_2D, 0, 0,
                                               PIPE_BIND_SAMPLER_VIEW);
+   st->transcode_etc = options->transcode_etc &&
+                       screen->is_format_supported(screen, 
PIPE_FORMAT_DXT1_SRGBA,
+                                                   PIPE_TEXTURE_2D, 0, 0,
+                                                   PIPE_BIND_SAMPLER_VIEW);
    st->has_astc_2d_ldr =
       screen->is_format_supported(screen, PIPE_FORMAT_ASTC_4x4_SRGB,
                                   PIPE_TEXTURE_2D, 0, 0, 
PIPE_BIND_SAMPLER_VIEW);
diff --git a/src/mesa/state_tracker/st_context.h 
b/src/mesa/state_tracker/st_context.h
index fe0a0859137..867a882c3e7 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -142,6 +142,7 @@ struct st_context
    boolean has_time_elapsed;
    boolean has_etc1;
    boolean has_etc2;
+   boolean transcode_etc;
    boolean has_astc_2d_ldr;
    boolean has_astc_5x5_ldr;
    boolean prefer_blit_based_texture_transfer;
diff --git a/src/mesa/state_tracker/st_format.c 
b/src/mesa/state_tracker/st_format.c
index cc5621072bb..6f71bfe087e 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -68,7 +68,7 @@ st_mesa_format_to_pipe_format(const struct st_context *st,
     * a destination format of the unpack/decompression function.
     */
    if (mesaFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)
-      return PIPE_FORMAT_R8G8B8A8_UNORM;
+      return st->transcode_etc ? PIPE_FORMAT_DXT1_RGB : 
PIPE_FORMAT_R8G8B8A8_UNORM;
 
    /* ETC2 formats are emulated as uncompressed ones.
     * The destination formats mustn't be changed, because they are also
@@ -82,13 +82,15 @@ st_mesa_format_to_pipe_format(const struct st_context *st,
 
       switch (mesaFormat) {
       case MESA_FORMAT_ETC2_RGB8:
-         return PIPE_FORMAT_R8G8B8A8_UNORM;
+         return st->transcode_etc ? PIPE_FORMAT_DXT1_RGB : 
PIPE_FORMAT_R8G8B8A8_UNORM;
       case MESA_FORMAT_ETC2_SRGB8:
-         return has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : 
PIPE_FORMAT_R8G8B8A8_SRGB;
+         return st->transcode_etc ? PIPE_FORMAT_DXT1_SRGB :
+                has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : 
PIPE_FORMAT_R8G8B8A8_SRGB;
       case MESA_FORMAT_ETC2_RGBA8_EAC:
-         return PIPE_FORMAT_R8G8B8A8_UNORM;
+         return st->transcode_etc ? PIPE_FORMAT_DXT5_RGBA : 
PIPE_FORMAT_R8G8B8A8_UNORM;
       case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
-         return has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : 
PIPE_FORMAT_R8G8B8A8_SRGB;
+         return st->transcode_etc ? PIPE_FORMAT_DXT5_SRGBA :
+                has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : 
PIPE_FORMAT_R8G8B8A8_SRGB;
       case MESA_FORMAT_ETC2_R11_EAC:
          return PIPE_FORMAT_R16_UNORM;
       case MESA_FORMAT_ETC2_RG11_EAC:
@@ -98,9 +100,10 @@ st_mesa_format_to_pipe_format(const struct st_context *st,
       case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
          return PIPE_FORMAT_R16G16_SNORM;
       case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
-         return PIPE_FORMAT_R8G8B8A8_UNORM;
+         return st->transcode_etc ? PIPE_FORMAT_DXT1_RGBA : 
PIPE_FORMAT_R8G8B8A8_UNORM;
       case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
-         return has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : 
PIPE_FORMAT_R8G8B8A8_SRGB;
+         return st->transcode_etc ? PIPE_FORMAT_DXT1_SRGBA :
+                has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : 
PIPE_FORMAT_R8G8B8A8_SRGB;
       default:
          unreachable("Unknown ETC2 format");
       }
diff --git a/src/util/driconf.h b/src/util/driconf.h
index 9c0c353b7b5..48be630d0e2 100644
--- a/src/util/driconf.h
+++ b/src/util/driconf.h
@@ -221,6 +221,9 @@
 #define DRI_CONF_FORCE_GL_NAMES_REUSE(def) \
    DRI_CONF_OPT_B(force_gl_names_reuse, def, "Force GL names reuse")
 
+#define DRI_CONF_TRANSCODE_ETC(def) \
+   DRI_CONF_OPT_B(transcode_etc, def, "Transcode ETC formats to DXTC if 
unsupported")
+
 #define DRI_CONF_GLX_EXTENSION_OVERRIDE(def) \
    DRI_CONF_OPT_S(glx_extension_override, def, \
                   "Allow enabling/disabling a list of GLX extensions")

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to