From d34d0f38e1ccd0a2cd66dfcddecff38c208cba77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Fri, 17 Dec 2021 17:55:36 +0100 Subject: [PATCH] radv: Support VRS for mesh shaders. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Timur Kristóf Reviewed-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/amd/vulkan/radv_cmd_buffer.c | 20 ++++++++++++++++---- src/amd/vulkan/radv_pipeline.c | 14 ++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index cc42eb0cb35..ea68e67f248 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -1650,7 +1650,7 @@ radv_emit_fragment_shading_rate(struct radv_cmd_buffer *cmd_buffer) uint32_t rate_x = MIN2(2, d->fragment_shading_rate.size.width) - 1; uint32_t rate_y = MIN2(2, d->fragment_shading_rate.size.height) - 1; uint32_t pa_cl_vrs_cntl = pipeline->graphics.vrs.pa_cl_vrs_cntl; - uint32_t vertex_comb_mode = d->fragment_shading_rate.combiner_ops[0]; + uint32_t pipeline_comb_mode = d->fragment_shading_rate.combiner_ops[0]; uint32_t htile_comb_mode = d->fragment_shading_rate.combiner_ops[1]; assert(cmd_buffer->device->physical_device->rad_info.chip_class >= GFX10_3); @@ -1670,7 +1670,7 @@ radv_emit_fragment_shading_rate(struct radv_cmd_buffer *cmd_buffer) /* As the result of min(A, 1x1) or replace(A, 1x1) are always 1x1, set the vertex rate * combiner mode as passthrough. */ - vertex_comb_mode = V_028848_VRS_COMB_MODE_PASSTHRU; + pipeline_comb_mode = V_028848_VRS_COMB_MODE_PASSTHRU; break; case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR: /* The result of max(A, 1x1) is always A. */ @@ -1690,7 +1690,13 @@ radv_emit_fragment_shading_rate(struct radv_cmd_buffer *cmd_buffer) /* VERTEX_RATE_COMBINER_MODE controls the combiner mode between the * draw rate and the vertex rate. */ - pa_cl_vrs_cntl |= S_028848_VERTEX_RATE_COMBINER_MODE(vertex_comb_mode); + if (cmd_buffer->state.mesh_shading) { + pa_cl_vrs_cntl |= S_028848_VERTEX_RATE_COMBINER_MODE(V_028848_VRS_COMB_MODE_PASSTHRU) | + S_028848_PRIMITIVE_RATE_COMBINER_MODE(pipeline_comb_mode); + } else { + pa_cl_vrs_cntl |= S_028848_VERTEX_RATE_COMBINER_MODE(pipeline_comb_mode) | + S_028848_PRIMITIVE_RATE_COMBINER_MODE(V_028848_VRS_COMB_MODE_PASSTHRU); + } /* HTILE_RATE_COMBINER_MODE controls the combiner mode between the primitive rate and the HTILE * rate. @@ -5065,7 +5071,13 @@ radv_CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipeline if (!pipeline) break; - cmd_buffer->state.mesh_shading = radv_pipeline_has_mesh(pipeline); + bool mesh_shading = radv_pipeline_has_mesh(pipeline); + if (mesh_shading != cmd_buffer->state.mesh_shading) { + /* Re-emit VRS state because the combiner is different (vertex vs primitive). */ + cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE; + } + + cmd_buffer->state.mesh_shading = mesh_shading; cmd_buffer->state.dirty |= RADV_CMD_DIRTY_PIPELINE | RADV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT; cmd_buffer->push_constant_stages |= pipeline->active_stages; diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 589e1d98789..da42fa92e90 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -1258,9 +1258,6 @@ gfx103_pipeline_init_vrs_state(struct radv_pipeline *pipeline, } else { vrs->pa_cl_vrs_cntl = S_028848_SAMPLE_ITER_COMBINER_MODE(V_028848_VRS_COMB_MODE_PASSTHRU); } - - /* The primitive combiner is always passthrough. */ - vrs->pa_cl_vrs_cntl |= S_028848_PRIMITIVE_RATE_COMBINER_MODE(V_028848_VRS_COMB_MODE_PASSTHRU); } static bool @@ -4835,8 +4832,11 @@ radv_pipeline_generate_hw_ngg(struct radeon_cmdbuf *ctx_cs, struct radeon_cmdbuf cull_dist_mask = outinfo->cull_dist_mask; total_mask = clip_dist_mask | cull_dist_mask; + /* Primitive shading rate is written as a per-primitive output in mesh shaders. */ + bool force_vrs_per_vertex = + pipeline->device->force_vrs != RADV_FORCE_VRS_NONE && es_type != MESA_SHADER_MESH; bool writes_primitive_shading_rate = - outinfo->writes_primitive_shading_rate || pipeline->device->force_vrs != RADV_FORCE_VRS_NONE; + outinfo->writes_primitive_shading_rate || force_vrs_per_vertex; bool misc_vec_ena = outinfo->writes_pointsize || outinfo->writes_layer || outinfo->writes_viewport_index || writes_primitive_shading_rate; bool es_enable_prim_id = outinfo->export_prim_id || (es && es->info.uses_prim_id); @@ -4861,7 +4861,8 @@ radv_pipeline_generate_hw_ngg(struct radeon_cmdbuf *ctx_cs, struct radeon_cmdbuf unsigned idx_format = V_028708_SPI_SHADER_1COMP; if (outinfo->writes_layer_per_primitive || - outinfo->writes_viewport_index_per_primitive) + outinfo->writes_viewport_index_per_primitive || + outinfo->writes_primitive_shading_rate_per_primitive) idx_format = V_028708_SPI_SHADER_2COMP; radeon_set_context_reg(ctx_cs, R_028708_SPI_SHADER_IDX_FORMAT, @@ -5637,7 +5638,8 @@ gfx103_pipeline_generate_vgt_draw_payload_cntl(struct radeon_cmdbuf *ctx_cs, bool enable_prim_payload = outinfo && (outinfo->writes_viewport_index_per_primitive || - outinfo->writes_layer_per_primitive); + outinfo->writes_layer_per_primitive || + outinfo->writes_primitive_shading_rate_per_primitive); radeon_set_context_reg(ctx_cs, R_028A98_VGT_DRAW_PAYLOAD_CNTL, S_028A98_EN_VRS_RATE(enable_vrs) |