summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>2018-01-10 02:41:30 +0100
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>2018-01-10 13:26:22 +0100
commit5db0bf99944ff2d3e83ef27d2aebe8f074d93d59 (patch)
tree20a46ecc34931d6c674013d910c1057ee1f31aae
parent11b9cdd2d702e4de3b66ef63aa23f4319b4bc74b (diff)
radv: Implement VK_EXT_discard_rectangles.
Tested with a modified deferred demo and no regressions in a 1.0.2 mustpass run. Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--src/amd/vulkan/radv_cmd_buffer.c51
-rw-r--r--src/amd/vulkan/radv_device.c6
-rw-r--r--src/amd/vulkan/radv_extensions.py1
-rw-r--r--src/amd/vulkan/radv_pipeline.c35
-rw-r--r--src/amd/vulkan/radv_private.h23
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 3114ae9fb43..4b5556bcc62 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);
@@ -1135,6 +1148,22 @@ radv_emit_scissor(struct radv_cmd_buffer *cmd_buffer)
}
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)
{
unsigned width = cmd_buffer->state.dynamic.line_width * 8;
@@ -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 4270e6a870b..baffa41d316 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 6bdb011d6cf..9980cfc398b 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 9ece79ef213..c3c17af8500 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 < (1u << MAX_DISCARD_RECTANGLES); ++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 b7c53d03fbd..7330dc6369a 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;
};