glsl/types: add new subroutine type (v3.2)
This type will be used to store the name of subroutine types as in subroutine void myfunc(void); will store myfunc into a subroutine type. This is required to the parser can identify a subroutine type in a uniform decleration as a valid type, and also for looking up the type later. Also add contains_subroutine method. v2: handle subroutine to int comparisons, needed for lowering pass. v3: do subroutine to int with it's own IR operation to avoid hacking on asserts (Kayden) v3.1: fix warnings in this patch, fix nir, fix tgsi v3.2: fixup tests Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Chris Forbes <chrisf@ijw.co.nz> Signed-off-by: Dave Airlie <airlied@redhat.com> tests: fix warnings
This commit is contained in:
@@ -1019,6 +1019,7 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
|
|||||||
case GLSL_TYPE_IMAGE:
|
case GLSL_TYPE_IMAGE:
|
||||||
case GLSL_TYPE_INTERFACE:
|
case GLSL_TYPE_INTERFACE:
|
||||||
case GLSL_TYPE_ATOMIC_UINT:
|
case GLSL_TYPE_ATOMIC_UINT:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
/* I assume a comparison of a struct containing a sampler just
|
/* I assume a comparison of a struct containing a sampler just
|
||||||
* ignores the sampler present in the type.
|
* ignores the sampler present in the type.
|
||||||
*/
|
*/
|
||||||
|
@@ -32,6 +32,7 @@ mtx_t glsl_type::mutex = _MTX_INITIALIZER_NP;
|
|||||||
hash_table *glsl_type::array_types = NULL;
|
hash_table *glsl_type::array_types = NULL;
|
||||||
hash_table *glsl_type::record_types = NULL;
|
hash_table *glsl_type::record_types = NULL;
|
||||||
hash_table *glsl_type::interface_types = NULL;
|
hash_table *glsl_type::interface_types = NULL;
|
||||||
|
hash_table *glsl_type::subroutine_types = NULL;
|
||||||
void *glsl_type::mem_ctx = NULL;
|
void *glsl_type::mem_ctx = NULL;
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -161,6 +162,22 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
|||||||
mtx_unlock(&glsl_type::mutex);
|
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
|
bool
|
||||||
glsl_type::contains_sampler() const
|
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
|
gl_texture_index
|
||||||
glsl_type::sampler_index() const
|
glsl_type::sampler_index() const
|
||||||
{
|
{
|
||||||
@@ -836,6 +869,36 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
|
|||||||
return (glsl_type *) entry->data;
|
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 *
|
const glsl_type *
|
||||||
glsl_type::get_mul_type(const glsl_type *type_a, const glsl_type *type_b)
|
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_SAMPLER:
|
||||||
case GLSL_TYPE_ATOMIC_UINT:
|
case GLSL_TYPE_ATOMIC_UINT:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -988,6 +1052,7 @@ glsl_type::uniform_locations() const
|
|||||||
case GLSL_TYPE_BOOL:
|
case GLSL_TYPE_BOOL:
|
||||||
case GLSL_TYPE_SAMPLER:
|
case GLSL_TYPE_SAMPLER:
|
||||||
case GLSL_TYPE_IMAGE:
|
case GLSL_TYPE_IMAGE:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case GLSL_TYPE_STRUCT:
|
case GLSL_TYPE_STRUCT:
|
||||||
@@ -1341,6 +1406,7 @@ glsl_type::count_attribute_slots() const
|
|||||||
case GLSL_TYPE_IMAGE:
|
case GLSL_TYPE_IMAGE:
|
||||||
case GLSL_TYPE_ATOMIC_UINT:
|
case GLSL_TYPE_ATOMIC_UINT:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -59,6 +59,7 @@ enum glsl_base_type {
|
|||||||
GLSL_TYPE_INTERFACE,
|
GLSL_TYPE_INTERFACE,
|
||||||
GLSL_TYPE_ARRAY,
|
GLSL_TYPE_ARRAY,
|
||||||
GLSL_TYPE_VOID,
|
GLSL_TYPE_VOID,
|
||||||
|
GLSL_TYPE_SUBROUTINE,
|
||||||
GLSL_TYPE_ERROR
|
GLSL_TYPE_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -263,6 +264,11 @@ struct glsl_type {
|
|||||||
enum glsl_interface_packing packing,
|
enum glsl_interface_packing packing,
|
||||||
const char *block_name);
|
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
|
* Get the type resulting from a multiplication of \p type_a * \p type_b
|
||||||
*/
|
*/
|
||||||
@@ -514,6 +520,13 @@ struct glsl_type {
|
|||||||
/**
|
/**
|
||||||
* Query if a type is unnamed/anonymous (named by the parser)
|
* 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
|
bool is_anonymous() const
|
||||||
{
|
{
|
||||||
return !strncmp(name, "#anon", 5);
|
return !strncmp(name, "#anon", 5);
|
||||||
@@ -679,6 +692,9 @@ private:
|
|||||||
/** Constructor for array types */
|
/** Constructor for array types */
|
||||||
glsl_type(const glsl_type *array, unsigned length);
|
glsl_type(const glsl_type *array, unsigned length);
|
||||||
|
|
||||||
|
/** Constructor for subroutine types */
|
||||||
|
glsl_type(const char *name);
|
||||||
|
|
||||||
/** Hash table containing the known array types. */
|
/** Hash table containing the known array types. */
|
||||||
static struct hash_table *array_types;
|
static struct hash_table *array_types;
|
||||||
|
|
||||||
@@ -688,6 +704,9 @@ private:
|
|||||||
/** Hash table containing the known interface types. */
|
/** Hash table containing the known interface types. */
|
||||||
static struct hash_table *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 bool record_key_compare(const void *a, const void *b);
|
||||||
static unsigned record_key_hash(const void *key);
|
static unsigned record_key_hash(const void *key);
|
||||||
|
|
||||||
|
@@ -260,6 +260,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
|
|||||||
case ir_unop_bit_count:
|
case ir_unop_bit_count:
|
||||||
case ir_unop_find_msb:
|
case ir_unop_find_msb:
|
||||||
case ir_unop_find_lsb:
|
case ir_unop_find_lsb:
|
||||||
|
case ir_unop_subroutine_to_int:
|
||||||
this->type = glsl_type::get_instance(GLSL_TYPE_INT,
|
this->type = glsl_type::get_instance(GLSL_TYPE_INT,
|
||||||
op0->type->vector_elements, 1);
|
op0->type->vector_elements, 1);
|
||||||
break;
|
break;
|
||||||
@@ -568,6 +569,7 @@ static const char *const operator_strs[] = {
|
|||||||
"frexp_sig",
|
"frexp_sig",
|
||||||
"frexp_exp",
|
"frexp_exp",
|
||||||
"noise",
|
"noise",
|
||||||
|
"subroutine_to_int",
|
||||||
"interpolate_at_centroid",
|
"interpolate_at_centroid",
|
||||||
"+",
|
"+",
|
||||||
"-",
|
"-",
|
||||||
|
@@ -1385,6 +1385,7 @@ enum ir_expression_operation {
|
|||||||
|
|
||||||
ir_unop_noise,
|
ir_unop_noise,
|
||||||
|
|
||||||
|
ir_unop_subroutine_to_int,
|
||||||
/**
|
/**
|
||||||
* Interpolate fs input at centroid
|
* Interpolate fs input at centroid
|
||||||
*
|
*
|
||||||
|
@@ -338,6 +338,12 @@ sign(operand a)
|
|||||||
return expr(ir_unop_sign, a);
|
return expr(ir_unop_sign, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ir_expression *
|
||||||
|
subr_to_int(operand a)
|
||||||
|
{
|
||||||
|
return expr(ir_unop_subroutine_to_int, a);
|
||||||
|
}
|
||||||
|
|
||||||
ir_expression*
|
ir_expression*
|
||||||
equal(operand a, operand b)
|
equal(operand a, operand b)
|
||||||
{
|
{
|
||||||
|
@@ -153,6 +153,7 @@ ir_expression *sqrt(operand a);
|
|||||||
ir_expression *log(operand a);
|
ir_expression *log(operand a);
|
||||||
ir_expression *sign(operand a);
|
ir_expression *sign(operand a);
|
||||||
|
|
||||||
|
ir_expression *subr_to_int(operand a);
|
||||||
ir_expression *equal(operand a, operand b);
|
ir_expression *equal(operand a, operand b);
|
||||||
ir_expression *nequal(operand a, operand b);
|
ir_expression *nequal(operand a, operand b);
|
||||||
ir_expression *less(operand a, operand b);
|
ir_expression *less(operand a, operand b);
|
||||||
|
@@ -362,6 +362,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
|
|||||||
case GLSL_TYPE_ATOMIC_UINT:
|
case GLSL_TYPE_ATOMIC_UINT:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
case GLSL_TYPE_INTERFACE:
|
case GLSL_TYPE_INTERFACE:
|
||||||
assert(!"Should not get here.");
|
assert(!"Should not get here.");
|
||||||
break;
|
break;
|
||||||
|
@@ -448,6 +448,10 @@ ir_validate::visit_leave(ir_expression *ir)
|
|||||||
ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
|
ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
|
||||||
assert(ir->type->base_type == GLSL_TYPE_INT);
|
assert(ir->type->base_type == GLSL_TYPE_INT);
|
||||||
break;
|
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_add:
|
||||||
case ir_binop_sub:
|
case ir_binop_sub:
|
||||||
case ir_binop_mul:
|
case ir_binop_mul:
|
||||||
|
@@ -89,6 +89,7 @@ copy_constant_to_storage(union gl_constant_value *storage,
|
|||||||
case GLSL_TYPE_ATOMIC_UINT:
|
case GLSL_TYPE_ATOMIC_UINT:
|
||||||
case GLSL_TYPE_INTERFACE:
|
case GLSL_TYPE_INTERFACE:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
/* All other types should have already been filtered by other
|
/* All other types should have already been filtered by other
|
||||||
* paths in the caller.
|
* paths in the caller.
|
||||||
|
@@ -59,6 +59,8 @@ type_size(const struct glsl_type *type)
|
|||||||
size += type_size(glsl_get_struct_field(type, i));
|
size += type_size(glsl_get_struct_field(type, i));
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
|
return 1;
|
||||||
case GLSL_TYPE_SAMPLER:
|
case GLSL_TYPE_SAMPLER:
|
||||||
return 0;
|
return 0;
|
||||||
case GLSL_TYPE_ATOMIC_UINT:
|
case GLSL_TYPE_ATOMIC_UINT:
|
||||||
|
@@ -102,6 +102,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
|
|||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
case GLSL_TYPE_INTERFACE:
|
case GLSL_TYPE_INTERFACE:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
ASSERT_TRUE(false);
|
ASSERT_TRUE(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -134,6 +135,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
|
|||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
case GLSL_TYPE_INTERFACE:
|
case GLSL_TYPE_INTERFACE:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
ASSERT_TRUE(false);
|
ASSERT_TRUE(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -238,6 +240,7 @@ verify_data(gl_constant_value *storage, unsigned storage_array_size,
|
|||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
case GLSL_TYPE_INTERFACE:
|
case GLSL_TYPE_INTERFACE:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
ASSERT_TRUE(false);
|
ASSERT_TRUE(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -1108,6 +1108,7 @@ type_size(const struct glsl_type *type)
|
|||||||
return size;
|
return size;
|
||||||
case GLSL_TYPE_SAMPLER:
|
case GLSL_TYPE_SAMPLER:
|
||||||
case GLSL_TYPE_IMAGE:
|
case GLSL_TYPE_IMAGE:
|
||||||
|
case GLSL_TYPE_SUBROUTINE:
|
||||||
/* Samplers take up one slot in UNIFORMS[], but they're baked in
|
/* Samplers take up one slot in UNIFORMS[], but they're baked in
|
||||||
* at link time.
|
* at link time.
|
||||||
*/
|
*/
|
||||||
@@ -1488,6 +1489,9 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
|
|||||||
result_src = op[0];
|
result_src = op[0];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ir_unop_subroutine_to_int:
|
||||||
|
emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
|
||||||
|
break;
|
||||||
case ir_unop_abs:
|
case ir_unop_abs:
|
||||||
emit_asm(ir, TGSI_OPCODE_ABS, result_dst, op[0]);
|
emit_asm(ir, TGSI_OPCODE_ABS, result_dst, op[0]);
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user