st/mesa/i965: Allow decompressing ETC2 to GL_RGBA
authorTomeu Vizoso <tomeu.vizoso@collabora.com>
Fri, 22 Jun 2018 13:59:08 +0000 (15:59 +0200)
committerGert Wollny <gw.fossdev@gmail.com>
Mon, 2 Jul 2018 07:33:33 +0000 (09:33 +0200)
When Mesa itself implements ETC2 decompression, it currently
decompresses to formats in the GL_BGRA component order.

That can be problematic for drivers which cannot upload the texture data
as GL_BGRA, such as Virgl when it's backed by GLES on the host.

So this commit adds a flag to _mesa_unpack_etc2_format so callers can
specify the optimal component order.

In Gallium's case, it will be requested if the format isn't in
PIPE_FORMAT_B8G8R8A8_SRGB format.

For i965, it will remain GL_BGRA, as before.

v2: * Remove unnecesary include (Emil Velikov)

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/mesa/drivers/dri/i965/intel_mipmap_tree.c
src/mesa/main/texcompress_etc.c
src/mesa/main/texcompress_etc.h
src/mesa/state_tracker/st_cb_texture.c

index 6b89bf6848afb7c969b65c2c226576087ce9e4e9..4a61cee08b5ec521141939943089832b21d1cbbb 100644 (file)
@@ -3356,7 +3356,7 @@ intel_miptree_unmap_etc(struct brw_context *brw,
    else
       _mesa_unpack_etc2_format(dst, mt->surf.row_pitch,
                                map->ptr, map->stride,
-                               map->w, map->h, mt->etc_format);
+                              map->w, map->h, mt->etc_format, true);
 
    intel_miptree_unmap_raw(mt);
    free(map->buffer);
index 099787b7f407633b1cc4f9d853ffb11a7fa40b19..b39ab33d36fc6607d29a6c35ac2c9b499e261172 100644 (file)
@@ -719,7 +719,8 @@ etc2_unpack_srgb8(uint8_t *dst_row,
                   const uint8_t *src_row,
                   unsigned src_stride,
                   unsigned width,
-                  unsigned height)
+                 unsigned height,
+                 bool bgra)
 {
    const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
    struct etc2_block block;
@@ -741,11 +742,14 @@ etc2_unpack_srgb8(uint8_t *dst_row,
             for (i = 0; i < w; i++) {
                etc2_rgb8_fetch_texel(&block, i, j, dst,
                                      false /* punchthrough_alpha */);
-               /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
-               tmp = dst[0];
-               dst[0] = dst[2];
-               dst[2] = tmp;
-               dst[3] = 255;
+
+              if (bgra) {
+                 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
+                 tmp = dst[0];
+                 dst[0] = dst[2];
+                 dst[2] = tmp;
+                 dst[3] = 255;
+              }
 
                dst += comps;
             }
@@ -801,7 +805,8 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row,
                          const uint8_t *src_row,
                          unsigned src_stride,
                          unsigned width,
-                         unsigned height)
+                        unsigned height,
+                        bool bgra)
 {
    /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block
     * of RGBA8888 information is compressed to 128 bits. To decode a block, the
@@ -825,11 +830,13 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row,
             for (i = 0; i < w; i++) {
                etc2_rgba8_fetch_texel(&block, i, j, dst);
 
-               /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
-               tmp = dst[0];
-               dst[0] = dst[2];
-               dst[2] = tmp;
-               dst[3] = dst[3];
+              if (bgra) {
+                 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
+                 tmp = dst[0];
+                 dst[0] = dst[2];
+                 dst[2] = tmp;
+                 dst[3] = dst[3];
+              }
 
                dst += comps;
             }
@@ -1058,7 +1065,8 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row,
                                      const uint8_t *src_row,
                                      unsigned src_stride,
                                      unsigned width,
-                                     unsigned height)
+                                    unsigned height,
+                                    bool bgra)
 {
    const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
    struct etc2_block block;
@@ -1078,11 +1086,14 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row,
             for (i = 0; i < w; i++) {
                etc2_rgb8_fetch_texel(&block, i, j, dst,
                                      true /* punchthrough_alpha */);
-               /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
-               tmp = dst[0];
-               dst[0] = dst[2];
-               dst[2] = tmp;
-               dst[3] = dst[3];
+
+              if (bgra) {
+                 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
+                 tmp = dst[0];
+                 dst[0] = dst[2];
+                 dst[2] = tmp;
+                 dst[3] = dst[3];
+              }
 
                dst += comps;
             }
@@ -1206,7 +1217,8 @@ _mesa_unpack_etc2_format(uint8_t *dst_row,
                          unsigned src_stride,
                          unsigned src_width,
                          unsigned src_height,
-                         mesa_format format)
+                        mesa_format format,
+                        bool bgra)
 {
    if (format == MESA_FORMAT_ETC2_RGB8)
       etc2_unpack_rgb8(dst_row, dst_stride,
@@ -1215,7 +1227,7 @@ _mesa_unpack_etc2_format(uint8_t *dst_row,
    else if (format == MESA_FORMAT_ETC2_SRGB8)
       etc2_unpack_srgb8(dst_row, dst_stride,
                         src_row, src_stride,
-                        src_width, src_height);
+                       src_width, src_height, bgra);
    else if (format == MESA_FORMAT_ETC2_RGBA8_EAC)
       etc2_unpack_rgba8(dst_row, dst_stride,
                         src_row, src_stride,
@@ -1223,7 +1235,7 @@ _mesa_unpack_etc2_format(uint8_t *dst_row,
    else if (format == MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC)
       etc2_unpack_srgb8_alpha8(dst_row, dst_stride,
                                src_row, src_stride,
-                               src_width, src_height);
+                              src_width, src_height, bgra);
    else if (format == MESA_FORMAT_ETC2_R11_EAC)
       etc2_unpack_r11(dst_row, dst_stride,
                       src_row, src_stride,
@@ -1247,7 +1259,7 @@ _mesa_unpack_etc2_format(uint8_t *dst_row,
    else if (format == MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1)
       etc2_unpack_srgb8_punchthrough_alpha1(dst_row, dst_stride,
                                             src_row, src_stride,
-                                            src_width, src_height);
+                                           src_width, src_height, bgra);
 }
 
 
index 319b7bea7154a7faa30ead618f234d0a996ccd1a..2c764b88b09a818c66b328f9de783c486edaa15b 100644 (file)
@@ -77,7 +77,8 @@ _mesa_unpack_etc2_format(uint8_t *dst_row,
                          unsigned src_stride,
                          unsigned src_width,
                          unsigned src_height,
-                         mesa_format format);
+                        mesa_format format,
+                        bool bgra);
 
 compressed_fetch_func
 _mesa_get_etc_fetch_func(mesa_format format);
index 40a1ce1108754c4c7b1d99fbe7866cd35f5e8bc0..99209abcd62aad60c7278ce424b4250f0e24245b 100644 (file)
@@ -326,10 +326,12 @@ st_UnmapTextureImage(struct gl_context *ctx,
                                        transfer->box.width, transfer->box.height);
          }
          else {
+           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);
+                                    texImage->TexFormat,
+                                    bgra);
          }
       }