[Mesa-dev] [PATCH v2 60/64] radeonsi: upload new descriptors when resident buffers are invalidated
Samuel Pitoiset
samuel.pitoiset at gmail.com
Wed Jun 7 14:47:19 UTC 2017
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?
Samuel
>
>> + radeon_emit(cs, va);
>> + radeon_emit(cs, va >> 32);
>> + radeon_emit_array(cs, desc->desc_list, num_dwords);
>> +}
>> +
>> +static void si_upload_bindless_descriptors(struct si_context *sctx)
>> +{
>> + unsigned num_resident_tex_handles, num_resident_img_handles;
>> + unsigned i;
>> +
>> + if (!sctx->bindless_descriptors_dirty)
>> + return;
>> +
>> + /* Wait for graphics/compute to be idle before updating the resident
>> + * descriptors directly in memory, in case the GPU is using them.
>> + */
>> + sctx->b.flags |= SI_CONTEXT_PS_PARTIAL_FLUSH;
>> + sctx->b.flags |= SI_CONTEXT_CS_PARTIAL_FLUSH;
>
> sctx->b.flags |= SI_CONTEXT_PS_PARTIAL_FLUSH |
> SI_CONTEXT_CS_PARTIAL_FLUSH;
>
> Marek
>
More information about the mesa-dev
mailing list