Mesa (main): lavapipe: implement EXT_extended_dynamic_state2

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 7 02:44:20 UTC 2021


Module: Mesa
Branch: main
Commit: 6741e4be31e1dbe36ad796bfd35d28c9e4615042
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6741e4be31e1dbe36ad796bfd35d28c9e4615042

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Tue Jul  6 14:26:05 2021 -0400

lavapipe: implement EXT_extended_dynamic_state2

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11736>

---

 src/gallium/frontends/lavapipe/lvp_cmd_buffer.c |  75 +++++++++++++
 src/gallium/frontends/lavapipe/lvp_device.c     |   8 ++
 src/gallium/frontends/lavapipe/lvp_execute.c    | 134 +++++++++++++++++++++---
 src/gallium/frontends/lavapipe/lvp_pipeline.c   |   3 +-
 src/gallium/frontends/lavapipe/lvp_private.h    |  30 ++++++
 5 files changed, 234 insertions(+), 16 deletions(-)

diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
index 446502bc010..c1e7feea185 100644
--- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
+++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
@@ -2183,3 +2183,78 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdSetStencilOpEXT(
    cmd->u.set_stencil_op.compare_op = compareOp;
    cmd_buf_queue(cmd_buffer, cmd);
 }
+
+VKAPI_ATTR void VKAPI_CALL lvp_CmdSetDepthBiasEnableEXT(
+    VkCommandBuffer                             commandBuffer,
+    VkBool32                                    depthBiasEnable)
+{
+   LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
+   struct lvp_cmd_buffer_entry *cmd;
+
+   cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_DEPTH_BIAS_ENABLE);
+   if (!cmd)
+      return;
+
+   cmd->u.set_depth_bias_enable.enable = depthBiasEnable == VK_TRUE;
+   cmd_buf_queue(cmd_buffer, cmd);
+}
+
+VKAPI_ATTR void VKAPI_CALL lvp_CmdSetLogicOpEXT(
+    VkCommandBuffer                             commandBuffer,
+    VkLogicOp                                   logicOp)
+{
+   LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
+   struct lvp_cmd_buffer_entry *cmd;
+
+   cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_LOGIC_OP);
+   if (!cmd)
+      return;
+
+   cmd->u.set_logic_op.op = logicOp;
+   cmd_buf_queue(cmd_buffer, cmd);
+}
+
+VKAPI_ATTR void VKAPI_CALL lvp_CmdSetPatchControlPointsEXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    patchControlPoints)
+{
+   LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
+   struct lvp_cmd_buffer_entry *cmd;
+
+   cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_PATCH_CONTROL_POINTS);
+   if (!cmd)
+      return;
+
+   cmd->u.set_patch_control_points.vertices_per_patch = patchControlPoints;
+   cmd_buf_queue(cmd_buffer, cmd);
+}
+
+VKAPI_ATTR void VKAPI_CALL lvp_CmdSetPrimitiveRestartEnableEXT(
+    VkCommandBuffer                             commandBuffer,
+    VkBool32                                    primitiveRestartEnable)
+{
+   LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
+   struct lvp_cmd_buffer_entry *cmd;
+
+   cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_PRIMITIVE_RESTART_ENABLE);
+   if (!cmd)
+      return;
+
+   cmd->u.set_primitive_restart_enable.enable = primitiveRestartEnable == VK_TRUE;
+   cmd_buf_queue(cmd_buffer, cmd);
+}
+
+VKAPI_ATTR void VKAPI_CALL lvp_CmdSetRasterizerDiscardEnableEXT(
+    VkCommandBuffer                             commandBuffer,
+    VkBool32                                    rasterizerDiscardEnable)
+{
+   LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
+   struct lvp_cmd_buffer_entry *cmd;
+
+   cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_RASTERIZER_DISCARD_ENABLE);
+   if (!cmd)
+      return;
+
+   cmd->u.set_rasterizer_discard_enable.enable = rasterizerDiscardEnable == VK_TRUE;
+   cmd_buf_queue(cmd_buffer, cmd);
+}
diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c
index 921c0f0577a..d316091b320 100644
--- a/src/gallium/frontends/lavapipe/lvp_device.c
+++ b/src/gallium/frontends/lavapipe/lvp_device.c
@@ -127,6 +127,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported =
    .EXT_calibrated_timestamps             = true,
    .EXT_conditional_rendering             = true,
    .EXT_extended_dynamic_state            = true,
+   .EXT_extended_dynamic_state2           = true,
    .EXT_host_query_reset                  = true,
    .EXT_index_type_uint8                  = true,
    .EXT_multi_draw                        = true,
