Actually it is not calculated in this way. - The `inside` flags for each of the four clip rectangles form a 4-bit binary number. The corresponding bit in this 16-bit number specifies whether the pixel is visible 1: we can only set clip rules for 4 rectangles at the same time. (b0011 means when pixel is determined inside the 0 and 1 discard rectangles) 2: 4BIT binary number is being used as an index to get the "inside" flag in the 16-bit ClipRule. Please note, The spec defines the rule for pixels within any operational discard rectangles. But the register defines the flag for all combinations of four rectangles that pixel could be finally determined as inside.
Thanks. Best Regards, David -----Original Message----- From: Bas Nieuwenhuizen [mailto:b...@basnieuwenhuizen.nl] Sent: Thursday, January 11, 2018 5:59 PM To: Mao, David <david....@amd.com> Cc: mesa-dev@lists.freedesktop.org Subject: Re: [Mesa-dev] [PATCH 2/2] radv: Implement VK_EXT_discard_rectangles. Now that I reread your email, no, that is not how we do it. For each bit i, we interpret the i itself as a bitmask. So e.g. if we have 3 rectangles in inclusive mode, the bits set would be any i, that has at least one of its 3 LSBs set (e.g. 1,2,3,4,5,6,7,9,10,11,12,13,14,15). In exclusive mode with 2 triangles we would set any i with the lower two LSBs zero (e.g. 0,4,8,12) On Thu, Jan 11, 2018 at 5:20 AM, Mao, David <david....@amd.com> wrote: > 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-boun...@lists.freedesktop.org] On > Behalf Of Bas Nieuwenhuizen > Sent: Wednesday, January 10, 2018 10:34 AM > To: mesa-dev@lists.freedesktop.org > Cc: Bas Nieuwenhuizen <b...@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@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev