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>
This commit is contained in:
Francisco Casas 2022-07-22 11:40:24 -04:00 committed by Alexandre Julliard
parent 1bba18aa75
commit 6989266e76
Notes: Alexandre Julliard 2022-10-18 00:13:00 +02:00
Approved-by: Zebediah Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/7
3 changed files with 50 additions and 2 deletions

View File

@ -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));

View File

@ -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,

View File

@ -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;