diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 1fe141a3..2d2e904b 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -4123,13 +4123,46 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (var->is_uniform && var->last_read) + unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; + + if (!var->is_uniform || !var->last_read || reg_size == 0) + continue; + + if (var->reg_reservation.reg_type == 'c') { - unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; + unsigned int reg_idx = var->reg_reservation.reg_index; + unsigned int i; - if (reg_size == 0) - continue; + assert(reg_size % 4 == 0); + for (i = 0; i < reg_size / 4; ++i) + { + if (get_available_writemask(&allocator, 1, UINT_MAX, reg_idx + i) != VKD3DSP_WRITEMASK_ALL) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "Overlapping register() reservations on 'c%u'.", reg_idx + i); + } + record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX); + } + + var->regs[HLSL_REGSET_NUMERIC].id = reg_idx; + var->regs[HLSL_REGSET_NUMERIC].allocation_size = reg_size / 4; + var->regs[HLSL_REGSET_NUMERIC].writemask = VKD3DSP_WRITEMASK_ALL; + var->regs[HLSL_REGSET_NUMERIC].allocated = true; + TRACE("Allocated reserved %s to %s.\n", var->name, + debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); + } + } + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; + + if (!var->is_uniform || !var->last_read || reg_size == 0) + continue; + + if (!var->regs[HLSL_REGSET_NUMERIC].allocated) + { var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, &allocator, 1, UINT_MAX, var->data_type); TRACE("Allocated %s to %s.\n", var->name, diff --git a/tests/hlsl/register-reservations-numeric.shader_test b/tests/hlsl/register-reservations-numeric.shader_test index f89cb139..9b2bae57 100644 --- a/tests/hlsl/register-reservations-numeric.shader_test +++ b/tests/hlsl/register-reservations-numeric.shader_test @@ -1,4 +1,4 @@ -[pixel shader fail(sm<6) todo] +[pixel shader fail(sm<6) todo(sm>=4)] // Overlapping register(cX) reservations are not allowed except on SM6, where they are aliased. // On SM1 this gives hr 0x88760b59. float a : register(c0); @@ -24,7 +24,7 @@ float4 main() : sv_target uniform 0 float4 0.1 0.2 0.3 0.4 uniform 4 float4 1.1 1.2 1.3 1.4 draw quad -todo(sm<6) probe all rgba (1.1, 1.4, 0.2, 0.3) +todo(sm>=4 & sm<6) probe all rgba (1.1, 1.4, 0.2, 0.3) [pixel shader] @@ -43,7 +43,7 @@ uniform 8 float4 2.1 2.2 2.3 2.4 uniform 12 float4 3.1 3.2 3.3 3.4 uniform 16 float4 4.1 4.2 4.3 4.4 draw quad -todo(sm<6) probe all rgba (4.1, 4.2, 1.3, 1.4) +todo(sm>=4 & sm<6) probe all rgba (4.1, 4.2, 1.3, 1.4) [require] @@ -64,7 +64,7 @@ uniform 4 float4 1.1 1.2 1.3 1.4 uniform 8 float4 2.1 2.2 2.3 2.4 uniform 12 float4 3.1 3.2 3.3 3.4 draw quad -todo probe all rgba (2.1, 0.1, 0.0, 0.0) +probe all rgba (2.1, 0.1, 0.0, 0.0) [require] @@ -132,7 +132,7 @@ uniform 4 float4 1.1 1.2 1.3 1.4 uniform 8 float4 2.1 2.2 2.3 2.4 uniform 12 float4 3.1 3.2 3.3 3.4 draw quad -todo probe all rgba (2.1, 2.2, 3.1, 0.0) +probe all rgba (2.1, 2.2, 3.1, 0.0) [require]