freedreno/a6xx: Build the right draw command for tessellation
authorKristian H. Kristensen <hoegsberg@google.com>
Wed, 23 Oct 2019 02:47:50 +0000 (19:47 -0700)
committerKristian H. Kristensen <hoegsberg@google.com>
Fri, 8 Nov 2019 00:40:27 +0000 (16:40 -0800)
We need to select the right primitive type, set a bit to turn on
tessellation and or in the TES output primitive type.

Signed-off-by: Kristian H. Kristensen <hoegsberg@google.com>
Acked-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a6xx/fd6_context.c
src/gallium/drivers/freedreno/a6xx/fd6_draw.c
src/gallium/drivers/freedreno/freedreno_batch.h

index 1247b903501923a28c5ddd928e2778eea05ff9a5..d613e4c5e2b4caf715be5b9293e2750083e5b05e 100644 (file)
@@ -77,6 +77,7 @@ static const uint8_t primtypes[] = {
                [PIPE_PRIM_LINE_STRIP_ADJACENCY]        = DI_PT_LINESTRIP_ADJ,
                [PIPE_PRIM_TRIANGLES_ADJACENCY]         = DI_PT_TRI_ADJ,
                [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY]    = DI_PT_TRISTRIP_ADJ,
+               [PIPE_PRIM_PATCHES]                     = DI_PT_PATCHES0,
                [PIPE_PRIM_MAX]                         = DI_PT_RECTLIST,  /* internal clear blits */
 };
 
index a635e66d9323b41d9a1a3beef7a5cd41fd44fc0a..4a36b7e7c9a9d6888f267760c690088e1d29c710 100644 (file)
@@ -211,6 +211,53 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
        struct fd_ringbuffer *ring = ctx->batch->draw;
        enum pc_di_primtype primtype = ctx->primtypes[info->mode];
 
+       uint32_t tess_draw0 = 0;
+       if (info->mode == PIPE_PRIM_PATCHES) {
+               shader_info *ds_info = &emit.ds->shader->nir->info;
+               uint32_t factor_stride;
+               uint32_t patch_type;
+
+               switch (ds_info->tess.primitive_mode) {
+               case GL_ISOLINES:
+                       patch_type = TESS_ISOLINES;
+                       factor_stride = 12;
+                       break;
+               case GL_TRIANGLES:
+                       patch_type = TESS_TRIANGLES;
+                       factor_stride = 20;
+                       break;
+               case GL_QUADS:
+                       patch_type = TESS_QUADS;
+                       factor_stride = 28;
+                       break;
+               default:
+                       unreachable("bad tessmode");
+               }
+
+               primtype = DI_PT_PATCHES0 + info->vertices_per_patch;
+               tess_draw0 |= CP_DRAW_INDX_OFFSET_0_PATCH_TYPE(patch_type) |
+                       CP_DRAW_INDX_OFFSET_0_TESS_ENABLE;
+
+               ctx->batch->tessellation = true;
+               ctx->batch->tessparam_size = MAX2(ctx->batch->tessparam_size,
+                               emit.hs->shader->output_size * 4 * info->count);
+               ctx->batch->tessfactor_size = MAX2(ctx->batch->tessfactor_size,
+                               factor_stride * info->count);
+
+               if (!ctx->batch->tess_addrs_constobj) {
+                       /* Reserve space for the bo address - we'll write them later in
+                        * setup_tess_buffers().  We need 2 bo address, but indirect
+                        * constant upload needs at least 4 vec4s.
+                        */
+                       unsigned size = 4 * 16;
+
+                       ctx->batch->tess_addrs_constobj = fd_submit_new_ringbuffer(
+                               ctx->batch->submit, size, FD_RINGBUFFER_STREAMING);
+
+                       ctx->batch->tess_addrs_constobj->cur += size;
+               }
+       }
+
        fd6_emit_state(ring, &emit);
 
        OUT_PKT4(ring, REG_A6XX_VFD_INDEX_OFFSET, 2);
@@ -230,11 +277,10 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
        emit_marker6(ring, 7);
 
        uint32_t draw0 =
+               CP_DRAW_INDX_OFFSET_0_VIS_CULL(USE_VISIBILITY) |
                CP_DRAW_INDX_OFFSET_0_PRIM_TYPE(primtype) |
-               CP_DRAW_INDX_OFFSET_0_VIS_CULL(USE_VISIBILITY);
-
-       if (emit.key.gs)
-               draw0 |= CP_DRAW_INDX_OFFSET_0_GS_ENABLE;
+               tess_draw0 |
+               COND(emit.key.gs, CP_DRAW_INDX_OFFSET_0_GS_ENABLE);
 
        if (info->index_size) {
                draw0 |=
index f5ae07eb892898b73e2314f08d199d2ad952d566..ecee0a8787819b8cc12b2fc3b32cf9b43e01767a 100644 (file)
@@ -103,6 +103,7 @@ struct fd_batch {
        bool flushed : 1;
        bool blit : 1;
        bool back_blit : 1;      /* only blit so far is resource shadowing back-blit */
+       bool tessellation : 1;      /* tessellation used in batch */
 
        /* Keep track if WAIT_FOR_IDLE is needed for registers we need
         * to update via RMW: