Module: vkd3d Branch: master Commit: 6989266e76fc670a92b68e3fa064d16706cce070 URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/6989266e76fc670a92b68e3fa064d1...
Author: Francisco Casas fcasas@codeweavers.com Date: Fri Jul 22 11:40:24 2022 -0400
vkd3d-shader/hlsl: Check for non-static object references.
It is responsibility of the shader's programmer to ensure that object references can be solved statically.
Resource arrays for ps_5_1 and vs_5_1 are an exception which is not properly handled yet. They probably deserve a different object type.
Signed-off-by: Francisco Casas fcasas@codeweavers.com
---
libs/vkd3d-shader/hlsl_codegen.c | 47 ++++++++++++++++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + tests/object-references.shader_test | 4 +-- 3 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 7f76fce1..6c4a0eec 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -967,6 +967,51 @@ static bool copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *bl return progress; }
+static void note_non_static_deref_expressions(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + const char *usage) +{ + unsigned int i; + + for (i = 0; i < deref->path_len; ++i) + { + struct hlsl_ir_node *path_node = deref->path[i].node; + + assert(path_node); + if (path_node->type != HLSL_IR_CONSTANT) + hlsl_note(ctx, &path_node->loc, VKD3D_SHADER_LOG_ERROR, + "Expression for %s within "%s" cannot be resolved statically.", + usage, deref->var->name); + } +} + +static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + void *context) +{ + unsigned int start, count; + + if (instr->type == HLSL_IR_RESOURCE_LOAD) + { + struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); + + if (!hlsl_component_index_range_from_deref(ctx, &load->resource, &start, &count)) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, + "Loaded resource from "%s" must be determinable at compile time.", + load->resource.var->name); + note_non_static_deref_expressions(ctx, &load->resource, "loaded resource"); + } + if (load->sampler.var && !hlsl_component_index_range_from_deref(ctx, &load->sampler, &start, &count)) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, + "Resource load sampler from "%s" must be determinable at compile time.", + load->sampler.var->name); + note_non_static_deref_expressions(ctx, &load->sampler, "resource load sampler"); + } + } + + return false; +} + static bool is_vec1(const struct hlsl_type *type) { return (type->type == HLSL_CLASS_SCALAR) || (type->type == HLSL_CLASS_VECTOR && type->dimx == 1); @@ -2236,6 +2281,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry if (ctx->profile->major_version < 4) transform_ir(ctx, lower_division, body, NULL);
+ transform_ir(ctx, validate_static_object_references, body, NULL); + /* TODO: move forward, remove when no longer needed */ transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); while (transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL)); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 8bde5523..aca5606b 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -118,6 +118,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS = 5019, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE = 5020, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO = 5021, + VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF = 5022,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, diff --git a/tests/object-references.shader_test b/tests/object-references.shader_test index c3952e03..6cff351a 100644 --- a/tests/object-references.shader_test +++ b/tests/object-references.shader_test @@ -89,7 +89,7 @@ draw quad probe all rgba (2132, 2132, 2132, 1111)
-[pixel shader fail todo] +[pixel shader fail] Texture2D tex[3]; uniform int n;
@@ -109,7 +109,7 @@ float4 main() : sv_target }
-[pixel shader fail todo] +[pixel shader fail] // Note: Only valid in shader model 5.1 Texture2D tex[3]; uniform int n;