Mesa (main): lavapipe: implement VK_EXT_line_rasterization

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jul 5 07:41:39 UTC 2021


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Fri Jul  2 10:37:47 2021 -0400

lavapipe: implement VK_EXT_line_rasterization

rectangular and strict lines aren't supported in this, and multisampling
must be disabled for correct line rasterization

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

---

 src/gallium/frontends/lavapipe/lvp_cmd_buffer.c | 17 +++++++++++++++
 src/gallium/frontends/lavapipe/lvp_device.c     | 18 ++++++++++++++++
 src/gallium/frontends/lavapipe/lvp_execute.c    | 28 +++++++++++++++++++++++--
 src/gallium/frontends/lavapipe/lvp_pipeline.c   | 14 +++++++++++++
 src/gallium/frontends/lavapipe/lvp_private.h    |  8 +++++++
 5 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
index 7230b5ae660..446502bc010 100644
--- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
+++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
@@ -1963,6 +1963,23 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdSetFrontFaceEXT(
    cmd_buf_queue(cmd_buffer, cmd);
 }
 
+VKAPI_ATTR void VKAPI_CALL lvp_CmdSetLineStippleEXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    lineStippleFactor,
+    uint16_t                                    lineStipplePattern)
+{
+   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_LINE_STIPPLE);
+   if (!cmd)
+      return;
+
+   cmd->u.set_line_stipple.line_stipple_factor = lineStippleFactor;
+   cmd->u.set_line_stipple.line_stipple_pattern = lineStipplePattern;
+   cmd_buf_queue(cmd_buffer, cmd);
+}
+
 VKAPI_ATTR void VKAPI_CALL lvp_CmdSetPrimitiveTopologyEXT(
     VkCommandBuffer                             commandBuffer,
     VkPrimitiveTopology                         primitiveTopology)
diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c
index 4cf903f8687..bd2dbe74344 100644
--- a/src/gallium/frontends/lavapipe/lvp_device.c
+++ b/src/gallium/frontends/lavapipe/lvp_device.c
@@ -140,6 +140,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported =
    .EXT_vertex_input_dynamic_state        = true,
    .EXT_custom_border_color               = true,
    .EXT_provoking_vertex                  = true,
+   .EXT_line_rasterization                = true,
    .GOOGLE_decorate_string                = true,
    .GOOGLE_hlsl_functionality1            = true,
 };
