Mesa (master): radv: add support for dynamic vertex input binding stride

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jul 13 08:45:59 UTC 2020


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

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Mon Apr 13 14:35:44 2020 +0200

radv: add support for dynamic vertex input binding stride

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

---

 src/amd/vulkan/radv_cmd_buffer.c | 40 ++++++++++++++++++++++++++++++++++++----
 src/amd/vulkan/radv_pipeline.c   | 10 ++++++++--
 src/amd/vulkan/radv_private.h    |  3 +++
 3 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 91b1b0f2d80..bfae582d30c 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -2689,8 +2689,8 @@ radv_flush_vertex_descriptors(struct radv_cmd_buffer *cmd_buffer,
 			uint32_t *desc = &((uint32_t *)vb_ptr)[i * 4];
 			uint32_t offset;
 			struct radv_buffer *buffer = cmd_buffer->vertex_bindings[i].buffer;
-			uint32_t stride = cmd_buffer->state.pipeline->binding_stride[i];
 			unsigned num_records;
+			unsigned stride;
 
 			if (!buffer)
 				continue;
@@ -2700,7 +2700,18 @@ radv_flush_vertex_descriptors(struct radv_cmd_buffer *cmd_buffer,
 			offset = cmd_buffer->vertex_bindings[i].offset;
 			va += offset + buffer->offset;
 
-			num_records = buffer->size - offset;
+			if (cmd_buffer->vertex_bindings[i].size) {
+				num_records = cmd_buffer->vertex_bindings[i].size;
+			} else {
+				num_records = buffer->size - offset;
+			}
+
+			if (cmd_buffer->state.pipeline->graphics.uses_dynamic_stride) {
+				stride = cmd_buffer->vertex_bindings[i].stride;
+			} else {
+				stride = cmd_buffer->state.pipeline->binding_stride[i];
+			}
+
 			if (cmd_buffer->device->physical_device->rad_info.chip_class != GFX8 && stride)
 				num_records /= stride;
 
@@ -3691,11 +3702,25 @@ VkResult radv_BeginCommandBuffer(
 }
 
 void radv_CmdBindVertexBuffers(
+        VkCommandBuffer                             commandBuffer,
+        uint32_t                                    firstBinding,
+        uint32_t                                    bindingCount,
+        const VkBuffer*                             pBuffers,
+        const VkDeviceSize*                         pOffsets)
+{
+	radv_CmdBindVertexBuffers2EXT(commandBuffer, firstBinding,
+				      bindingCount, pBuffers, pOffsets,
+				      NULL, NULL);
+}
+
+void radv_CmdBindVertexBuffers2EXT(
 	VkCommandBuffer                             commandBuffer,
 	uint32_t                                    firstBinding,
 	uint32_t                                    bindingCount,
 	const VkBuffer*                             pBuffers,
-	const VkDeviceSize*                         pOffsets)
+	const VkDeviceSize*                         pOffsets,
+	const VkDeviceSize*                         pSizes,
+	const VkDeviceSize*                         pStrides)
 {
 	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
 	struct radv_vertex_binding *vb = cmd_buffer->vertex_bindings;
@@ -3708,15 +3733,22 @@ void radv_CmdBindVertexBuffers(
 	for (uint32_t i = 0; i < bindingCount; i++) {
 		RADV_FROM_HANDLE(radv_buffer, buffer, pBuffers[i]);
 		uint32_t idx = firstBinding + i;
+		VkDeviceSize size = pSizes ? pSizes[i] : 0;
+		VkDeviceSize stride = pStrides ? pStrides[i] : 0;
 
+		/* pSizes and pStrides are optional. */
 		if (!changed &&
 		    (vb[idx].buffer != buffer ||
-		     vb[idx].offset != pOffsets[i])) {
+		     vb[idx].offset != pOffsets[i] ||
+		     vb[idx].size != size ||
+		     vb[idx].stride != stride)) {
 			changed = true;
 		}
 
 		vb[idx].buffer = buffer;
 		vb[idx].offset = pOffsets[i];
+		vb[idx].size = size;
+		vb[idx].stride = stride;
 
 		if (buffer) {
 			radv_cs_add_buffer(cmd_buffer->device->ws,
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index ea1f92891ea..f6df654a54b 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -1293,6 +1293,8 @@ static unsigned radv_dynamic_state_mask(VkDynamicState state)
 		return RADV_DYNAMIC_STENCIL_TEST_ENABLE;
 	case VK_DYNAMIC_STATE_STENCIL_OP_EXT:
 		return RADV_DYNAMIC_STENCIL_OP;
+	case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT:
+		return RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE;
 	default:
 		unreachable("Unhandled dynamic state");
 	}
@@ -1304,10 +1306,11 @@ static uint32_t radv_pipeline_needed_dynamic_state(const VkGraphicsPipelineCreat
 
 	/* If rasterization is disabled we do not care about any of the
 	 * dynamic states, since they are all rasterization related only,
-	 * except primitive topology.
+	 * except primitive topology and vertex binding stride.
 	 */
 	if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable)
-		return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY;
+		return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY |
+		       RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE;
 
 	if (!pCreateInfo->pRasterizationState->depthBiasEnable)
 		states &= ~RADV_DYNAMIC_DEPTH_BIAS;
@@ -1559,6 +1562,9 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
 		dynamic->line_stipple.pattern = rast_line_info->lineStipplePattern;
 	}
 
+	if (!(states & RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE))
+		pipeline->graphics.uses_dynamic_stride = true;
+
 	pipeline->dynamic_state.mask = states;
 }
 
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 359110eeec2..53fc176baa3 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1036,6 +1036,8 @@ enum radv_cmd_flush_bits {
 struct radv_vertex_binding {
 	struct radv_buffer *                          buffer;
 	VkDeviceSize                                 offset;
+	VkDeviceSize size;
+	VkDeviceSize stride;
 };
 
 struct radv_streamout_binding {
@@ -1678,6 +1680,7 @@ struct radv_pipeline {
 			unsigned tess_patch_control_points;
 			unsigned pa_su_sc_mode_cntl;
 			unsigned db_depth_control;
+			bool uses_dynamic_stride;
 
 			/* Used for rbplus */
 			uint32_t col_format;



More information about the mesa-commit mailing list