radv: add support for dynamic cull mode and front face
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Mon, 13 Apr 2020 09:33:44 +0000 (11:33 +0200)
committerMarge Bot <eric+marge@anholt.net>
Mon, 13 Jul 2020 08:31:54 +0000 (08:31 +0000)
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5718>

src/amd/vulkan/radv_cmd_buffer.c
src/amd/vulkan/radv_meta.c
src/amd/vulkan/radv_meta.h
src/amd/vulkan/radv_pipeline.c
src/amd/vulkan/radv_private.h

index 723a94c8192955c3cae41ff08548814b7123bc96..8ad1a86f5ce94ee4c2e564ceaccca269d81f7e26 100644 (file)
@@ -96,6 +96,8 @@ const struct radv_dynamic_state default_dynamic_state = {
                .factor = 0u,
                .pattern = 0u,
        },
+       .cull_mode = 0u,
+       .front_face = 0u,
 };
 
 static void
@@ -221,6 +223,20 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer,
                }
        }
 
+       if (copy_mask & RADV_DYNAMIC_CULL_MODE) {
+               if (dest->cull_mode != src->cull_mode) {
+                       dest->cull_mode = src->cull_mode;
+                       dest_mask |= RADV_DYNAMIC_CULL_MODE;
+               }
+       }
+
+       if (copy_mask & RADV_DYNAMIC_FRONT_FACE) {
+               if (dest->front_face != src->front_face) {
+                       dest->front_face = src->front_face;
+                       dest_mask |= RADV_DYNAMIC_FRONT_FACE;
+               }
+       }
+
        cmd_buffer->state.dirty |= dest_mask;
 }
 
@@ -1188,6 +1204,12 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
             pipeline->graphics.can_use_guardband)
                cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_SCISSOR;
 
+       if (!cmd_buffer->state.emitted_pipeline ||
+           cmd_buffer->state.emitted_pipeline->graphics.pa_su_sc_mode_cntl !=
+           pipeline->graphics.pa_su_sc_mode_cntl)
+               cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_CULL_MODE |
+                                          RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
+
        radeon_emit_array(cmd_buffer->cs, pipeline->cs.buf, pipeline->cs.cdw);
 
        if (!cmd_buffer->state.emitted_pipeline ||
@@ -1338,6 +1360,29 @@ radv_emit_line_stipple(struct radv_cmd_buffer *cmd_buffer)
                               S_028A0C_AUTO_RESET_CNTL(auto_reset_cntl));
 }
 
+static void
+radv_emit_culling(struct radv_cmd_buffer *cmd_buffer, uint32_t states)
+{
+       unsigned pa_su_sc_mode_cntl = cmd_buffer->state.pipeline->graphics.pa_su_sc_mode_cntl;
+       struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
+
+       if (states & RADV_CMD_DIRTY_DYNAMIC_CULL_MODE) {
+               pa_su_sc_mode_cntl &= C_028814_CULL_FRONT;
+               pa_su_sc_mode_cntl |= S_028814_CULL_FRONT(!!(d->cull_mode & VK_CULL_MODE_FRONT_BIT));
+
+               pa_su_sc_mode_cntl &= C_028814_CULL_BACK;
+               pa_su_sc_mode_cntl |= S_028814_CULL_BACK(!!(d->cull_mode & VK_CULL_MODE_BACK_BIT));
+       }
+
+       if (states & RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE) {
+               pa_su_sc_mode_cntl &= C_028814_FACE;
+               pa_su_sc_mode_cntl |= S_028814_FACE(d->front_face);
+       }
+
+       radeon_set_context_reg(cmd_buffer->cs, R_028814_PA_SU_SC_MODE_CNTL,
+                              pa_su_sc_mode_cntl);
+}
+
 static void
 radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer,
                         int index,
@@ -2242,6 +2287,10 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer)
        if (states & RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE)
                radv_emit_line_stipple(cmd_buffer);
 
+       if (states & (RADV_CMD_DIRTY_DYNAMIC_CULL_MODE |
+                     RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE))
+               radv_emit_culling(cmd_buffer, states);
+
        cmd_buffer->state.dirty &= ~states;
 }
 
@@ -4191,6 +4240,36 @@ void radv_CmdSetLineStippleEXT(
        state->dirty |= RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
 }
 
+void radv_CmdSetCullModeEXT(
+       VkCommandBuffer                             commandBuffer,
+       VkCullModeFlags                             cullMode)
+{
+       RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+       struct radv_cmd_state *state = &cmd_buffer->state;
+
+       if (state->dynamic.cull_mode == cullMode)
+               return;
+
+       state->dynamic.cull_mode = cullMode;
+
+       state->dirty |= RADV_CMD_DIRTY_DYNAMIC_CULL_MODE;
+}
+
+void radv_CmdSetFrontFaceEXT(
+       VkCommandBuffer                             commandBuffer,
+       VkFrontFace                                 frontFace)
+{
+       RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+       struct radv_cmd_state *state = &cmd_buffer->state;
+
+       if (state->dynamic.front_face == frontFace)
+               return;
+
+       state->dynamic.front_face = frontFace;
+
+       state->dirty |= RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
+}
+
 void radv_CmdExecuteCommands(
        VkCommandBuffer                             commandBuffer,
        uint32_t                                    commandBufferCount,
index 1fb32f94621d5ebc0280b54fb5f4c21cb21e5ba8..2f56c92374c22213d6ff5a51cbff7c17c67ba827 100644 (file)
@@ -62,6 +62,9 @@ radv_meta_save(struct radv_meta_saved_state *state,
                typed_memcpy(state->scissor.scissors,
                             cmd_buffer->state.dynamic.scissor.scissors,
                             MAX_SCISSORS);
+
+               state->cull_mode = cmd_buffer->state.dynamic.cull_mode;
+               state->front_face = cmd_buffer->state.dynamic.front_face;
        }
 
        if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
@@ -123,8 +126,13 @@ radv_meta_restore(const struct radv_meta_saved_state *state,
                             state->scissor.scissors,
                             MAX_SCISSORS);
 
+               cmd_buffer->state.dynamic.cull_mode = state->cull_mode;
+               cmd_buffer->state.dynamic.front_face = state->front_face;
+
                cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_VIEWPORT |
-                                          RADV_CMD_DIRTY_DYNAMIC_SCISSOR;
+                                          RADV_CMD_DIRTY_DYNAMIC_SCISSOR |
+                                          RADV_CMD_DIRTY_DYNAMIC_CULL_MODE |
+                                          RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
        }
 
        if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
index e3711aa47935f1264b8cb5388caa83733354ccc8..c3b4d9c72ea63f700ac76d266c9a7a404905c6ec 100644 (file)
@@ -58,6 +58,9 @@ struct radv_meta_saved_state {
        struct radv_attachment_state *attachments;
        struct radv_framebuffer *framebuffer;
        VkRect2D render_area;
+
+       VkCullModeFlags cull_mode;
+       VkFrontFace front_face;
 };
 
 VkResult radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand);
index 0c36fb7b96cf79aa072dc491ec04a663335f08eb..c03e0f43c75566463b91e38efcee638a8b85389a 100644 (file)
@@ -1298,6 +1298,10 @@ static unsigned radv_dynamic_state_mask(VkDynamicState state)
                return RADV_DYNAMIC_SAMPLE_LOCATIONS;
        case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT:
                return RADV_DYNAMIC_LINE_STIPPLE;
+       case VK_DYNAMIC_STATE_CULL_MODE_EXT:
+               return RADV_DYNAMIC_CULL_MODE;
+       case VK_DYNAMIC_STATE_FRONT_FACE_EXT:
+               return RADV_DYNAMIC_FRONT_FACE;
        default:
                unreachable("Unhandled dynamic state");
        }
