Mesa (master): radv: implement VK_EXT_line_rasterization

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Feb 13 07:45:16 UTC 2020


Module: Mesa
Branch: master
Commit: 556c9401495930c23a10ca2a26db098d12663e27
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=556c9401495930c23a10ca2a26db098d12663e27

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Fri Sep 13 13:40:44 2019 +0200

radv: implement VK_EXT_line_rasterization

Only Bresenham lines are supported. GFX9 is currently disabled
because there is some CTS failures for some weird reasons.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2982>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2982>

---

 src/amd/vulkan/radv_cmd_buffer.c  | 45 +++++++++++++++++++++++++++++++++++++++
 src/amd/vulkan/radv_device.c      | 17 +++++++++++++++
 src/amd/vulkan/radv_extensions.py |  2 ++
 src/amd/vulkan/radv_pipeline.c    | 33 ++++++++++++++++++++++++++++
 src/amd/vulkan/radv_private.h     | 22 +++++++++++++------
 5 files changed, 112 insertions(+), 7 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index d516c26d96c..66c7d0721ba 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -92,6 +92,10 @@ const struct radv_dynamic_state default_dynamic_state = {
 		.front = 0u,
 		.back = 0u,
 	},
+	.line_stipple = {
+		.factor = 0u,
+		.pattern = 0u,
+	},
 };
 
 static void
@@ -212,6 +216,14 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer,
 		}
 	}
 
+	if (copy_mask & RADV_DYNAMIC_LINE_STIPPLE) {
+		if (memcmp(&dest->line_stipple, &src->line_stipple,
+			   sizeof(src->line_stipple))) {
+			dest->line_stipple = src->line_stipple;
+			dest_mask |= RADV_DYNAMIC_LINE_STIPPLE;
+		}
+	}
+
 	cmd_buffer->state.dirty |= dest_mask;
 }
 
@@ -1317,6 +1329,22 @@ radv_emit_depth_bias(struct radv_cmd_buffer *cmd_buffer)
 	radeon_emit(cmd_buffer->cs, bias); /* BACK OFFSET */
 }
 
+static void
+radv_emit_line_stipple(struct radv_cmd_buffer *cmd_buffer)
+{
+	struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
+	struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
+	uint32_t auto_reset_cntl = 1;
+
+	if (pipeline->graphics.topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP)
+		auto_reset_cntl = 2;
+
+	radeon_set_context_reg(cmd_buffer->cs, R_028A0C_PA_SC_LINE_STIPPLE,
+			       S_028A0C_LINE_PATTERN(d->line_stipple.pattern) |
+			       S_028A0C_REPEAT_COUNT(d->line_stipple.factor - 1) |
+			       S_028A0C_AUTO_RESET_CNTL(auto_reset_cntl));
+}
+
 static void
 radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer,
 			 int index,
@@ -2202,6 +2230,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer)
 	if (states & RADV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS)
 		radv_emit_sample_locations(cmd_buffer);
 
+	if (states & RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE)
+		radv_emit_line_stipple(cmd_buffer);
+
 	cmd_buffer->state.dirty &= ~states;
 }
 
@@ -4107,6 +4138,20 @@ void radv_CmdSetSampleLocationsEXT(
 	state->dirty |= RADV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
 }
 
+void radv_CmdSetLineStippleEXT(
+	VkCommandBuffer                             commandBuffer,
+	uint32_t                                    lineStippleFactor,
+	uint16_t                                    lineStipplePattern)
+{
+	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+	struct radv_cmd_state *state = &cmd_buffer->state;
+
+	state->dynamic.line_stipple.factor = lineStippleFactor;
+	state->dynamic.line_stipple.pattern = lineStipplePattern;
+
+	state->dirty |= RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
+}
+
 void radv_CmdExecuteCommands(
 	VkCommandBuffer                             commandBuffer,
 	uint32_t                                    commandBufferCount,
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index a016ff3886d..ca0909ff73d 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -1270,6 +1270,17 @@ void radv_GetPhysicalDeviceFeatures2(
 			features->subgroupBroadcastDynamicId = true;
 			break;
 		}
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {
+			VkPhysicalDeviceLineRasterizationFeaturesEXT *features =
+				(VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;
+			features->rectangularLines = false;
+			features->bresenhamLines = true;
+			features->smoothLines = false;
+			features->stippledRectangularLines = false;
+			features->stippledBresenhamLines = true;
+			features->stippledSmoothLines = false;
+			break;
+		}
 		default:
 			break;
 		}
@@ -1889,6 +1900,12 @@ void radv_GetPhysicalDeviceProperties2(
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES:
 			radv_get_physical_device_properties_1_2(pdevice, (void *)ext);
 			break;
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
+			VkPhysicalDeviceLineRasterizationPropertiesEXT *props =
+				(VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
+			props->lineSubPixelPrecisionBits = 4;
+			break;
+		}
 		default:
 			break;
 		}
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 57aa67be616..32e14a640e2 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -128,6 +128,8 @@ EXTENSIONS = [
     Extension('VK_EXT_host_query_reset',                  1, True),
     Extension('VK_EXT_index_type_uint8',                  1, 'device->rad_info.chip_class >= GFX8'),
     Extension('VK_EXT_inline_uniform_block',              1, True),
+    # Disable line rasterization on GFX9 until the CTS failures have been resolved.
+    Extension('VK_EXT_line_rasterization',                1, 'device->rad_info.chip_class != GFX9'),
     Extension('VK_EXT_memory_budget',                     1, True),
     Extension('VK_EXT_memory_priority',                   1, True),
     Extension('VK_EXT_pci_bus_info',                      2, True),
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index b065ca4258c..c3c69b34015 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -1242,6 +1242,23 @@ radv_pipeline_init_multisample_state(struct radv_pipeline *pipeline,
 	ms->pa_sc_mode_cntl_0 = S_028A48_ALTERNATE_RBS_PER_TILE(pipeline->device->physical_device->rad_info.chip_class >= GFX9) |
 	                        S_028A48_VPORT_SCISSOR_ENABLE(1);
 
+	const VkPipelineRasterizationLineStateCreateInfoEXT *rast_line =
+		vk_find_struct_const(pCreateInfo->pRasterizationState->pNext,
+				     PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT);
+	if (rast_line) {
+		ms->pa_sc_mode_cntl_0 |= S_028A48_LINE_STIPPLE_ENABLE(rast_line->stippledLineEnable);
+		if (rast_line->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT) {
+			/* From the Vulkan spec 1.1.129:
+			 *
+			 * "When VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT lines
+			 *  are being rasterized, sample locations may all be
+			 *  treated as being at the pixel center (this may
+			 *  affect attribute and depth interpolation)."
+			 */
+			ms->num_samples = 1;
+		}
+	}
+
 	if (ms->num_samples > 1) {
 		RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass);
 		struct radv_subpass *subpass = &pass->subpasses[pCreateInfo->subpass];
@@ -1397,6 +1414,8 @@ static unsigned radv_dynamic_state_mask(VkDynamicState state)
 		return RADV_DYNAMIC_DISCARD_RECTANGLE;
 	case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT:
 		return RADV_DYNAMIC_SAMPLE_LOCATIONS;
+	case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT:
+		return RADV_DYNAMIC_LINE_STIPPLE;
 	default:
 		unreachable("Unhandled dynamic state");
 	}
@@ -1432,6 +1451,11 @@ static uint32_t radv_pipeline_needed_dynamic_state(const VkGraphicsPipelineCreat
 				  PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT))
 		states &= ~RADV_DYNAMIC_SAMPLE_LOCATIONS;
 
+	if (!pCreateInfo->pRasterizationState ||
+	    !vk_find_struct_const(pCreateInfo->pRasterizationState->pNext,
+				  PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT))
+		states &= ~RADV_DYNAMIC_LINE_STIPPLE;
+
 	/* TODO: blend constants & line width. */
 
 	return states;
@@ -1584,6 +1608,14 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
 		}
 	}
 
