[PATCH 2/3] etnaviv: Add support for swizzled texture formats

Wladimir J. van der Laan laanwj at gmail.com
Tue May 16 08:41:28 UTC 2017


---
 src/gallium/drivers/etnaviv/etnaviv_format.c  | 50 +++++++++++++++++++++------
 src/gallium/drivers/etnaviv/etnaviv_format.h  |  3 ++
 src/gallium/drivers/etnaviv/etnaviv_texture.c | 15 +++++---
 3 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_format.c b/src/gallium/drivers/etnaviv/etnaviv_format.c
index 88bb520..23bb6c1 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_format.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_format.c
@@ -40,6 +40,7 @@ struct etna_format {
    unsigned tex;
    unsigned rs;
    boolean present;
+   const unsigned char tex_swz[4];
 };
 
 #define RS_FORMAT_NONE ~0
@@ -56,22 +57,27 @@ struct etna_format {
 #define TX_FORMAT_EXT_SHIFT      8
 #define TX_FORMAT_EXT_MASK       0xff00
 
-/* vertex + texture (base) */
-#define VT(pipe, vtxfmt, texfmt, rsfmt)           \
+#define SWIZ_XYZW {0,1,2,3}
+#define SWIZ_X001 {0,4,4,5}
+
+/* vertex + texture (base, with swizzle) */
+#define VT(pipe, vtxfmt, texfmt, swiz, rsfmt)             \
    [PIPE_FORMAT_##pipe] = {                               \
       .vtx = VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_##vtxfmt, \
       .tex = TEXTURE_FORMAT_##texfmt,                     \
       .rs = RS_FORMAT_##rsfmt,                            \
       .present = 1,                                       \
+      .tex_swz = (const unsigned char[])swiz,             \
    }
 
-/* vertex + texture (extended) */
-#define VTE(pipe, vtxfmt, extfmt, rsfmt)           \
+/* vertex + texture (extended, with swizzle) */
+#define VTE(pipe, vtxfmt, extfmt, swiz, rsfmt)            \
    [PIPE_FORMAT_##pipe] = {                               \
       .vtx = VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_##vtxfmt, \
       .tex = TEXTURE_FORMAT_EXT_##extfmt << TX_FORMAT_EXT_SHIFT, \
       .rs = RS_FORMAT_##rsfmt,                            \
       .present = 1,                                       \
+      .tex_swz = (const unsigned char[])swiz,             \
    }
 
 /* texture-only (base) */
@@ -81,15 +87,27 @@ struct etna_format {
       .tex = TEXTURE_FORMAT_##fmt, \
       .rs = RS_FORMAT_##rsfmt,     \
       .present = 1,                \
+      .tex_swz = (const unsigned char[])SWIZ_XYZW,         \
    }
 
-/* texture-only (extended) */
-#define _TE(pipe, fmt, rsfmt)       \
+/* texture-only (base, with swizzle) */
+#define _TS(pipe, fmt, rsfmt, swiz)       \
+   [PIPE_FORMAT_##pipe] = {        \
+      .vtx = ETNA_NO_MATCH,        \
+      .tex = TEXTURE_FORMAT_##fmt, \
+      .rs = RS_FORMAT_##rsfmt,     \
+      .present = 1,                \
+      .tex_swz = (const unsigned char[])swiz,         \
+   }
+
+/* texture-only (extended, with swizzle) */
+#define _TE(pipe, fmt, rsfmt, swiz)       \
    [PIPE_FORMAT_##pipe] = {        \
       .vtx = ETNA_NO_MATCH,        \
       .tex = TEXTURE_FORMAT_EXT_##fmt << TX_FORMAT_EXT_SHIFT, \
       .rs = RS_FORMAT_##rsfmt,     \
       .present = 1,                \
+      .tex_swz = (const unsigned char[])swiz,           \
    }
 
 /* vertex-only */
@@ -103,8 +121,8 @@ struct etna_format {
 
 static struct etna_format formats[PIPE_FORMAT_COUNT] = {
    /* 8-bit */
-   V_(R8_UNORM,   UNSIGNED_BYTE, NONE),
-   VTE(R8_SNORM,  BYTE,          R8_SNORM, NONE),
+   VT(R8_UNORM,   UNSIGNED_BYTE, L8, SWIZ_X001, NONE),
+   VTE(R8_SNORM,  BYTE,          R8_SNORM, SWIZ_XYZW, NONE),
    V_(R8_UINT,    UNSIGNED_BYTE, NONE),
    V_(R8_SINT,    BYTE,          NONE),
    V_(R8_USCALED, UNSIGNED_BYTE, NONE),
@@ -131,7 +149,7 @@ static struct etna_format formats[PIPE_FORMAT_COUNT] = {
    _T(B5G5R5A1_UNORM, A1R5G5B5, A1R5G5B5),
    _T(B5G5R5X1_UNORM, X1R5G5B5, X1R5G5B5),
 
-   VTE(R8G8_UNORM,  UNSIGNED_BYTE,  G8R8, NONE),
+   VTE(R8G8_UNORM,  UNSIGNED_BYTE,  G8R8, SWIZ_XYZW, NONE),
    V_(R8G8_SNORM,   BYTE,           NONE),
    V_(R8G8_UINT,    UNSIGNED_BYTE,  NONE),
    V_(R8G8_SINT,    BYTE,           NONE),
@@ -247,7 +265,6 @@ static struct etna_format formats[PIPE_FORMAT_COUNT] = {
 uint32_t
 translate_texture_format(enum pipe_format fmt)
 {
-   /* XXX with swizzle on newer chips we can support much more */
    if (!formats[fmt].present || formats[fmt].tex == ETNA_NO_MATCH)
       return ETNA_NO_MATCH;
 
@@ -263,6 +280,19 @@ translate_texture_format_ext(enum pipe_format fmt)
    return (formats[fmt].tex & TX_FORMAT_EXT_MASK) >> TX_FORMAT_EXT_SHIFT;
 }
 
+bool
+translate_texture_format_swiz(enum pipe_format fmt, unsigned char tex_swz[4])
+{
+   if (!formats[fmt].present)
+      return false;
+
+   tex_swz[0] = formats[fmt].tex_swz[0];
+   tex_swz[1] = formats[fmt].tex_swz[1];
+   tex_swz[2] = formats[fmt].tex_swz[2];
+   tex_swz[3] = formats[fmt].tex_swz[3];
+   return true;
+}
+
 uint32_t
 translate_rs_format(enum pipe_format fmt)
 {
diff --git a/src/gallium/drivers/etnaviv/etnaviv_format.h b/src/gallium/drivers/etnaviv/etnaviv_format.h
index 5dbab4d..ce75161 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_format.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_format.h
@@ -47,4 +47,7 @@ translate_rs_format_rb_swap(enum pipe_format fmt);
 uint32_t
 translate_vertex_format_type(enum pipe_format fmt);
 
+bool
+translate_texture_format_swiz(enum pipe_format fmt, unsigned char tex_swz[4]);
+
 #endif /* ETNAVIV_FORMAT_H_ */
diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture.c b/src/gallium/drivers/etnaviv/etnaviv_texture.c
index 28df5b2..473369e 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_texture.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_texture.c
@@ -212,11 +212,18 @@ etna_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
       return NULL;
    }
 
+   /* Compose swizzle from sampler view and texture format */
+   unsigned char swiz_so[4] = {so->swizzle_r,so->swizzle_g,so->swizzle_b,so->swizzle_a};
+   unsigned char swiz_fmt[4];
+   unsigned char swiz_out[4];
+   translate_texture_format_swiz(sv->base.format, swiz_fmt);
+   util_format_compose_swizzles(swiz_fmt, swiz_so, swiz_out);
+
    sv->TE_SAMPLER_CONFIG1 = VIVS_TE_SAMPLER_CONFIG1_FORMAT_EXT(translate_texture_format_ext(sv->base.format)) |
-                            VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_R(so->swizzle_r) |
-                            VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_G(so->swizzle_g) |
-                            VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_B(so->swizzle_b) |
-                            VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_A(so->swizzle_a) |
+                            VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_R(swiz_out[0]) |
+                            VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_G(swiz_out[1]) |
+                            VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_B(swiz_out[2]) |
+                            VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_A(swiz_out[3]) |
                             VIVS_TE_SAMPLER_CONFIG1_HALIGN(res->halign);
    sv->TE_SAMPLER_SIZE = VIVS_TE_SAMPLER_SIZE_WIDTH(res->base.width0) |
                          VIVS_TE_SAMPLER_SIZE_HEIGHT(res->base.height0);
-- 
2.7.4



More information about the etnaviv mailing list