[Mesa-dev] [PATCH 2/2] radv: Implement VK_EXT_discard_rectangles.
Bas Nieuwenhuizen
bas at basnieuwenhuizen.nl
Wed Jan 10 10:45:44 UTC 2018
On Wed, Jan 10, 2018 at 11:16 AM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
>
>
> On 01/10/2018 03:34 AM, Bas Nieuwenhuizen wrote:
>>
>> 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);
>> +
>> +
>
>
> Extra line here.
>
>
>> +
>> 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) {
>
>
> Where does 16 come from?
(1u << MAX_DISCARD_RECTANGLES) . I'll update it locally.
>
>
>> + /* 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;
>> };
>>
More information about the mesa-dev
mailing list