mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 20:00:10 +01:00
glsl: add packed for struct types
We need this for OpenCL kernels because we have to apply C rules for alignment and padding inside structs and for this we also have to know if a struct is packed or not. v2: fix for kernel params Signed-off-by: Karol Herbst <kherbst@redhat.com> Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
This commit is contained in:
parent
b98955e128
commit
659f333b3a
6 changed files with 49 additions and 12 deletions
|
|
@ -94,11 +94,11 @@ glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
||||||
const char *name) :
|
const char *name, bool packed) :
|
||||||
gl_type(0),
|
gl_type(0),
|
||||||
base_type(GLSL_TYPE_STRUCT), sampled_type(GLSL_TYPE_VOID),
|
base_type(GLSL_TYPE_STRUCT), sampled_type(GLSL_TYPE_VOID),
|
||||||
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
|
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
|
||||||
interface_packing(0), interface_row_major(0),
|
interface_packing(0), interface_row_major(0), packed(packed),
|
||||||
vector_elements(0), matrix_columns(0),
|
vector_elements(0), matrix_columns(0),
|
||||||
length(num_fields), explicit_stride(0)
|
length(num_fields), explicit_stride(0)
|
||||||
{
|
{
|
||||||
|
|
@ -1129,9 +1129,10 @@ glsl_type::record_key_hash(const void *a)
|
||||||
const glsl_type *
|
const glsl_type *
|
||||||
glsl_type::get_struct_instance(const glsl_struct_field *fields,
|
glsl_type::get_struct_instance(const glsl_struct_field *fields,
|
||||||
unsigned num_fields,
|
unsigned num_fields,
|
||||||
const char *name)
|
const char *name,
|
||||||
|
bool packed)
|
||||||
{
|
{
|
||||||
const glsl_type key(fields, num_fields, name);
|
const glsl_type key(fields, num_fields, name, packed);
|
||||||
|
|
||||||
mtx_lock(&glsl_type::hash_mutex);
|
mtx_lock(&glsl_type::hash_mutex);
|
||||||
|
|
||||||
|
|
@ -1143,7 +1144,7 @@ glsl_type::get_struct_instance(const glsl_struct_field *fields,
|
||||||
const struct hash_entry *entry = _mesa_hash_table_search(struct_types,
|
const struct hash_entry *entry = _mesa_hash_table_search(struct_types,
|
||||||
&key);
|
&key);
|
||||||
if (entry == NULL) {
|
if (entry == NULL) {
|
||||||
const glsl_type *t = new glsl_type(fields, num_fields, name);
|
const glsl_type *t = new glsl_type(fields, num_fields, name, packed);
|
||||||
|
|
||||||
entry = _mesa_hash_table_insert(struct_types, t, (void *) t);
|
entry = _mesa_hash_table_insert(struct_types, t, (void *) t);
|
||||||
}
|
}
|
||||||
|
|
@ -1151,6 +1152,7 @@ glsl_type::get_struct_instance(const glsl_struct_field *fields,
|
||||||
assert(((glsl_type *) entry->data)->base_type == GLSL_TYPE_STRUCT);
|
assert(((glsl_type *) entry->data)->base_type == GLSL_TYPE_STRUCT);
|
||||||
assert(((glsl_type *) entry->data)->length == num_fields);
|
assert(((glsl_type *) entry->data)->length == num_fields);
|
||||||
assert(strcmp(((glsl_type *) entry->data)->name, name) == 0);
|
assert(strcmp(((glsl_type *) entry->data)->name, name) == 0);
|
||||||
|
assert(((glsl_type *) entry->data)->packed == packed);
|
||||||
|
|
||||||
mtx_unlock(&glsl_type::hash_mutex);
|
mtx_unlock(&glsl_type::hash_mutex);
|
||||||
|
|
||||||
|
|
@ -2447,6 +2449,8 @@ encode_type_to_blob(struct blob *blob, const glsl_type *type)
|
||||||
if (type->is_interface()) {
|
if (type->is_interface()) {
|
||||||
blob_write_uint32(blob, type->interface_packing);
|
blob_write_uint32(blob, type->interface_packing);
|
||||||
blob_write_uint32(blob, type->interface_row_major);
|
blob_write_uint32(blob, type->interface_row_major);
|
||||||
|
} else {
|
||||||
|
blob_write_uint32(blob, type->packed);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case GLSL_TYPE_VOID:
|
case GLSL_TYPE_VOID:
|
||||||
|
|
@ -2535,7 +2539,8 @@ decode_type_from_blob(struct blob_reader *blob)
|
||||||
t = glsl_type::get_interface_instance(fields, num_fields, packing,
|
t = glsl_type::get_interface_instance(fields, num_fields, packing,
|
||||||
row_major, name);
|
row_major, name);
|
||||||
} else {
|
} else {
|
||||||
t = glsl_type::get_struct_instance(fields, num_fields, name);
|
unsigned packed = blob_read_uint32(blob);
|
||||||
|
t = glsl_type::get_struct_instance(fields, num_fields, name, packed);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(fields);
|
free(fields);
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,13 @@ struct glsl_type {
|
||||||
unsigned interface_packing:2;
|
unsigned interface_packing:2;
|
||||||
unsigned interface_row_major:1;
|
unsigned interface_row_major:1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For \c GLSL_TYPE_STRUCT this specifies if the struct is packed or not.
|
||||||
|
*
|
||||||
|
* Only used for Compute kernels
|
||||||
|
*/
|
||||||
|
unsigned packed:1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glsl_type() : mem_ctx(NULL)
|
glsl_type() : mem_ctx(NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -314,7 +321,8 @@ public:
|
||||||
*/
|
*/
|
||||||
static const glsl_type *get_struct_instance(const glsl_struct_field *fields,
|
static const glsl_type *get_struct_instance(const glsl_struct_field *fields,
|
||||||
unsigned num_fields,
|
unsigned num_fields,
|
||||||
const char *name);
|
const char *name,
|
||||||
|
bool packed = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the instance of an interface block type
|
* Get the instance of an interface block type
|
||||||
|
|
@ -946,7 +954,7 @@ private:
|
||||||
|
|
||||||
/** Constructor for record types */
|
/** Constructor for record types */
|
||||||
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, bool packed = false);
|
||||||
|
|
||||||
/** Constructor for interface types */
|
/** Constructor for interface types */
|
||||||
glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
||||||
|
|
|
||||||
|
|
@ -510,9 +510,10 @@ glsl_array_type(const glsl_type *base, unsigned elements,
|
||||||
|
|
||||||
const glsl_type *
|
const glsl_type *
|
||||||
glsl_struct_type(const glsl_struct_field *fields,
|
glsl_struct_type(const glsl_struct_field *fields,
|
||||||
unsigned num_fields, const char *name)
|
unsigned num_fields, const char *name,
|
||||||
|
bool packed)
|
||||||
{
|
{
|
||||||
return glsl_type::get_struct_instance(fields, num_fields, name);
|
return glsl_type::get_struct_instance(fields, num_fields, name, packed);
|
||||||
}
|
}
|
||||||
|
|
||||||
const glsl_type *
|
const glsl_type *
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,8 @@ const struct glsl_type *glsl_array_type(const struct glsl_type *base,
|
||||||
unsigned explicit_stride);
|
unsigned explicit_stride);
|
||||||
|
|
||||||
const struct glsl_type *glsl_struct_type(const struct glsl_struct_field *fields,
|
const struct glsl_type *glsl_struct_type(const struct glsl_struct_field *fields,
|
||||||
unsigned num_fields, const char *name);
|
unsigned num_fields, const char *name,
|
||||||
|
bool packed);
|
||||||
const struct glsl_type *glsl_interface_type(const struct glsl_struct_field *fields,
|
const struct glsl_type *glsl_interface_type(const struct glsl_struct_field *fields,
|
||||||
unsigned num_fields,
|
unsigned num_fields,
|
||||||
enum glsl_interface_packing packing,
|
enum glsl_interface_packing packing,
|
||||||
|
|
|
||||||
|
|
@ -819,6 +819,13 @@ struct_member_decoration_cb(struct vtn_builder *b,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SpvDecorationCPacked:
|
case SpvDecorationCPacked:
|
||||||
|
if (b->shader->info.stage != MESA_SHADER_KERNEL)
|
||||||
|
vtn_warn("Decoration only allowed for CL-style kernels: %s",
|
||||||
|
spirv_decoration_to_string(dec->decoration));
|
||||||
|
else
|
||||||
|
ctx->type->packed = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case SpvDecorationSaturatedConversion:
|
case SpvDecorationSaturatedConversion:
|
||||||
case SpvDecorationFuncParamAttr:
|
case SpvDecorationFuncParamAttr:
|
||||||
case SpvDecorationFPRoundingMode:
|
case SpvDecorationFPRoundingMode:
|
||||||
|
|
@ -979,6 +986,13 @@ type_decoration_cb(struct vtn_builder *b,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SpvDecorationCPacked:
|
case SpvDecorationCPacked:
|
||||||
|
if (b->shader->info.stage != MESA_SHADER_KERNEL)
|
||||||
|
vtn_warn("Decoration only allowed for CL-style kernels: %s",
|
||||||
|
spirv_decoration_to_string(dec->decoration));
|
||||||
|
else
|
||||||
|
type->packed = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case SpvDecorationSaturatedConversion:
|
case SpvDecorationSaturatedConversion:
|
||||||
case SpvDecorationFuncParamAttr:
|
case SpvDecorationFuncParamAttr:
|
||||||
case SpvDecorationFPRoundingMode:
|
case SpvDecorationFPRoundingMode:
|
||||||
|
|
@ -1242,6 +1256,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
||||||
val->type->length = num_fields;
|
val->type->length = num_fields;
|
||||||
val->type->members = ralloc_array(b, struct vtn_type *, num_fields);
|
val->type->members = ralloc_array(b, struct vtn_type *, num_fields);
|
||||||
val->type->offsets = ralloc_array(b, unsigned, num_fields);
|
val->type->offsets = ralloc_array(b, unsigned, num_fields);
|
||||||
|
val->type->packed = false;
|
||||||
|
|
||||||
NIR_VLA(struct glsl_struct_field, fields, count);
|
NIR_VLA(struct glsl_struct_field, fields, count);
|
||||||
for (unsigned i = 0; i < num_fields; i++) {
|
for (unsigned i = 0; i < num_fields; i++) {
|
||||||
|
|
@ -1266,7 +1281,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
||||||
|
|
||||||
const char *name = val->name ? val->name : "struct";
|
const char *name = val->name ? val->name : "struct";
|
||||||
|
|
||||||
val->type->type = glsl_struct_type(fields, num_fields, name);
|
val->type->type = glsl_struct_type(fields, num_fields, name, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -335,6 +335,13 @@ struct vtn_type {
|
||||||
* (i.e. a block that contains only builtins).
|
* (i.e. a block that contains only builtins).
|
||||||
*/
|
*/
|
||||||
bool builtin_block:1;
|
bool builtin_block:1;
|
||||||
|
|
||||||
|
/* for structs and unions it specifies the minimum alignment of the
|
||||||
|
* members. 0 means packed.
|
||||||
|
*
|
||||||
|
* Set by CPacked and Alignment Decorations in kernels.
|
||||||
|
*/
|
||||||
|
bool packed:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Members for pointer types */
|
/* Members for pointer types */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue