summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlejandro Piñeiro <[email protected]>2019-01-16 16:50:29 +0100
committerArcady Goldmints-Orlov <[email protected]>2019-06-30 16:58:26 -0500
commit0019d6152749fab000c12daf4d3c7b0d4fba2caf (patch)
tree2823fd65795032fe1cdba076ef92906c3f2f14b0
parentc23522add233301f10cd7ca2d2570f10b1184815 (diff)
glsl/nir: add glsl_types::explicit_size plus nir C wrapper
While using SPIR-V shaders (ARB_gl_spirv), layout data is not implicit to a specific value (std140, std430, etc) but explicitly included on the type (explicit values for offset, stride and row_major). So this method is equivalent to the existing std140_size and std430_size, but using such explicit values. Note that the value returned by this method is only valid if such data is set, so when dealing with SPIR-V shaders. v2: (all changes suggested by Jason Ekstrand) * Iterate through all struct members, instead of assume that fields are ordered by offset * Use else if * Take into account the case that explicit_stride > elem_size, to fine graine the final size on arrays and matrices * Handle different bit-sizes in general, not just 32 and 64. v3: (change suggested by Caio Marcelo de Oliveira Filho) * fix up explicit_size() to consider interface types Signed-off-by: Alejandro Piñeiro <[email protected]> Signed-off-by: Antia Puentes <[email protected]> Signed-off-by: Neil Roberts <[email protected]> Reviewed-by: Timothy Arceri <[email protected]> Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]>
-rw-r--r--src/compiler/glsl_types.cpp68
-rw-r--r--src/compiler/glsl_types.h13
-rw-r--r--src/compiler/nir_types.cpp6
-rw-r--r--src/compiler/nir_types.h2
4 files changed, 89 insertions, 0 deletions
diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp
index ded355ee308..123a8e40255 100644
--- a/src/compiler/glsl_types.cpp
+++ b/src/compiler/glsl_types.cpp
@@ -2124,6 +2124,74 @@ glsl_type::std430_array_stride(bool row_major) const
return stride;
}
+/* Note that the value returned by this method is only correct if the
+ * explit offset, and stride values are set, so only with SPIR-V shaders.
+ * Should not be used with GLSL shaders.
+ */
+
+unsigned
+glsl_type::explicit_size(bool align_to_stride) const
+{
+ if (this->is_struct() || this->is_interface()) {
+ if (this->length > 0) {
+ unsigned size = 0;
+
+ for (unsigned i = 0; i < this->length; i++) {
+ assert(this->fields.structure[i].offset >= 0);
+ unsigned last_byte = this->fields.structure[i].offset +
+ this->fields.structure[i].type->explicit_size();
+ size = MAX2(size, last_byte);
+ }
+
+ return size;
+ } else {
+ return 0;
+ }
+ } else if (this->is_array()) {
+ /* From ARB_program_interface_query spec:
+ *
+ * "For the property of BUFFER_DATA_SIZE, then the implementation-dependent
+ * minimum total buffer object size, in basic machine units, required to
+ * hold all active variables associated with an active uniform block, shader
+ * storage block, or atomic counter buffer is written to <params>. If the
+ * final member of an active shader storage block is array with no declared
+ * size, the minimum buffer size is computed assuming the array was declared
+ * as an array with one element."
+ *
+ */
+ if (this->is_unsized_array())
+ return this->explicit_stride;
+
+ assert(this->length > 0);
+ unsigned elem_size = align_to_stride ? this->explicit_stride : this->fields.array->explicit_size();
+ assert(this->explicit_stride >= elem_size);
+
+ return this->explicit_stride * (this->length - 1) + elem_size;
+ } else if (this->is_matrix()) {
+ const struct glsl_type *elem_type;
+ unsigned length;
+
+ if (this->interface_row_major) {
+ elem_type = get_instance(this->base_type,
+ this->matrix_columns, 1);
+ length = this->vector_elements;
+ } else {
+ elem_type = get_instance(this->base_type,
+ this->vector_elements, 1);
+ length = this->matrix_columns;
+ }
+
+ unsigned elem_size = align_to_stride ? this->explicit_stride : elem_type->explicit_size();
+
+ assert(this->explicit_stride);
+ return this->explicit_stride * (length - 1) + elem_size;
+ }
+
+ unsigned N = this->bit_size() / 8;
+
+ return this->vector_elements * N;
+}
+
unsigned
glsl_type::std430_size(bool row_major) const
{
diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h
index 1e550986e47..3fd49a759c6 100644
--- a/src/compiler/glsl_types.h
+++ b/src/compiler/glsl_types.h
@@ -544,6 +544,19 @@ public:
unsigned cl_size() const;
/**
+ * Size in bytes of this type based on its explicit data.
+ *
+ * When using SPIR-V shaders (ARB_gl_spirv), memory layouts are expressed
+ * through explicit offset, stride and matrix layout, so the size
+ * can/should be computed used those values.
+ *
+ * Note that the value returned by this method is only correct if such
+ * values are set, so only with SPIR-V shaders. Should not be used with
+ * GLSL shaders.
+ */
+ unsigned explicit_size(bool align_to_stride=false) const;
+
+ /**
* \brief Can this type be implicitly converted to another?
*
* \return True if the types are identical or if this type can be converted
diff --git a/src/compiler/nir_types.cpp b/src/compiler/nir_types.cpp
index e2dfc40ff0b..69f89a7fd74 100644
--- a/src/compiler/nir_types.cpp
+++ b/src/compiler/nir_types.cpp
@@ -721,3 +721,9 @@ glsl_type_get_image_count(const struct glsl_type *type)
return 0;
}
+
+unsigned
+glsl_get_explicit_size(const struct glsl_type *type, bool align_to_stride)
+{
+ return type->explicit_size(align_to_stride);
+}
diff --git a/src/compiler/nir_types.h b/src/compiler/nir_types.h
index 7bcf4c08f4c..806ba824084 100644
--- a/src/compiler/nir_types.h
+++ b/src/compiler/nir_types.h
@@ -102,6 +102,8 @@ int glsl_get_cl_size(const struct glsl_type *type);
int glsl_get_cl_alignment(const struct glsl_type *type);
+unsigned glsl_get_explicit_size(const struct glsl_type *type, bool align_to_stride);
+
static inline unsigned
glsl_get_bit_size(const struct glsl_type *type)
{