vkd3d-shader/hlsl: Validate state block function calls.

This commit is contained in:
Francisco Casas 2024-06-06 17:50:05 -04:00 committed by Henri Verbeet
parent af7c4010f4
commit 60c8a813a3
Notes: Henri Verbeet 2024-07-09 21:10:32 +02:00
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/915
5 changed files with 72 additions and 2 deletions

View File

@ -56,6 +56,70 @@ static void string_storage_destroy(struct rb_entry *entry, void *context)
vkd3d_free(string_entry);
}
struct state_block_function_info
{
const char *name;
unsigned int min_args, max_args;
};
static const struct state_block_function_info *get_state_block_function_info(const char *name)
{
static const struct state_block_function_info valid_functions[] =
{
{"SetBlendState", 3, 3},
{"SetDepthStencilState", 2, 2},
{"SetRasterizerState", 1, 1},
{"SetVertexShader", 1, 1},
{"SetDomainShader", 1, 1},
{"SetHullShader", 1, 1},
{"SetGeometryShader", 1, 1},
{"SetPixelShader", 1, 1},
{"SetComputeShader", 1, 1},
{"OMSetRenderTargets", 2, 9},
};
for (unsigned int i = 0; i < ARRAY_SIZE(valid_functions); ++i)
{
if (!strcmp(name, valid_functions[i].name))
return &valid_functions[i];
}
return NULL;
}
bool hlsl_validate_state_block_entry(struct hlsl_ctx *ctx, struct hlsl_state_block_entry *entry,
const struct vkd3d_shader_location *loc)
{
if (entry->is_function_call)
{
const struct state_block_function_info *info = get_state_block_function_info(entry->name);
if (!info)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_STATE_BLOCK_ENTRY,
"Invalid state block function '%s'.", entry->name);
return false;
}
if (entry->args_count < info->min_args || entry->args_count > info->max_args)
{
if (info->min_args == info->max_args)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_STATE_BLOCK_ENTRY,
"Invalid argument count for state block function '%s' (expected %u).",
entry->name, info->min_args);
}
else
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_STATE_BLOCK_ENTRY,
"Invalid argument count for state block function '%s' (expected from %u to %u).",
entry->name, info->min_args, info->max_args);
}
return false;
}
}
return true;
}
struct fx_write_context;
struct fx_write_context_ops

View File

@ -1293,6 +1293,9 @@ bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const
void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func);
void hlsl_dump_var_default_values(const struct hlsl_ir_var *var);
bool hlsl_validate_state_block_entry(struct hlsl_ctx *ctx, struct hlsl_state_block_entry *entry,
const struct vkd3d_shader_location *loc);
void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body);
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);

View File

@ -7405,6 +7405,8 @@ state_block:
hlsl_src_from_node(&entry->args[i], $4.args[i]);
vkd3d_free($4.args);
hlsl_validate_state_block_entry(ctx, entry, &@4);
$$ = $1;
state_block_add_entry($$, entry);
}

View File

@ -151,6 +151,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_HLSL_DUPLICATE_SWITCH_CASE = 5028,
VKD3D_SHADER_ERROR_HLSL_MISSING_TECHNIQUE = 5029,
VKD3D_SHADER_ERROR_HLSL_UNKNOWN_MODIFIER = 5030,
VKD3D_SHADER_ERROR_HLSL_INVALID_STATE_BLOCK_ENTRY = 5031,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301,

View File

@ -27,7 +27,7 @@ sampler sam
float4 main() : sv_target { return 0; }
[pixel shader fail(sm<6) todo]
[pixel shader fail(sm<6)]
sampler sam
{
SetSomeotherState();
@ -36,7 +36,7 @@ sampler sam
float4 main() : sv_target { return 0; }
[pixel shader fail(sm<6) todo]
[pixel shader fail(sm<6)]
sampler sam
{
Setblendstate(1, 2, 3); // Test case-sensitivity.