[Mesa-dev] [PATCH v5 27/70] glsl: Add std430 interface packing support to program_resource_visitor's member functions
Iago Toral Quiroga
itoral at igalia.com
Thu Sep 10 06:35:43 PDT 2015
From: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
They are used to calculate the offset, array stride of uniform/shader storage
buffer variables. Take into account this info to get the right value for std430.
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
---
src/glsl/link_uniform_blocks.cpp | 19 +++++++---
src/glsl/link_uniforms.cpp | 81 ++++++++++++++++++++++++++++------------
src/glsl/linker.h | 6 ++-
3 files changed, 76 insertions(+), 30 deletions(-)
diff --git a/src/glsl/link_uniform_blocks.cpp b/src/glsl/link_uniform_blocks.cpp
index c891d03..8f65f4a 100644
--- a/src/glsl/link_uniform_blocks.cpp
+++ b/src/glsl/link_uniform_blocks.cpp
@@ -68,14 +68,18 @@ private:
}
virtual void enter_record(const glsl_type *type, const char *,
- bool row_major) {
+ bool row_major, const unsigned packing) {
assert(type->is_record());
- this->offset = glsl_align(
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ this->offset = glsl_align(
+ this->offset, type->std430_base_alignment(row_major));
+ else
+ this->offset = glsl_align(
this->offset, type->std140_base_alignment(row_major));
}
virtual void leave_record(const glsl_type *type, const char *,
- bool row_major) {
+ bool row_major, const unsigned packing) {
assert(type->is_record());
/* If this is the last field of a structure, apply rule #9. The
@@ -85,12 +89,17 @@ private:
* the member following the sub-structure is rounded up to the next
* multiple of the base alignment of the structure."
*/
- this->offset = glsl_align(
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ this->offset = glsl_align(
+ this->offset, type->std430_base_alignment(row_major));
+ else
+ this->offset = glsl_align(
this->offset, type->std140_base_alignment(row_major));
}
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major, const glsl_type *,
+ const unsigned packing,
bool /* last_field */)
{
assert(this->index < this->num_variables);
@@ -122,7 +131,7 @@ private:
unsigned alignment = 0;
unsigned size = 0;
- if (v->Type->interface_packing == GLSL_INTERFACE_PACKING_STD430) {
+ if (packing == GLSL_INTERFACE_PACKING_STD430) {
alignment = type->std430_base_alignment(v->RowMajor);
size = type->std430_size(v->RowMajor);
} else {
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index fefc1ec..1d678c2 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -63,7 +63,9 @@ program_resource_visitor::process(const glsl_type *type, const char *name)
|| type->without_array()->is_interface());
char *name_copy = ralloc_strdup(NULL, name);
- recursion(type, &name_copy, strlen(name), false, NULL, false);
+ unsigned packing = type->interface_packing;
+
+ recursion(type, &name_copy, strlen(name), false, NULL, packing, false);
ralloc_free(name_copy);
}
@@ -74,6 +76,10 @@ program_resource_visitor::process(ir_variable *var)
const bool row_major =
var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
+ const unsigned packing = var->get_interface_type() ?
+ var->get_interface_type()->interface_packing :
+ var->type->interface_packing;
+
/* false is always passed for the row_major parameter to the other
* processing functions because no information is available to do
* otherwise. See the warning in linker.h.
@@ -110,7 +116,8 @@ program_resource_visitor::process(ir_variable *var)
* lowering is only applied to non-uniform interface blocks, so we
* can safely pass false for row_major.
*/
- recursion(var->type, &name, new_length, row_major, NULL, false);
+ recursion(var->type, &name, new_length, row_major, NULL, packing,
+ false);
}
ralloc_free(name);
} else if (var->data.from_named_ifc_block_nonarray) {
@@ -134,22 +141,22 @@ program_resource_visitor::process(ir_variable *var)
* is only applied to non-uniform interface blocks, so we can safely
* pass false for row_major.
*/
- recursion(var->type, &name, strlen(name), row_major, NULL, false);
+ recursion(var->type, &name, strlen(name), row_major, NULL, packing, false);
ralloc_free(name);
} else if (t->without_array()->is_record()) {
char *name = ralloc_strdup(NULL, var->name);
- recursion(var->type, &name, strlen(name), row_major, NULL, false);
+ recursion(var->type, &name, strlen(name), row_major, NULL, packing, false);
ralloc_free(name);
} else if (t->is_interface()) {
char *name = ralloc_strdup(NULL, var->type->name);
- recursion(var->type, &name, strlen(name), row_major, NULL, false);
+ recursion(var->type, &name, strlen(name), row_major, NULL, packing, false);
ralloc_free(name);
} else if (t->is_array() && t->fields.array->is_interface()) {
char *name = ralloc_strdup(NULL, var->type->fields.array->name);
- recursion(var->type, &name, strlen(name), row_major, NULL, false);
+ recursion(var->type, &name, strlen(name), row_major, NULL, packing, false);
ralloc_free(name);
} else {
- this->visit_field(t, var->name, row_major, NULL, false);
+ this->visit_field(t, var->name, row_major, NULL, packing, false);
}
}
@@ -157,6 +164,7 @@ void
program_resource_visitor::recursion(const glsl_type *t, char **name,
size_t name_length, bool row_major,
const glsl_type *record_type,
+ const unsigned packing,
bool last_field)
{
/* Records need to have each field processed individually.
@@ -170,7 +178,7 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
record_type = t;
if (t->is_record())
- this->enter_record(t, *name, row_major);
+ this->enter_record(t, *name, row_major, packing);
for (unsigned i = 0; i < t->length; i++) {
const char *field = t->fields.structure[i].name;
@@ -204,6 +212,7 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
recursion(t->fields.structure[i].type, name, new_length,
field_row_major,
record_type,
+ packing,
(i + 1) == t->length);
/* Only the first leaf-field of the record gets called with the
@@ -214,7 +223,7 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
if (t->is_record()) {
(*name)[name_length] = '\0';
- this->leave_record(t, *name, row_major);
+ this->leave_record(t, *name, row_major, packing);
}
} else if (t->is_array() && (t->fields.array->is_record()
|| t->fields.array->is_interface())) {
@@ -235,6 +244,7 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
recursion(t->fields.array, name, new_length, row_major,
record_type,
+ packing,
(i + 1) == t->length);
/* Only the first leaf-field of the record gets called with the
@@ -243,7 +253,7 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
record_type = NULL;
}
} else {
- this->visit_field(t, *name, row_major, record_type, last_field);
+ this->visit_field(t, *name, row_major, record_type, packing, last_field);
}
}
@@ -251,6 +261,7 @@ void
program_resource_visitor::visit_field(const glsl_type *type, const char *name,
bool row_major,
const glsl_type *,
+ const unsigned,
bool /* last_field */)
{
visit_field(type, name, row_major);
@@ -264,12 +275,14 @@ program_resource_visitor::visit_field(const glsl_struct_field *field)
}
void
-program_resource_visitor::enter_record(const glsl_type *, const char *, bool)
+program_resource_visitor::enter_record(const glsl_type *, const char *, bool,
+ const unsigned)
{
}
void
-program_resource_visitor::leave_record(const glsl_type *, const char *, bool)
+program_resource_visitor::leave_record(const glsl_type *, const char *, bool,
+ const unsigned)
{
}
@@ -579,25 +592,34 @@ private:
}
virtual void enter_record(const glsl_type *type, const char *,
- bool row_major) {
+ bool row_major, const unsigned packing) {
assert(type->is_record());
if (this->ubo_block_index == -1)
return;
- this->ubo_byte_offset = glsl_align(
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ this->ubo_byte_offset = glsl_align(
+ this->ubo_byte_offset, type->std430_base_alignment(row_major));
+ else
+ this->ubo_byte_offset = glsl_align(
this->ubo_byte_offset, type->std140_base_alignment(row_major));
}
virtual void leave_record(const glsl_type *type, const char *,
- bool row_major) {
+ bool row_major, const unsigned packing) {
assert(type->is_record());
if (this->ubo_block_index == -1)
return;
- this->ubo_byte_offset = glsl_align(
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ this->ubo_byte_offset = glsl_align(
+ this->ubo_byte_offset, type->std430_base_alignment(row_major));
+ else
+ this->ubo_byte_offset = glsl_align(
this->ubo_byte_offset, type->std140_base_alignment(row_major));
}
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major, const glsl_type *record_type,
+ const unsigned packing,
bool /* last_field */)
{
assert(!type->without_array()->is_record());
@@ -667,14 +689,23 @@ private:
if (this->ubo_block_index != -1) {
this->uniforms[id].block_index = this->ubo_block_index;
- const unsigned alignment = type->std140_base_alignment(row_major);
+ unsigned alignment = type->std140_base_alignment(row_major);
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ alignment = type->std430_base_alignment(row_major);
this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment);
this->uniforms[id].offset = this->ubo_byte_offset;
- this->ubo_byte_offset += type->std140_size(row_major);
-
- if (type->is_array()) {
- this->uniforms[id].array_stride =
- glsl_align(type->fields.array->std140_size(row_major), 16);
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ this->ubo_byte_offset += type->std430_size(row_major);
+ else
+ this->ubo_byte_offset += type->std140_size(row_major);
+
+ if (type->is_array()) {
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ this->uniforms[id].array_stride =
+ type->fields.array->std430_array_stride(row_major);
+ else
+ this->uniforms[id].array_stride =
+ glsl_align(type->fields.array->std140_size(row_major), 16);
} else {
this->uniforms[id].array_stride = 0;
}
@@ -685,7 +716,11 @@ private:
const unsigned items = row_major ? matrix->matrix_columns : matrix->vector_elements;
assert(items <= 4);
- this->uniforms[id].matrix_stride = glsl_align(items * N, 16);
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ this->uniforms[id].matrix_stride = items < 3 ? items * N :
+ glsl_align(items * N, 16);
+ else
+ this->uniforms[id].matrix_stride = glsl_align(items * N, 16);
this->uniforms[id].row_major = row_major;
} else {
this->uniforms[id].matrix_stride = 0;
diff --git a/src/glsl/linker.h b/src/glsl/linker.h
index ce3dc32..fb8f81e 100644
--- a/src/glsl/linker.h
+++ b/src/glsl/linker.h
@@ -153,6 +153,7 @@ protected:
*/
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major, const glsl_type *record_type,
+ const unsigned packing,
bool last_field);
/**
@@ -176,10 +177,10 @@ protected:
virtual void visit_field(const glsl_struct_field *field);
virtual void enter_record(const glsl_type *type, const char *name,
- bool row_major);
+ bool row_major, const unsigned packing);
virtual void leave_record(const glsl_type *type, const char *name,
- bool row_major);
+ bool row_major, const unsigned packing);
private:
/**
@@ -191,6 +192,7 @@ private:
*/
void recursion(const glsl_type *t, char **name, size_t name_length,
bool row_major, const glsl_type *record_type,
+ const unsigned packing,
bool last_field);
};
--
1.9.1
More information about the mesa-dev
mailing list