From: Kristian H. Kristensen Date: Wed, 23 Oct 2019 02:47:50 +0000 (-0700) Subject: freedreno/a6xx: Build the right draw command for tessellation X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f0ef3e96970e0b8388c9d7be678b70217b3a8506;p=mesa.git freedreno/a6xx: Build the right draw command for tessellation 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 Acked-by: Eric Anholt Reviewed-by: Rob Clark --- diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_context.c b/src/gallium/drivers/freedreno/a6xx/fd6_context.c index 1247b903501..d613e4c5e2b 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_context.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_context.c @@ -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 */ }; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c index a635e66d932..4a36b7e7c9a 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c @@ -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 |= diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h index f5ae07eb892..ecee0a87878 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.h +++ b/src/gallium/drivers/freedreno/freedreno_batch.h @@ -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: