On 25.05.2017 12:51, Samuel Pitoiset wrote:
On 05/24/2017 01:01 PM, Nicolai Hähnle wrote:
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?

https://hastebin.com/jiduzevage

Works fine.

I really think this is pure chance (and I think I see why it works in the code), but in part it's because you didn't test rendering with a uniform array of samplers.

On the second thought, the whole uni->is_bindless_handle design can't possibly work. Consider an array

  layout(bindless_texture) uniform sampler2D tex[2];

which is bound with

  glUniform1i(loc, tex_unit);
  glUniformHandleui64ARB(loc + 1, handle);

We don't need uni->is_bindless_handle; what we do need is that each of _mesa_uniform, _mesa_uniform_handle, and _mesa_get_uniform use size_mul == 2 unconditionally when the uniform is bindless.

Cheers,
Nicolai


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.

I don't see where a mismatch could happen actually.


Cheers,
Nicolai


On 19.05.2017 18:52, Samuel Pitoiset wrote:
Signed-off-by: Samuel Pitoiset <samuel.pitoi...@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.
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to