turnip: Move CP_SET_SUBDRAW_SIZE to vkCmdBindPipeline() time.
Now that the subdraw size is constant for a pipeline, this lets tess draws avoid the slow path in vkCmdDraw*(). Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6089>
This commit is contained in:
@@ -2212,11 +2212,12 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
|
||||
cmd->state.dirty |= TU_CMD_DIRTY_DESC_SETS_LOAD | TU_CMD_DIRTY_SHADER_CONSTS |
|
||||
TU_CMD_DIRTY_LRZ | TU_CMD_DIRTY_VS_PARAMS;
|
||||
|
||||
struct tu_cs *cs = &cmd->draw_cs;
|
||||
|
||||
/* note: this also avoids emitting draw states before renderpass clears,
|
||||
* which may use the 3D clear path (for MSAA cases)
|
||||
*/
|
||||
if (!(cmd->state.dirty & TU_CMD_DIRTY_DRAW_STATE)) {
|
||||
struct tu_cs *cs = &cmd->draw_cs;
|
||||
uint32_t mask = ~pipeline->dynamic_state_mask & BITFIELD_MASK(TU_DYNAMIC_STATE_COUNT);
|
||||
|
||||
tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * (7 + util_bitcount(mask)));
|
||||
@@ -2232,12 +2233,24 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
|
||||
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DYNAMIC + i, pipeline->dynamic_state[i]);
|
||||
}
|
||||
|
||||
if (cmd->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY &&
|
||||
(pipeline->active_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)) {
|
||||
if (pipeline->active_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
|
||||
cmd->state.has_tess = true;
|
||||
|
||||
/* Set up the tess factor address if this is the first tess pipeline bound
|
||||
* to the primary cmdbuf.
|
||||
*/
|
||||
tu6_lazy_emit_tessfactor_addr(cmd);
|
||||
if (cmd->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY)
|
||||
tu6_lazy_emit_tessfactor_addr(cmd);
|
||||
|
||||
/* maximum number of patches that can fit in tess factor/param buffers */
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
tu_cs_emit(cs, subdraw_size);
|
||||
}
|
||||
|
||||
if (cmd->state.line_mode != pipeline->line_mode) {
|
||||
@@ -2251,7 +2264,7 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
|
||||
* attribute and depth interpolation).
|
||||
*/
|
||||
if (cmd->state.subpass && cmd->state.subpass->samples) {
|
||||
tu6_emit_msaa(&cmd->draw_cs, cmd->state.subpass->samples, cmd->state.line_mode);
|
||||
tu6_emit_msaa(cs, cmd->state.subpass->samples, cmd->state.line_mode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3507,20 +3520,6 @@ tu6_emit_consts_geom(struct tu_cmd_buffer *cmd,
|
||||
return tu_cs_end_draw_state(&cmd->sub_cs, &cs);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
tu6_setup_tess(struct tu_cmd_buffer *cmd,
|
||||
const struct tu_pipeline *pipeline,
|
||||
uint32_t *subdraw_size)
|
||||
{
|
||||
/* maximum number of patches that can fit in tess factor/param buffers */
|
||||
*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);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static enum tu_lrz_direction
|
||||
tu6_lrz_depth_mode(struct A6XX_GRAS_LRZ_CNTL *gras_lrz_cntl,
|
||||
VkCompareOp depthCompareOp,
|
||||
@@ -3798,7 +3797,6 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
|
||||
uint32_t draw_count)
|
||||
{
|
||||
const struct tu_pipeline *pipeline = cmd->state.pipeline;
|
||||
VkResult result;
|
||||
|
||||
tu_emit_cache_flush_renderpass(cmd, cs);
|
||||
|
||||
@@ -3813,12 +3811,8 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
|
||||
.tess_upper_left_domain_origin =
|
||||
pipeline->tess.upper_left_domain_origin));
|
||||
|
||||
bool has_tess =
|
||||
pipeline->active_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||
|
||||
/* Early exit if there is nothing to emit, saves CPU cycles */
|
||||
if (!(cmd->state.dirty & ~TU_CMD_DIRTY_COMPUTE_DESC_SETS_LOAD) &&
|
||||
!has_tess)
|
||||
if (!(cmd->state.dirty & ~TU_CMD_DIRTY_COMPUTE_DESC_SETS_LOAD))
|
||||
return VK_SUCCESS;
|
||||
|
||||
bool dirty_lrz = cmd->state.dirty & (TU_CMD_DIRTY_LRZ | TU_CMD_DIRTY_RB_DEPTH_CNTL | TU_CMD_DIRTY_RB_STENCIL_CNTL);
|
||||
@@ -3872,18 +3866,6 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
|
||||
tu6_emit_consts(cmd, pipeline, descriptors_state, MESA_SHADER_FRAGMENT);
|
||||
}
|
||||
|
||||
if (has_tess) {
|
||||
uint32_t subdraw_size;
|
||||
|
||||
cmd->state.has_tess = true;
|
||||
result = tu6_setup_tess(cmd, pipeline, &subdraw_size);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
tu_cs_emit_pkt7(cs, CP_SET_SUBDRAW_SIZE, 1);
|
||||
tu_cs_emit(cs, subdraw_size);
|
||||
}
|
||||
|
||||
/* for the first draw in a renderpass, re-emit all the draw states
|
||||
*
|
||||
* and if a draw-state disabling path (CmdClearAttachments 3D fallback) was
|
||||
|
Reference in New Issue
Block a user