[Mesa-dev] [RFC PATCH 22/65] mesa: handle bindless uniforms bound to texture/image units
Nicolai Hähnle
nhaehnle at gmail.com
Wed May 24 11:01:56 UTC 2017
Something else just occurred to me. Do you have a test case where an
array of bindless sampler uniforms is set at once with glUniform1iv?
That should have a 32- vs. 64-bit mismatch when the user-supplied array
is directly memcpy()'d to uni->storage. I think you need to fix that
mismatch. On the plus side, that probably makes patch #23 unnecessary.
Cheers,
Nicolai
On 19.05.2017 18:52, Samuel Pitoiset wrote:
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
> src/mesa/main/uniform_query.cpp | 122 ++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 116 insertions(+), 6 deletions(-)
>
> diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
> index cc145f29e9..be04e48d53 100644
> --- a/src/mesa/main/uniform_query.cpp
> +++ b/src/mesa/main/uniform_query.cpp
> @@ -993,9 +993,25 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
> bool changed = false;
> for (int j = 0; j < count; j++) {
> unsigned unit = uni->opaque[i].index + offset + j;
> - if (sh->Program->SamplerUnits[unit] != ((unsigned *) values)[j]) {
> - sh->Program->SamplerUnits[unit] = ((unsigned *) values)[j];
> - changed = true;
> + unsigned value = ((unsigned *)values)[j];
> +
> + if (uni->is_bindless) {
> + struct gl_bindless_sampler *sampler =
> + &sh->Program->sh.BindlessSamplers[unit];
> +
> + /* Mark this bindless sampler as bound to a texture unit.
> + */
> + if (sampler->unit != value) {
> + sampler->unit = value;
> + changed = true;
> + }
> + sampler->bound = true;
> + sh->Program->sh.HasBoundBindlessSampler = true;
> + } else {
> + if (sh->Program->SamplerUnits[unit] != value) {
> + sh->Program->SamplerUnits[unit] = value;
> + changed = true;
> + }
> }
> }
>
> @@ -1024,9 +1040,23 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
> if (!uni->opaque[i].active)
> continue;
>
> - for (int j = 0; j < count; j++)
> - sh->Program->sh.ImageUnits[uni->opaque[i].index + offset + j] =
> - ((GLint *) values)[j];
> + for (int j = 0; j < count; j++) {
> + unsigned unit = uni->opaque[i].index + offset + j;
> + unsigned value = ((unsigned *)values)[j];
> +
> + if (uni->is_bindless) {
> + struct gl_bindless_image *image =
> + &sh->Program->sh.BindlessImages[unit];
> +
> + /* Mark this bindless image as bound to an image unit.
> + */
> + image->unit = value;
> + image->bound = true;
> + sh->Program->sh.HasBoundBindlessImage = true;
> + } else {
> + sh->Program->sh.ImageUnits[unit] = value;
> + }
> + }
> }
>
> ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
> @@ -1173,6 +1203,40 @@ _mesa_uniform_matrix(GLint location, GLsizei count,
> _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
> }
>
> +static void
> +update_bound_bindless_sampler_flag(struct gl_program *prog)
> +{
> + unsigned i;
> +
> + 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)
> + return;
> + }
> + prog->sh.HasBoundBindlessSampler = false;
> +}
> +
> +static void
> +update_bound_bindless_image_flag(struct gl_program *prog)
> +{
> + unsigned i;
> +
> + 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)
> + return;
> + }
> + prog->sh.HasBoundBindlessImage = false;
> +}
> +
> /**
> * Called via glUniformHandleui64*ARB() functions.
> */
> @@ -1236,6 +1300,52 @@ _mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values,
> sizeof(uni->storage[0]) * components * count * size_mul);
>
> _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
> +
> + if (uni->type->is_sampler()) {
> + /* Mark this bindless sampler as not bound to a texture unit because
> + * it refers to a texture handle.
> + */
> + for (int i = 0; i < MESA_SHADER_STAGES; i++) {
> + struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
> +
> + /* If the shader stage doesn't use the sampler uniform, skip this. */
> + if (!uni->opaque[i].active)
> + continue;
> +
> + for (int j = 0; j < count; j++) {
> + unsigned unit = uni->opaque[i].index + offset + j;
> + struct gl_bindless_sampler *sampler =
> + &sh->Program->sh.BindlessSamplers[unit];
> +
> + sampler->bound = false;
> + }
> +
> + update_bound_bindless_sampler_flag(sh->Program);
> + }
> + }
> +
> + if (uni->type->is_image()) {
> + /* Mark this bindless image as not bound to an image unit because it
> + * refers to a texture handle.
> + */
> + for (int i = 0; i < MESA_SHADER_STAGES; i++) {
> + struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
> +
> + /* If the shader stage doesn't use the sampler uniform, skip this. */
> + if (!uni->opaque[i].active)
> + continue;
> +
> + for (int j = 0; j < count; j++) {
> + unsigned unit = uni->opaque[i].index + offset + j;
> + struct gl_bindless_image *image =
> + &sh->Program->sh.BindlessImages[unit];
> +
> + image->bound = false;
> + }
> +
> + update_bound_bindless_image_flag(sh->Program);
> + }
> + }
> }
>
> extern "C" bool
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list