[Mesa-dev] [PATCH 2/2] radv: Implement VK_EXT_discard_rectangles.

Mao, David David.Mao at amd.com
Thu Jan 11 04:20:18 UTC 2018


Hi Bas,
If I read it correctly, you are trying to interpret the ClipRule as a mask. 
You set the bit i if the ith rectangle is need to be inclusive. 
Am I right?
IIRC, It is not a right interpretation. 
Where did you read the register spec?  I would like to take a look.
Thanks. 

Best Regards,
David


-----Original Message-----
From: mesa-dev [mailto:mesa-dev-bounces at lists.freedesktop.org] On Behalf Of Bas Nieuwenhuizen
Sent: Wednesday, January 10, 2018 10:34 AM
To: mesa-dev at lists.freedesktop.org
Cc: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Subject: [Mesa-dev] [PATCH 2/2] radv: Implement VK_EXT_discard_rectangles.

Tested with a modified deferred demo and no regressions in a 1.0.2 mustpass run.
---
 src/amd/vulkan/radv_cmd_buffer.c  | 51 +++++++++++++++++++++++++++++++++++++++
 src/amd/vulkan/radv_device.c      |  6 +++++
 src/amd/vulkan/radv_extensions.py |  1 +
 src/amd/vulkan/radv_pipeline.c    | 35 +++++++++++++++++++++++++++
 src/amd/vulkan/radv_private.h     | 23 +++++++++++++-----
 5 files changed, 110 insertions(+), 6 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 3114ae9fb4..4c42dc2b13 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -91,6 +91,7 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer,
 	 */
 	dest->viewport.count = src->viewport.count;
 	dest->scissor.count = src->scissor.count;
+	dest->discard_rectangle.count = src->discard_rectangle.count;
 
 	if (copy_mask & RADV_DYNAMIC_VIEWPORT) {
 		if (memcmp(&dest->viewport.viewports, &src->viewport.viewports, @@ -168,6 +169,16 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer,
 		}
 	}
 
+	if (copy_mask & RADV_DYNAMIC_DISCARD_RECTANGLE) {
+		if (memcmp(&dest->discard_rectangle.rectangles, &src->discard_rectangle.rectangles,
+			   src->discard_rectangle.count * sizeof(VkRect2D))) {
+			typed_memcpy(dest->discard_rectangle.rectangles,
+				     src->discard_rectangle.rectangles,
+				     src->discard_rectangle.count);
+			dest_mask |= RADV_DYNAMIC_DISCARD_RECTANGLE;
+		}
+	}
+
 	cmd_buffer->state.dirty |= dest_mask;
 }
 
@@ -1098,6 +1109,8 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
 	}
 	radeon_set_context_reg(cmd_buffer->cs, R_028A6C_VGT_GS_OUT_PRIM_TYPE, pipeline->graphics.gs_out);
 
+	radeon_set_context_reg(cmd_buffer->cs, R_02820C_PA_SC_CLIPRECT_RULE, 
+pipeline->graphics.pa_sc_cliprect_rule);
+
 	if (unlikely(cmd_buffer->device->trace_bo))
 		radv_save_pipeline(cmd_buffer, pipeline, RING_GFX);
 
@@ -1134,6 +1147,22 @@ radv_emit_scissor(struct radv_cmd_buffer *cmd_buffer)
 			       cmd_buffer->state.pipeline->graphics.ms.pa_sc_mode_cntl_0 | S_028A48_VPORT_SCISSOR_ENABLE(count ? 1 : 0));  }
 
+static void
+radv_emit_discard_rectangle(struct radv_cmd_buffer *cmd_buffer) {
+	if (!cmd_buffer->state.dynamic.discard_rectangle.count)
+		return;
+
+	radeon_set_context_reg_seq(cmd_buffer->cs, R_028210_PA_SC_CLIPRECT_0_TL,
+	                           cmd_buffer->state.dynamic.discard_rectangle.count * 2);
+	for (unsigned i = 0; i < cmd_buffer->state.dynamic.discard_rectangle.count; ++i) {
+		VkRect2D rect = cmd_buffer->state.dynamic.discard_rectangle.rectangles[i];
+		radeon_emit(cmd_buffer->cs, S_028210_TL_X(rect.offset.x) | S_028210_TL_Y(rect.offset.y));
+		radeon_emit(cmd_buffer->cs, S_028214_BR_X(rect.offset.x + rect.extent.width) |
+		                            S_028214_BR_Y(rect.offset.y + rect.extent.height));
+	}
+}
+
 static void
 radv_emit_line_width(struct radv_cmd_buffer *cmd_buffer)  { @@ -1627,6 +1656,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer)
 				       RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS))
 		radv_emit_depth_biais(cmd_buffer);
 
