[Mesa-dev] [PATCH v2 60/64] radeonsi: upload new descriptors when resident buffers are invalidated

Marek Olšák maraeo at gmail.com
Wed Jun 7 14:53:35 UTC 2017


On Wed, Jun 7, 2017 at 4:47 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
>
>
> On 06/07/2017 03:59 PM, Marek Olšák wrote:
>>
>> On Tue, May 30, 2017 at 10:36 PM, Samuel Pitoiset
>> <samuel.pitoiset at gmail.com> wrote:
>>>
>>> When texture buffers are invalidated the addr in the resident
>>> descriptor has to be updated but we can't create a new descriptor
>>> because the resident handle has to be the same.
>>>
>>> Instead, use the WRITE_DATA packet which allows to update memory
>>> directly but graphics/compute have to be idle in case the GPU is
>>> reading the descriptor.
>>>
>>> v2: - store pipe_sampler_view instead of si_sampler_view
>>>
>>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
>>> ---
>>>   src/gallium/drivers/radeon/r600_pipe_common.h |   4 +
>>>   src/gallium/drivers/radeonsi/si_descriptors.c | 145
>>> ++++++++++++++++++++++++++
>>>   src/gallium/drivers/radeonsi/si_pipe.h        |   3 +
>>>   3 files changed, 152 insertions(+)
>>>
>>> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h
>>> b/src/gallium/drivers/radeon/r600_pipe_common.h
>>> index b17b690fab..6c4df2e733 100644
>>> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
>>> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
>>> @@ -181,6 +181,10 @@ struct r600_resource {
>>>
>>>          /* Whether the resource has been exported via
>>> resource_get_handle. */
>>>          unsigned                        external_usage; /*
>>> PIPE_HANDLE_USAGE_* */
>>> +
>>> +       /* Whether this resource is referenced by bindless handles. */
>>> +       bool                            texture_handle_allocated;
>>> +       bool                            image_handle_allocated;
>>>   };
>>>
>>>   struct r600_transfer {
>>> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c
>>> b/src/gallium/drivers/radeonsi/si_descriptors.c
>>> index 357039a78a..1b58afba2a 100644
>>> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
>>> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
>>> @@ -1857,6 +1857,67 @@ static void si_rebind_buffer(struct pipe_context
>>> *ctx, struct pipe_resource *buf
>>>                          }
>>>                  }
>>>          }
>>> +
>>> +       /* Bindless texture handles */
>>> +       if (rbuffer->texture_handle_allocated) {
>>> +               unsigned num_resident_tex_handles;
>>> +
>>> +               num_resident_tex_handles =
>>> sctx->resident_tex_handles.size /
>>> +                                          sizeof(struct
>>> si_texture_handle *);
>>> +
>>> +               for (i = 0; i < num_resident_tex_handles; i++) {
>>> +                       struct si_texture_handle *tex_handle =
>>> +
>>> *util_dynarray_element(&sctx->resident_tex_handles,
>>> +                                                      struct
>>> si_texture_handle *, i);
>>> +                       struct pipe_sampler_view *view =
>>> tex_handle->view;
>>> +                       struct si_bindless_descriptor *desc =
>>> tex_handle->desc;
>>> +
>>> +                       if (view->texture == buf) {
>>> +                               si_set_buf_desc_address(rbuffer,
>>> +
>>> view->u.buf.offset,
>>> +
>>> &desc->desc_list[4]);
>>> +                               desc->dirty = true;
>>> +                               sctx->bindless_descriptors_dirty = true;
>>> +
>>> +                               radeon_add_to_buffer_list_check_mem(
>>> +                                       &sctx->b, &sctx->b.gfx, rbuffer,
>>> +                                       RADEON_USAGE_READ,
>>> +                                       RADEON_PRIO_SAMPLER_BUFFER,
>>> true);
>>> +                       }
>>> +               }
>>> +       }
>>> +
>>> +       /* Bindless image handles */
>>> +       if (rbuffer->image_handle_allocated) {
>>> +               unsigned num_resident_img_handles;
>>> +
>>> +               num_resident_img_handles =
>>> sctx->resident_img_handles.size /
>>> +                                          sizeof(struct si_image_handle
>>> *);
>>> +
>>> +               for (i = 0; i < num_resident_img_handles; i++) {
>>> +                       struct si_image_handle *img_handle =
>>> +
>>> *util_dynarray_element(&sctx->resident_img_handles,
>>> +                                                      struct
>>> si_image_handle *, i);
>>> +                       struct pipe_image_view *view = &img_handle->view;
>>> +                       struct si_bindless_descriptor *desc =
>>> img_handle->desc;
>>> +
>>> +                       if (view->resource == buf) {
>>> +                               if (view->access &
>>> PIPE_IMAGE_ACCESS_WRITE)
>>> +                                       si_mark_image_range_valid(view);
>>> +
>>> +                               si_set_buf_desc_address(rbuffer,
>>> +
>>> view->u.buf.offset,
>>> +
>>> &desc->desc_list[4]);
>>> +                               desc->dirty = true;
>>> +                               sctx->bindless_descriptors_dirty = true;
>>> +
>>> +                               radeon_add_to_buffer_list_check_mem(
>>> +                                       &sctx->b, &sctx->b.gfx, rbuffer,
>>> +                                       RADEON_USAGE_READWRITE,
>>> +                                       RADEON_PRIO_SAMPLER_BUFFER,
>>> true);
>>> +                       }
>>> +               }
>>> +       }
>>>   }
>>>
>>>   /* Reallocate a buffer a update all resource bindings where the buffer
>>> is
>>> @@ -2204,6 +2265,11 @@ si_create_bindless_descriptor(struct si_context
>>> *sctx, uint32_t *desc_list,
>>>          util_memcpy_cpu_to_le32(ptr + desc->offset, desc_list, size);
>>>          sscreen->b.ws->buffer_unmap(desc->buffer->buf);
>>>
>>> +       /* Keep track of the initial descriptor especially for buffers
>>> +        * invalidation because we might need to know the previous
>>> address.
>>> +        */
>>> +       memcpy(desc->desc_list, desc_list, sizeof(desc->desc_list));
>>> +
>>>          return desc;
>>>   }
>>>
>>> @@ -2254,6 +2320,8 @@ static uint64_t si_create_texture_handle(struct
>>> pipe_context *ctx,
>>>
>>>          pipe_sampler_view_reference(&tex_handle->view, view);
>>>
>>> +       r600_resource(sview->base.texture)->texture_handle_allocated =
>>> true;
>>> +
>>>          return handle;
>>>   }
>>>
>>> @@ -2367,6 +2435,8 @@ static uint64_t si_create_image_handle(struct
>>> pipe_context *ctx,
>>>
>>>          util_copy_image_view(&img_handle->view, view);
>>>
>>> +       r600_resource(view->resource)->image_handle_allocated = true;
>>> +
>>>          return handle;
>>>   }
>>>
>>> @@ -2666,6 +2736,76 @@ void si_init_all_descriptors(struct si_context
>>> *sctx)
>>>          si_set_user_data_base(sctx, PIPE_SHADER_FRAGMENT,
>>> R_00B030_SPI_SHADER_USER_DATA_PS_0);
>>>   }
>>>
>>> +static void si_upload_bindless_descriptor(struct si_context *sctx,
>>> +                                         struct si_bindless_descriptor
>>> *desc)
>>> +{
>>> +       struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
>>> +       uint64_t va = desc->buffer->gpu_address + desc->offset;
>>> +       unsigned num_dwords = sizeof(desc->desc_list) / 4;
>>> +
>>> +       radeon_emit(cs, PKT3(PKT3_WRITE_DATA, 2 + num_dwords, 0));
>>> +       radeon_emit(cs, S_370_DST_SEL(V_370_TC_L2) |
>>> +                   S_370_WR_CONFIRM(1) |
>>> +                   S_370_ENGINE_SEL(V_370_PFP));
>>
>>
>> I recommend using ME for the upload (instead of PFP).
>
>
> Ah yeah, because the packet will be forwarded by PFP to ME anyway?

I think it's better because PFP won't be stalled by WRITE_DATA.

Marek


More information about the mesa-dev mailing list