From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl_codegen.c | 46 +++++++++++++++++++++++++++----- tests/cbuffer.shader_test | 22 +++++++-------- 2 files changed, 51 insertions(+), 17 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 90995eb8..e34b4afe 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2860,17 +2860,51 @@ static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint3 return NULL; }
-static void calculate_buffer_offset(struct hlsl_ir_var *var) +static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) { + unsigned int var_reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; + enum hlsl_type_class var_type = var->data_type->type; struct hlsl_buffer *buffer = var->buffer;
- buffer->size = hlsl_type_get_sm4_offset(var->data_type, buffer->size); + if (var->reg_reservation.offset_type == 'c') + { + if (var->reg_reservation.offset_index % 4) + { + if (var_type == 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_type == 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_type == 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_type == 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 = buffer->size; TRACE("Allocated buffer offset %u to %s.\n", var->buffer_offset, var->name); - buffer->size += var->data_type->reg_size[HLSL_REGSET_NUMERIC]; + buffer->size = max(buffer->size, var->buffer_offset + var_reg_size); if (var->last_read) - buffer->used_size = buffer->size; + buffer->used_size = max(buffer->used_size, var->buffer_offset + var_reg_size); }
static void allocate_buffers(struct hlsl_ctx *ctx) @@ -2886,7 +2920,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) if (var->is_param) var->buffer = ctx->params_buffer;
- calculate_buffer_offset(var); + calculate_buffer_offset(ctx, var); } }
diff --git a/tests/cbuffer.shader_test b/tests/cbuffer.shader_test index 628a441a..bf711629 100644 --- a/tests/cbuffer.shader_test +++ b/tests/cbuffer.shader_test @@ -152,7 +152,7 @@ uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 uniform 8 float4 9.0 10.0 11.0 12.0 draw quad -todo probe all rgba (509, 610, 711, 812) +probe all rgba (509, 610, 711, 812)
[pixel shader] @@ -180,7 +180,7 @@ uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 uniform 12 float4 12.0 13.0 14.0 15.0 draw quad -todo probe all rgba (12468.0, 13509.0, 14010.0, 15011.0) +probe all rgba (12468.0, 13509.0, 14010.0, 15011.0)
[pixel shader] @@ -197,10 +197,10 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 3.0 4.0 draw quad -todo probe all rgba (2.0, 3.0, 2.0, 3.0) +probe all rgba (2.0, 3.0, 2.0, 3.0)
-[pixel shader fail todo] +[pixel shader fail] // Elements must respect register boundaries. cbuffer buffer { @@ -213,7 +213,7 @@ float4 main() : sv_target }
-[pixel shader fail todo] +[pixel shader fail] // Matrices must be aligned. cbuffer buffer { @@ -226,7 +226,7 @@ float4 main() : sv_target }
-[pixel shader fail todo] +[pixel shader fail] // Arrays must be aligned. cbuffer buffer { @@ -239,7 +239,7 @@ float4 main() : sv_target }
-[pixel shader fail todo] +[pixel shader fail] // Structs must be aligned. struct apple { @@ -257,7 +257,7 @@ float4 main() : sv_target }
-[pixel shader fail todo] +[pixel shader fail] // Invalid offset on unused buffer. cbuffer buffer { @@ -270,7 +270,7 @@ float4 main() : sv_target }
-[pixel shader fail todo] +[pixel shader fail] // Invalid offset on unused variable. cbuffer buffer { @@ -302,7 +302,7 @@ uniform 0 float 1.0 uniform 1 float 2.0 uniform 4 float4 5.0 6.0 7.0 8.0 draw quad -todo probe all rgba (512.0, 612.0, 712.0, 812.0) +probe all rgba (512.0, 612.0, 712.0, 812.0)
[pixel shader fail todo] @@ -333,7 +333,7 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 3.0 4.0 draw quad -todo probe all rgba (3.0, 4.0, 3.0, 4.0) +probe all rgba (3.0, 4.0, 3.0, 4.0)
[pixel shader fail]