From 76b8758253fc640616bb00d47a0362353cba4ada Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Mon, 15 May 2017 14:15:40 +0200 Subject: [PATCH] st/mesa: make bindless samplers/images bound to units resident MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Samuel Pitoiset Reviewed-by: Nicolai Hähnle Reviewed-by: Marek Olšák --- src/mesa/state_tracker/st_atom_constbuf.c | 6 ++ src/mesa/state_tracker/st_texture.c | 94 +++++++++++++++++++++++ src/mesa/state_tracker/st_texture.h | 8 ++ 3 files changed, 108 insertions(+) diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index 0c669940660..e4b585101da 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -80,6 +80,12 @@ void st_upload_constants(struct st_context *st, struct gl_program *prog) } } + /* Make all bindless samplers/images bound texture/image units resident in + * the context. + */ + st_make_bound_samplers_resident(st, prog); + st_make_bound_images_resident(st, prog); + /* update constants */ if (params && params->NumParameters) { struct pipe_constant_buffer cb; diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 0f72eb778ad..9de3b9a2e9b 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -540,3 +540,97 @@ st_create_image_handle_from_unit(struct st_context *st, return pipe->create_image_handle(pipe, &img); } + + +/** + * Make all bindless samplers bound to texture units resident in the context. + */ +void +st_make_bound_samplers_resident(struct st_context *st, + struct gl_program *prog) +{ + enum pipe_shader_type shader = st_shader_stage_to_ptarget(prog->info.stage); + struct st_bound_handles *bound_handles = &st->bound_texture_handles[shader]; + struct pipe_context *pipe = st->pipe; + GLuint64 handle; + int i; + + /* Remove previous bound texture handles for this stage. */ + st_destroy_bound_texture_handles_per_stage(st, shader); + + if (likely(!prog->sh.HasBoundBindlessSampler)) + return; + + for (i = 0; i < prog->sh.NumBindlessSamplers; i++) { + struct gl_bindless_sampler *sampler = &prog->sh.BindlessSamplers[i]; + + if (!sampler->bound) + continue; + + /* Request a new texture handle from the driver and make it resident. */ + handle = st_create_texture_handle_from_unit(st, prog, sampler->unit); + if (!handle) + continue; + + pipe->make_texture_handle_resident(st->pipe, handle, true); + + /* Overwrite the texture unit value by the resident handle before + * uploading the constant buffer. + */ + *(uint64_t *)sampler->data = handle; + + /* Store the handle in the context. */ + bound_handles->handles = (uint64_t *) + realloc(bound_handles->handles, + (bound_handles->num_handles + 1) * sizeof(uint64_t)); + bound_handles->handles[bound_handles->num_handles] = handle; + bound_handles->num_handles++; + } +} + + +/** + * Make all bindless images bound to image units resident in the context. + */ +void +st_make_bound_images_resident(struct st_context *st, + struct gl_program *prog) +{ + enum pipe_shader_type shader = st_shader_stage_to_ptarget(prog->info.stage); + struct st_bound_handles *bound_handles = &st->bound_image_handles[shader]; + struct pipe_context *pipe = st->pipe; + GLuint64 handle; + int i; + + /* Remove previous bound image handles for this stage. */ + st_destroy_bound_image_handles_per_stage(st, shader); + + if (likely(!prog->sh.HasBoundBindlessImage)) + return; + + for (i = 0; i < prog->sh.NumBindlessImages; i++) { + struct gl_bindless_image *image = &prog->sh.BindlessImages[i]; + + if (!image->bound) + continue; + + /* Request a new image handle from the driver and make it resident. */ + handle = st_create_image_handle_from_unit(st, prog, image->unit); + if (!handle) + continue; + + pipe->make_image_handle_resident(st->pipe, handle, GL_READ_WRITE, true); + + /* Overwrite the image unit value by the resident handle before uploading + * the constant buffer. + */ + *(uint64_t *)image->data = handle; + + /* Store the handle in the context. */ + bound_handles->handles = (uint64_t *) + realloc(bound_handles->handles, + (bound_handles->num_handles + 1) * sizeof(uint64_t)); + bound_handles->handles[bound_handles->num_handles] = handle; + bound_handles->num_handles++; + } +} diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 18b5870b393..450d940e76e 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -293,4 +293,12 @@ st_update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_view, GLuint texUnit, unsigned glsl_version); +void +st_make_bound_samplers_resident(struct st_context *st, + struct gl_program *prog); + +void +st_make_bound_images_resident(struct st_context *st, + struct gl_program *prog); + #endif -- 2.30.2