@@ -1412,6 +1416,16 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
                             pCreateInfo->pColorBlendState->blendConstants, 4);
        }
 
+       if (states & RADV_DYNAMIC_CULL_MODE) {
+               dynamic->cull_mode =
+                       pCreateInfo->pRasterizationState->cullMode;
+       }
+
+       if (states & RADV_DYNAMIC_FRONT_FACE) {
+               dynamic->front_face =
+                       pCreateInfo->pRasterizationState->frontFace;
+       }
+
        /* If there is no depthstencil attachment, then don't read
         * pDepthStencilState. The Vulkan spec states that pDepthStencilState may
         * be NULL in this case. Even if pDepthStencilState is non-NULL, there is
@@ -3692,16 +3706,16 @@ radv_pipeline_generate_raster_state(struct radeon_cmdbuf *ctx_cs,
                               S_028BE4_ROUND_MODE(V_028BE4_X_ROUND_TO_EVEN) |
                               S_028BE4_QUANT_MODE(V_028BE4_X_16_8_FIXED_POINT_1_256TH));
 
-       radeon_set_context_reg(ctx_cs, R_028814_PA_SU_SC_MODE_CNTL,
-                              S_028814_FACE(vkraster->frontFace) |
-                              S_028814_CULL_FRONT(!!(vkraster->cullMode & VK_CULL_MODE_FRONT_BIT)) |
-                              S_028814_CULL_BACK(!!(vkraster->cullMode & VK_CULL_MODE_BACK_BIT)) |
-                              S_028814_POLY_MODE(vkraster->polygonMode != VK_POLYGON_MODE_FILL) |
-                              S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(vkraster->polygonMode)) |
-                              S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(vkraster->polygonMode)) |
-                              S_028814_POLY_OFFSET_FRONT_ENABLE(vkraster->depthBiasEnable ? 1 : 0) |
-                              S_028814_POLY_OFFSET_BACK_ENABLE(vkraster->depthBiasEnable ? 1 : 0) |
-                              S_028814_POLY_OFFSET_PARA_ENABLE(vkraster->depthBiasEnable ? 1 : 0));
+       pipeline->graphics.pa_su_sc_mode_cntl =
+               S_028814_FACE(vkraster->frontFace) |
+               S_028814_CULL_FRONT(!!(vkraster->cullMode & VK_CULL_MODE_FRONT_BIT)) |
+               S_028814_CULL_BACK(!!(vkraster->cullMode & VK_CULL_MODE_BACK_BIT)) |
+               S_028814_POLY_MODE(vkraster->polygonMode != VK_POLYGON_MODE_FILL) |
+               S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(vkraster->polygonMode)) |
+               S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(vkraster->polygonMode)) |
+               S_028814_POLY_OFFSET_FRONT_ENABLE(vkraster->depthBiasEnable ? 1 : 0) |
+               S_028814_POLY_OFFSET_BACK_ENABLE(vkraster->depthBiasEnable ? 1 : 0) |
+               S_028814_POLY_OFFSET_PARA_ENABLE(vkraster->depthBiasEnable ? 1 : 0);
 
        /* Conservative rasterization. */
        if (mode != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) {
index 6903af4255f6983fbf2dae7ab97f045458deba80..6286a67962a56a3e4f82ec5baa9dd5f2205defe1 100644 (file)
@@ -1132,6 +1132,9 @@ struct radv_dynamic_state {
                uint32_t factor;
                uint16_t pattern;
        } line_stipple;
+
+       VkCullModeFlags cull_mode;
+       VkFrontFace front_face;
 };
 
 extern const struct radv_dynamic_state default_dynamic_state;
@@ -1650,6 +1653,7 @@ struct radv_pipeline {
                        bool disable_out_of_order_rast_for_occlusion;
                        uint8_t topology;
                        unsigned tess_patch_control_points;
+                       unsigned pa_su_sc_mode_cntl;
 
                        /* Used for rbplus */
                        uint32_t col_format;