On Tue, May 30, 2017 at 10:36 PM, Samuel Pitoiset <samuel.pitoi...@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.pitoi...@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). > + 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev