diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 6a75cac8015..f110df7cdba 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -108,6 +108,7 @@ const struct radv_dynamic_state default_dynamic_state = { }, .depth_bias_enable = 0u, .primitive_restart_enable = 0u, + .rasterizer_discard_enable = 0u, }; static void @@ -313,6 +314,13 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy } } + if (copy_mask & RADV_DYNAMIC_RASTERIZER_DISCARD_ENABLE) { + if (dest->rasterizer_discard_enable != src->rasterizer_discard_enable) { + dest->rasterizer_discard_enable = src->rasterizer_discard_enable; + dest_mask |= RADV_DYNAMIC_RASTERIZER_DISCARD_ENABLE; + } + } + cmd_buffer->state.dirty |= dest_mask; } @@ -1278,6 +1286,11 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer) RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS; + if (!cmd_buffer->state.emitted_pipeline || + cmd_buffer->state.emitted_pipeline->graphics.pa_cl_clip_cntl != + pipeline->graphics.pa_cl_clip_cntl) + cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE; + if (!cmd_buffer->state.emitted_pipeline) cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS | @@ -1607,6 +1620,18 @@ radv_emit_primitive_restart_enable(struct radv_cmd_buffer *cmd_buffer) } } +static void +radv_emit_rasterizer_discard_enable(struct radv_cmd_buffer *cmd_buffer) +{ + unsigned pa_cl_clip_cntl = cmd_buffer->state.pipeline->graphics.pa_cl_clip_cntl; + struct radv_dynamic_state *d = &cmd_buffer->state.dynamic; + + pa_cl_clip_cntl &= C_028810_DX_RASTERIZATION_KILL; + pa_cl_clip_cntl |= S_028810_DX_RASTERIZATION_KILL(d->rasterizer_discard_enable); + + radeon_set_context_reg(cmd_buffer->cs, R_028810_PA_CL_CLIP_CNTL, pa_cl_clip_cntl); +} + static void radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer, int index, struct radv_color_buffer_info *cb, struct radv_image_view *iview, @@ -2607,6 +2632,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer) if (states & RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE) radv_emit_primitive_restart_enable(cmd_buffer); + if (states & RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE) + radv_emit_rasterizer_discard_enable(cmd_buffer); + cmd_buffer->state.dirty &= ~states; } @@ -4790,6 +4818,21 @@ radv_CmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer, VkBool32 pri state->dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE; } +void +radv_CmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer, + VkBool32 rasterizerDiscardEnable) +{ + RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + struct radv_cmd_state *state = &cmd_buffer->state; + + if (state->dynamic.rasterizer_discard_enable == rasterizerDiscardEnable) + return; + + state->dynamic.rasterizer_discard_enable = rasterizerDiscardEnable; + + state->dirty |= RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE; +} + void radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCmdBuffers) diff --git a/src/amd/vulkan/radv_meta.c b/src/amd/vulkan/radv_meta.c index 7bc6cd3c5eb..8416e9adfda 100644 --- a/src/amd/vulkan/radv_meta.c +++ b/src/amd/vulkan/radv_meta.c @@ -95,6 +95,8 @@ radv_meta_save(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_ state->depth_bias_enable = cmd_buffer->state.dynamic.depth_bias_enable; state->primitive_restart_enable = cmd_buffer->state.dynamic.primitive_restart_enable; + + state->rasterizer_discard_enable = cmd_buffer->state.dynamic.rasterizer_discard_enable; } if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) { @@ -182,6 +184,8 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf cmd_buffer->state.dynamic.primitive_restart_enable = state->primitive_restart_enable; + cmd_buffer->state.dynamic.rasterizer_discard_enable = state->rasterizer_discard_enable; + cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_VIEWPORT | RADV_CMD_DIRTY_DYNAMIC_SCISSOR | RADV_CMD_DIRTY_DYNAMIC_CULL_MODE | RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE | @@ -190,7 +194,8 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_OP | RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE | - RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE; + RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE | + RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE; } if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) { diff --git a/src/amd/vulkan/radv_meta.h b/src/amd/vulkan/radv_meta.h index d6519231a2b..c827baf969c 100644 --- a/src/amd/vulkan/radv_meta.h +++ b/src/amd/vulkan/radv_meta.h @@ -93,6 +93,7 @@ struct radv_meta_saved_state { bool depth_bias_enable; bool primitive_restart_enable; + bool rasterizer_discard_enable; }; VkResult radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand); diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index a14b8afd918..4f676917642 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -82,10 +82,25 @@ struct radv_dsa_order_invariance { bool pass_set; }; +static bool +radv_is_state_dynamic(const VkGraphicsPipelineCreateInfo *pCreateInfo, VkDynamicState state) +{ + if (pCreateInfo->pDynamicState) { + uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount; + for (uint32_t i = 0; i < count; i++) { + if (pCreateInfo->pDynamicState->pDynamicStates[i] == state) + return true; + } + } + + return false; +} + static const VkPipelineMultisampleStateCreateInfo * radv_pipeline_get_multisample_state(const VkGraphicsPipelineCreateInfo *pCreateInfo) { - if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable) + if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable || + radv_is_state_dynamic(pCreateInfo, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)) return pCreateInfo->pMultisampleState; return NULL; } @@ -108,8 +123,9 @@ radv_pipeline_get_depth_stencil_state(const VkGraphicsPipelineCreateInfo *pCreat RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass); struct radv_subpass *subpass = pass->subpasses + pCreateInfo->subpass; - if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable && - subpass->depth_stencil_attachment) + if ((!pCreateInfo->pRasterizationState->rasterizerDiscardEnable && + subpass->depth_stencil_attachment) || + radv_is_state_dynamic(pCreateInfo, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)) return pCreateInfo->pDepthStencilState; return NULL; } @@ -120,7 +136,8 @@ radv_pipeline_get_color_blend_state(const VkGraphicsPipelineCreateInfo *pCreateI RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass); struct radv_subpass *subpass = pass->subpasses + pCreateInfo->subpass; - if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable && subpass->has_color_att) + if ((!pCreateInfo->pRasterizationState->rasterizerDiscardEnable && subpass->has_color_att) || + radv_is_state_dynamic(pCreateInfo, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)) return pCreateInfo->pColorBlendState; return NULL; } @@ -927,20 +944,6 @@ radv_order_invariant_stencil_state(const VkStencilOpState *state) radv_order_invariant_stencil_op(state->failOp)); } -static bool -radv_is_state_dynamic(const VkGraphicsPipelineCreateInfo *pCreateInfo, VkDynamicState state) -{ - if (pCreateInfo->pDynamicState) { - uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount; - for (uint32_t i = 0; i < count; i++) { - if (pCreateInfo->pDynamicState->pDynamicStates[i] == state) - return true; - } - } - - return false; -} - static bool radv_pipeline_has_dynamic_ds_states(const VkGraphicsPipelineCreateInfo *pCreateInfo) { @@ -1385,7 +1388,8 @@ radv_pipeline_needed_dynamic_state(const VkGraphicsPipelineCreateInfo *pCreateIn * except primitive topology, primitive restart enable and vertex * binding stride. */ - if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable) + if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable && + !radv_is_state_dynamic(pCreateInfo, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)) return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY | RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE | RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE; @@ -1741,6 +1745,11 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, !!pCreateInfo->pInputAssemblyState->primitiveRestartEnable; } + if (states & RADV_DYNAMIC_RASTERIZER_DISCARD_ENABLE) { + dynamic->rasterizer_discard_enable = + pCreateInfo->pRasterizationState->rasterizerDiscardEnable; + } + pipeline->dynamic_state.mask = states; } @@ -1776,6 +1785,21 @@ radv_pipeline_init_raster_state(struct radv_pipeline *pipeline, pipeline->graphics.pa_su_sc_mode_cntl |= S_028814_KEEP_TOGETHER_ENABLE(raster_info->polygonMode != VK_POLYGON_MODE_FILL); } + + bool depth_clip_disable = raster_info->depthClampEnable; + const VkPipelineRasterizationDepthClipStateCreateInfoEXT *depth_clip_state = + vk_find_struct_const(raster_info->pNext, + PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT); + if (depth_clip_state) { + depth_clip_disable = !depth_clip_state->depthClipEnable; + } + + pipeline->graphics.pa_cl_clip_cntl = + S_028810_DX_CLIP_SPACE_DEF(1) | // vulkan uses DX conventions. + S_028810_ZCLIP_NEAR_DISABLE(depth_clip_disable ? 1 : 0) | + S_028810_ZCLIP_FAR_DISABLE(depth_clip_disable ? 1 : 0) | + S_028810_DX_RASTERIZATION_KILL(raster_info->rasterizerDiscardEnable ? 1 : 0) | + S_028810_DX_LINEAR_ATTR_CLIP_ENA(1); } static void @@ -4228,22 +4252,6 @@ radv_pipeline_generate_raster_state(struct radeon_cmdbuf *ctx_cs, const VkPipelineRasterizationStateCreateInfo *vkraster = pCreateInfo->pRasterizationState; const VkConservativeRasterizationModeEXT mode = radv_get_conservative_raster_mode(vkraster); uint32_t pa_sc_conservative_rast = S_028C4C_NULL_SQUAD_AA_MASK_ENABLE(1); - bool depth_clip_disable = vkraster->depthClampEnable; - - const VkPipelineRasterizationDepthClipStateCreateInfoEXT *depth_clip_state = - vk_find_struct_const(vkraster->pNext, - PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT); - if (depth_clip_state) { - depth_clip_disable = !depth_clip_state->depthClipEnable; - } - - radeon_set_context_reg( - ctx_cs, R_028810_PA_CL_CLIP_CNTL, - S_028810_DX_CLIP_SPACE_DEF(1) | // vulkan uses DX conventions. - S_028810_ZCLIP_NEAR_DISABLE(depth_clip_disable ? 1 : 0) | - S_028810_ZCLIP_FAR_DISABLE(depth_clip_disable ? 1 : 0) | - S_028810_DX_RASTERIZATION_KILL(vkraster->rasterizerDiscardEnable ? 1 : 0) | - S_028810_DX_LINEAR_ATTR_CLIP_ENA(1)); radeon_set_context_reg(ctx_cs, R_028BDC_PA_SC_LINE_CNTL, S_028BDC_DX10_DIAMOND_TEST_ENA(1)); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 87ede4c5781..8f7d8ae5cd3 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1215,6 +1215,7 @@ struct radv_dynamic_state { bool depth_bias_enable; bool primitive_restart_enable; + bool rasterizer_discard_enable; }; extern const struct radv_dynamic_state default_dynamic_state; @@ -1721,6 +1722,7 @@ struct radv_pipeline { unsigned tess_patch_control_points; unsigned pa_su_sc_mode_cntl; unsigned db_depth_control; + unsigned pa_cl_clip_cntl; bool uses_dynamic_stride; /* Used for rbplus */