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