[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