diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index b694174de68..c9df9c08d6a 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -1218,20 +1218,18 @@ radv_emit_depth_bounds(struct radv_cmd_buffer *cmd_buffer) static void radv_emit_depth_bias(struct radv_cmd_buffer *cmd_buffer) { - struct radv_raster_state *raster = &cmd_buffer->state.pipeline->graphics.raster; struct radv_dynamic_state *d = &cmd_buffer->state.dynamic; unsigned slope = fui(d->depth_bias.slope * 16.0f); unsigned bias = fui(d->depth_bias.bias * cmd_buffer->state.offset_scale); - if (G_028814_POLY_OFFSET_FRONT_ENABLE(raster->pa_su_sc_mode_cntl)) { - radeon_set_context_reg_seq(cmd_buffer->cs, - R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 5); - radeon_emit(cmd_buffer->cs, fui(d->depth_bias.clamp)); /* CLAMP */ - radeon_emit(cmd_buffer->cs, slope); /* FRONT SCALE */ - radeon_emit(cmd_buffer->cs, bias); /* FRONT OFFSET */ - radeon_emit(cmd_buffer->cs, slope); /* BACK SCALE */ - radeon_emit(cmd_buffer->cs, bias); /* BACK OFFSET */ - } + + radeon_set_context_reg_seq(cmd_buffer->cs, + R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 5); + radeon_emit(cmd_buffer->cs, fui(d->depth_bias.clamp)); /* CLAMP */ + radeon_emit(cmd_buffer->cs, slope); /* FRONT SCALE */ + radeon_emit(cmd_buffer->cs, bias); /* FRONT OFFSET */ + radeon_emit(cmd_buffer->cs, slope); /* BACK SCALE */ + radeon_emit(cmd_buffer->cs, bias); /* BACK OFFSET */ } static void @@ -1633,37 +1631,35 @@ void radv_set_db_count_control(struct radv_cmd_buffer *cmd_buffer) static void radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer) { - if (G_028810_DX_RASTERIZATION_KILL(cmd_buffer->state.pipeline->graphics.raster.pa_cl_clip_cntl)) - return; + uint32_t states = cmd_buffer->state.dirty & cmd_buffer->state.emitted_pipeline->graphics.needed_dynamic_state; - if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_VIEWPORT)) + if (states & (RADV_CMD_DIRTY_DYNAMIC_VIEWPORT)) radv_emit_viewport(cmd_buffer); - if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_SCISSOR | RADV_CMD_DIRTY_DYNAMIC_VIEWPORT)) + if (states & (RADV_CMD_DIRTY_DYNAMIC_SCISSOR | RADV_CMD_DIRTY_DYNAMIC_VIEWPORT)) radv_emit_scissor(cmd_buffer); - if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_DYNAMIC_LINE_WIDTH) + if (states & RADV_CMD_DIRTY_DYNAMIC_LINE_WIDTH) radv_emit_line_width(cmd_buffer); - if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) + if (states & RADV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) radv_emit_blend_constants(cmd_buffer); - if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE | + if (states & (RADV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK | RADV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK)) radv_emit_stencil(cmd_buffer); - if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS) + if (states & RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS) radv_emit_depth_bounds(cmd_buffer); - if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_PIPELINE | - RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS)) + if (states & RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS) radv_emit_depth_bias(cmd_buffer); - if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE) + if (states & RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE) radv_emit_discard_rectangle(cmd_buffer); - cmd_buffer->state.dirty &= ~RADV_CMD_DIRTY_DYNAMIC_ALL; + cmd_buffer->state.dirty &= ~states; } static void diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 589e49a813d..6bdb1160cb2 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -1031,15 +1031,48 @@ static unsigned radv_dynamic_state_mask(VkDynamicState state) } } +static uint32_t radv_pipeline_needed_dynamic_state(const VkGraphicsPipelineCreateInfo *pCreateInfo) +{ + uint32_t states = RADV_DYNAMIC_ALL; + + /* If rasterization is disabled we do not care about any of the dynamic states, + * since they are all rasterization related only. */ + if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable) + return 0; + + if (!pCreateInfo->pRasterizationState->depthBiasEnable) + states &= ~RADV_DYNAMIC_DEPTH_BIAS; + + if (!pCreateInfo->pDepthStencilState || + !pCreateInfo->pDepthStencilState->depthBoundsTestEnable) + states &= ~RADV_DYNAMIC_DEPTH_BOUNDS; + + if (!pCreateInfo->pDepthStencilState || + !pCreateInfo->pDepthStencilState->stencilTestEnable) + states &= ~(RADV_DYNAMIC_STENCIL_COMPARE_MASK | + RADV_DYNAMIC_STENCIL_WRITE_MASK | + RADV_DYNAMIC_STENCIL_REFERENCE); + + if (!vk_find_struct_const(pCreateInfo->pNext, PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT)) + states &= ~RADV_DYNAMIC_DISCARD_RECTANGLE; + + /* TODO: blend constants & line width. */ + + return states; +} + + static void radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, const VkGraphicsPipelineCreateInfo *pCreateInfo) { - uint32_t states = RADV_DYNAMIC_ALL; + uint32_t needed_states = radv_pipeline_needed_dynamic_state(pCreateInfo); + uint32_t states = needed_states; RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass); struct radv_subpass *subpass = &pass->subpasses[pCreateInfo->subpass]; pipeline->dynamic_state = default_dynamic_state; + pipeline->graphics.needed_dynamic_state = needed_states; if (pCreateInfo->pDynamicState) { /* Remove all of the states that are marked as dynamic */ @@ -1050,26 +1083,23 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, struct radv_dynamic_state *dynamic = &pipeline->dynamic_state; - /* Section 9.2 of the Vulkan 1.0.15 spec says: - * - * pViewportState is [...] NULL if the pipeline - * has rasterization disabled. - */ - if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable) { + if (needed_states & RADV_DYNAMIC_VIEWPORT) { assert(pCreateInfo->pViewportState); dynamic->viewport.count = pCreateInfo->pViewportState->viewportCount; if (states & RADV_DYNAMIC_VIEWPORT) { typed_memcpy(dynamic->viewport.viewports, - pCreateInfo->pViewportState->pViewports, - pCreateInfo->pViewportState->viewportCount); + pCreateInfo->pViewportState->pViewports, + pCreateInfo->pViewportState->viewportCount); } + } + if (needed_states & RADV_DYNAMIC_SCISSOR) { dynamic->scissor.count = pCreateInfo->pViewportState->scissorCount; if (states & RADV_DYNAMIC_SCISSOR) { typed_memcpy(dynamic->scissor.scissors, - pCreateInfo->pViewportState->pScissors, - pCreateInfo->pViewportState->scissorCount); + pCreateInfo->pViewportState->pScissors, + pCreateInfo->pViewportState->scissorCount); } } @@ -1120,7 +1150,7 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, * disabled or if the subpass of the render pass the pipeline is created * against does not use a depth/stencil attachment. */ - if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable && + if (needed_states && subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) { assert(pCreateInfo->pDepthStencilState); @@ -1155,7 +1185,7 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, const VkPipelineDiscardRectangleStateCreateInfoEXT *discard_rectangle_info = vk_find_struct_const(pCreateInfo->pNext, PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT); - if (discard_rectangle_info) { + if (states & RADV_DYNAMIC_DISCARD_RECTANGLE) { dynamic->discard_rectangle.count = discard_rectangle_info->discardRectangleCount; typed_memcpy(dynamic->discard_rectangle.rectangles, discard_rectangle_info->pDiscardRectangles, @@ -1181,8 +1211,6 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, } pipeline->graphics.pa_sc_cliprect_rule = mask; } else { - states &= ~RADV_DYNAMIC_DISCARD_RECTANGLE; - /* Allow from all rectangle combinations */ pipeline->graphics.pa_sc_cliprect_rule = 0xffff; } @@ -2441,7 +2469,6 @@ radv_pipeline_init(struct radv_pipeline *pipeline, pipeline->layout = radv_pipeline_layout_from_handle(pCreateInfo->layout); assert(pipeline->layout); - radv_pipeline_init_dynamic_state(pipeline, pCreateInfo); radv_pipeline_init_blend_state(pipeline, pCreateInfo, extra); const VkPipelineShaderStageCreateInfo *pStages[MESA_SHADER_STAGES] = { 0, }; @@ -2476,6 +2503,8 @@ radv_pipeline_init(struct radv_pipeline *pipeline, /* prim vertex count will need TESS changes */ pipeline->graphics.prim_vertex_count = prim_size_table[pipeline->graphics.prim]; + radv_pipeline_init_dynamic_state(pipeline, pCreateInfo); + /* Ensure that some export memory is always allocated, for two reasons: * * 1) Correctness: The hardware ignores the EXEC mask if no export diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index f650b9a360e..29c885a26ef 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1262,6 +1262,7 @@ struct radv_pipeline { struct radv_prim_vertex_count prim_vertex_count; bool can_use_guardband; uint32_t pa_sc_cliprect_rule; + uint32_t needed_dynamic_state; } graphics; };