On Thursday 14 September 2017, Samuel Pitoiset wrote:
> 
> On 09/13/2017 06:34 PM, Fredrik Höglund wrote:
> > On Wednesday 13 September 2017, Samuel Pitoiset wrote:
> >> When binding a new pipeline, we applied all dynamic states
> >> without checking if they really need to be re-emitted. This
> >> doesn't seem to be useful for the meta operations because only
> >> the viewports/scissors are updated.
> >>
> >> This should reduce the number of commands added to the IB
> >> when a new graphics pipeline is bound.
> >>
> >> Signed-off-by: Samuel Pitoiset <samuel.pitoi...@gmail.com>
> >> ---
> >>   src/amd/vulkan/radv_cmd_buffer.c | 100 
> >> +++++++++++++++++++++++++++++----------
> >>   src/amd/vulkan/radv_private.h    |   7 +--
> >>   2 files changed, 79 insertions(+), 28 deletions(-)
> >>
> >> diff --git a/src/amd/vulkan/radv_cmd_buffer.c 
> >> b/src/amd/vulkan/radv_cmd_buffer.c
> >> index 561ca2fbce..9e76cf6c2c 100644
> >> --- a/src/amd/vulkan/radv_cmd_buffer.c
> >> +++ b/src/amd/vulkan/radv_cmd_buffer.c
> >> @@ -78,43 +78,92 @@ const struct radv_dynamic_state default_dynamic_state 
> >> = {
> >>    },
> >>   };
> >>   
> >> -void
> >> +uint32_t
> >>   radv_dynamic_state_copy(struct radv_dynamic_state *dest,
> >>                    const struct radv_dynamic_state *src,
> >>                    uint32_t copy_mask)
> >>   {
> >> +  uint32_t dest_mask = 0;
> >> +
> >>    if (copy_mask & (1 << VK_DYNAMIC_STATE_VIEWPORT)) {
> >> -          dest->viewport.count = src->viewport.count;
> >> -          typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
> >> -                       src->viewport.count);
> >> +          if (memcmp(&dest->viewport, &src->viewport,
> >> +                     sizeof(src->viewport))) {
> > 
> > I think only the first src->viewport.count viewports should be compared,
> > since those are the only ones used by the pipeline, and the only ones
> > that are copied.
> 
> Yeah, looks better.
> 
> > 
> > The dest->viewport.count assignment should probably also be done
> > outside of the if (copy_mask & ...) block, since the viewport count is
> > fixed at pipeline creation time, and does not depend on whether the state
> > is dynamic or not.
> 
> The number of viewports can also be updated in vkCmdSetViewport() if the 
> initial value is less than the total count.

The implementation does that, but I don't think the specification
supports it.

The Vulkan specification (1.0.61) says:

"The number of viewports used by a pipeline is controlled by the
viewportCount member of the VkPipelineViewportStateCreateInfo structure
used in pipeline creation"

pViewports is ignored when the state is dynamic, but viewportCount
"must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive"

So I don't think the count is meant to be dynamic.

> > 
> > This also goes for the scissor state below.
> > 
> >> +                  dest->viewport.count = src->viewport.count;
> >> +                  typed_memcpy(dest->viewport.viewports,
> >> +                               src->viewport.viewports,
> >> +                               src->viewport.count);
> >> +                  dest_mask |= 1 << VK_DYNAMIC_STATE_VIEWPORT;
> >> +          }
> >>    }
> >>   
> >>    if (copy_mask & (1 << VK_DYNAMIC_STATE_SCISSOR)) {
> >> -          dest->scissor.count = src->scissor.count;
> >> -          typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
> >> -                       src->scissor.count);
> >> +          if (memcmp(&dest->scissor, &src->scissor,
> >> +                     sizeof(src->scissor))) {
> >> +                  dest->scissor.count = src->scissor.count;
> >> +                  typed_memcpy(dest->scissor.scissors,
> >> +                               src->scissor.scissors, src->scissor.count);
> >> +                  dest_mask |= 1 << VK_DYNAMIC_STATE_SCISSOR;
> >> +          }
> >>    }
> >>   
> >> -  if (copy_mask & (1 << VK_DYNAMIC_STATE_LINE_WIDTH))
> >> -          dest->line_width = src->line_width;
> >> +  if (copy_mask & (1 << VK_DYNAMIC_STATE_LINE_WIDTH)) {
> >> +          if (dest->line_width != src->line_width) {
> >> +                  dest->line_width = src->line_width;
> >> +                  dest_mask |= 1 << VK_DYNAMIC_STATE_LINE_WIDTH;
> >> +          }
> >> +  }
> >>   
> >> -  if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS))
> >> -          dest->depth_bias = src->depth_bias;
> >> +  if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) {
> >> +          if (memcmp(&dest->depth_bias, &src->depth_bias,
> >> +                     sizeof(src->depth_bias))) {
> >> +                  dest->depth_bias = src->depth_bias;
> >> +                  dest_mask |= 1 << VK_DYNAMIC_STATE_DEPTH_BIAS;
> >> +          }
> >> +  }
> >>   
> >> -  if (copy_mask & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS))
> >> -          typed_memcpy(dest->blend_constants, src->blend_constants, 4);
> >> +  if (copy_mask & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS)) {
> >> +          if (memcmp(&dest->blend_constants, &src->blend_constants,
> >> +                     sizeof(src->blend_constants))) {
> >> +                  typed_memcpy(dest->blend_constants,
> >> +                               src->blend_constants, 4);
> >> +                  dest_mask |= 1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS;
> >> +          }
> >> +  }
> >>   
> >> -  if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS))
> >> -          dest->depth_bounds = src->depth_bounds;
> >> +  if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS)) {
> >> +          if (memcmp(&dest->depth_bounds, &src->depth_bounds,
> >> +                     sizeof(src->depth_bounds))) {
> >> +                  dest->depth_bounds = src->depth_bounds;
> >> +                  dest_mask |= 1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS;
> >> +          }
> >> +  }
> >>   
> >> -  if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK))
> >> -          dest->stencil_compare_mask = src->stencil_compare_mask;
> >> +  if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) {
> >> +          if (memcmp(&dest->stencil_compare_mask,
> >> +                     &src->stencil_compare_mask,
> >> +                     sizeof(src->stencil_compare_mask))) {
> >> +                  dest->stencil_compare_mask = src->stencil_compare_mask;
> >> +                  dest_mask |= 1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
> >> +          }
> >> +  }
> >>   
> >> -  if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK))
> >> -          dest->stencil_write_mask = src->stencil_write_mask;
> >> +  if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) {
> >> +          if (memcmp(&dest->stencil_write_mask, &src->stencil_write_mask,
> >> +                     sizeof(src->stencil_write_mask))) {
> >> +                  dest->stencil_write_mask = src->stencil_write_mask;
> >> +                  dest_mask |= 1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
> >> +          }
> >> +  }
> >> +
> >> +  if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) {
> >> +          if (memcmp(&dest->stencil_reference, &src->stencil_reference,
> >> +                     sizeof(src->stencil_reference))) {
> >> +                  dest->stencil_reference = src->stencil_reference;
> >> +                  dest_mask |= 1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE;
> >> +          }
> >> +  }
> >>   
> >> -  if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE))
> >> -          dest->stencil_reference = src->stencil_reference;
> >> +  return dest_mask;
> >>   }
> >>   
> >>   bool radv_cmd_buffer_uses_mec(struct radv_cmd_buffer *cmd_buffer)
> >> @@ -2445,6 +2494,7 @@ void radv_CmdBindPipeline(
> >>   {
> >>    RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
> >>    RADV_FROM_HANDLE(radv_pipeline, pipeline, _pipeline);
> >> +  uint32_t dirty_mask;
> >>   
> >>    radv_mark_descriptor_sets_dirty(cmd_buffer);
> >>   
> >> @@ -2462,10 +2512,10 @@ void radv_CmdBindPipeline(
> >>            cmd_buffer->push_constant_stages |= pipeline->active_stages;
> >>   
> >>            /* Apply the dynamic state from the pipeline */
> >> -          cmd_buffer->state.dirty |= pipeline->dynamic_state.mask;
> >> -          radv_dynamic_state_copy(&cmd_buffer->state.dynamic,
> >> -                                  &pipeline->dynamic_state,
> >> -                                  pipeline->dynamic_state.mask);
> >> +          dirty_mask = radv_dynamic_state_copy(&cmd_buffer->state.dynamic,
> >> +                                               &pipeline->dynamic_state,
> >> +                                               
> >> pipeline->dynamic_state.mask);
> >> +          cmd_buffer->state.dirty |= dirty_mask;
> >>   
> >>            if (pipeline->graphics.esgs_ring_size > 
> >> cmd_buffer->esgs_ring_size_needed)
> >>                    cmd_buffer->esgs_ring_size_needed = 
> >> pipeline->graphics.esgs_ring_size;
> >> diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
> >> index 0cebb3e7e1..9c67da49a2 100644
> >> --- a/src/amd/vulkan/radv_private.h
> >> +++ b/src/amd/vulkan/radv_private.h
> >> @@ -747,9 +747,10 @@ struct radv_dynamic_state {
> >>   
> >>   extern const struct radv_dynamic_state default_dynamic_state;
> >>   
> >> -void radv_dynamic_state_copy(struct radv_dynamic_state *dest,
> >> -                       const struct radv_dynamic_state *src,
> >> -                       uint32_t copy_mask);
> >> +uint32_t
> >> +radv_dynamic_state_copy(struct radv_dynamic_state *dest,
> >> +                  const struct radv_dynamic_state *src,
> >> +                  uint32_t copy_mask);
> >>   
> >>   const char *
> >>   radv_get_debug_option_name(int id);
> >>
> > 
> 

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

Reply via email to