vkd3d-shader/fx: Introduce write_var_type().

This commit is contained in:
Anna (navi) Figueiredo Gomes
2025-11-16 21:06:25 +01:00
committed by Henri Verbeet
parent ffc8f98bba
commit 38e6ba2d58
Notes: Henri Verbeet 2025-12-09 17:21:48 +01:00
Approved-by: Francisco Casas (@fcasas)
Approved-by: Nikolay Sivov (@nsivov)
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1340

View File

@@ -127,7 +127,9 @@ struct type_entry
{ {
struct list entry; struct list entry;
const char *name; const char *name;
const struct hlsl_type *element_type;
uint32_t elements_count; uint32_t elements_count;
uint32_t unpacked_size;
uint32_t modifiers; uint32_t modifiers;
uint32_t offset; uint32_t offset;
}; };
@@ -369,46 +371,27 @@ static void write_fx_4_annotations(struct hlsl_scope *scope, struct fx_write_con
set_u32(buffer, count_offset, count); set_u32(buffer, count_offset, count);
} }
static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx); static uint32_t write_fx_4_type(const struct type_entry *type, struct fx_write_context *fx);
static const char * get_fx_4_type_name(const struct hlsl_type *type); static const char * get_fx_4_type_name(const struct hlsl_type *type);
static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_context *fx); static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_context *fx);
static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx) static uint32_t write_type(const struct type_entry *type, struct fx_write_context *fx)
{ {
unsigned int elements_count, modifiers;
const struct hlsl_type *element_type;
struct type_entry *type_entry; struct type_entry *type_entry;
const char *name;
VKD3D_ASSERT(fx->ctx->profile->major_version >= 4);
if (type->class == HLSL_CLASS_ARRAY)
{
elements_count = hlsl_get_multiarray_size(type);
element_type = hlsl_get_multiarray_element_type(type);
}
else
{
elements_count = 0;
element_type = type;
}
name = get_fx_4_type_name(element_type);
modifiers = element_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK;
/* We don't try to reuse nameless types; they will get the same /* We don't try to reuse nameless types; they will get the same
* "<unnamed>" name, but are not available for the type cache. */ * "<unnamed>" name, but are not available for the type cache. */
if (name) if (type->name)
{ {
LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry) LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry)
{ {
if (strcmp(type_entry->name, name)) if (strcmp(type_entry->name, type->name))
continue; continue;
if (type_entry->elements_count != elements_count) if (type_entry->elements_count != type->elements_count)
continue; continue;
if (type_entry->modifiers != modifiers) if (type_entry->modifiers != type->modifiers)
continue; continue;
return type_entry->offset; return type_entry->offset;
@@ -418,17 +401,42 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context
if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry)))) if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry))))
return 0; return 0;
*type_entry = *type;
type_entry->offset = write_fx_4_type(type, fx); type_entry->offset = write_fx_4_type(type, fx);
type_entry->name = name;
type_entry->elements_count = elements_count;
type_entry->modifiers = modifiers;
if (name) if (type_entry->name)
list_add_tail(&fx->types, &type_entry->entry); list_add_tail(&fx->types, &type_entry->entry);
return type_entry->offset; return type_entry->offset;
} }
static void type_entry_from_type(struct type_entry *e, const struct hlsl_type *type, const struct fx_write_context *fx)
{
const struct hlsl_type *element_type = hlsl_get_multiarray_element_type(type);
VKD3D_ASSERT(fx->ctx->profile->major_version >= 4);
*e = (struct type_entry)
{
.elements_count = type->class == HLSL_CLASS_ARRAY ? hlsl_get_multiarray_size(type) : 0,
/* Structures can only contain numeric fields, this is validated
* during variable declaration. */
.unpacked_size = type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float),
.modifiers = element_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK,
.name = get_fx_4_type_name(element_type),
.element_type = element_type,
};
}
static uint32_t write_var_type(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct type_entry entry;
type_entry_from_type(&entry, var->data_type, fx);
return write_type(&entry, fx);
}
static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_context_ops *ops, static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_context_ops *ops,
struct fx_write_context *fx) struct fx_write_context *fx)
{ {
@@ -1253,7 +1261,7 @@ static bool is_numeric_fx_4_type(const struct hlsl_type *type)
return type->class == HLSL_CLASS_STRUCT || hlsl_is_numeric_type(type); return type->class == HLSL_CLASS_STRUCT || hlsl_is_numeric_type(type);
} }
static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx) static uint32_t write_fx_4_type(const struct type_entry *type, struct fx_write_context *fx)
{ {
struct field_offsets struct field_offsets
{ {
@@ -1262,21 +1270,16 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
uint32_t offset; uint32_t offset;
uint32_t type; uint32_t type;
}; };
uint32_t name_offset, offset, unpacked_size, packed_size, stride, numeric_desc; uint32_t name_offset, offset, packed_size, stride, numeric_desc;
const struct hlsl_type *element_type = type->element_type;
struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
uint32_t elements_count = type->elements_count;
uint32_t unpacked_size = type->unpacked_size;
struct field_offsets *field_offsets = NULL; struct field_offsets *field_offsets = NULL;
const struct hlsl_type *element_type;
struct hlsl_ctx *ctx = fx->ctx; struct hlsl_ctx *ctx = fx->ctx;
uint32_t elements_count = 0; const char *name = type->name;
const char *name;
size_t i; size_t i;
if (type->class == HLSL_CLASS_ARRAY)
elements_count = hlsl_get_multiarray_size(type);
element_type = hlsl_get_multiarray_element_type(type);
name = get_fx_4_type_name(element_type);
name_offset = write_string(name ? name : "<unnamed>", fx); name_offset = write_string(name ? name : "<unnamed>", fx);
if (element_type->class == HLSL_CLASS_STRUCT) if (element_type->class == HLSL_CLASS_STRUCT)
{ {
@@ -1286,11 +1289,13 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
for (i = 0; i < element_type->e.record.field_count; ++i) for (i = 0; i < element_type->e.record.field_count; ++i)
{ {
const struct hlsl_struct_field *field = &element_type->e.record.fields[i]; const struct hlsl_struct_field *field = &element_type->e.record.fields[i];
struct type_entry entry;
type_entry_from_type(&entry, field->type, fx);
field_offsets[i].name = write_string(field->name, fx); field_offsets[i].name = write_string(field->name, fx);
field_offsets[i].semantic = write_string(field->semantic.raw_name, fx); field_offsets[i].semantic = write_string(field->semantic.raw_name, fx);
field_offsets[i].offset = field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float); field_offsets[i].offset = field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float);
field_offsets[i].type = write_type(field->type, fx); field_offsets[i].type = write_type(&entry, fx);
} }
} }
@@ -1342,9 +1347,6 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
return 0; return 0;
} }
/* Structures can only contain numeric fields, this is validated during variable declaration. */
unpacked_size = type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float);
packed_size = 0; packed_size = 0;
if (is_numeric_fx_4_type(element_type)) if (is_numeric_fx_4_type(element_type))
packed_size = hlsl_type_component_count(element_type) * sizeof(float); packed_size = hlsl_type_component_count(element_type) * sizeof(float);
@@ -2190,7 +2192,7 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st
if (var->has_explicit_bind_point) if (var->has_explicit_bind_point)
flags |= FX_4_HAS_EXPLICIT_BIND_POINT; flags |= FX_4_HAS_EXPLICIT_BIND_POINT;
type_offset = write_type(var->data_type, fx); type_offset = write_var_type(var, fx);
name_offset = write_string(var->name, fx); name_offset = write_string(var->name, fx);
semantic_offset = write_string(var->semantic.raw_name, fx); semantic_offset = write_string(var->semantic.raw_name, fx);
@@ -2225,7 +2227,7 @@ static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_conte
struct hlsl_ctx *ctx = fx->ctx; struct hlsl_ctx *ctx = fx->ctx;
name_offset = write_string(var->name, fx); name_offset = write_string(var->name, fx);
type_offset = write_type(var->data_type, fx); type_offset = write_var_type(var, fx);
put_u32(buffer, name_offset); put_u32(buffer, name_offset);
put_u32(buffer, type_offset); put_u32(buffer, type_offset);
@@ -3353,7 +3355,7 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_
if (var->reg_reservation.reg_type) if (var->reg_reservation.reg_type)
bind_point = var->reg_reservation.reg_index; bind_point = var->reg_reservation.reg_index;
type_offset = write_type(var->data_type, fx); type_offset = write_var_type(var, fx);
name_offset = write_string(var->name, fx); name_offset = write_string(var->name, fx);
semantic_offset = write_string(var->semantic.raw_name, fx); semantic_offset = write_string(var->semantic.raw_name, fx);