summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian H. Kristensen <[email protected]>2019-10-22 19:47:50 -0700
committerKristian H. Kristensen <[email protected]>2019-11-07 16:40:27 -0800
commitf0ef3e96970e0b8388c9d7be678b70217b3a8506 (patch)
treec7aa888e07b07f0c5430a24cb72d886f77ec4dc7
parent7272e8a70965d679d4545dffbc8099d99431f80b (diff)
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 <[email protected]> Acked-by: Eric Anholt <[email protected]> Reviewed-by: Rob Clark <[email protected]>
-rw-r--r--src/gallium/drivers/freedreno/a6xx/fd6_context.c1
-rw-r--r--src/gallium/drivers/freedreno/a6xx/fd6_draw.c54
-rw-r--r--src/gallium/drivers/freedreno/freedreno_batch.h1
3 files changed, 52 insertions, 4 deletions
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: