freedreno/a2xx: add missing vertex formats (SSCALE/USCALE/FIXED)
authorJonathan Marek <jonathan@marek.ca>
Fri, 6 Sep 2019 16:59:15 +0000 (12:59 -0400)
committerJonathan Marek <jonathan@marek.ca>
Wed, 30 Oct 2019 18:04:17 +0000 (18:04 +0000)
Mostly for vertex formats, but they are supported as texture formats too
(untested however).

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Rob Clark <robdclark@gmail.com>
src/freedreno/registers/a2xx.xml
src/gallium/drivers/freedreno/a2xx/fd2_gmem.c
src/gallium/drivers/freedreno/a2xx/fd2_program.c
src/gallium/drivers/freedreno/a2xx/fd2_screen.c
src/gallium/drivers/freedreno/a2xx/fd2_texture.c
src/gallium/drivers/freedreno/a2xx/fd2_util.c
src/gallium/drivers/freedreno/a2xx/fd2_util.h
src/gallium/drivers/freedreno/a2xx/instr-a2xx.h

index 4817ab31bb3316dee2fb39d789ae75a7d3c8db75..e486f804bc71fa5874f22052e6415b7e6e50290d 100644 (file)
@@ -1620,7 +1620,7 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
                <bitfield name="SWIZ_Y" low="4" high="6" type="sq_tex_swiz"/>
                <bitfield name="SWIZ_Z" low="7" high="9" type="sq_tex_swiz"/>
                <bitfield name="SWIZ_W" low="10" high="12" type="sq_tex_swiz"/>
-               <bitfield name="EXP_ADJUST" low="13" high="18" type="uint"/>
+               <bitfield name="EXP_ADJUST" low="13" high="18" type="int"/>
                <bitfield name="XY_MAG_FILTER" low="19" high="20" type="sq_tex_filter"/>
                <bitfield name="XY_MIN_FILTER" low="21" high="22" type="sq_tex_filter"/>
                <bitfield name="MIP_FILTER" low="23" high="24" type="sq_tex_filter"/>
index 6a78db5377e97ee758c2eb4b1a14f91d46e88329..bf112149b03d317408d36280239ae5c7dc39e939 100644 (file)
@@ -52,6 +52,7 @@ static uint32_t fmt2swap(enum pipe_format format)
        case PIPE_FORMAT_B5G5R5X1_UNORM:
        case PIPE_FORMAT_B4G4R4A4_UNORM:
        case PIPE_FORMAT_B4G4R4X4_UNORM:
+       case PIPE_FORMAT_B2G3R3_UNORM:
                return 1;
        default:
                return 0;
@@ -248,7 +249,7 @@ emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base,
                        A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
                        A2XX_SQ_TEX_0_PITCH(slice->pitch));
        OUT_RELOC(ring, rsc->bo, offset,
-                       fd2_pipe2surface(format) |
+                       A2XX_SQ_TEX_1_FORMAT(fd2_pipe2surface(format).format) |
                        A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL), 0);
        OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) |
                        A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1));
index c4c23ff0d5b5cdcf385efa35436ec01b2d2dfce1..9efc473b4a7677c9325f8b3485665317ac03267d 100644 (file)
@@ -166,30 +166,15 @@ static void
 patch_vtx_fetch(struct fd_context *ctx, struct pipe_vertex_element *elem,
        instr_fetch_vtx_t *instr, uint16_t dst_swiz)
 {
-       struct pipe_vertex_buffer *vb =
-                               &ctx->vtx.vertexbuf.vb[elem->vertex_buffer_index];
-       enum pipe_format format = elem->src_format;
-       const struct util_format_description *desc =
-                       util_format_description(format);
-       unsigned j;
-
-       /* Find the first non-VOID channel. */
-       for (j = 0; j < 4; j++)
-               if (desc->channel[j].type != UTIL_FORMAT_TYPE_VOID)
-                       break;
-
-       instr->format = fd2_pipe2surface(format);
-       instr->num_format_all = !desc->channel[j].normalized;
-       instr->format_comp_all = desc->channel[j].type == UTIL_FORMAT_TYPE_SIGNED;
-       instr->stride = vb->stride;
+       struct surface_format fmt = fd2_pipe2surface(elem->src_format);
+
+       instr->dst_swiz = fd2_vtx_swiz(elem->src_format, dst_swiz);
+       instr->format_comp_all = fmt.sign == SQ_TEX_SIGN_SIGNED;
+       instr->num_format_all = fmt.num_format;
+       instr->format = fmt.format;
+       instr->exp_adjust_all = fmt.exp_adjust;
+       instr->stride = ctx->vtx.vertexbuf.vb[elem->vertex_buffer_index].stride;
        instr->offset = elem->src_offset;
-
-       unsigned swiz = 0;
-       for (int i = 0; i < 4; i++) {
-               unsigned s = dst_swiz >> i*3 & 7;
-               swiz |= (s >= 4 ? s : desc->swizzle[s]) << i*3;
-       }
-       instr->dst_swiz = swiz;
 }
 
 static void
index 42c0c024e615573a45dc3f4ae75ae258b5964533..361660857eef7f2a910e6d6368387adca80f4fb0 100644 (file)
@@ -59,13 +59,13 @@ fd2_screen_is_format_supported(struct pipe_screen *pscreen,
        }
 
        if ((usage & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_VERTEX_BUFFER)) &&
-           !util_format_is_srgb(format)) {
-               enum a2xx_sq_surfaceformat fmt = fd2_pipe2surface(format);
-               unsigned block_size = util_format_get_blocksize(format);
-               if (fmt != ~0)
-                       retval |= usage & PIPE_BIND_VERTEX_BUFFER;
-               if (fmt != ~0 && block_size != 3 && block_size != 6 &&
-                   (block_size != 12 || format == PIPE_FORMAT_R32G32B32_FLOAT))
+                       !util_format_is_srgb(format) &&
+                       !util_format_is_pure_integer(format) &&
+                       fd2_pipe2surface(format).format != FMT_INVALID) {
+               retval |= usage & PIPE_BIND_VERTEX_BUFFER;
+               /* the only npot blocksize supported texture format is R32G32B32_FLOAT */
+               if (util_is_power_of_two_or_zero(util_format_get_blocksize(format)) ||
+                               format == PIPE_FORMAT_R32G32B32_FLOAT)
                        retval |= usage & PIPE_BIND_SAMPLER_VIEW;
        }
 
index 7aa26ca56734c74feeb83bb78fa7130476821e90..b6ceb323f0b9d5873573b41fd70571fc08ce6e0f 100644 (file)
@@ -170,6 +170,7 @@ fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 {
        struct fd2_pipe_sampler_view *so = CALLOC_STRUCT(fd2_pipe_sampler_view);
        struct fd_resource *rsc = fd_resource(prsc);
+       struct surface_format fmt = fd2_pipe2surface(cso->format);
 
        if (!so)
                return NULL;
@@ -180,26 +181,24 @@ fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
        so->base.reference.count = 1;
        so->base.context = pctx;
 
-       enum sq_tex_sign sign = SQ_TEX_SIGN_UNSIGNED;
-       if (util_format_is_snorm(cso->format))
-               sign = SQ_TEX_SIGN_SIGNED;
-       /* note: SQ_TEX_SIGN_GAMMA same as SQ_TEX_SIGN_UNSIGNED (a200) */
-
        so->tex0 =
-               A2XX_SQ_TEX_0_SIGN_X(sign) |
-               A2XX_SQ_TEX_0_SIGN_Y(sign) |
-               A2XX_SQ_TEX_0_SIGN_Z(sign) |
-               A2XX_SQ_TEX_0_SIGN_W(sign) |
+               A2XX_SQ_TEX_0_SIGN_X(fmt.sign) |
+               A2XX_SQ_TEX_0_SIGN_Y(fmt.sign) |
+               A2XX_SQ_TEX_0_SIGN_Z(fmt.sign) |
+               A2XX_SQ_TEX_0_SIGN_W(fmt.sign) |
                A2XX_SQ_TEX_0_PITCH(rsc->slices[0].pitch) |
                COND(rsc->tile_mode, A2XX_SQ_TEX_0_TILED);
        so->tex1 =
-               A2XX_SQ_TEX_1_FORMAT(fd2_pipe2surface(cso->format)) |
+               A2XX_SQ_TEX_1_FORMAT(fmt.format) |
                A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL);
        so->tex2 =
                A2XX_SQ_TEX_2_HEIGHT(prsc->height0 - 1) |
                A2XX_SQ_TEX_2_WIDTH(prsc->width0 - 1);
-       so->tex3 = fd2_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
-                       cso->swizzle_b, cso->swizzle_a);
+       so->tex3 =
+               A2XX_SQ_TEX_3_NUM_FORMAT(fmt.num_format) |
+               fd2_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
+                            cso->swizzle_b, cso->swizzle_a) |
+               A2XX_SQ_TEX_3_EXP_ADJUST(fmt.exp_adjust);
 
        so->tex4 =
                A2XX_SQ_TEX_4_MIP_MIN_LEVEL(fd_sampler_first_level(cso)) |
index af570701e54a2cb9f17553356b1eda8a0d77906a..ed1bbb1368dada4f313490248f69b663db0d4fe9 100644 (file)
@@ -29,8 +29,8 @@
 
 #include "fd2_util.h"
 
