[Mesa-dev] [PATCH 7/7] st/mesa: implement ASTC 2D LDR fallback for all drivers

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


From: Marek Olšák <marek.olsak at amd.com>

---
 src/mesa/state_tracker/st_cb_texture.c | 17 +++++++-
 src/mesa/state_tracker/st_context.c    |  3 ++
 src/mesa/state_tracker/st_context.h    |  1 +
 src/mesa/state_tracker/st_extensions.c |  5 +++
 src/mesa/state_tracker/st_format.c     | 56 ++++++++++++++++++++++++++
 5 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 80eb171dfd8..56d8c411472 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -34,20 +34,21 @@
 #include "main/format_utils.h"
 #include "main/glformats.h"
 #include "main/image.h"
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/mipmap.h"
 #include "main/pack.h"
 #include "main/pbo.h"
 #include "main/pixeltransfer.h"
 #include "main/texcompress.h"
+#include "main/texcompress_astc.h"
 #include "main/texcompress_etc.h"
 #include "main/texgetimage.h"
 #include "main/teximage.h"
 #include "main/texobj.h"
 #include "main/texstore.h"
 
 #include "state_tracker/st_debug.h"
 #include "state_tracker/st_context.h"
 #include "state_tracker/st_cb_bitmap.h"
 #include "state_tracker/st_cb_fbo.h"
@@ -220,20 +221,23 @@ st_FreeTextureImageBuffer(struct gl_context *ctx,
 
 bool
 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;
 
+   if (_mesa_is_format_astc_2d(format))
+      return !st->has_astc_2d_ldr;
+
    return false;
 }
 
 static void
 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))
@@ -330,28 +334,34 @@ st_UnmapTextureImage(struct gl_context *ctx,
       struct pipe_transfer *transfer = itransfer->transfer;
 
       assert(z == transfer->box.z);
 
       if (transfer->usage & PIPE_TRANSFER_WRITE) {
          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 {
+         } 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");
          }
       }
 
       itransfer->temp_data = NULL;
       itransfer->temp_stride = 0;
       itransfer->map = 0;
    }
 
    st_texture_image_unmap(st, stImage, slice);
 }
@@ -1408,20 +1418,21 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
    unsigned dstz = texImage->Face + texImage->TexObject->MinLayer;
    unsigned dst_level = 0;
 
    st_flush_bitmap_cache(st);
    st_invalidate_readpix_cache(st);
 
    if (stObj->pt == stImage->pt)
       dst_level = texImage->TexObject->MinLevel + texImage->Level;
 
    assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
