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
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
}
}
+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 */
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);
}
}
* 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);
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,
}
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;
}
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, };
/* 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