+	if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE)
+		radv_emit_discard_rectangle(cmd_buffer);
+
 	cmd_buffer->state.dirty &= ~RADV_CMD_DIRTY_DYNAMIC_ALL;  }
 
@@ -2882,6 +2914,25 @@ void radv_CmdSetStencilReference(
 	cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
 }
 
+void radv_CmdSetDiscardRectangleEXT(
+	VkCommandBuffer                             commandBuffer,
+	uint32_t                                    firstDiscardRectangle,
+	uint32_t                                    discardRectangleCount,
+	const VkRect2D*                             pDiscardRectangles)
+{
+	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+	struct radv_cmd_state *state = &cmd_buffer->state;
+	MAYBE_UNUSED const uint32_t total_count = firstDiscardRectangle + 
+discardRectangleCount;
+
+	assert(firstDiscardRectangle < MAX_DISCARD_RECTANGLES);
+	assert(total_count >= 1 && total_count <= MAX_DISCARD_RECTANGLES);
+
+
+	typed_memcpy(&state->dynamic.discard_rectangle.rectangles[firstDiscardRectangle],
+	             pDiscardRectangles, discardRectangleCount);
+
+	state->dirty |= RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE;
+}
 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 4270e6a870..baffa41d31 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -794,6 +794,12 @@ void radv_GetPhysicalDeviceProperties2KHR(
 			properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR;
 			break;
 		}
+		case  VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT: {
+			VkPhysicalDeviceDiscardRectanglePropertiesEXT *properties =
+			    (VkPhysicalDeviceDiscardRectanglePropertiesEXT*)ext;
+			properties->maxDiscardRectangles = MAX_DISCARD_RECTANGLES;
+			break;
+		}
 		default:
 			break;
 		}
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 6bdb011d6c..9980cfc398 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -81,6 +81,7 @@ EXTENSIONS = [
     Extension('VK_KHR_xcb_surface',                       6, 'VK_USE_PLATFORM_XCB_KHR'),
     Extension('VK_KHR_xlib_surface',                      6, 'VK_USE_PLATFORM_XLIB_KHR'),
     Extension('VK_KHX_multiview',                         1, True),
+    Extension('VK_EXT_discard_rectangles',                1, True),
     Extension('VK_EXT_external_memory_dma_buf',           1, True),
     Extension('VK_EXT_global_priority',                   1, 'device->rad_info.has_ctx_priority'),
     Extension('VK_AMD_draw_indirect_count',               1, True),
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 9ece79ef21..3f95ab3f5b 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -1006,6 +1006,8 @@ static unsigned radv_dynamic_state_mask(VkDynamicState state)
 		return RADV_DYNAMIC_STENCIL_WRITE_MASK;
 	case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
 		return RADV_DYNAMIC_STENCIL_REFERENCE;
+	case VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT:
+		return RADV_DYNAMIC_DISCARD_RECTANGLE;
 	default:
 		unreachable("Unhandled dynamic state");
 	}
@@ -1133,6 +1135,39 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
 		}
 	}
 
+	const  VkPipelineDiscardRectangleStateCreateInfoEXT *discard_rectangle_info =
+			vk_find_struct_const(pCreateInfo->pNext, PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT);
+	if (discard_rectangle_info) {
+		dynamic->discard_rectangle.count = discard_rectangle_info->discardRectangleCount;
+		typed_memcpy(dynamic->discard_rectangle.rectangles,
+		             discard_rectangle_info->pDiscardRectangles,
+		             discard_rectangle_info->discardRectangleCount);
+
+		unsigned mask = 0;
+
+		for (unsigned i = 0; i < 16; ++i) {
+			/* Interpret i as a bitmask, and then set the bit in the mask if
+			 * that combination of rectangles in which the pixel is contained
+			 * should pass the cliprect test. */
+			unsigned relevant_subset = i & ((1u << 
+discard_rectangle_info->discardRectangleCount) - 1);
+
+			if (discard_rectangle_info->discardRectangleMode == VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT &&
+			    !relevant_subset)
+				continue;
+
+			if (discard_rectangle_info->discardRectangleMode == VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT &&
+			    relevant_subset)
+				continue;
+
+			mask |= 1u << i;
+		}
+		pipeline->graphics.pa_sc_cliprect_rule = mask;
+	} else {
+		states &= ~RADV_DYNAMIC_DISCARD_RECTANGLE;
+
+		/* Allow from all rectangle combinations */
+		pipeline->graphics.pa_sc_cliprect_rule = 0xffff;
+	}
 	pipeline->dynamic_state.mask = states;  }
 
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index b7c53d03fb..7330dc6369 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -81,6 +81,7 @@ typedef uint32_t xcb_window_t;
 #define MAX_RTS          8
 #define MAX_VIEWPORTS   16
 #define MAX_SCISSORS    16
+#define MAX_DISCARD_RECTANGLES 4
 #define MAX_PUSH_CONSTANTS_SIZE 128
 #define MAX_PUSH_DESCRIPTORS 32
 #define MAX_DYNAMIC_BUFFERS 16
@@ -739,7 +740,8 @@ enum radv_dynamic_state_bits {
 	RADV_DYNAMIC_STENCIL_COMPARE_MASK = 1 << 6,
 	RADV_DYNAMIC_STENCIL_WRITE_MASK   = 1 << 7,
 	RADV_DYNAMIC_STENCIL_REFERENCE    = 1 << 8,
-	RADV_DYNAMIC_ALL                  = (1 << 9) - 1,
+	RADV_DYNAMIC_DISCARD_RECTANGLE    = 1 << 9,
+	RADV_DYNAMIC_ALL                  = (1 << 10) - 1,
 };
 
 enum radv_cmd_dirty_bits {
@@ -754,11 +756,12 @@ enum radv_cmd_dirty_bits {
 	RADV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK      = 1 << 6,
 	RADV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK        = 1 << 7,
 	RADV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE         = 1 << 8,
-	RADV_CMD_DIRTY_DYNAMIC_ALL                       = (1 << 9) - 1,
-	RADV_CMD_DIRTY_PIPELINE                          = 1 << 9,
-	RADV_CMD_DIRTY_INDEX_BUFFER                      = 1 << 10,
-	RADV_CMD_DIRTY_FRAMEBUFFER                       = 1 << 11,
-	RADV_CMD_DIRTY_VERTEX_BUFFER                     = 1 << 12,
+	RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE         = 1 << 9,
+	RADV_CMD_DIRTY_DYNAMIC_ALL                       = (1 << 10) - 1,
+	RADV_CMD_DIRTY_PIPELINE                          = 1 << 10,
+	RADV_CMD_DIRTY_INDEX_BUFFER                      = 1 << 11,
+	RADV_CMD_DIRTY_FRAMEBUFFER                       = 1 << 12,
+	RADV_CMD_DIRTY_VERTEX_BUFFER                     = 1 << 13,
 };
 
 enum radv_cmd_flush_bits {
@@ -803,6 +806,11 @@ struct radv_scissor_state {
 	VkRect2D                                          scissors[MAX_SCISSORS];
 };
 
+struct radv_discard_rectangle_state {
+	uint32_t                                          count;
+	VkRect2D                                          rectangles[MAX_DISCARD_RECTANGLES];
+};
+
 struct radv_dynamic_state {
 	/**
 	 * Bitmask of (1 << VK_DYNAMIC_STATE_*).
@@ -843,6 +851,8 @@ struct radv_dynamic_state {
 		uint32_t                                  front;
 		uint32_t                                  back;
 	} stencil_reference;
+
+	struct radv_discard_rectangle_state               discard_rectangle;
 };
 
 extern const struct radv_dynamic_state default_dynamic_state; @@ -1239,6 +1249,7 @@ struct radv_pipeline {
 			uint32_t vtx_reuse_depth;
 			struct radv_prim_vertex_count prim_vertex_count;
  			bool can_use_guardband;
+			uint32_t pa_sc_cliprect_rule;
 		} graphics;
 	};
 
--
2.15.1

_______________________________________________
mesa-dev mailing list
mesa-dev at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list