vkd3d-shader/d3dbc: Avoid hlsl_type_get_regset() in d3dbc.c.

In SM1 we can expect all variables to always belong to a single regset.
structs in particular, should always be allocated to HLSL_REGSET_NUM,
since they are only allowed if all their components are numeric.

We are not covering the structs case because of the use of
hlsl_type_get_regset(), which is currently not defined for structs.

So the current shader

    struct
    {
        float4 a;
        float4 b;
    } apple;

    float4 main() : sv_target
    {
        return apple.a + apple.b;
    }

fails with

    vkd3d/libs/vkd3d-shader/hlsl.c:224: Aborting, reached unreachable code.

The solution is to iterate over all regsets to find the one where the
variable is allocated (if any), and ignore all others.
This commit is contained in:
Francisco Casas 2023-06-09 12:23:25 -04:00 committed by Alexandre Julliard
parent bce2a898b3
commit c1ca0dafe8
Notes: Alexandre Julliard 2023-06-22 22:04:01 +02:00
Approved-by: Zebediah Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/244

View File

@ -1281,10 +1281,13 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
enum hlsl_regset regset = hlsl_type_get_regset(var->data_type);
unsigned int r;
if (!var->semantic.name && var->regs[regset].allocated)
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
{
if (var->semantic.name || !var->regs[r].allocated)
continue;
++uniform_count;
if (var->is_param && var->is_uniform)
@ -1321,20 +1324,23 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
enum hlsl_regset regset = hlsl_type_get_regset(var->data_type);
unsigned int r;
if (!var->semantic.name && var->regs[regset].allocated)
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
{
if (var->semantic.name || !var->regs[r].allocated)
continue;
put_u32(buffer, 0); /* name */
if (regset == HLSL_REGSET_NUMERIC)
if (r == HLSL_REGSET_NUMERIC)
{
put_u32(buffer, vkd3d_make_u32(D3DXRS_FLOAT4, var->regs[regset].id));
put_u32(buffer, var->data_type->reg_size[regset] / 4);
put_u32(buffer, vkd3d_make_u32(D3DXRS_FLOAT4, var->regs[r].id));
put_u32(buffer, var->data_type->reg_size[r] / 4);
}
else
{
put_u32(buffer, vkd3d_make_u32(D3DXRS_SAMPLER, var->regs[regset].id));
put_u32(buffer, var->regs[regset].bind_count);
put_u32(buffer, vkd3d_make_u32(D3DXRS_SAMPLER, var->regs[r].id));
put_u32(buffer, var->regs[r].bind_count);
}
put_u32(buffer, 0); /* type */
put_u32(buffer, 0); /* FIXME: default value */
@ -1345,12 +1351,16 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
enum hlsl_regset regset = hlsl_type_get_regset(var->data_type);
unsigned int r;
if (!var->semantic.name && var->regs[regset].allocated)
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
{
size_t var_offset = vars_start + (uniform_count * 5 * sizeof(uint32_t));
size_t name_offset;
size_t var_offset, name_offset;
if (var->semantic.name || !var->regs[r].allocated)
continue;
var_offset = vars_start + (uniform_count * 5 * sizeof(uint32_t));
name_offset = put_string(buffer, var->name);
set_u32(buffer, var_offset, name_offset - ctab_start);