-enum a2xx_sq_surfaceformat
-fd2_pipe2surface(enum pipe_format format)
+static enum a2xx_sq_surfaceformat
+pipe2surface(enum pipe_format format, struct surface_format *fmt)
 {
        const struct util_format_description *desc = util_format_description(format);
 
@@ -66,6 +66,15 @@ fd2_pipe2surface(enum pipe_format format)
        for (unsigned i = 0; i < 4; i++)
                channel_size |= desc->channel[i].size << i*8;
 
+       unsigned i = util_format_get_first_non_void_channel(format);
+       if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
+               desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
+               fmt->sign = SQ_TEX_SIGN_SIGNED;
+       if (!desc->channel[i].normalized)
+               fmt->num_format = SQ_TEX_NUM_FORMAT_INT;
+       if (desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
+               fmt->exp_adjust = -16;
+
        /* Note: the 3 channel 24bpp/48bpp/96bpp formats are only for vertex fetch
         * we can use the 4 channel format and ignore the 4th component just isn't used
         * XXX: is it possible for the extra loaded component to cause a MMU fault?
@@ -83,7 +92,7 @@ fd2_pipe2surface(enum pipe_format format)
                CASE(32, 32, 32,  0): return FMT_32_32_32_FLOAT;
                CASE(32, 32, 32, 32): return FMT_32_32_32_32_FLOAT;
                }
-       } else if (desc->is_unorm || desc->is_snorm) {
+       } else {
                switch (channel_size) {
                CASE( 8,  0,  0,  0): return FMT_8;
                CASE( 8,  8,  0,  0): return FMT_8_8;
@@ -102,6 +111,7 @@ fd2_pipe2surface(enum pipe_format format)
                CASE( 5,  6,  5,  0): return FMT_5_6_5;
                CASE(10, 10, 10,  2): return FMT_2_10_10_10;
                CASE( 8, 24,  0,  0): return FMT_24_8;
+               CASE( 2,  3,  3,  0): return FMT_2_3_3; /* Note: R/B swapped */
                }
        }
 #undef CASE
@@ -109,6 +119,18 @@ fd2_pipe2surface(enum pipe_format format)
        return ~0;
 }
 
+struct surface_format
+fd2_pipe2surface(enum pipe_format format)
+{
+       struct surface_format fmt = {
+               .sign = SQ_TEX_SIGN_UNSIGNED,
+               .num_format = SQ_TEX_NUM_FORMAT_FRAC,
+               .exp_adjust = 0,
+       };
+       fmt.format = pipe2surface(format, &fmt);
+       return fmt;
+}
+
 enum a2xx_colorformatx
 fd2_pipe2color(enum pipe_format format)
 {
@@ -116,6 +138,8 @@ fd2_pipe2color(enum pipe_format format)
        /* 8-bit buffers. */
        case PIPE_FORMAT_R8_UNORM:
                return COLORX_8;
+       case PIPE_FORMAT_B2G3R3_UNORM:
+               return COLORX_2_3_3; /* note: untested */
 
        /* 16-bit buffers. */
        case PIPE_FORMAT_B5G6R5_UNORM:
@@ -190,3 +214,18 @@ fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r, unsigned swizzle_g,
                        A2XX_SQ_TEX_3_SWIZ_Z(tex_swiz(rswiz[2])) |
                        A2XX_SQ_TEX_3_SWIZ_W(tex_swiz(rswiz[3]));
 }
+
+uint32_t
+fd2_vtx_swiz(enum pipe_format format, unsigned swizzle)
+{
+       const struct util_format_description *desc =
+                       util_format_description(format);
+       unsigned char swiz[4], rswiz[4];
+
+       for (unsigned i = 0; i < 4; i++)
+               swiz[i] = (swizzle >> i * 3) & 7;
+
+       util_format_compose_swizzles(desc->swizzle, swiz, rswiz);
+
+       return rswiz[0] | rswiz[1] << 3 | rswiz[2] << 6 | rswiz[3] << 9;
+}
index d2758f3f0b298a5650758df201cfae7222d1bbdf..cf945b14475e9a43af387f804818c0c49950edab 100644 (file)
 
 #include "a2xx.xml.h"
 
-enum a2xx_sq_surfaceformat fd2_pipe2surface(enum pipe_format format);
+struct surface_format {
+#define FMT_INVALID 0x7f
+       enum a2xx_sq_surfaceformat format : 7;
+       enum sq_tex_sign sign : 2;
+       enum sq_tex_num_format num_format : 1;
+       int exp_adjust : 6;
+};
+
+struct surface_format fd2_pipe2surface(enum pipe_format format);
 enum a2xx_colorformatx fd2_pipe2color(enum pipe_format format);
 uint32_t fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r,
                unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
+uint32_t fd2_vtx_swiz(enum pipe_format format, unsigned swizzle);
 
 /* convert x,y to dword */
 static inline uint32_t xy2d(uint16_t x, uint16_t y)
index 2591062ee3c56b4c86f1ae8192fadc81979ddbac..0078b24b509f438352112ca938b17da02bb36ff2 100644 (file)
@@ -372,8 +372,8 @@ typedef struct PACKED {
        uint8_t             signed_rf_mode_all       : 1;
        uint8_t             reserved1                : 1;
        instr_surf_fmt_t    format                   : 6;
-       uint8_t             reserved2                : 1;
-       uint8_t             exp_adjust_all           : 7;
+       uint8_t             reserved2                : 2;
+       uint8_t             exp_adjust_all           : 6;
        uint8_t             reserved3                : 1;
        uint8_t             pred_select              : 1;
        /* dword2: */