[Mesa-dev] [PATCH v3 07/63] mesa: add support for glUniformHandleui64*ARB()
Samuel Pitoiset
samuel.pitoiset at gmail.com
Fri Jun 9 13:35:05 UTC 2017
Bindless sampler/image handles are represented using 64-bit
unsigned integers.
The ARB_bindless_texture spec says:
"The error INVALID_OPERATION is generated by UniformHandleui64{v}ARB
if the sampler or image uniform being updated has the "bound_sampler"
or "bound_image" layout qualifier"."
Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
---
src/compiler/glsl/ir_uniform.h | 6 ++++
src/compiler/glsl/link_uniforms.cpp | 1 +
src/compiler/glsl/shader_cache.cpp | 2 ++
src/mesa/main/uniform_query.cpp | 64 +++++++++++++++++++++++++++++++++++++
src/mesa/main/uniforms.c | 15 +++++++++
src/mesa/main/uniforms.h | 4 +++
6 files changed, 92 insertions(+)
diff --git a/src/compiler/glsl/ir_uniform.h b/src/compiler/glsl/ir_uniform.h
index b6aec7fc4a..9841df8cde 100644
--- a/src/compiler/glsl/ir_uniform.h
+++ b/src/compiler/glsl/ir_uniform.h
@@ -201,6 +201,12 @@ struct gl_uniform_storage {
* top-level shader storage block member. (GL_TOP_LEVEL_ARRAY_STRIDE).
*/
unsigned top_level_array_stride;
+
+ /**
+ * Whether this uniform variable has the bindless_sampler or bindless_image
+ * layout qualifier as specified by ARB_bindless_texture.
+ */
+ bool is_bindless;
};
#ifdef __cplusplus
diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp
index b11739ce78..7c3ca75416 100644
--- a/src/compiler/glsl/link_uniforms.cpp
+++ b/src/compiler/glsl/link_uniforms.cpp
@@ -754,6 +754,7 @@ private:
this->uniforms[id].is_shader_storage =
current_var->is_in_shader_storage_block();
+ this->uniforms[id].is_bindless = current_var->data.bindless;
/* Do not assign storage if the uniform is a builtin or buffer object */
if (!this->uniforms[id].builtin &&
diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp
index dd56501258..1ad8fdd62a 100644
--- a/src/compiler/glsl/shader_cache.cpp
+++ b/src/compiler/glsl/shader_cache.cpp
@@ -578,6 +578,7 @@ write_uniforms(struct blob *metadata, struct gl_shader_program *prog)
blob_write_uint32(metadata, prog->data->UniformStorage[i].is_shader_storage);
blob_write_uint32(metadata, prog->data->UniformStorage[i].matrix_stride);
blob_write_uint32(metadata, prog->data->UniformStorage[i].row_major);
+ blob_write_uint32(metadata, prog->data->UniformStorage[i].is_bindless);
blob_write_uint32(metadata,
prog->data->UniformStorage[i].num_compatible_subroutines);
blob_write_uint32(metadata,
@@ -642,6 +643,7 @@ read_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog)
uniforms[i].is_shader_storage = blob_read_uint32(metadata);
uniforms[i].matrix_stride = blob_read_uint32(metadata);
uniforms[i].row_major = blob_read_uint32(metadata);
+ uniforms[i].is_bindless = blob_read_uint32(metadata);
uniforms[i].num_compatible_subroutines = blob_read_uint32(metadata);
uniforms[i].top_level_array_size = blob_read_uint32(metadata);
uniforms[i].top_level_array_stride = blob_read_uint32(metadata);
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index e6c78bf69c..c0e3ca45e5 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -1274,6 +1274,70 @@ _mesa_uniform_matrix(GLint location, GLsizei count,
_mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
}
+/**
+ * Called via glUniformHandleui64*ARB() functions.
+ */
+extern "C" void
+_mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values,
+ struct gl_context *ctx, struct gl_shader_program *shProg)
+{
+ unsigned offset;
+ struct gl_uniform_storage *const uni =
+ validate_uniform_parameters(location, count, &offset,
+ ctx, shProg, "glUniformHandleui64*ARB");
+ if (uni == NULL)
+ return;
+
+ if (!uni->is_bindless) {
+ /* From section "Errors" of the ARB_bindless_texture spec:
+ *
+ * "The error INVALID_OPERATION is generated by
+ * UniformHandleui64{v}ARB if the sampler or image uniform being
+ * updated has the "bound_sampler" or "bound_image" layout qualifier."
+ *
+ * From section 4.4.6 of the ARB_bindless_texture spec:
+ *
+ * "In the absence of these qualifiers, sampler and image uniforms are
+ * considered "bound". Additionally, if GL_ARB_bindless_texture is not
+ * enabled, these uniforms are considered "bound"."
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUniformHandleui64*ARB(non-bindless sampler/image uniform)");
+ return;
+ }
+
+ const unsigned components = uni->type->vector_elements;
+ const int size_mul = 2;
+
+ if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
+ log_uniform(values, GLSL_TYPE_UINT64, components, 1, count,
+ false, shProg, location, uni);
+ }
+
+ /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
+ *
+ * "When loading N elements starting at an arbitrary position k in a
+ * uniform declared as an array, elements k through k + N - 1 in the
+ * array will be replaced with the new values. Values for any array
+ * element that exceeds the highest array element index used, as
+ * reported by GetActiveUniform, will be ignored by the GL."
+ *
+ * Clamp 'count' to a valid value. Note that for non-arrays a count > 1
+ * will have already generated an error.
+ */
+ if (uni->array_elements != 0) {
+ count = MIN2(count, (int) (uni->array_elements - offset));
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+ /* Store the data in the "actual type" backing storage for the uniform.
+ */
+ memcpy(&uni->storage[size_mul * components * offset], values,
+ sizeof(uni->storage[0]) * components * count * size_mul);
+
+ _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
+}
extern "C" bool
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index a9e7cda17c..67c238e4f3 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -297,12 +297,17 @@ _mesa_Uniform4iv(GLint location, GLsizei count, const GLint * value)
void GLAPIENTRY
_mesa_UniformHandleui64ARB(GLint location, GLuint64 value)
{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_uniform_handle(location, 1, &value, ctx, ctx->_Shader->ActiveProgram);
}
void GLAPIENTRY
_mesa_UniformHandleui64vARB(GLint location, GLsizei count,
const GLuint64 *value)
{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_uniform_handle(location, count, value, ctx,
+ ctx->_Shader->ActiveProgram);
}
@@ -501,12 +506,22 @@ void GLAPIENTRY
_mesa_ProgramUniformHandleui64ARB(GLuint program, GLint location,
GLuint64 value)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformHandleui64ARB");
+ _mesa_uniform_handle(location, 1, &value, ctx, shProg);
}
void GLAPIENTRY
_mesa_ProgramUniformHandleui64vARB(GLuint program, GLint location,
GLsizei count, const GLuint64 *values)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformHandleui64vARB");
+ _mesa_uniform_handle(location, count, values, ctx, shProg);
}
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index 553e8717ba..bd42b4f036 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -453,6 +453,10 @@ _mesa_uniform_matrix(GLint location, GLsizei count,
GLuint cols, GLuint rows, enum glsl_base_type basicType);
void
+_mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values,
+ struct gl_context *, struct gl_shader_program *);
+
+void
_mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
GLsizei bufSize, enum glsl_base_type returnType,
GLvoid *paramsOut);
--
2.13.1
More information about the mesa-dev
mailing list