@@ -644,6 +645,13 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2(
          features->multiDraw = true;
          break;
       }
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: {
+         VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features = (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext;
+         features->extendedDynamicState2 = true;
+         features->extendedDynamicState2LogicOp = true;
+         features->extendedDynamicState2PatchControlPoints = true;
+         break;
+      }
       default:
          break;
       }
diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c
index 81694cea4d5..044934ef04b 100644
--- a/src/gallium/frontends/lavapipe/lvp_execute.c
+++ b/src/gallium/frontends/lavapipe/lvp_execute.c
@@ -78,6 +78,12 @@ struct rendering_state {
    struct pipe_framebuffer_state framebuffer;
 
    struct pipe_blend_state blend_state;
+   struct {
+      float offset_units;
+      float offset_scale;
+      float offset_clamp;
+      bool enabled;
+   } depth_bias;
    struct pipe_rasterizer_state rs_state;
    struct pipe_depth_stencil_alpha_state dsa_state;
 
@@ -221,6 +227,12 @@ static void emit_state(struct rendering_state *state)
           (state->gs_output_lines == GS_OUTPUT_LINES ||
            (state->gs_output_lines == GS_OUTPUT_NONE && u_reduced_prim(state->info.mode) == PIPE_PRIM_LINES)))
          state->rs_state.multisample = false;
+      assert(offsetof(struct pipe_rasterizer_state, offset_clamp) - offsetof(struct pipe_rasterizer_state, offset_units) == sizeof(float) * 2);
+      if (state->depth_bias.enabled) {
+         memcpy(&state->rs_state.offset_units, &state->depth_bias, sizeof(float) * 3);
+      } else {
+         memset(&state->rs_state.offset_units, 0, sizeof(float) * 3);
+      }
       cso_set_rasterizer(state->cso, &state->rs_state);
       state->rs_dirty = false;
       state->rs_state.multisample = ms;
@@ -353,6 +365,41 @@ get_viewport_xform(const VkViewport *viewport,
    translate[2] = n;
 }
 
+/* enum re-indexing:
+
+    VK_DYNAMIC_STATE_VIEWPORT
+    VK_DYNAMIC_STATE_SCISSOR
+    VK_DYNAMIC_STATE_LINE_WIDTH
+    VK_DYNAMIC_STATE_DEPTH_BIAS
+    VK_DYNAMIC_STATE_BLEND_CONSTANTS
+    VK_DYNAMIC_STATE_DEPTH_BOUNDS
+    VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
+    VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
+    VK_DYNAMIC_STATE_STENCIL_REFERENCE
+
+    VK_DYNAMIC_STATE_LINE_STIPPLE_EXT
+
+    VK_DYNAMIC_STATE_CULL_MODE_EXT
+    VK_DYNAMIC_STATE_FRONT_FACE_EXT
+    VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT
+    VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT
+    VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT
+    VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT
+    VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT
+    VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT
+    VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT
+    VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT
+    VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT
+    VK_DYNAMIC_STATE_STENCIL_OP_EXT
+
+    VK_DYNAMIC_STATE_VERTEX_INPUT_EXT
+
+    VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT
+    VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT
+    VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT
+    VK_DYNAMIC_STATE_LOGIC_OP_EXT
+    VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT
+*/
 static int conv_dynamic_state_idx(VkDynamicState dyn_state)
 {
    if (dyn_state <= VK_DYNAMIC_STATE_STENCIL_REFERENCE)
@@ -365,6 +412,11 @@ static int conv_dynamic_state_idx(VkDynamicState dyn_state)
       return dyn_state - VK_DYNAMIC_STATE_CULL_MODE_EXT + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2;
    if (dyn_state == VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)
       return (VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT) + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1;
+   if (dyn_state >= VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT &&
+       dyn_state <= VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)
+      return dyn_state - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT +
+             VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT +
+             VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1;
    assert(0);
    return -1;
 }
@@ -444,7 +496,8 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
    if (pipeline->graphics_create_info.pRasterizationState) {
       const VkPipelineRasterizationStateCreateInfo *rsc = pipeline->graphics_create_info.pRasterizationState;
       state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable;
-      state->rs_state.rasterizer_discard = rsc->rasterizerDiscardEnable;
+      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)])
+         state->rs_state.rasterizer_discard = rsc->rasterizerDiscardEnable;
 
       state->rs_state.line_smooth = pipeline->line_smooth;
       state->rs_state.line_stipple_enable = pipeline->line_stipple_enable;
@@ -465,14 +518,12 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
          state->rs_state.line_stipple_pattern = pipeline->line_stipple_pattern;
       }
 
+      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT)])
+         state->depth_bias.enabled = pipeline->graphics_create_info.pRasterizationState->depthBiasEnable;
       if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BIAS]) {
-         if (pipeline->graphics_create_info.pRasterizationState->depthBiasEnable) {
-            state->rs_state.offset_units = rsc->depthBiasConstantFactor;
-            state->rs_state.offset_scale = rsc->depthBiasSlopeFactor;
-            state->rs_state.offset_clamp = rsc->depthBiasClamp;
-         } else {
-            state->rs_state.offset_clamp = state->rs_state.offset_scale = state->rs_state.offset_units = 0.0;
-         }
+         state->depth_bias.offset_units = rsc->depthBiasConstantFactor;
+         state->depth_bias.offset_scale = rsc->depthBiasSlopeFactor;
+         state->depth_bias.offset_clamp = rsc->depthBiasClamp;
       }
 
       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_CULL_MODE_EXT)])
@@ -578,7 +629,8 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
 
       if (cb->logicOpEnable) {
          state->blend_state.logicop_enable = VK_TRUE;
-         state->blend_state.logicop_func = vk_conv_logic_op(cb->logicOp);
+         if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LOGIC_OP_EXT)])
+            state->blend_state.logicop_func = vk_conv_logic_op(cb->logicOp);
       }
 
       if (cb->attachmentCount > 1)
@@ -676,12 +728,15 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
          state->info.mode = vk_conv_topology(ia->topology);
          state->rs_dirty = true;
       }
-      state->info.primitive_restart = ia->primitiveRestartEnable;
+      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)])
+         state->info.primitive_restart = ia->primitiveRestartEnable;
    }
 
    if (pipeline->graphics_create_info.pTessellationState) {
-      const VkPipelineTessellationStateCreateInfo *ts = pipeline->graphics_create_info.pTessellationState;
-      state->info.vertices_per_patch = ts->patchControlPoints;
+      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT)]) {
+         const VkPipelineTessellationStateCreateInfo *ts = pipeline->graphics_create_info.pTessellationState;
+         state->info.vertices_per_patch = ts->patchControlPoints;
+      }
    } else
       state->info.vertices_per_patch = 0;
 
@@ -1639,9 +1694,9 @@ static void handle_set_line_width(struct lvp_cmd_buffer_entry *cmd,
 static void handle_set_depth_bias(struct lvp_cmd_buffer_entry *cmd,
                                   struct rendering_state *state)
 {
-   state->rs_state.offset_units = cmd->u.set_depth_bias.constant_factor;
-   state->rs_state.offset_scale = cmd->u.set_depth_bias.slope_factor;
-   state->rs_state.offset_clamp = cmd->u.set_depth_bias.clamp;
+   state->depth_bias.offset_units = cmd->u.set_depth_bias.constant_factor;
+   state->depth_bias.offset_scale = cmd->u.set_depth_bias.slope_factor;
+   state->depth_bias.offset_clamp = cmd->u.set_depth_bias.clamp;
    state->rs_dirty = true;
 }
 
@@ -2970,6 +3025,40 @@ static void handle_set_line_stipple(struct lvp_cmd_buffer_entry *cmd,
    state->rs_dirty = true;
 }
 
+static void handle_set_depth_bias_enable(struct lvp_cmd_buffer_entry *cmd,
+                                         struct rendering_state *state)
+{
+   state->rs_dirty |= state->depth_bias.enabled != cmd->u.set_depth_bias_enable.enable;
+   state->depth_bias.enabled = cmd->u.set_depth_bias_enable.enable;
+}
+
+static void handle_set_logic_op(struct lvp_cmd_buffer_entry *cmd,
+                                struct rendering_state *state)
+{
+   unsigned op = vk_conv_logic_op(cmd->u.set_logic_op.op);
+   state->rs_dirty |= state->blend_state.logicop_func != op;
+   state->blend_state.logicop_func = op;
+}
+
+static void handle_set_patch_control_points(struct lvp_cmd_buffer_entry *cmd,
+                                            struct rendering_state *state)
+{
+   state->info.vertices_per_patch = cmd->u.set_patch_control_points.vertices_per_patch;
+}
+
+static void handle_set_primitive_restart_enable(struct lvp_cmd_buffer_entry *cmd,
+                                                struct rendering_state *state)
+{
+   state->info.primitive_restart = cmd->u.set_primitive_restart_enable.enable;
+}
+
+static void handle_set_rasterizer_discard_enable(struct lvp_cmd_buffer_entry *cmd,
+                                                 struct rendering_state *state)
+{
+   state->rs_dirty |= state->rs_state.rasterizer_discard != cmd->u.set_rasterizer_discard_enable.enable;
+   state->rs_state.rasterizer_discard = cmd->u.set_rasterizer_discard_enable.enable;
+}
+
 static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
                                    struct rendering_state *state)
 {
@@ -3185,6 +3274,21 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
       case LVP_CMD_SET_LINE_STIPPLE:
          handle_set_line_stipple(cmd, state);
          break;
+      case LVP_CMD_SET_DEPTH_BIAS_ENABLE:
+         handle_set_depth_bias_enable(cmd, state);
+         break;
+      case LVP_CMD_SET_LOGIC_OP:
+         handle_set_logic_op(cmd, state);
+         break;
+      case LVP_CMD_SET_PATCH_CONTROL_POINTS:
+         handle_set_patch_control_points(cmd, state);
+         break;
+      case LVP_CMD_SET_PRIMITIVE_RESTART_ENABLE:
+         handle_set_primitive_restart_enable(cmd, state);
+         break;
+      case LVP_CMD_SET_RASTERIZER_DISCARD_ENABLE:
+         handle_set_rasterizer_discard_enable(cmd, state);
+         break;
       }
       first = false;
       did_flush = false;
diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c
index 75a54b878d1..bc6dec2f13a 100644
--- a/src/gallium/frontends/lavapipe/lvp_pipeline.c
+++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c
@@ -299,7 +299,8 @@ deep_copy_graphics_create_info(void *mem_ctx,
    }
 
    /* pViewportState */
-   bool rasterization_disabled = src->pRasterizationState->rasterizerDiscardEnable;
+   bool rasterization_disabled = !dynamic_state_contains(src->pDynamicState, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT) &&
+                                 src->pRasterizationState->rasterizerDiscardEnable;
    if (src->pViewportState && !rasterization_disabled) {
       VkPipelineViewportStateCreateInfo *viewport_state;
       viewport_state = ralloc(mem_ctx, VkPipelineViewportStateCreateInfo);
diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h
index d2dee50cd72..830b2e78b06 100644
--- a/src/gallium/frontends/lavapipe/lvp_private.h
+++ b/src/gallium/frontends/lavapipe/lvp_private.h
@@ -683,6 +683,11 @@ enum lvp_cmds {
    LVP_CMD_SET_STENCIL_TEST_ENABLE,
    LVP_CMD_SET_STENCIL_OP,
    LVP_CMD_SET_LINE_STIPPLE,
+   LVP_CMD_SET_DEPTH_BIAS_ENABLE,
+   LVP_CMD_SET_LOGIC_OP,
+   LVP_CMD_SET_PATCH_CONTROL_POINTS,
+   LVP_CMD_SET_PRIMITIVE_RESTART_ENABLE,
+   LVP_CMD_SET_RASTERIZER_DISCARD_ENABLE,
 };
 
 struct lvp_cmd_bind_pipeline {
@@ -1069,6 +1074,26 @@ struct lvp_cmd_set_line_stipple {
    uint16_t line_stipple_pattern;
 };
 
+struct lvp_cmd_set_depth_bias_enable {
+   bool enable;
+};
+
+struct lvp_cmd_set_logic_op {
+   VkLogicOp op;
+};
+
+struct lvp_cmd_set_patch_control_points {
+   uint32_t vertices_per_patch;
+};
+
+struct lvp_cmd_set_primitive_restart_enable {
+   bool enable;
+};
+
+struct lvp_cmd_set_rasterizer_discard_enable {
+   bool enable;
+};
+
 struct lvp_cmd_buffer_entry {
    struct list_head cmd_link;
    uint32_t cmd_type;
@@ -1127,6 +1152,11 @@ struct lvp_cmd_buffer_entry {
       struct lvp_cmd_set_stencil_test_enable set_stencil_test_enable;
       struct lvp_cmd_set_stencil_op set_stencil_op;
       struct lvp_cmd_set_line_stipple set_line_stipple;
+      struct lvp_cmd_set_depth_bias_enable set_depth_bias_enable;
+      struct lvp_cmd_set_logic_op set_logic_op;
+      struct lvp_cmd_set_patch_control_points set_patch_control_points;
+      struct lvp_cmd_set_primitive_restart_enable set_primitive_restart_enable;
+      struct lvp_cmd_set_rasterizer_discard_enable set_rasterizer_discard_enable;
    } u;
 };
 



More information about the mesa-commit mailing list