summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2017-05-11 18:42:22 +0200
committerSamuel Pitoiset <[email protected]>2017-06-14 10:04:36 +0200
commitfe9f7095e826aa8702f724e7445ff8dc539cfd7d (patch)
treef6f068fba0682dc1370051fd7b00e1624f665618
parent804e6f2b76a383f99666177343bce5000788348a (diff)
mesa: handle bindless uniforms bound to texture/image units
Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r--src/mesa/main/uniform_query.cpp122
1 files changed, 116 insertions, 6 deletions
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index c0e3ca45e56..5ac85c014ee 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -1094,9 +1094,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;
+ }
}
}
@@ -1125,9 +1141,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;
@@ -1274,6 +1304,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.
*/
@@ -1337,6 +1401,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