vkd3d-shader/hlsl: Move default values indexing fixup to the tpf writer stage.

The primary goal here is to move compilation profile type and version
check outside of a parsing stage. Default values for parameters were
never subjected to this fixup, and it does look tpf-specific, so moving
it where it belongs.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
Nikolay Sivov 2024-09-26 23:50:56 +02:00 committed by Henri Verbeet
parent f28d39b609
commit 5e52ccbf3d
Notes: Henri Verbeet 2024-10-01 17:35:05 +02:00
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1126
2 changed files with 46 additions and 58 deletions

View File

@ -2324,55 +2324,6 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d
return true;
}
/* For some reason, for matrices, values from default value initializers end up in different
* components than from regular initializers. Default value initializers fill the matrix in
* vertical reading order (left-to-right top-to-bottom) instead of regular reading order
* (top-to-bottom left-to-right), so they have to be adjusted.
* An exception is that the order of matrix initializers for function parameters are row-major
* (top-to-bottom left-to-right). */
static unsigned int get_component_index_from_default_initializer_index(struct hlsl_ctx *ctx,
struct hlsl_type *type, unsigned int index)
{
unsigned int element_comp_count, element, x, y, i;
unsigned int base = 0;
if (ctx->profile->major_version < 4)
return index;
if (ctx->profile->type == VKD3D_SHADER_TYPE_EFFECT)
return index;
switch (type->class)
{
case HLSL_CLASS_MATRIX:
x = index / type->dimy;
y = index % type->dimy;
return y * type->dimx + x;
case HLSL_CLASS_ARRAY:
element_comp_count = hlsl_type_component_count(type->e.array.type);
element = index / element_comp_count;
base = element * element_comp_count;
return base + get_component_index_from_default_initializer_index(ctx, type->e.array.type, index - base);
case HLSL_CLASS_STRUCT:
for (i = 0; i < type->e.record.field_count; ++i)
{
struct hlsl_type *field_type = type->e.record.fields[i].type;
element_comp_count = hlsl_type_component_count(field_type);
if (index - base < element_comp_count)
return base + get_component_index_from_default_initializer_index(ctx, field_type, index - base);
base += element_comp_count;
}
break;
default:
return index;
}
vkd3d_unreachable();
}
static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src,
bool is_default_values_initializer)
@ -2397,7 +2348,6 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
if (is_default_values_initializer)
{
struct hlsl_default_value default_value = {0};
unsigned int dst_index;
if (hlsl_is_numeric_type(dst_comp_type))
{
@ -2420,13 +2370,8 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
return;
default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc);
if (dst->is_param)
dst_index = *store_index;
else
dst_index = get_component_index_from_default_initializer_index(ctx, dst->data_type, *store_index);
if (dst->default_values)
dst->default_values[dst_index] = default_value;
dst->default_values[*store_index] = default_value;
hlsl_block_cleanup(&block);
}

View File

@ -3649,6 +3649,48 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
return extern_resources;
}
/* For some reason, for matrices, values from default value initializers end up in different
* components than from regular initializers. Default value initializers fill the matrix in
* vertical reading order (left-to-right top-to-bottom) instead of regular reading order
* (top-to-bottom left-to-right), so they have to be adjusted.
* An exception is that the order of matrix initializers for function parameters are row-major
* (top-to-bottom left-to-right). */
static unsigned int get_component_index_from_default_initializer_index(struct hlsl_type *type, unsigned int index)
{
unsigned int element_comp_count, element, x, y, i;
unsigned int base = 0;
switch (type->class)
{
case HLSL_CLASS_MATRIX:
x = index / type->dimy;
y = index % type->dimy;
return y * type->dimx + x;
case HLSL_CLASS_ARRAY:
element_comp_count = hlsl_type_component_count(type->e.array.type);
element = index / element_comp_count;
base = element * element_comp_count;
return base + get_component_index_from_default_initializer_index(type->e.array.type, index - base);
case HLSL_CLASS_STRUCT:
for (i = 0; i < type->e.record.field_count; ++i)
{
struct hlsl_type *field_type = type->e.record.fields[i].type;
element_comp_count = hlsl_type_component_count(field_type);
if (index - base < element_comp_count)
return base + get_component_index_from_default_initializer_index(field_type, index - base);
base += element_comp_count;
}
break;
default:
return index;
}
vkd3d_unreachable();
}
static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
{
uint32_t binding_desc_size = (hlsl_version_ge(ctx, 5, 1) ? 10 : 8) * sizeof(uint32_t);
@ -3849,7 +3891,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
for (k = 0; k < comp_count; ++k)
{
struct hlsl_type *comp_type = hlsl_type_get_component_type(ctx, var->data_type, k);
unsigned int comp_offset;
unsigned int comp_offset, comp_index;
enum hlsl_regset regset;
if (comp_type->class == HLSL_CLASS_STRING)
@ -3859,7 +3901,8 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
continue;
}
comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, &regset);
comp_index = get_component_index_from_default_initializer_index(var->data_type, k);
comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, comp_index, &regset);
if (regset == HLSL_REGSET_NUMERIC)
{
if (comp_type->e.numeric.type == HLSL_TYPE_DOUBLE)