From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl_codegen.c | 96 ++++++++++++------- .../register-reservations-numeric.shader_test | 10 +- 2 files changed, 67 insertions(+), 39 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index fbd75a441..cd4bf4845 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -4205,45 +4205,52 @@ static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint3 return NULL; }
-static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) +static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, bool register_reservation) { unsigned int var_reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; enum hlsl_type_class var_class = var->data_type->class; struct hlsl_buffer *buffer = var->buffer;
- if (var->reg_reservation.offset_type == 'c') + if (register_reservation) { - if (var->reg_reservation.offset_index % 4) + var->buffer_offset = 4 * var->reg_reservation.reg_index; + } + else + { + if (var->reg_reservation.offset_type == 'c') { - if (var_class == HLSL_CLASS_MATRIX) - { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, - "packoffset() reservations with matrix types must be aligned with the beginning of a register."); - } - else if (var_class == HLSL_CLASS_ARRAY) - { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, - "packoffset() reservations with array types must be aligned with the beginning of a register."); - } - else if (var_class == HLSL_CLASS_STRUCT) - { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, - "packoffset() reservations with struct types must be aligned with the beginning of a register."); - } - else if (var_class == HLSL_CLASS_VECTOR) + if (var->reg_reservation.offset_index % 4) { - unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index); - - if (var->reg_reservation.offset_index != aligned_offset) + if (var_class == HLSL_CLASS_MATRIX) + { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, - "packoffset() reservations with vector types cannot span multiple registers."); + "packoffset() reservations with matrix types must be aligned with the beginning of a register."); + } + else if (var_class == HLSL_CLASS_ARRAY) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "packoffset() reservations with array types must be aligned with the beginning of a register."); + } + else if (var_class == HLSL_CLASS_STRUCT) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "packoffset() reservations with struct types must be aligned with the beginning of a register."); + } + else if (var_class == HLSL_CLASS_VECTOR) + { + unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index); + + if (var->reg_reservation.offset_index != aligned_offset) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "packoffset() reservations with vector types cannot span multiple registers."); + } } + var->buffer_offset = var->reg_reservation.offset_index; + } + else + { + var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size); } - var->buffer_offset = var->reg_reservation.offset_index; - } - else - { - var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size); }
TRACE("Allocated buffer offset %u to %s.\n", var->buffer_offset, var->name); @@ -4312,6 +4319,11 @@ static void validate_buffer_offsets(struct hlsl_ctx *ctx) } }
+static bool var_has_buffer_offset_register_reservation(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var) +{ + return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer; +} + static void allocate_buffers(struct hlsl_ctx *ctx) { struct hlsl_buffer *buffer; @@ -4320,13 +4332,29 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (var->is_uniform && !hlsl_type_is_resource(var->data_type)) - { - if (var->is_param) - var->buffer = ctx->params_buffer; + if (!var->is_uniform || hlsl_type_is_resource(var->data_type)) + continue;
- calculate_buffer_offset(ctx, var); - } + if (var->is_param) + var->buffer = ctx->params_buffer; + } + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->is_uniform || hlsl_type_is_resource(var->data_type)) + continue; + + if (var_has_buffer_offset_register_reservation(ctx, var)) + calculate_buffer_offset(ctx, var, true); + } + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->is_uniform || hlsl_type_is_resource(var->data_type)) + continue; + + if (!var_has_buffer_offset_register_reservation(ctx, var)) + calculate_buffer_offset(ctx, var, false); }
validate_buffer_offsets(ctx); diff --git a/tests/hlsl/register-reservations-numeric.shader_test b/tests/hlsl/register-reservations-numeric.shader_test index 602d08430..3396f706e 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)] // 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) +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) +probe all rgba (4.1, 4.2, 1.3, 1.4)
[require] @@ -85,7 +85,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(sm<6) probe all rgba (2.1, 2.2, 0.0, 0.0) +probe all rgba (2.1, 2.2, 0.0, 0.0)
[require] @@ -156,7 +156,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(sm<6) probe all rgba (2.1, 2.2, 2.3, 0.0) +probe all rgba (2.1, 2.2, 2.3, 0.0)
[pixel shader]