@@ -512,6 +513,17 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2(
          features->privateData = true;
          break;
       }
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {
+         VkPhysicalDeviceLineRasterizationFeaturesEXT *features =
+            (VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;
+         features->rectangularLines = false;
+         features->bresenhamLines = true;
+         features->smoothLines = true;
+         features->stippledRectangularLines = false;
+         features->stippledBresenhamLines = true;
+         features->stippledSmoothLines = true;
+         break;
+      }
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
          VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
             (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;
@@ -927,6 +939,12 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties2(
          properties->filterMinmaxSingleComponentFormats = true;
          break;
       }
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
+         VkPhysicalDeviceLineRasterizationPropertiesEXT *properties =
+            (VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
+         properties->lineSubPixelPrecisionBits = 4;
+         break;
+      }
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: {
          VkPhysicalDeviceSubgroupProperties *properties =
             (VkPhysicalDeviceSubgroupProperties*)ext;
diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c
index c88b9dca738..020c6394d99 100644
--- a/src/gallium/frontends/lavapipe/lvp_execute.c
+++ b/src/gallium/frontends/lavapipe/lvp_execute.c
@@ -38,6 +38,7 @@
 #include "util/u_sampler.h"
 #include "util/u_box.h"
 #include "util/u_inlines.h"
+#include "util/u_prim.h"
 #include "util/u_prim_restart.h"
 #include "util/format/u_format_zs.h"
 
@@ -116,6 +117,7 @@ struct rendering_state {
    int num_shader_buffers[PIPE_SHADER_TYPES];
    bool iv_dirty[PIPE_SHADER_TYPES];
    bool sb_dirty[PIPE_SHADER_TYPES];
+   bool disable_multisample;
    enum gs_output gs_output_lines : 2;
    void *ss_cso[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
    void *velems_cso;
@@ -214,8 +216,14 @@ static void emit_state(struct rendering_state *state)
    }
 
    if (state->rs_dirty) {
+      bool ms = state->rs_state.multisample;
+      if (state->disable_multisample &&
+          (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;
       cso_set_rasterizer(state->cso, &state->rs_state);
       state->rs_dirty = false;
+      state->rs_state.multisample = ms;
    }
 
    if (state->dsa_dirty) {
@@ -438,7 +446,8 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
       state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable;
       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;
       state->rs_state.fill_front = vk_polygon_mode_to_pipe(rsc->polygonMode);
       state->rs_state.fill_back = vk_polygon_mode_to_pipe(rsc->polygonMode);
       state->rs_state.point_size_per_vertex = true;
@@ -470,6 +479,7 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
       state->rs_dirty = true;
    }
 
+   state->disable_multisample = pipeline->disable_multisample;
    if (pipeline->graphics_create_info.pMultisampleState) {
       const VkPipelineMultisampleStateCreateInfo *ms = pipeline->graphics_create_info.pMultisampleState;
       state->rs_state.multisample = ms->rasterizationSamples > 1;
@@ -658,8 +668,10 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
    {
       const VkPipelineInputAssemblyStateCreateInfo *ia = pipeline->graphics_create_info.pInputAssemblyState;
 
-      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT)])
+      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT)]) {
          state->info.mode = vk_conv_topology(ia->topology);
+         state->rs_dirty = true;
+      }
       state->info.primitive_restart = ia->primitiveRestartEnable;
    }
 
@@ -2886,6 +2898,7 @@ static void handle_set_primitive_topology(struct lvp_cmd_buffer_entry *cmd,
                                           struct rendering_state *state)
 {
    state->info.mode = vk_conv_topology(cmd->u.set_primitive_topology.prim);
+   state->rs_dirty = true;
 }
 
 
@@ -2945,6 +2958,14 @@ static void handle_set_stencil_op(struct lvp_cmd_buffer_entry *cmd,
    state->dsa_dirty = true;
 }
 
+static void handle_set_line_stipple(struct lvp_cmd_buffer_entry *cmd,
+                                    struct rendering_state *state)
+{
+   state->rs_state.line_stipple_factor = cmd->u.set_line_stipple.line_stipple_factor - 1;
+   state->rs_state.line_stipple_pattern = cmd->u.set_line_stipple.line_stipple_pattern;
+   state->rs_dirty = true;
+}
+
 static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
                                    struct rendering_state *state)
 {
@@ -3157,6 +3178,9 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
       case LVP_CMD_SET_STENCIL_OP:
          handle_set_stencil_op(cmd, state);
          break;
+      case LVP_CMD_SET_LINE_STIPPLE:
+         handle_set_line_stipple(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 f01f7b00bd2..63b8041f43f 100644
--- a/src/gallium/frontends/lavapipe/lvp_pipeline.c
+++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c
@@ -806,6 +806,20 @@ lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
                            PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT);
    pipeline->provoking_vertex_last = pv_state && pv_state->provokingVertexMode == VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT;
 
+   const VkPipelineRasterizationLineStateCreateInfoEXT *line_state =
+      vk_find_struct_const(pCreateInfo->pRasterizationState,
+                           PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT);
+   if (line_state) {
+      /* always draw bresenham if !smooth */
+      pipeline->line_stipple_enable = line_state->stippledLineEnable;
+      pipeline->line_smooth = line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
+      pipeline->disable_multisample = line_state->lineRasterizationMode != VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
+      if (!dynamic_state_contains(pipeline->graphics_create_info.pDynamicState, VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)) {
+         pipeline->line_stipple_factor = line_state->lineStippleFactor - 1;
+         pipeline->line_stipple_pattern = line_state->lineStipplePattern;
+      }
+   }
+
 
    for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
       VK_FROM_HANDLE(vk_shader_module, module,
diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h
index 35f2f07a71b..d2dee50cd72 100644
--- a/src/gallium/frontends/lavapipe/lvp_private.h
+++ b/src/gallium/frontends/lavapipe/lvp_private.h
@@ -483,6 +483,7 @@ struct lvp_pipeline {
    uint16_t line_stipple_pattern;
    bool line_stipple_enable;
    bool line_smooth;
+   bool disable_multisample;
    bool gs_output_lines;
    bool provoking_vertex_last;
 };
@@ -681,6 +682,7 @@ enum lvp_cmds {
    LVP_CMD_SET_DEPTH_BOUNDS_TEST_ENABLE,
    LVP_CMD_SET_STENCIL_TEST_ENABLE,
    LVP_CMD_SET_STENCIL_OP,
+   LVP_CMD_SET_LINE_STIPPLE,
 };
 
 struct lvp_cmd_bind_pipeline {
@@ -1062,6 +1064,11 @@ struct lvp_cmd_set_stencil_op {
    VkCompareOp compare_op;
 };
 
+struct lvp_cmd_set_line_stipple {
+   uint32_t line_stipple_factor;
+   uint16_t line_stipple_pattern;
+};
+
 struct lvp_cmd_buffer_entry {
    struct list_head cmd_link;
    uint32_t cmd_type;
@@ -1119,6 +1126,7 @@ struct lvp_cmd_buffer_entry {
       struct lvp_cmd_set_depth_bounds_test_enable set_depth_bounds_test_enable;
       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;
    } u;
 };
 



More information about the mesa-commit mailing list