From c90c77924a1bf307ea81394bc36441ab95e748b8 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Thu, 18 Aug 2022 12:31:34 +0200 Subject: [PATCH] tu: Split out primtype calculation for tess With pipeline libraries, we may not know the HW primtype if the user passes a primtype of PATCHES because the tess shaders and input assembly state may be in different pipelines. We need to split out the patch control points and only determine the final primtype once everything has been merged. In preparation for this, and for dynamic patch control points, calculate the final primtype dynamically. We already had a draw-time workaround for dynamic primtype we can now remove, so this actually reduces the amount of draw-time work we have to do anyway. Part-of: --- src/freedreno/vulkan/tu_cmd_buffer.c | 18 ++++-------------- src/freedreno/vulkan/tu_pipeline.c | 3 +-- src/freedreno/vulkan/tu_pipeline.h | 1 + 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index ff161b6be1f..c9cc6571ef6 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -2568,7 +2568,7 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer, uint32_t subdraw_size = MIN2(TU_TESS_FACTOR_SIZE / ir3_tess_factor_stride(pipeline->tess.patch_type), TU_TESS_PARAM_SIZE / pipeline->tess.param_stride); /* convert from # of patches to draw count */ - subdraw_size *= (pipeline->ia.primtype - DI_PT_PATCHES0); + subdraw_size *= pipeline->tess.patch_control_points; /* TODO: Move this packet to pipeline state, since it's constant based on the pipeline. */ tu_cs_emit_pkt7(cs, CP_SET_SUBDRAW_SIZE, 1); @@ -4540,20 +4540,10 @@ static uint32_t tu_draw_initiator(struct tu_cmd_buffer *cmd, enum pc_di_src_sel src_sel) { const struct tu_pipeline *pipeline = cmd->state.pipeline; - enum pc_di_primtype primtype = pipeline->ia.primtype; + enum pc_di_primtype primtype = cmd->state.primtype; - if (pipeline->dynamic_state_mask & BIT(TU_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY)) { - if (primtype < DI_PT_PATCHES0) { - /* If tesselation used, only VK_PRIMITIVE_TOPOLOGY_PATCH_LIST can be - * set via vkCmdSetPrimitiveTopology, but primtype is already - * calculated at the pipeline creation based on control points - * for each patch. - * - * Just use the primtype as is for the case. - */ - primtype = cmd->state.primtype; - } - } + if (primtype == DI_PT_PATCHES0) + primtype += pipeline->tess.patch_control_points; uint32_t initiator = CP_DRAW_INDX_OFFSET_0_PRIM_TYPE(primtype) | diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 1c932f6f30b..be91a075d15 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -3424,9 +3424,8 @@ tu_pipeline_builder_parse_tessellation(struct tu_pipeline_builder *builder, const VkPipelineTessellationStateCreateInfo *tess_info = builder->create_info->pTessellationState; - assert(pipeline->ia.primtype == DI_PT_PATCHES0); assert(tess_info->patchControlPoints <= 32); - pipeline->ia.primtype += tess_info->patchControlPoints; + pipeline->tess.patch_control_points = tess_info->patchControlPoints; const VkPipelineTessellationDomainOriginStateCreateInfo *domain_info = vk_find_struct_const(tess_info->pNext, PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO); pipeline->tess.upper_left_domain_origin = !domain_info || diff --git a/src/freedreno/vulkan/tu_pipeline.h b/src/freedreno/vulkan/tu_pipeline.h index c4796f310bb..8f48d661fd6 100644 --- a/src/freedreno/vulkan/tu_pipeline.h +++ b/src/freedreno/vulkan/tu_pipeline.h @@ -207,6 +207,7 @@ struct tu_pipeline struct { uint32_t patch_type; + uint32_t patch_control_points; uint32_t param_stride; bool upper_left_domain_origin; } tess;