[Mesa-dev] [PATCH 5/5] st/mesa: convert the ETC1 format to an uncompressed one if unsupported

Glenn Kennard glenn.kennard at gmail.com
Sun Aug 3 09:23:38 PDT 2014


On Sun, 03 Aug 2014 14:40:40 +0200, Marek Olšák <maraeo at gmail.com> wrote:

> From: Marek Olšák <marek.olsak at amd.com>
>
> I don't know of any hardware which supports it.
> With this, GL_OES_compressed_ETC1_RGB8_texture is supported if RGBA8
> is supported.
> ---
>  docs/relnotes/10.3.html                |  1 +
>  src/mesa/state_tracker/st_cb_texture.c | 31  
> ++++++++++++++++++++++---------
>  src/mesa/state_tracker/st_context.c    |  3 +++
>  src/mesa/state_tracker/st_context.h    |  1 +
>  src/mesa/state_tracker/st_extensions.c |  4 +++-
>  src/mesa/state_tracker/st_format.c     | 13 +++++++++++--
>  6 files changed, 41 insertions(+), 12 deletions(-)
>
> diff --git a/docs/relnotes/10.3.html b/docs/relnotes/10.3.html
> index c0828da..a1f2777 100644
> --- a/docs/relnotes/10.3.html
> +++ b/docs/relnotes/10.3.html
> @@ -60,6 +60,7 @@ Note: some of the new features are only available with  
> certain drivers.
>  <li>GL_ARB_fragment_layer_viewport on nv50, nvc0, llvmpipe, r600</li>
>  <li>GL_AMD_vertex_shader_viewport_index on i965/gen7+, r600</li>
>  <li>GL_ARB_clear_texture on i965</li>
> +<li>GL_OES_compressed_ETC1_RGB8_texture on nv30, nv50, nvc0, r300,  
> r600, radeonsi, softpipe, llvmpipe</li>
>  <li>A new software rasterizer driver (kms_swrast_dri.so) that works with
>  DRM drivers that don't have a full-fledged GEM (such as qxl or  
> simpledrm)</li>
>  </ul>
> diff --git a/src/mesa/state_tracker/st_cb_texture.c  
> b/src/mesa/state_tracker/st_cb_texture.c
> index ee3a234..5a5efcb 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -208,7 +208,8 @@ st_MapTextureImage(struct gl_context *ctx,
>     map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h,  
> 1,
>                                &transfer);
>     if (map) {
> -      if (_mesa_is_format_etc2(texImage->TexFormat)) {
> +      if (_mesa_is_format_etc2(texImage->TexFormat) ||
> +          (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 &&  
> !st->has_etc1)) {
>           /* ETC isn't supported by gallium and it's represented
>            * by uncompressed formats. Only write transfers with  
> precompressed
>            * data are supported by ES3, which makes this really simple.
> @@ -250,7 +251,8 @@ st_UnmapTextureImage(struct gl_context *ctx,
>     struct st_context *st = st_context(ctx);
>     struct st_texture_image *stImage  = st_texture_image(texImage);
> -   if (_mesa_is_format_etc2(texImage->TexFormat)) {
> +   if (_mesa_is_format_etc2(texImage->TexFormat) ||
> +       (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1))  
> {
>        /* Decompress the ETC texture to the mapped one. */
>        unsigned z = slice + stImage->base.Face;
>        struct st_texture_image_transfer *itransfer =  
> &stImage->transfer[z];
> @@ -258,10 +260,18 @@ st_UnmapTextureImage(struct gl_context *ctx,
>       assert(z == transfer->box.z);
> -      _mesa_unpack_etc2_format(itransfer->map, transfer->stride,
> -                               itransfer->temp_data,  
> itransfer->temp_stride,
> -                               transfer->box.width,  
> transfer->box.height,
> -                               texImage->TexFormat);
> +      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 {
> +         _mesa_unpack_etc2_format(itransfer->map, transfer->stride,
> +                                  itransfer->temp_data,  
> itransfer->temp_stride,
> +                                  transfer->box.width,  
> transfer->box.height,
> +                                  texImage->TexFormat);
> +      }
>       free(itransfer->temp_data);
>        itransfer->temp_data = NULL;
> @@ -657,7 +667,8 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
>     unsigned bind;
>     GLubyte *map;
> -   assert(!_mesa_is_format_etc2(texImage->TexFormat));
> +   assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
> +          texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
>    if (!st->prefer_blit_based_texture_transfer) {
>        goto fallback;
> @@ -916,7 +927,8 @@ st_GetTexImage(struct gl_context * ctx,
>     ubyte *map = NULL;
>     boolean done = FALSE;
> -   assert(!_mesa_is_format_etc2(texImage->TexFormat));
> +   assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
> +          texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
>    if (!st->prefer_blit_based_texture_transfer &&
>         !_mesa_is_format_compressed(texImage->TexFormat)) {
> @@ -1354,7 +1366,8 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint  
> dims,
>     unsigned bind;
>     GLint srcY0, srcY1;
> -   assert(!_mesa_is_format_etc2(texImage->TexFormat));
> +   assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
> +          texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
>    if (!strb || !strb->surface || !stImage->pt) {
>        debug_printf("%s: null strb or stImage\n", __FUNCTION__);
> diff --git a/src/mesa/state_tracker/st_context.c  
> b/src/mesa/state_tracker/st_context.c
> index c805a09..ccd19f3 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -189,6 +189,9 @@ 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->prefer_blit_based_texture_transfer = screen->get_param(screen,
>                                PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER);
> diff --git a/src/mesa/state_tracker/st_context.h  
> b/src/mesa/state_tracker/st_context.h
> index 361a24b..6d572bd 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -86,6 +86,7 @@ struct st_context
>     boolean has_stencil_export; /**< can do shader stencil export? */
>     boolean has_time_elapsed;
>     boolean has_shader_model3;
> +   boolean has_etc1;
>     boolean prefer_blit_based_texture_transfer;
>    boolean needs_texcoord_semantic;
> diff --git a/src/mesa/state_tracker/st_extensions.c  
> b/src/mesa/state_tracker/st_extensions.c
> index 3974adb..60aa8cc 100644
> --- a/src/mesa/state_tracker/st_extensions.c
> +++ b/src/mesa/state_tracker/st_extensions.c
> @@ -513,7 +513,9 @@ void st_init_extensions(struct st_context *st)
>          GL_TRUE }, /* at least one format must be supported */
>       { { o(OES_compressed_ETC1_RGB8_texture) },
> -        { PIPE_FORMAT_ETC1_RGB8 } },
> +        { PIPE_FORMAT_ETC1_RGB8,
> +          PIPE_FORMAT_R8G8B8A8_UNORM },
> +        GL_TRUE }, /* at least one format must be supported */
>       { { o(ARB_stencil_texturing) },
>          { PIPE_FORMAT_X24S8_UINT,
> diff --git a/src/mesa/state_tracker/st_format.c  
> b/src/mesa/state_tracker/st_format.c
> index 3d822a5..ae71dd7 100644
> --- a/src/mesa/state_tracker/st_format.c
> +++ b/src/mesa/state_tracker/st_format.c
> @@ -323,8 +323,10 @@ st_mesa_format_to_pipe_format(struct st_context  
> *st, mesa_format mesaFormat)
>     case MESA_FORMAT_LA_LATC2_SNORM:
>        return PIPE_FORMAT_LATC2_SNORM;
> +   /* The destination RGBA format mustn't be changed, because it's also
> +    * a destination format of the unpack/decompression function. */
>     case MESA_FORMAT_ETC1_RGB8:
> -      return PIPE_FORMAT_ETC1_RGB8;
> +      return st->has_etc1 ? PIPE_FORMAT_ETC1_RGB8 :  
> PIPE_FORMAT_R8G8B8A8_UNORM;
>    /* signed normalized formats */
>     case MESA_FORMAT_R_SNORM8:
> @@ -801,9 +803,11 @@ test_format_conversion(struct st_context *st)
>    /* test all Mesa formats */
>     for (i = 1; i < MESA_FORMAT_COUNT; i++) {
> -      /* ETC2 formats are translated differently, skip them. */
> +      /* ETC formats are translated differently, skip them. */
>        if (_mesa_is_format_etc2(i))
>           continue;
> +      if (i == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)
> +         continue;
>       enum pipe_format pf = st_mesa_format_to_pipe_format(st, i);
>        if (pf != PIPE_FORMAT_NONE) {
> @@ -815,6 +819,11 @@ test_format_conversion(struct st_context *st)
>     /* Test all Gallium formats */
>     for (i = 1; i < PIPE_FORMAT_COUNT; i++) {
>        mesa_format mf = st_pipe_format_to_mesa_format(i);
> +
> +      /* ETC formats are translated differently, skip them. */
> +      if (i == PIPE_FORMAT_ETC1_RGB8 && !st->has_etc1)
> +         continue;
> +
>        if (mf != MESA_FORMAT_NONE) {
>           enum pipe_format pf = st_mesa_format_to_pipe_format(st, mf);
>           assert(pf == i);

Reviewed-by: Glenn Kennard <glenn.kennard at gmail.com>


More information about the mesa-dev mailing list