+	const VkPipelineRasterizationLineStateCreateInfoEXT *rast_line_info =
+		vk_find_struct_const(pCreateInfo->pRasterizationState->pNext,
+				     PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT);
+	if (needed_states & RADV_DYNAMIC_LINE_STIPPLE) {
+		dynamic->line_stipple.factor = rast_line_info->lineStippleFactor;
+		dynamic->line_stipple.pattern = rast_line_info->lineStipplePattern;
+	}
+
 	pipeline->dynamic_state.mask = states;
 }
 
@@ -5019,6 +5051,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
 	uint32_t gs_out;
 	uint32_t prim = si_translate_prim(pCreateInfo->pInputAssemblyState->topology);
 
+	pipeline->graphics.topology = pCreateInfo->pInputAssemblyState->topology;
 	pipeline->graphics.can_use_guardband = radv_prim_can_use_guardband(pCreateInfo->pInputAssemblyState->topology);
 
 	if (radv_pipeline_has_gs(pipeline)) {
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 537355f6c9a..af2f05859a1 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -971,7 +971,8 @@ enum radv_dynamic_state_bits {
 	RADV_DYNAMIC_STENCIL_REFERENCE    = 1 << 8,
 	RADV_DYNAMIC_DISCARD_RECTANGLE    = 1 << 9,
 	RADV_DYNAMIC_SAMPLE_LOCATIONS     = 1 << 10,
-	RADV_DYNAMIC_ALL                  = (1 << 11) - 1,
+	RADV_DYNAMIC_LINE_STIPPLE	  = 1 << 11,
+	RADV_DYNAMIC_ALL                  = (1 << 12) - 1,
 };
 
 enum radv_cmd_dirty_bits {
@@ -988,12 +989,13 @@ enum radv_cmd_dirty_bits {
 	RADV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE         = 1 << 8,
 	RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE         = 1 << 9,
 	RADV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS          = 1 << 10,
-	RADV_CMD_DIRTY_DYNAMIC_ALL                       = (1 << 11) - 1,
-	RADV_CMD_DIRTY_PIPELINE                          = 1 << 11,
-	RADV_CMD_DIRTY_INDEX_BUFFER                      = 1 << 12,
-	RADV_CMD_DIRTY_FRAMEBUFFER                       = 1 << 13,
-	RADV_CMD_DIRTY_VERTEX_BUFFER                     = 1 << 14,
-	RADV_CMD_DIRTY_STREAMOUT_BUFFER                  = 1 << 15,
+	RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE		 = 1 << 11,
+	RADV_CMD_DIRTY_DYNAMIC_ALL                       = (1 << 12) - 1,
+	RADV_CMD_DIRTY_PIPELINE                          = 1 << 12,
+	RADV_CMD_DIRTY_INDEX_BUFFER                      = 1 << 13,
+	RADV_CMD_DIRTY_FRAMEBUFFER                       = 1 << 14,
+	RADV_CMD_DIRTY_VERTEX_BUFFER                     = 1 << 15,
+	RADV_CMD_DIRTY_STREAMOUT_BUFFER                  = 1 << 16,
 };
 
 enum radv_cmd_flush_bits {
@@ -1125,6 +1127,11 @@ struct radv_dynamic_state {
 	struct radv_discard_rectangle_state               discard_rectangle;
 
 	struct radv_sample_locations_state                sample_location;
+
+	struct {
+		uint32_t factor;
+		uint16_t pattern;
+	} line_stipple;
 };
 
 extern const struct radv_dynamic_state default_dynamic_state;
@@ -1640,6 +1647,7 @@ struct radv_pipeline {
  			bool can_use_guardband;
 			uint32_t needed_dynamic_state;
 			bool disable_out_of_order_rast_for_occlusion;
+			uint8_t topology;
 
 			/* Used for rbplus */
 			uint32_t col_format;



More information about the mesa-commit mailing list