+          !_mesa_is_format_astc_2d(texImage->TexFormat) &&
           texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
 
    if (!dst)
       goto fallback;
 
    /* Try texture_subdata, which should be the fastest memcpy path. */
    if (pixels &&
        !_mesa_is_bufferobj(unpack->BufferObj) &&
        _mesa_texstore_can_use_memcpy(ctx, texImage->_BaseFormat,
                                      texImage->TexFormat, format, type,
@@ -1868,20 +1879,21 @@ st_GetTexSubImage(struct gl_context * ctx,
    GLenum gl_target = texImage->TexObject->Target;
    enum pipe_texture_target pipe_target;
    unsigned dims;
    struct pipe_blit_info blit;
    unsigned bind;
    struct pipe_transfer *tex_xfer;
    ubyte *map = NULL;
    boolean done = FALSE;
 
    assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
+          !_mesa_is_format_astc_2d(texImage->TexFormat) &&
           texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
 
    st_flush_bitmap_cache(st);
 
    if (!st->prefer_blit_based_texture_transfer &&
        !_mesa_is_format_compressed(texImage->TexFormat)) {
       /* Try to avoid the fallback if we're doing texture decompression here */
       goto fallback;
    }
 
@@ -2385,20 +2397,21 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
    struct pipe_blit_info blit;
    enum pipe_format dst_format;
    GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
    unsigned bind;
    GLint srcY0, srcY1;
 
    st_flush_bitmap_cache(st);
    st_invalidate_readpix_cache(st);
 
    assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
+          !_mesa_is_format_astc_2d(texImage->TexFormat) &&
           texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
 
    if (!strb || !strb->surface || !stImage->pt) {
       debug_printf("%s: null strb or stImage\n", __func__);
       return;
    }
 
    if (_mesa_texstore_needs_transfer_ops(ctx, texImage->_BaseFormat,
                                          texImage->TexFormat)) {
       goto fallback;
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index b7330acfcca..c124793fa40 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -431,20 +431,23 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe,
 
    st->has_stencil_export =
       screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT);
    st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3);
    st->has_etc1 = screen->is_format_supported(screen, PIPE_FORMAT_ETC1_RGB8,
                                               PIPE_TEXTURE_2D, 0,
                                               PIPE_BIND_SAMPLER_VIEW);
    st->has_etc2 = screen->is_format_supported(screen, PIPE_FORMAT_ETC2_RGB8,
                                               PIPE_TEXTURE_2D, 0,
                                               PIPE_BIND_SAMPLER_VIEW);
+   st->has_astc_2d_ldr =
+      screen->is_format_supported(screen, PIPE_FORMAT_ASTC_4x4_SRGB,
+                                  PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW);
    st->prefer_blit_based_texture_transfer = screen->get_param(screen,
                               PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER);
    st->force_persample_in_shader =
       screen->get_param(screen, PIPE_CAP_SAMPLE_SHADING) &&
       !screen->get_param(screen, PIPE_CAP_FORCE_PERSAMPLE_INTERP);
    st->has_shareable_shaders = screen->get_param(screen,
                                                  PIPE_CAP_SHAREABLE_SHADERS);
    st->needs_texcoord_semantic =
       screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD);
    st->apply_texture_swizzle_to_border_color =
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index a4d52b40ae4..6b1b5633ecc 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -113,20 +113,21 @@ struct st_context
    struct draw_stage *feedback_stage;  /**< For GL_FEEDBACK rendermode */
    struct draw_stage *selection_stage;  /**< For GL_SELECT rendermode */
    struct draw_stage *rastpos_stage;  /**< For glRasterPos */
    GLboolean clamp_frag_color_in_shader;
    GLboolean clamp_vert_color_in_shader;
    boolean has_stencil_export; /**< can do shader stencil export? */
    boolean has_time_elapsed;
    boolean has_shader_model3;
    boolean has_etc1;
    boolean has_etc2;
+   boolean has_astc_2d_ldr;
    boolean prefer_blit_based_texture_transfer;
    boolean force_persample_in_shader;
    boolean has_shareable_shaders;
    boolean has_half_float_packing;
    boolean has_multi_draw_indirect;
    boolean can_bind_const_buffer_as_vertex;
 
    /**
     * If a shader can be created when we get its source.
     * This means it has only 1 variant, not counting glBitmap and
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index aaf1aa10ac6..2ec47581c50 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -795,20 +795,25 @@ void st_init_extensions(struct pipe_screen *screen,
           PIPE_FORMAT_ASTC_8x5_SRGB,
           PIPE_FORMAT_ASTC_8x6_SRGB,
           PIPE_FORMAT_ASTC_8x8_SRGB,
           PIPE_FORMAT_ASTC_10x5_SRGB,
           PIPE_FORMAT_ASTC_10x6_SRGB,
           PIPE_FORMAT_ASTC_10x8_SRGB,
           PIPE_FORMAT_ASTC_10x10_SRGB,
           PIPE_FORMAT_ASTC_12x10_SRGB,
           PIPE_FORMAT_ASTC_12x12_SRGB } },
 
+      /* ASTC software fallback support. */
+      { { o(KHR_texture_compression_astc_ldr) },
+        { PIPE_FORMAT_R8G8B8A8_UNORM,
+          PIPE_FORMAT_R8G8B8A8_SRGB } },
+
       { { o(EXT_texture_shared_exponent) },
         { PIPE_FORMAT_R9G9B9E5_FLOAT } },
 
       { { o(EXT_texture_snorm) },
         { PIPE_FORMAT_R8G8B8A8_SNORM } },
 
       { { o(EXT_texture_sRGB),
           o(EXT_texture_sRGB_decode) },
         { PIPE_FORMAT_A8B8G8R8_SRGB,
 	  PIPE_FORMAT_B8G8R8A8_SRGB,
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 45513e8683e..afe810f4d15 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -480,75 +480,131 @@ st_mesa_format_to_pipe_format(const struct st_context *st,
       return st->has_etc2 ? PIPE_FORMAT_ETC2_R11_SNORM : PIPE_FORMAT_R16_SNORM;
    case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
       return st->has_etc2 ? PIPE_FORMAT_ETC2_RG11_SNORM : PIPE_FORMAT_R16G16_SNORM;
    case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
       return st->has_etc2 ? PIPE_FORMAT_ETC2_RGB8A1 : PIPE_FORMAT_R8G8B8A8_UNORM;
    case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
       return st->has_etc2 ? PIPE_FORMAT_ETC2_SRGB8A1 :
 	 has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : PIPE_FORMAT_R8G8B8A8_SRGB;
 
    case MESA_FORMAT_RGBA_ASTC_4x4:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_4x4;
    case MESA_FORMAT_RGBA_ASTC_5x4:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_5x4;
    case MESA_FORMAT_RGBA_ASTC_5x5:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_5x5;
    case MESA_FORMAT_RGBA_ASTC_6x5:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_6x5;
    case MESA_FORMAT_RGBA_ASTC_6x6:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_6x6;
    case MESA_FORMAT_RGBA_ASTC_8x5:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_8x5;
    case MESA_FORMAT_RGBA_ASTC_8x6:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_8x6;
    case MESA_FORMAT_RGBA_ASTC_8x8:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_8x8;
    case MESA_FORMAT_RGBA_ASTC_10x5:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_10x5;
    case MESA_FORMAT_RGBA_ASTC_10x6:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_10x6;
    case MESA_FORMAT_RGBA_ASTC_10x8:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_10x8;
    case MESA_FORMAT_RGBA_ASTC_10x10:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_10x10;
    case MESA_FORMAT_RGBA_ASTC_12x10:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_12x10;
    case MESA_FORMAT_RGBA_ASTC_12x12:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
       return PIPE_FORMAT_ASTC_12x12;
 
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_4x4_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_5x4_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_5x5_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_6x5_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_6x6_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x5:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_8x5_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x6:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_8x6_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x8:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_8x8_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x5:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_10x5_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x6:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_10x6_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x8:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_10x8_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_10x10_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_12x10_SRGB;
    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12:
+      if (!st->has_astc_2d_ldr)
+         return PIPE_FORMAT_R8G8B8A8_SRGB;
       return PIPE_FORMAT_ASTC_12x12_SRGB;
 
    default:
       return PIPE_FORMAT_NONE;
    }
 }
 
 
 /**
  * Translate Gallium format to Mesa format.
-- 
2.17.1



More information about the mesa-dev mailing list