vkd3d-shader/hlsl: Allow effect calls on default value initializers.

This commit is contained in:
Francisco Casas 2024-06-25 18:36:32 -04:00 committed by Henri Verbeet
parent 4aa262d773
commit ffc1449412
Notes: Henri Verbeet 2024-09-14 16:53:12 +02:00
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1057
6 changed files with 68 additions and 24 deletions

View File

@ -609,6 +609,7 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx
{
switch (node->type)
{
case HLSL_IR_COMPILE:
case HLSL_IR_CONSTANT:
case HLSL_IR_EXPR:
case HLSL_IR_STRING_CONSTANT:
@ -627,7 +628,6 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx
case HLSL_IR_RESOURCE_LOAD:
case HLSL_IR_RESOURCE_STORE:
case HLSL_IR_SWITCH:
case HLSL_IR_COMPILE:
case HLSL_IR_STATEBLOCK_CONSTANT:
hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
"Expected literal expression.");
@ -1227,7 +1227,8 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type,
}
static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src);
struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src,
bool is_default_values_initializer);
static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters *parameters,
struct parse_parameter *param, const struct vkd3d_shader_location *loc)
@ -1285,7 +1286,8 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters
for (i = 0; i < param->initializer.args_count; ++i)
{
initialize_var_components(ctx, param->initializer.instrs, var, &store_index, param->initializer.args[i]);
initialize_var_components(ctx, param->initializer.instrs, var,
&store_index, param->initializer.args[i], true);
}
free_parse_initializer(&param->initializer);
@ -2368,7 +2370,8 @@ static unsigned int get_component_index_from_default_initializer_index(struct hl
}
static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src)
struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src,
bool is_default_values_initializer)
{
unsigned int src_comp_count = hlsl_type_component_count(src->data_type);
struct hlsl_deref dst_deref;
@ -2387,11 +2390,28 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index);
if (dst->default_values)
if (is_default_values_initializer)
{
struct hlsl_default_value default_value = {0};
unsigned int dst_index;
if (hlsl_is_numeric_type(dst_comp_type))
{
if (src->type == HLSL_IR_COMPILE)
{
/* Default values are discarded if they contain an object
* literal expression for a numeric component. */
if (dst->default_values)
{
hlsl_warning(ctx, &src->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE,
"Component %u in variable '%s' initializer is object literal. Default values discarded.",
k, dst->name);
vkd3d_free(dst->default_values);
dst->default_values = NULL;
}
}
else
{
if (!hlsl_clone_block(ctx, &block, instrs))
return;
default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc);
@ -2401,10 +2421,13 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
else
dst_index = get_component_index_from_default_initializer_index(ctx, dst->data_type, *store_index);
if (dst->default_values)
dst->default_values[dst_index] = default_value;
hlsl_block_cleanup(&block);
}
}
}
else
{
if (!(conv = add_implicit_conversion(ctx, instrs, load, dst_comp_type, &src->loc)))
@ -2793,7 +2816,8 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var
for (k = 0; k < v->initializer.args_count; ++k)
{
initialize_var_components(ctx, v->initializer.instrs, var, &store_index, v->initializer.args[k]);
initialize_var_components(ctx, v->initializer.instrs, var,
&store_index, v->initializer.args[k], is_default_values_initializer);
}
if (is_default_values_initializer)
@ -4785,17 +4809,17 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
if (!(var = hlsl_new_synthetic_var(ctx, "coords", hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 2), loc)))
return false;
initialize_var_components(ctx, params->instrs, var, &idx, coords);
initialize_var_components(ctx, params->instrs, var, &idx, coords, false);
if (hlsl_version_ge(ctx, 4, 0))
{
if (!(half = hlsl_new_float_constant(ctx, 0.5f, loc)))
return false;
hlsl_block_add_instr(params->instrs, half);
initialize_var_components(ctx, params->instrs, var, &idx, half);
initialize_var_components(ctx, params->instrs, var, &idx, half, false);
}
else
initialize_var_components(ctx, params->instrs, var, &idx, coords);
initialize_var_components(ctx, params->instrs, var, &idx, coords, false);
if (!(load = hlsl_new_var_load(ctx, var, loc)))
return false;
@ -5276,7 +5300,7 @@ static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type
return NULL;
for (i = 0; i < params->args_count; ++i)
initialize_var_components(ctx, params->instrs, var, &idx, params->args[i]);
initialize_var_components(ctx, params->instrs, var, &idx, params->args[i], false);
if (!(load = hlsl_new_var_load(ctx, var, loc)))
return NULL;

View File

@ -165,6 +165,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT = 5303,
VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT = 5304,
VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE = 5305,
VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE = 5306,
VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000,

View File

@ -83,7 +83,7 @@ technique10
// Without initializer
technique10 < int a; > {}
[effect fail]
[effect fail todo]
// Only numeric types and strings are allowed
technique10 < DepthStencilState ds = { 0 }; > {}

View File

@ -20,3 +20,11 @@ float4 main() : sv_target
[test]
todo(sm<6) draw quad
probe (0, 0) rgba (0.1, 0.1, 0.2, 0.4)
[pixel shader fail]
float4 fun() { return 0; };
float a[CompileShader(ps_2_0, main())];
float4 main() : sv_target { return 0; }

View File

@ -294,6 +294,17 @@ float4 main() : sv_target
}
% This compiles but default values for 'p' aren't written to the output binary.
[pixel shader fail(sm>=6)]
float4 fun() { return 0; };
float2 p = {5, CompileShader(ps_2_0, fun())};
float4 main() : sv_target
{
return p.xyxy;
}
[require]
shader model >= 5.0

View File

@ -161,13 +161,13 @@ float4 main() : sv_target { return 0; }
PixelShader ps1 = {42}; // braces make the type checking more permissive.
% This compiles, but the default value of "f" is not written.
[pixel shader todo fail(sm>=6)]
[pixel shader fail(sm>=6)]
float4 fun() : sv_target { return 0; }
float f = {CompileShader(ps_2_0, fun())};
float4 main() : sv_target { return f; }
% This also compiles, but the default value of "f" is not written.
[pixel shader todo fail(sm>=6)]
[pixel shader fail(sm>=6)]
float4 fun() : sv_target { return 0; }
float4 f = {1, 2, compile ps_2_0 fun(), 4};
float4 main() : sv_target { return f; }
@ -225,7 +225,7 @@ shader model < 6.0
% The following test segfaults on DXC.
[pixel shader todo]
[pixel shader]
float f;
float4 foo(uniform float r) : sv_target { return r; }
@ -247,7 +247,7 @@ technique
float4 main() : sv_target { return 0; }
[test]
todo draw quad
todo(glsl) draw quad
probe (0, 0) rgba (0, 0, 0, 0)