summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl
diff options
context:
space:
mode:
authorAlejandro Piñeiro <[email protected]>2018-08-31 12:20:49 +0200
committerArcady Goldmints-Orlov <[email protected]>2019-06-30 16:58:27 -0500
commitde05a6ccf59b429629a4e7b93fbe2eaf5960325d (patch)
tree51e2131f77a751662a7778b3a2a93fe9a5ca7ac4 /src/compiler/glsl
parenteb50d1d2a6357cec66822f8f6861f220923a946c (diff)
nir/linker: fill up uniform_storage with explicit data
Specifically, offset, stride (coming from arrays or matrices) and row_major. On GLSL, most of that info is computed using the layout qualifier, but on ARB_gl_spirv they are explicit, and for Mesa, included on the glsl_type. From ARB_gl_spirv spec: "Mapping of layouts std140/std430 -> explicit *Offset*, *ArrayStride*, and *MatrixStride* Decoration on struct members"" "7.6.2.spv SPIR-V Uniform Offsets and Strides The SPIR-V decorations *GLSLShared* or *GLSLPacked* must not be used. A variable in the *Uniform* Storage Class decorated as a *Block* must be explicitly laid out using the *Offset*, *ArrayStride*, and *MatrixStride* decorations" For offset we needed to include the parent and index_in_parent while processing the type, as the offset is maintained on glsl_struct_field of the parent type, not on the type itself. v2: Fix the default values for MATRIX_STRIDE, ARRAY_STRIDE and ROW_MAJOR when the variable is not backed by a buffer object (Antia Puentes). v3: Update after Jason series "SPIR-V: Use NIR deref instructions for UBO/SSBO access" that included just one explicit stride, instead of a previous patch we wrote that had matrix_stride and array_stride (Alejandro) Signed-off-by: Antia Puentes <[email protected]> Signed-off-by: Alejandro Piñeiro <[email protected]> Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r--src/compiler/glsl/gl_nir_link_uniforms.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/compiler/glsl/gl_nir_link_uniforms.c b/src/compiler/glsl/gl_nir_link_uniforms.c
index bb126a40baa..54d9acd21b0 100644
--- a/src/compiler/glsl/gl_nir_link_uniforms.c
+++ b/src/compiler/glsl/gl_nir_link_uniforms.c
@@ -282,6 +282,8 @@ nir_link_uniform(struct gl_context *ctx,
struct gl_program *stage_program,
gl_shader_stage stage,
const struct glsl_type *type,
+ const struct glsl_type *parent_type,
+ unsigned index_in_parent,
int location,
struct nir_link_uniforms_state *state)
{
@@ -309,7 +311,7 @@ nir_link_uniform(struct gl_context *ctx,
field_type = glsl_get_array_element(type);
int entries = nir_link_uniform(ctx, prog, stage_program, stage,
- field_type, location,
+ field_type, type, i, location,
state);
if (entries == -1)
return -1;
@@ -371,15 +373,54 @@ nir_link_uniform(struct gl_context *ctx,
uniform->is_shader_storage = nir_variable_is_in_ssbo(state->current_var);
+ /* Set fields whose default value depend on the variable being inside a
+ * block.
+ *
+ * From the OpenGL 4.6 spec, 7.3 Program objects:
+ *
+ * "For the property ARRAY_STRIDE, ... For active variables not declared
+ * as an array of basic types, zero is written to params. For active
+ * variables not backed by a buffer object, -1 is written to params,
+ * regardless of the variable type."
+ *
+ * "For the property MATRIX_STRIDE, ... For active variables not declared
+ * as a matrix or array of matrices, zero is written to params. For active
+ * variables not backed by a buffer object, -1 is written to params,
+ * regardless of the variable type."
+ *
+ * For the property IS_ROW_MAJOR, ... For active variables backed by a
+ * buffer object, declared as a single matrix or array of matrices, and
+ * stored in row-major order, one is written to params. For all other
+ * active variables, zero is written to params.
+ */
+ uniform->array_stride = -1;
+ uniform->matrix_stride = -1;
+ uniform->row_major = false;
+
+ if (nir_variable_is_in_block(state->current_var)) {
+ uniform->array_stride = glsl_type_is_array(type) ?
+ glsl_get_explicit_stride(type) : 0;
+
+ if (glsl_type_is_matrix(type)) {
+ assert(parent_type);
+ uniform->matrix_stride = glsl_get_explicit_stride(type);
+
+ uniform->row_major = glsl_matrix_type_is_row_major(type);
+ } else {
+ uniform->matrix_stride = 0;
+ }
+ }
+
+ if (parent_type)
+ uniform->offset = glsl_get_struct_field_offset(parent_type, index_in_parent);
+ else
+ uniform->offset = 0;
+
/* @FIXME: the initialization of the following will be done as we
* implement support for their specific features, like SSBO, atomics,
* etc.
*/
uniform->block_index = -1;
- uniform->offset = -1;
- uniform->matrix_stride = -1;
- uniform->array_stride = -1;
- uniform->row_major = false;
uniform->builtin = false;
uniform->atomic_buffer_index = -1;
uniform->top_level_array_size = 0;
@@ -543,6 +584,7 @@ gl_nir_link_uniforms(struct gl_context *ctx,
state.current_type = type_tree;
int res = nir_link_uniform(ctx, prog, sh->Program, shader_type, type,
+ NULL, 0,
location, &state);
free_type_tree(type_tree);