On Tue, May 30, 2017 at 10:36 PM, Samuel Pitoiset <samuel.pitoi...@gmail.com> wrote: > This implements the Gallium interface. Decompression of resident > textures/images will follow in the next patches. > > v2: - fix a memleak related to util_copy_image_view() > - remove "texture" parameter from create_texture_handle() > - store pipe_sampler_view instead of si_sampler_view > - make use pipe_sampler_view_reference() to fix a refcount issue > - rename si_resident_descriptor to si_bindless_descriptor > - use util_dynarray_* > - add more comments > > Signed-off-by: Samuel Pitoiset <samuel.pitoi...@gmail.com> > --- > src/gallium/drivers/radeonsi/si_descriptors.c | 249 > ++++++++++++++++++++++++++ > src/gallium/drivers/radeonsi/si_pipe.c | 15 ++ > src/gallium/drivers/radeonsi/si_pipe.h | 20 +++ > 3 files changed, 284 insertions(+) > > diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c > b/src/gallium/drivers/radeonsi/si_descriptors.c > index b2e2e4b760..238cca4561 100644 > --- a/src/gallium/drivers/radeonsi/si_descriptors.c > +++ b/src/gallium/drivers/radeonsi/si_descriptors.c > @@ -60,6 +60,7 @@ > #include "sid.h" > #include "gfx9d.h" > > +#include "util/hash_table.h" > #include "util/u_format.h" > #include "util/u_memory.h" > #include "util/u_upload_mgr.h" > @@ -2130,6 +2131,248 @@ void si_bindless_descriptor_slab_free(void *priv, > struct pb_slab *pslab) > FREE(slab); > } > > +static struct si_bindless_descriptor * > +si_create_bindless_descriptor(struct si_context *sctx, uint32_t *desc_list, > + unsigned size) > +{ > + struct si_screen *sscreen = sctx->screen; > + struct si_bindless_descriptor *desc; > + struct pb_slab_entry *entry; > + void *ptr; > + > + /* Sub-allocate the bindless descriptor from a slab to avoid dealing > + * with a ton of buffers and for reducing the winsys overhead. > + */ > + entry = pb_slab_alloc(&sctx->bindless_descriptor_slabs, 64, 0); > + if (!entry) > + return NULL; > + > + desc = NULL; > + desc = container_of(entry, desc, entry); > + > + /* Upload the descriptor directly in VRAM. Because the slabs are > + * currentlyu never reclaimed, we don't need to synchronize the > + * operation. > + */ > + ptr = sscreen->b.ws->buffer_map(desc->buffer->buf, NULL, > + PIPE_TRANSFER_WRITE | > + PIPE_TRANSFER_UNSYNCHRONIZED); > + util_memcpy_cpu_to_le32(ptr + desc->offset, desc_list, size); > + sscreen->b.ws->buffer_unmap(desc->buffer->buf);
I recommend removing this unmap call. Unmapping is costly and creating a lot of handles can be slow. > + > + return desc; > +} > + > +static uint64_t si_create_texture_handle(struct pipe_context *ctx, > + struct pipe_sampler_view *view, > + const struct pipe_sampler_state > *state) > +{ > + struct si_sampler_view *sview = (struct si_sampler_view *)view; > + struct si_context *sctx = (struct si_context *)ctx; > + struct si_texture_handle *tex_handle; > + struct si_sampler_state *sstate; > + uint32_t desc_list[16]; > + uint64_t handle; > + > + tex_handle = CALLOC_STRUCT(si_texture_handle); > + if (!tex_handle) > + return 0; > + > + memset(desc_list, 0, sizeof(desc_list)); > + si_init_descriptor_list(&desc_list[0], 16, 1, > null_texture_descriptor); > + > + sstate = ctx->create_sampler_state(ctx, state); > + if (!sstate) { > + FREE(tex_handle); > + return 0; > + } > + > + si_set_sampler_view_desc(sctx, sview, sstate, &desc_list[0]); > + ctx->delete_sampler_state(ctx, sstate); > + > + tex_handle->desc = si_create_bindless_descriptor(sctx, desc_list, > + sizeof(desc_list)); > + if (!tex_handle->desc) { > + FREE(tex_handle); > + return 0; > + } > + > + handle = tex_handle->desc->buffer->gpu_address + > + tex_handle->desc->offset; > + > + if (!_mesa_hash_table_insert(sctx->tex_handles, (void *)handle, > + tex_handle)) { > + pb_slab_free(&sctx->bindless_descriptor_slabs, > + &tex_handle->desc->entry); > + FREE(tex_handle); > + return 0; > + } > + > + pipe_sampler_view_reference(&tex_handle->view, view); > + > + return handle; > +} > + > +static void si_delete_texture_handle(struct pipe_context *ctx, uint64_t > handle) > +{ > + struct si_context *sctx = (struct si_context *)ctx; > + struct si_texture_handle *tex_handle; > + struct hash_entry *entry; > + > + entry = _mesa_hash_table_search(sctx->tex_handles, (void *)handle); > + if (!entry) > + return; > + > + tex_handle = (struct si_texture_handle *)entry->data; > + > + pipe_sampler_view_reference(&tex_handle->view, NULL); > + _mesa_hash_table_remove(sctx->tex_handles, entry); > + pb_slab_free(&sctx->bindless_descriptor_slabs, > + &tex_handle->desc->entry); > + FREE(tex_handle); > +} > + > +static void si_make_texture_handle_resident(struct pipe_context *ctx, > + uint64_t handle, bool resident) > +{ > + struct si_context *sctx = (struct si_context *)ctx; > + struct si_texture_handle *tex_handle; > + struct si_sampler_view *sview; > + struct hash_entry *entry; > + > + entry = _mesa_hash_table_search(sctx->tex_handles, (void *)handle); > + if (!entry) > + return; > + > + tex_handle = (struct si_texture_handle *)entry->data; > + sview = (struct si_sampler_view *)tex_handle->view; > + > + if (resident) { > + /* Add the texture handle to the per-context list. */ > + util_dynarray_append(&sctx->resident_tex_handles, > + struct si_texture_handle *, tex_handle); > + > + /* Add the buffers to the current CS in case si_begin_new_cs() > + * is not going to be called. > + */ > + radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, > + tex_handle->desc->buffer, > + RADEON_USAGE_READ, > + RADEON_PRIO_DESCRIPTORS); > + > + si_sampler_view_add_buffer(sctx, sview->base.texture, > + RADEON_USAGE_READ, > + sview->is_stencil_sampler, false); > + } else { > + /* Remove the texture handle from the per-context list. */ > + util_dynarray_delete(&sctx->resident_tex_handles, > + struct si_texture_handle *, tex_handle); > + } > +} > + > +static uint64_t si_create_image_handle(struct pipe_context *ctx, > + const struct pipe_image_view *view) > +{ > + struct si_context *sctx = (struct si_context *)ctx; > + struct si_image_handle *img_handle; > + uint32_t desc_list[16]; > + uint64_t handle; > + > + if (!view || !view->resource) > + return 0; > + > + img_handle = CALLOC_STRUCT(si_image_handle); > + if (!img_handle) > + return 0; > + > + memset(desc_list, 0, sizeof(desc_list)); > + si_init_descriptor_list(&desc_list[0], 8, 1, null_image_descriptor); > + > + si_set_shader_image_desc(sctx, view, false, &desc_list[0]); > + > + img_handle->desc = si_create_bindless_descriptor(sctx, desc_list, > + sizeof(desc_list)); > + if (!img_handle->desc) { > + util_copy_image_view(&img_handle->view, NULL); This call is unnecessary, because img_handle->view contains zeros here. Marek _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev