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

Samuel Pitoiset samuel.pitoiset at gmail.com
Wed Jan 10 10:49:31 UTC 2018



On 01/10/2018 11:45 AM, Bas Nieuwenhuizen wrote:
> 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.

Ah yeah, with this updated, series is:

Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>

> 
>>
>>
>>> +                       /* 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