glsl: Add GLSL_TYPE_INTERFACE
Interfaces are structurally identical to structures from the compiler's point of view. They have some additional restrictions, and generally GPUs use different instructions to access them. Using a different base type should make this a bit easier. This commit also adds the glsl_type::interface_packing fields. For GLSL_TYPE_INTERFACE types, this will track the specified packing mode. It is analogous to gl_uniform_buffer::_Packing. v2: Add serveral missing GLSL_TYPE_INTERFACE cases in switch-statements. v3: Add information about glsl_type::interface_packing. Move row_major checking in glsl_type::record_key_compare from this patch to the previous patch. Both suggested by Paul Berry. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Paul Berry <stereotype441@gmail.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -857,6 +857,7 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
|
|||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_SAMPLER:
|
case GLSL_TYPE_SAMPLER:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
/* 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.
|
||||||
*/
|
*/
|
||||||
|
@@ -34,6 +34,7 @@ extern "C" {
|
|||||||
|
|
||||||
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;
|
||||||
void *glsl_type::mem_ctx = NULL;
|
void *glsl_type::mem_ctx = NULL;
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -51,7 +52,7 @@ glsl_type::glsl_type(GLenum gl_type,
|
|||||||
gl_type(gl_type),
|
gl_type(gl_type),
|
||||||
base_type(base_type),
|
base_type(base_type),
|
||||||
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
|
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
|
||||||
sampler_type(0),
|
sampler_type(0), interface_packing(0),
|
||||||
vector_elements(vector_elements), matrix_columns(matrix_columns),
|
vector_elements(vector_elements), matrix_columns(matrix_columns),
|
||||||
length(0)
|
length(0)
|
||||||
{
|
{
|
||||||
@@ -69,7 +70,7 @@ glsl_type::glsl_type(GLenum gl_type,
|
|||||||
gl_type(gl_type),
|
gl_type(gl_type),
|
||||||
base_type(GLSL_TYPE_SAMPLER),
|
base_type(GLSL_TYPE_SAMPLER),
|
||||||
sampler_dimensionality(dim), sampler_shadow(shadow),
|
sampler_dimensionality(dim), sampler_shadow(shadow),
|
||||||
sampler_array(array), sampler_type(type),
|
sampler_array(array), sampler_type(type), interface_packing(0),
|
||||||
vector_elements(0), matrix_columns(0),
|
vector_elements(0), matrix_columns(0),
|
||||||
length(0)
|
length(0)
|
||||||
{
|
{
|
||||||
@@ -82,7 +83,29 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
|||||||
const char *name) :
|
const char *name) :
|
||||||
base_type(GLSL_TYPE_STRUCT),
|
base_type(GLSL_TYPE_STRUCT),
|
||||||
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
|
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
|
||||||
sampler_type(0),
|
sampler_type(0), interface_packing(0),
|
||||||
|
vector_elements(0), matrix_columns(0),
|
||||||
|
length(num_fields)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
init_ralloc_type_ctx();
|
||||||
|
this->name = ralloc_strdup(this->mem_ctx, name);
|
||||||
|
this->fields.structure = ralloc_array(this->mem_ctx,
|
||||||
|
glsl_struct_field, length);
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
this->fields.structure[i].type = fields[i].type;
|
||||||
|
this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
|
||||||
|
fields[i].name);
|
||||||
|
this->fields.structure[i].row_major = fields[i].row_major;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
||||||
|
enum glsl_interface_packing packing, const char *name) :
|
||||||
|
base_type(GLSL_TYPE_INTERFACE),
|
||||||
|
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
|
||||||
|
sampler_type(0), interface_packing((unsigned) packing),
|
||||||
vector_elements(0), matrix_columns(0),
|
vector_elements(0), matrix_columns(0),
|
||||||
length(num_fields)
|
length(num_fields)
|
||||||
{
|
{
|
||||||
@@ -430,7 +453,7 @@ _mesa_glsl_release_types(void)
|
|||||||
glsl_type::glsl_type(const glsl_type *array, unsigned length) :
|
glsl_type::glsl_type(const glsl_type *array, unsigned length) :
|
||||||
base_type(GLSL_TYPE_ARRAY),
|
base_type(GLSL_TYPE_ARRAY),
|
||||||
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
|
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
|
||||||
sampler_type(0),
|
sampler_type(0), interface_packing(0),
|
||||||
vector_elements(0), matrix_columns(0),
|
vector_elements(0), matrix_columns(0),
|
||||||
name(NULL), length(length)
|
name(NULL), length(length)
|
||||||
{
|
{
|
||||||
@@ -562,6 +585,9 @@ glsl_type::record_key_compare(const void *a, const void *b)
|
|||||||
if (key1->length != key2->length)
|
if (key1->length != key2->length)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (key1->interface_packing != key2->interface_packing)
|
||||||
|
return 1;
|
||||||
|
|
||||||
for (unsigned i = 0; i < key1->length; i++) {
|
for (unsigned i = 0; i < key1->length; i++) {
|
||||||
if (key1->fields.structure[i].type != key2->fields.structure[i].type)
|
if (key1->fields.structure[i].type != key2->fields.structure[i].type)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -624,10 +650,38 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const glsl_type *
|
||||||
|
glsl_type::get_interface_instance(const glsl_struct_field *fields,
|
||||||
|
unsigned num_fields,
|
||||||
|
enum glsl_interface_packing packing,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
const glsl_type key(fields, num_fields, packing, name);
|
||||||
|
|
||||||
|
if (interface_types == NULL) {
|
||||||
|
interface_types = hash_table_ctor(64, record_key_hash, record_key_compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
const glsl_type *t = (glsl_type *) hash_table_find(interface_types, & key);
|
||||||
|
if (t == NULL) {
|
||||||
|
t = new glsl_type(fields, num_fields, packing, name);
|
||||||
|
|
||||||
|
hash_table_insert(interface_types, (void *) t, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(t->base_type == GLSL_TYPE_INTERFACE);
|
||||||
|
assert(t->length == num_fields);
|
||||||
|
assert(strcmp(t->name, name) == 0);
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const glsl_type *
|
const glsl_type *
|
||||||
glsl_type::field_type(const char *name) const
|
glsl_type::field_type(const char *name) const
|
||||||
{
|
{
|
||||||
if (this->base_type != GLSL_TYPE_STRUCT)
|
if (this->base_type != GLSL_TYPE_STRUCT
|
||||||
|
&& this->base_type != GLSL_TYPE_INTERFACE)
|
||||||
return error_type;
|
return error_type;
|
||||||
|
|
||||||
for (unsigned i = 0; i < this->length; i++) {
|
for (unsigned i = 0; i < this->length; i++) {
|
||||||
@@ -642,7 +696,8 @@ glsl_type::field_type(const char *name) const
|
|||||||
int
|
int
|
||||||
glsl_type::field_index(const char *name) const
|
glsl_type::field_index(const char *name) const
|
||||||
{
|
{
|
||||||
if (this->base_type != GLSL_TYPE_STRUCT)
|
if (this->base_type != GLSL_TYPE_STRUCT
|
||||||
|
&& this->base_type != GLSL_TYPE_INTERFACE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (unsigned i = 0; i < this->length; i++) {
|
for (unsigned i = 0; i < this->length; i++) {
|
||||||
@@ -664,7 +719,8 @@ glsl_type::component_slots() const
|
|||||||
case GLSL_TYPE_BOOL:
|
case GLSL_TYPE_BOOL:
|
||||||
return this->components();
|
return this->components();
|
||||||
|
|
||||||
case GLSL_TYPE_STRUCT: {
|
case GLSL_TYPE_STRUCT:
|
||||||
|
case GLSL_TYPE_INTERFACE: {
|
||||||
unsigned size = 0;
|
unsigned size = 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < this->length; i++)
|
for (unsigned i = 0; i < this->length; i++)
|
||||||
|
@@ -54,6 +54,7 @@ enum glsl_base_type {
|
|||||||
GLSL_TYPE_BOOL,
|
GLSL_TYPE_BOOL,
|
||||||
GLSL_TYPE_SAMPLER,
|
GLSL_TYPE_SAMPLER,
|
||||||
GLSL_TYPE_STRUCT,
|
GLSL_TYPE_STRUCT,
|
||||||
|
GLSL_TYPE_INTERFACE,
|
||||||
GLSL_TYPE_ARRAY,
|
GLSL_TYPE_ARRAY,
|
||||||
GLSL_TYPE_VOID,
|
GLSL_TYPE_VOID,
|
||||||
GLSL_TYPE_ERROR
|
GLSL_TYPE_ERROR
|
||||||
@@ -69,6 +70,12 @@ enum glsl_sampler_dim {
|
|||||||
GLSL_SAMPLER_DIM_EXTERNAL
|
GLSL_SAMPLER_DIM_EXTERNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum glsl_interface_packing {
|
||||||
|
GLSL_INTERFACE_PACKING_STD140,
|
||||||
|
GLSL_INTERFACE_PACKING_SHARED,
|
||||||
|
GLSL_INTERFACE_PACKING_PACKED
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#include "GL/gl.h"
|
#include "GL/gl.h"
|
||||||
#include "ralloc.h"
|
#include "ralloc.h"
|
||||||
@@ -84,6 +91,7 @@ struct glsl_type {
|
|||||||
* only \c GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT,
|
* only \c GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT,
|
||||||
* and \c GLSL_TYPE_UINT are valid.
|
* and \c GLSL_TYPE_UINT are valid.
|
||||||
*/
|
*/
|
||||||
|
unsigned interface_packing:2;
|
||||||
|
|
||||||
/* Callers of this ralloc-based new need not call delete. It's
|
/* Callers of this ralloc-based new need not call delete. It's
|
||||||
* easier to just ralloc_free 'mem_ctx' (or any of its ancestors). */
|
* easier to just ralloc_free 'mem_ctx' (or any of its ancestors). */
|
||||||
@@ -130,8 +138,9 @@ struct glsl_type {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* For \c GLSL_TYPE_ARRAY, this is the length of the array. For
|
* For \c GLSL_TYPE_ARRAY, this is the length of the array. For
|
||||||
* \c GLSL_TYPE_STRUCT, it is the number of elements in the structure and
|
* \c GLSL_TYPE_STRUCT or \c GLSL_TYPE_INTERFACE, it is the number of
|
||||||
* the number of values pointed to by \c fields.structure (below).
|
* elements in the structure and the number of values pointed to by
|
||||||
|
* \c fields.structure (below).
|
||||||
*/
|
*/
|
||||||
unsigned length;
|
unsigned length;
|
||||||
|
|
||||||
@@ -231,6 +240,14 @@ struct glsl_type {
|
|||||||
unsigned num_fields,
|
unsigned num_fields,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the instance of an interface block type
|
||||||
|
*/
|
||||||
|
static const glsl_type *get_interface_instance(const glsl_struct_field *fields,
|
||||||
|
unsigned num_fields,
|
||||||
|
enum glsl_interface_packing packing,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query the total number of scalars that make up a scalar, vector or matrix
|
* Query the total number of scalars that make up a scalar, vector or matrix
|
||||||
*/
|
*/
|
||||||
@@ -393,6 +410,14 @@ struct glsl_type {
|
|||||||
return base_type == GLSL_TYPE_STRUCT;
|
return base_type == GLSL_TYPE_STRUCT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query whether or not a type is an interface
|
||||||
|
*/
|
||||||
|
bool is_interface() const
|
||||||
|
{
|
||||||
|
return base_type == GLSL_TYPE_INTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query whether or not a type is the void type singleton.
|
* Query whether or not a type is the void type singleton.
|
||||||
*/
|
*/
|
||||||
@@ -491,6 +516,10 @@ private:
|
|||||||
glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
|
/** Constructor for interface types */
|
||||||
|
glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
||||||
|
enum glsl_interface_packing packing, const char *name);
|
||||||
|
|
||||||
/** Constructor for array types */
|
/** Constructor for array types */
|
||||||
glsl_type(const glsl_type *array, unsigned length);
|
glsl_type(const glsl_type *array, unsigned length);
|
||||||
|
|
||||||
@@ -500,6 +529,9 @@ private:
|
|||||||
/** Hash table containing the known record types. */
|
/** Hash table containing the known record types. */
|
||||||
static struct hash_table *record_types;
|
static struct hash_table *record_types;
|
||||||
|
|
||||||
|
/** Hash table containing the known interface types. */
|
||||||
|
static struct hash_table *interface_types;
|
||||||
|
|
||||||
static int record_key_compare(const void *a, const void *b);
|
static int 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);
|
||||||
|
|
||||||
|
@@ -378,6 +378,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
|
|||||||
case GLSL_TYPE_SAMPLER:
|
case GLSL_TYPE_SAMPLER:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
assert(!"Should not get here.");
|
assert(!"Should not get here.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -69,6 +69,7 @@ copy_constant_to_storage(union gl_constant_value *storage,
|
|||||||
break;
|
break;
|
||||||
case GLSL_TYPE_ARRAY:
|
case GLSL_TYPE_ARRAY:
|
||||||
case GLSL_TYPE_STRUCT:
|
case GLSL_TYPE_STRUCT:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
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
|
||||||
|
@@ -96,6 +96,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
|
|||||||
case GLSL_TYPE_ARRAY:
|
case GLSL_TYPE_ARRAY:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
ASSERT_TRUE(false);
|
ASSERT_TRUE(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -122,6 +123,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
|
|||||||
case GLSL_TYPE_ARRAY:
|
case GLSL_TYPE_ARRAY:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
ASSERT_TRUE(false);
|
ASSERT_TRUE(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -219,6 +221,7 @@ verify_data(gl_constant_value *storage, unsigned storage_array_size,
|
|||||||
case GLSL_TYPE_ARRAY:
|
case GLSL_TYPE_ARRAY:
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
ASSERT_TRUE(false);
|
ASSERT_TRUE(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -457,6 +457,7 @@ fs_visitor::type_size(const struct glsl_type *type)
|
|||||||
return 0;
|
return 0;
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
assert(!"not reached");
|
assert(!"not reached");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -700,6 +700,7 @@ fs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r,
|
|||||||
|
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
assert(!"not reached");
|
assert(!"not reached");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -287,6 +287,7 @@ brw_type_for_base_type(const struct glsl_type *type)
|
|||||||
return BRW_REGISTER_TYPE_UD;
|
return BRW_REGISTER_TYPE_UD;
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
assert(!"not reached");
|
assert(!"not reached");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -511,6 +511,7 @@ type_size(const struct glsl_type *type)
|
|||||||
return 1;
|
return 1;
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -625,6 +625,7 @@ type_size(const struct glsl_type *type)
|
|||||||
return 1;
|
return 1;
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
assert(!"Invalid type in type_size");
|
assert(!"Invalid type in type_size");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2536,6 +2537,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
|
|||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
case GLSL_TYPE_STRUCT:
|
case GLSL_TYPE_STRUCT:
|
||||||
case GLSL_TYPE_ERROR:
|
case GLSL_TYPE_ERROR:
|
||||||
|
case GLSL_TYPE_INTERFACE:
|
||||||
assert(!"Should not get here.");
|
assert(!"Should not get here.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user