diff options
author | Samuel Pitoiset <[email protected]> | 2017-05-15 14:15:40 +0200 |
---|---|---|
committer | Samuel Pitoiset <[email protected]> | 2017-06-14 10:04:36 +0200 |
commit | 76b8758253fc640616bb00d47a0362353cba4ada (patch) | |
tree | 2ba3968ac09abeff49c75f995e31043f079b6f5e /src/mesa/state_tracker/st_texture.c | |
parent | 66a2589d00e38f0d25530ec70274cf42c35e1f9d (diff) |
st/mesa: make bindless samplers/images bound to units resident
Signed-off-by: Samuel Pitoiset <[email protected]>
Reviewed-by: Nicolai Hähnle <[email protected]>
Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker/st_texture.c')
-rw-r--r-- | src/mesa/state_tracker/st_texture.c | 94 |
1 files changed, 94 insertions, 0 deletions
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++; + } +} |