[Mesa-dev] [PATCH v2 23/64] mesa: handle bindless uniforms bound to texture/image units
Samuel Pitoiset
samuel.pitoiset at gmail.com
Tue May 30 20:35:54 UTC 2017
v2: - set changed to true when !sampler->bound
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..7bd04e1935 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->bound) {
+ 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
--
2.13.0
More information about the mesa-dev
mailing list