From aed7c5aa31f3896137a5cdd60f87c30cee3798b8 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 2 Dec 2020 23:59:24 -0500 Subject: [PATCH] turnip: do not emit draw states in draw_cs outside of renderpass This avoids a possible issue with MSAA sysmem clears, which use a 3D clear path which assumes draw states are disabled, and are emitted in draw_cs in BeginRenderPass. (checking for TU_CMD_DIRTY_DRAW_STATE also allows not emitting the draw states if they will be re-emitted on the next draw anyway. the previous patch makes it so TU_CMD_DIRTY_DRAW_STATE is always set outside of renderpasses) Signed-off-by: Jonathan Marek Part-of: --- src/freedreno/vulkan/tu_cmd_buffer.c | 44 ++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 800224a..cebccb3 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -1773,8 +1773,13 @@ tu_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS) { assert(cs->cur == cs->end); /* validate draw state size */ - tu_cs_emit_pkt7(&cmd->draw_cs, CP_SET_DRAW_STATE, 3); - tu_cs_emit_draw_state(&cmd->draw_cs, TU_DRAW_STATE_DESC_SETS, cmd->state.desc_sets); + /* 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)) { + tu_cs_emit_pkt7(&cmd->draw_cs, CP_SET_DRAW_STATE, 3); + tu_cs_emit_draw_state(&cmd->draw_cs, TU_DRAW_STATE_DESC_SETS, cmd->state.desc_sets); + } } } @@ -2066,6 +2071,12 @@ tu_cmd_dynamic_state(struct tu_cmd_buffer *cmd, uint32_t id, uint32_t size) assert(id < ARRAY_SIZE(cmd->state.dynamic_state)); cmd->state.dynamic_state[id] = tu_cs_draw_state(&cmd->sub_cs, &cs, size); + /* 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) + return cs; + tu_cs_emit_pkt7(&cmd->draw_cs, CP_SET_DRAW_STATE, 3); tu_cs_emit_draw_state(&cmd->draw_cs, TU_DRAW_STATE_DYNAMIC + id, cmd->state.dynamic_state[id]); @@ -2091,20 +2102,25 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer, cmd->state.pipeline = pipeline; cmd->state.dirty |= TU_CMD_DIRTY_DESC_SETS_LOAD | TU_CMD_DIRTY_SHADER_CONSTS | TU_CMD_DIRTY_LRZ; - struct tu_cs *cs = &cmd->draw_cs; - uint32_t mask = ~pipeline->dynamic_state_mask & BITFIELD_MASK(TU_DYNAMIC_STATE_COUNT); - uint32_t i; + /* 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); + uint32_t i; - tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * (6 + util_bitcount(mask))); - tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM, pipeline->program.state); - tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM_BINNING, pipeline->program.binning_state); - tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VI, pipeline->vi.state); - tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VI_BINNING, pipeline->vi.binning_state); - tu_cs_emit_draw_state(cs, TU_DRAW_STATE_RAST, pipeline->rast_state); - tu_cs_emit_draw_state(cs, TU_DRAW_STATE_BLEND, pipeline->blend_state); + tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * (6 + util_bitcount(mask))); + tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM, pipeline->program.state); + tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM_BINNING, pipeline->program.binning_state); + tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VI, pipeline->vi.state); + tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VI_BINNING, pipeline->vi.binning_state); + tu_cs_emit_draw_state(cs, TU_DRAW_STATE_RAST, pipeline->rast_state); + tu_cs_emit_draw_state(cs, TU_DRAW_STATE_BLEND, pipeline->blend_state); - for_each_bit(i, mask) - tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DYNAMIC + i, pipeline->dynamic_state[i]); + for_each_bit(i, mask) + tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DYNAMIC + i, pipeline->dynamic_state[i]); + } /* the vertex_buffers draw state always contains all the currently * bound vertex buffers. update its size to only emit the vbs which -- 2.7.4