summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/link_uniform_block_active_visitor.cpp39
-rw-r--r--src/glsl/link_uniform_block_active_visitor.h1
-rw-r--r--src/glsl/opt_dead_code.cpp29
3 files changed, 65 insertions, 4 deletions
diff --git a/src/glsl/link_uniform_block_active_visitor.cpp b/src/glsl/link_uniform_block_active_visitor.cpp
index 854309f9baa..9da6a4bba48 100644
--- a/src/glsl/link_uniform_block_active_visitor.cpp
+++ b/src/glsl/link_uniform_block_active_visitor.cpp
@@ -73,6 +73,45 @@ process_block(void *mem_ctx, struct hash_table *ht, ir_variable *var)
}
ir_visitor_status
+link_uniform_block_active_visitor::visit(ir_variable *var)
+{
+ if (!var->is_in_uniform_block())
+ return visit_continue;
+
+ const glsl_type *const block_type = var->is_interface_instance()
+ ? var->type : var->get_interface_type();
+
+ /* Section 2.11.6 (Uniform Variables) of the OpenGL ES 3.0.3 spec says:
+ *
+ * "All members of a named uniform block declared with a shared or
+ * std140 layout qualifier are considered active, even if they are not
+ * referenced in any shader in the program. The uniform block itself is
+ * also considered active, even if no member of the block is
+ * referenced."
+ */
+ if (block_type->interface_packing == GLSL_INTERFACE_PACKING_PACKED)
+ return visit_continue;
+
+ /* Process the block. Bail if there was an error.
+ */
+ link_uniform_block_active *const b =
+ process_block(this->mem_ctx, this->ht, var);
+ if (b == NULL) {
+ linker_error(this->prog,
+ "uniform block `%s' has mismatching definitions",
+ var->get_interface_type()->name);
+ this->success = false;
+ return visit_stop;
+ }
+
+ assert(b->num_array_elements == 0);
+ assert(b->array_elements == NULL);
+ assert(b->type != NULL);
+
+ return visit_continue;
+}
+
+ir_visitor_status
link_uniform_block_active_visitor::visit_enter(ir_dereference_array *ir)
{
ir_dereference_variable *const d = ir->array->as_dereference_variable();
diff --git a/src/glsl/link_uniform_block_active_visitor.h b/src/glsl/link_uniform_block_active_visitor.h
index 64de8268007..e5ea501553c 100644
--- a/src/glsl/link_uniform_block_active_visitor.h
+++ b/src/glsl/link_uniform_block_active_visitor.h
@@ -51,6 +51,7 @@ public:
virtual ir_visitor_status visit_enter(ir_dereference_array *);
virtual ir_visitor_status visit(ir_dereference_variable *);
+ virtual ir_visitor_status visit(ir_variable *);
bool success;
diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp
index 3df01b4137d..f45bf5dfdf8 100644
--- a/src/glsl/opt_dead_code.cpp
+++ b/src/glsl/opt_dead_code.cpp
@@ -99,10 +99,31 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
* stage. Also, once uniform locations have been assigned, the
* declaration cannot be deleted.
*/
- if (entry->var->data.mode == ir_var_uniform &&
- (uniform_locations_assigned ||
- entry->var->constant_value))
- continue;
+ if (entry->var->data.mode == ir_var_uniform) {
+ if (uniform_locations_assigned || entry->var->constant_value)
+ continue;
+
+ /* Section 2.11.6 (Uniform Variables) of the OpenGL ES 3.0.3 spec
+ * says:
+ *
+ * "All members of a named uniform block declared with a
+ * shared or std140 layout qualifier are considered active,
+ * even if they are not referenced in any shader in the
+ * program. The uniform block itself is also considered
+ * active, even if no member of the block is referenced."
+ *
+ * If the variable is in a uniform block with one of those
+ * layouts, do not eliminate it.
+ */
+ if (entry->var->is_in_uniform_block()) {
+ const glsl_type *const block_type =
+ entry->var->is_interface_instance()
+ ? entry->var->type : entry->var->get_interface_type();
+
+ if (block_type->interface_packing != GLSL_INTERFACE_PACKING_PACKED)
+ continue;
+ }
+ }
entry->var->remove();
progress = true;