radv: Determine unneeded dynamic states.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Tue, 16 Jan 2018 13:32:35 +0000 (14:32 +0100)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Tue, 30 Jan 2018 21:00:17 +0000 (22:00 +0100)
Which avoids setting or emitting them.

Reviewed-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/amd/vulkan/radv_cmd_buffer.c
src/amd/vulkan/radv_pipeline.c
src/amd/vulkan/radv_private.h

index b694174..c9df9c0 100644 (file)
@@ -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
index 589e49a..6bdb116 100644 (file)
@@ -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
index f650b9a..29c885a 100644 (file)
@@ -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;
        };