summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/ast_to_hir.cpp1
-rw-r--r--src/glsl/glsl_types.cpp66
-rw-r--r--src/glsl/glsl_types.h19
-rw-r--r--src/glsl/ir.cpp2
-rw-r--r--src/glsl/ir.h1
-rw-r--r--src/glsl/ir_builder.cpp6
-rw-r--r--src/glsl/ir_builder.h1
-rw-r--r--src/glsl/ir_clone.cpp1
-rw-r--r--src/glsl/ir_validate.cpp4
-rw-r--r--src/glsl/link_uniform_initializers.cpp1
-rw-r--r--src/glsl/nir/nir_lower_io.c2
-rw-r--r--src/glsl/tests/uniform_initializer_utils.cpp3
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp4
13 files changed, 111 insertions, 0 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index a45b6e8f026..3b836f8d33c 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -1019,6 +1019,7 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
case GLSL_TYPE_IMAGE:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_ATOMIC_UINT:
+ case GLSL_TYPE_SUBROUTINE:
/* I assume a comparison of a struct containing a sampler just
* ignores the sampler present in the type.
*/
diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index cd6df5adad9..8510671d2f3 100644
--- a/src/glsl/glsl_types.cpp
+++ b/src/glsl/glsl_types.cpp
@@ -32,6 +32,7 @@ mtx_t glsl_type::mutex = _MTX_INITIALIZER_NP;
hash_table *glsl_type::array_types = NULL;
hash_table *glsl_type::record_types = NULL;
hash_table *glsl_type::interface_types = NULL;
+hash_table *glsl_type::subroutine_types = NULL;
void *glsl_type::mem_ctx = NULL;
void
@@ -161,6 +162,22 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
mtx_unlock(&glsl_type::mutex);
}
+glsl_type::glsl_type(const char *subroutine_name) :
+ gl_type(0),
+ base_type(GLSL_TYPE_SUBROUTINE),
+ sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+ sampler_type(0), interface_packing(0),
+ vector_elements(0), matrix_columns(0),
+ length(0)
+{
+ mtx_lock(&glsl_type::mutex);
+
+ init_ralloc_type_ctx();
+ assert(subroutine_name != NULL);
+ this->name = ralloc_strdup(this->mem_ctx, subroutine_name);
+ this->vector_elements = 1;
+ mtx_unlock(&glsl_type::mutex);
+}
bool
glsl_type::contains_sampler() const
@@ -231,6 +248,22 @@ glsl_type::contains_opaque() const {
}
}
+bool
+glsl_type::contains_subroutine() const
+{
+ if (this->is_array()) {
+ return this->fields.array->contains_subroutine();
+ } else if (this->is_record()) {
+ for (unsigned int i = 0; i < this->length; i++) {
+ if (this->fields.structure[i].type->contains_subroutine())
+ return true;
+ }
+ return false;
+ } else {
+ return this->is_subroutine();
+ }
+}
+
gl_texture_index
glsl_type::sampler_index() const
{
@@ -836,6 +869,36 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
return (glsl_type *) entry->data;
}
+const glsl_type *
+glsl_type::get_subroutine_instance(const char *subroutine_name)
+{
+ const glsl_type key(subroutine_name);
+
+ mtx_lock(&glsl_type::mutex);
+
+ if (subroutine_types == NULL) {
+ subroutine_types = _mesa_hash_table_create(NULL, record_key_hash,
+ record_key_compare);
+ }
+
+ const struct hash_entry *entry = _mesa_hash_table_search(subroutine_types,
+ &key);
+ if (entry == NULL) {
+ mtx_unlock(&glsl_type::mutex);
+ const glsl_type *t = new glsl_type(subroutine_name);
+ mtx_lock(&glsl_type::mutex);
+
+ entry = _mesa_hash_table_insert(subroutine_types, t, (void *) t);
+ }
+
+ assert(((glsl_type *) entry->data)->base_type == GLSL_TYPE_SUBROUTINE);
+ assert(strcmp(((glsl_type *) entry->data)->name, subroutine_name) == 0);
+
+ mtx_unlock(&glsl_type::mutex);
+
+ return (glsl_type *) entry->data;
+}
+
const glsl_type *
glsl_type::get_mul_type(const glsl_type *type_a, const glsl_type *type_b)
@@ -968,6 +1031,7 @@ glsl_type::component_slots() const
case GLSL_TYPE_SAMPLER:
case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_VOID:
+ case GLSL_TYPE_SUBROUTINE:
case GLSL_TYPE_ERROR:
break;
}
@@ -988,6 +1052,7 @@ glsl_type::uniform_locations() const
case GLSL_TYPE_BOOL:
case GLSL_TYPE_SAMPLER:
case GLSL_TYPE_IMAGE:
+ case GLSL_TYPE_SUBROUTINE:
return 1;
case GLSL_TYPE_STRUCT:
@@ -1341,6 +1406,7 @@ glsl_type::count_attribute_slots() const
case GLSL_TYPE_IMAGE:
case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_VOID:
+ case GLSL_TYPE_SUBROUTINE:
case GLSL_TYPE_ERROR:
break;
}
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index dff6a9a9d05..52672b313c0 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -59,6 +59,7 @@ enum glsl_base_type {
GLSL_TYPE_INTERFACE,
GLSL_TYPE_ARRAY,
GLSL_TYPE_VOID,
+ GLSL_TYPE_SUBROUTINE,
GLSL_TYPE_ERROR
};
@@ -264,6 +265,11 @@ struct glsl_type {
const char *block_name);
/**
+ * Get the instance of an subroutine type
+ */
+ static const glsl_type *get_subroutine_instance(const char *subroutine_name);
+
+ /**
* Get the type resulting from a multiplication of \p type_a * \p type_b
*/
static const glsl_type *get_mul_type(const glsl_type *type_a,
@@ -514,6 +520,13 @@ struct glsl_type {
/**
* Query if a type is unnamed/anonymous (named by the parser)
*/
+
+ bool is_subroutine() const
+ {
+ return base_type == GLSL_TYPE_SUBROUTINE;
+ }
+ bool contains_subroutine() const;
+
bool is_anonymous() const
{
return !strncmp(name, "#anon", 5);
@@ -679,6 +692,9 @@ private:
/** Constructor for array types */
glsl_type(const glsl_type *array, unsigned length);
+ /** Constructor for subroutine types */
+ glsl_type(const char *name);
+
/** Hash table containing the known array types. */
static struct hash_table *array_types;
@@ -688,6 +704,9 @@ private:
/** Hash table containing the known interface types. */
static struct hash_table *interface_types;
+ /** Hash table containing the known subroutine types. */
+ static struct hash_table *subroutine_types;
+
static bool record_key_compare(const void *a, const void *b);
static unsigned record_key_hash(const void *key);
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 8fb7ca40cf1..fa1d85a5026 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -260,6 +260,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
case ir_unop_bit_count:
case ir_unop_find_msb:
case ir_unop_find_lsb:
+ case ir_unop_subroutine_to_int:
this->type = glsl_type::get_instance(GLSL_TYPE_INT,
op0->type->vector_elements, 1);
break;
@@ -568,6 +569,7 @@ static const char *const operator_strs[] = {
"frexp_sig",
"frexp_exp",
"noise",
+ "subroutine_to_int",
"interpolate_at_centroid",
"+",
"-",
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 98951221b02..8294b8a19bd 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -1385,6 +1385,7 @@ enum ir_expression_operation {
ir_unop_noise,
+ ir_unop_subroutine_to_int,
/**
* Interpolate fs input at centroid
*
diff --git a/src/glsl/ir_builder.cpp b/src/glsl/ir_builder.cpp
index e44b05c991c..cd03859cac0 100644
--- a/src/glsl/ir_builder.cpp
+++ b/src/glsl/ir_builder.cpp
@@ -338,6 +338,12 @@ sign(operand a)
return expr(ir_unop_sign, a);
}
+ir_expression *
+subr_to_int(operand a)
+{
+ return expr(ir_unop_subroutine_to_int, a);
+}
+
ir_expression*
equal(operand a, operand b)
{
diff --git a/src/glsl/ir_builder.h b/src/glsl/ir_builder.h
index 87026588113..f76453ffcf0 100644
--- a/src/glsl/ir_builder.h
+++ b/src/glsl/ir_builder.h
@@ -153,6 +153,7 @@ ir_expression *sqrt(operand a);
ir_expression *log(operand a);
ir_expression *sign(operand a);
+ir_expression *subr_to_int(operand a);
ir_expression *equal(operand a, operand b);
ir_expression *nequal(operand a, operand b);
ir_expression *less(operand a, operand b);
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 914e0e4d540..49834ffbabf 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -362,6 +362,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_VOID:
case GLSL_TYPE_ERROR:
+ case GLSL_TYPE_SUBROUTINE:
case GLSL_TYPE_INTERFACE:
assert(!"Should not get here.");
break;
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index 684bef28035..3f0dea74e27 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -448,6 +448,10 @@ ir_validate::visit_leave(ir_expression *ir)
ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->type->base_type == GLSL_TYPE_INT);
break;
+ case ir_unop_subroutine_to_int:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_SUBROUTINE);
+ assert(ir->type->base_type == GLSL_TYPE_INT);
+ break;
case ir_binop_add:
case ir_binop_sub:
case ir_binop_mul:
diff --git a/src/glsl/link_uniform_initializers.cpp b/src/glsl/link_uniform_initializers.cpp
index 6322a2d52cc..d61ae91f4ad 100644
--- a/src/glsl/link_uniform_initializers.cpp
+++ b/src/glsl/link_uniform_initializers.cpp
@@ -89,6 +89,7 @@ copy_constant_to_storage(union gl_constant_value *storage,
case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_VOID:
+ case GLSL_TYPE_SUBROUTINE:
case GLSL_TYPE_ERROR:
/* All other types should have already been filtered by other
* paths in the caller.
diff --git a/src/glsl/nir/nir_lower_io.c b/src/glsl/nir/nir_lower_io.c
index a9dd77691b2..f6e5e2beda4 100644
--- a/src/glsl/nir/nir_lower_io.c
+++ b/src/glsl/nir/nir_lower_io.c
@@ -59,6 +59,8 @@ type_size(const struct glsl_type *type)
size += type_size(glsl_get_struct_field(type, i));
}
return size;
+ case GLSL_TYPE_SUBROUTINE:
+ return 1;
case GLSL_TYPE_SAMPLER:
return 0;
case GLSL_TYPE_ATOMIC_UINT:
diff --git a/src/glsl/tests/uniform_initializer_utils.cpp b/src/glsl/tests/uniform_initializer_utils.cpp
index b90bdcaed3b..5006387036f 100644
--- a/src/glsl/tests/uniform_initializer_utils.cpp
+++ b/src/glsl/tests/uniform_initializer_utils.cpp
@@ -102,6 +102,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
case GLSL_TYPE_VOID:
case GLSL_TYPE_ERROR:
case GLSL_TYPE_INTERFACE:
+ case GLSL_TYPE_SUBROUTINE:
ASSERT_TRUE(false);
break;
}
@@ -134,6 +135,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
case GLSL_TYPE_VOID:
case GLSL_TYPE_ERROR:
case GLSL_TYPE_INTERFACE:
+ case GLSL_TYPE_SUBROUTINE:
ASSERT_TRUE(false);
break;
}
@@ -238,6 +240,7 @@ verify_data(gl_constant_value *storage, unsigned storage_array_size,
case GLSL_TYPE_VOID:
case GLSL_TYPE_ERROR:
case GLSL_TYPE_INTERFACE:
+ case GLSL_TYPE_SUBROUTINE:
ASSERT_TRUE(false);
break;
}
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index b0fc6254edb..9553791b07a 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1108,6 +1108,7 @@ type_size(const struct glsl_type *type)
return size;
case GLSL_TYPE_SAMPLER:
case GLSL_TYPE_IMAGE:
+ case GLSL_TYPE_SUBROUTINE:
/* Samplers take up one slot in UNIFORMS[], but they're baked in
* at link time.
*/
@@ -1488,6 +1489,9 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
result_src = op[0];
}
break;
+ case ir_unop_subroutine_to_int:
+ emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
+ break;
case ir_unop_abs:
emit_asm(ir, TGSI_OPCODE_ABS, result_dst, op[0]);
break;