From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl_codegen.c | 27 +++++++++++++++++++++------ tests/cbuffer.shader_test | 16 ++++++++-------- 2 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index aa1d2d3f..84cca40e 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2859,17 +2859,32 @@ 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]; struct hlsl_buffer *buffer = var->buffer;
- buffer->size = hlsl_type_get_sm4_offset(var->data_type, buffer->size); + if (var->offset_reservation.type == 'c') + { + unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, + var->offset_reservation.index); + + if (aligned_offset != var->offset_reservation.index) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "Reservation with swizzle in packoffset() breaks register boundaries."); + } + var->buffer_offset = var->offset_reservation.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) @@ -2885,7 +2900,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 a40af632..b8f54e77 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] // Invalid offset on unused buffer. cbuffer buffer { @@ -226,7 +226,7 @@ float4 main() : sv_target }
-[pixel shader fail todo] +[pixel shader fail] // Invalid offset on unused variable. cbuffer buffer { @@ -258,7 +258,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] @@ -289,7 +289,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]