vkd3d-shader/hlsl: Don't forbid first base type cast on var assignments.

This commit is contained in:
Francisco Casas 2025-01-21 03:00:12 -03:00 committed by Henri Verbeet
parent 0a15ab702f
commit 4d18fb39b6
Notes: Henri Verbeet 2025-01-22 15:04:09 +01:00
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1350
3 changed files with 19 additions and 16 deletions

View File

@ -2099,11 +2099,12 @@ static bool invert_swizzle_matrix(const struct hlsl_matrix_swizzle *swizzle,
} }
static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *lhs, static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *lhs,
enum parse_assign_op assign_op, struct hlsl_ir_node *rhs) enum parse_assign_op assign_op, struct hlsl_ir_node *rhs, bool is_function_out_arg)
{ {
struct hlsl_type *lhs_type = lhs->data_type; struct hlsl_type *lhs_type = lhs->data_type;
unsigned int writemask = 0, width = 0; unsigned int writemask = 0, width = 0;
bool matrix_writemask = false; bool matrix_writemask = false;
bool first_cast = true;
if (lhs->data_type->class == HLSL_CLASS_ERROR || rhs->data_type->class == HLSL_CLASS_ERROR) if (lhs->data_type->class == HLSL_CLASS_ERROR || rhs->data_type->class == HLSL_CLASS_ERROR)
{ {
@ -2149,7 +2150,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
hlsl_fixme(ctx, &cast->loc, "Size change on the LHS."); hlsl_fixme(ctx, &cast->loc, "Size change on the LHS.");
return false; return false;
} }
if (hlsl_version_ge(ctx, 4, 0)) if (hlsl_version_ge(ctx, 4, 0) && (!is_function_out_arg || !first_cast))
{ {
hlsl_error(ctx, &cast->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, hlsl_error(ctx, &cast->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE,
"Base type casts are not allowed on the LHS for profiles >= 4."); "Base type casts are not allowed on the LHS for profiles >= 4.");
@ -2159,6 +2160,8 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
lhs_type = lhs->data_type; lhs_type = lhs->data_type;
if (lhs_type->class == HLSL_CLASS_VECTOR || (lhs_type->class == HLSL_CLASS_MATRIX && matrix_writemask)) if (lhs_type->class == HLSL_CLASS_VECTOR || (lhs_type->class == HLSL_CLASS_MATRIX && matrix_writemask))
lhs_type = hlsl_get_vector_type(ctx, lhs->data_type->e.numeric.type, width); lhs_type = hlsl_get_vector_type(ctx, lhs->data_type->e.numeric.type, width);
first_cast = false;
} }
else if (lhs->type == HLSL_IR_SWIZZLE) else if (lhs->type == HLSL_IR_SWIZZLE)
{ {
@ -2370,7 +2373,7 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d
return false; return false;
hlsl_block_add_instr(block, one); hlsl_block_add_instr(block, one);
if (!add_assignment(ctx, block, lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, one)) if (!add_assignment(ctx, block, lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, one, false))
return false; return false;
if (post) if (post)
@ -3272,7 +3275,7 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx,
return NULL; return NULL;
hlsl_block_add_instr(args->instrs, &load->node); hlsl_block_add_instr(args->instrs, &load->node);
if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node)) if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node, true))
return NULL; return NULL;
} }
} }
@ -5457,7 +5460,7 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op
hlsl_error(ctx, &orig_val->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, hlsl_error(ctx, &orig_val->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST,
"Output argument to '%s' is const.", name); "Output argument to '%s' is const.", name);
if (!add_assignment(ctx, params->instrs, orig_val, ASSIGN_OP_ASSIGN, interlocked)) if (!add_assignment(ctx, params->instrs, orig_val, ASSIGN_OP_ASSIGN, interlocked, true))
return false; return false;
} }
@ -6394,7 +6397,7 @@ static bool add_assignment_from_component(struct hlsl_ctx *ctx, struct hlsl_bloc
if (!(load = hlsl_add_load_component(ctx, instrs, src, component, loc))) if (!(load = hlsl_add_load_component(ctx, instrs, src, component, loc)))
return false; return false;
if (!add_assignment(ctx, instrs, dest, ASSIGN_OP_ASSIGN, load)) if (!add_assignment(ctx, instrs, dest, ASSIGN_OP_ASSIGN, load, false))
return false; return false;
return true; return true;
@ -6550,7 +6553,7 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc
return false; return false;
hlsl_block_add_instr(block, sample_info); hlsl_block_add_instr(block, sample_info);
if (!add_assignment(ctx, block, args[ARG_SAMPLE_COUNT], ASSIGN_OP_ASSIGN, sample_info)) if (!add_assignment(ctx, block, args[ARG_SAMPLE_COUNT], ASSIGN_OP_ASSIGN, sample_info, false))
return false; return false;
} }
@ -9839,7 +9842,7 @@ assignment_expr:
hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Statement modifies a const expression."); hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Statement modifies a const expression.");
hlsl_block_add_block($3, $1); hlsl_block_add_block($3, $1);
destroy_block($1); destroy_block($1);
if (!add_assignment(ctx, $3, lhs, $2, rhs)) if (!add_assignment(ctx, $3, lhs, $2, rhs, false))
YYABORT; YYABORT;
$$ = $3; $$ = $3;
} }

View File

@ -25,7 +25,7 @@ probe (0, 0) rgba (-1.0, -1.0, 2.0, 4.0)
% In SM 6 a cast seems to implicitly promote the type to const, % In SM 6 a cast seems to implicitly promote the type to const,
% so it fails to match the parameter of func(). % so it fails to match the parameter of func().
[pixel shader fail(sm>=6) todo(sm>=4)] [pixel shader fail(sm>=6)]
uniform float4 f; uniform float4 f;
@ -43,12 +43,12 @@ float4 main() : sv_target
[test] [test]
uniform 0 float4 -1.9 -1.0 2.9 4.0 uniform 0 float4 -1.9 -1.0 2.9 4.0
todo(sm>=4) draw quad draw quad
probe (0, 0) rgba (-1.0, -1.0, 2.0, 4.0) probe (0, 0) rgba (-1.0, -1.0, 2.0, 4.0)
% As above, but declare "x" as float4 and cast it to int4. % As above, but declare "x" as float4 and cast it to int4.
[pixel shader fail(sm>=6) todo(sm>=4)] [pixel shader fail(sm>=6)]
uniform float4 f; uniform float4 f;
@ -66,7 +66,7 @@ float4 main() : sv_target
[test] [test]
uniform 0 float4 -1.9 -1.0 2.9 4.0 uniform 0 float4 -1.9 -1.0 2.9 4.0
todo(sm>=4) draw quad draw quad
probe (0, 0) rgba (-1.0, -1.0, 2.0, 4.0) probe (0, 0) rgba (-1.0, -1.0, 2.0, 4.0)
@ -93,7 +93,7 @@ probe (0, 0) rgba (-1.0, 0.0, 1.0, -3000000.0) 4
% An explicit cast gets applied right before assignment, as if it was on the lhs. % An explicit cast gets applied right before assignment, as if it was on the lhs.
[pixel shader fail(sm>=6) todo(sm>=4)] [pixel shader fail(sm>=6)]
void fun(out float4 f) void fun(out float4 f)
{ {
f = float4(1.4, 2.6, 3.9, 4.3); f = float4(1.4, 2.6, 3.9, 4.3);
@ -108,7 +108,7 @@ float4 main() : sv_target
} }
[test] [test]
todo(sm>=4) draw quad draw quad
probe (0, 0) rgba(1, 2, 3, 4) probe (0, 0) rgba(1, 2, 3, 4)

View File

@ -162,7 +162,7 @@ float4 main() : sv_target
return float4(6789); return float4(6789);
} }
[pixel shader todo(sm>=4)] [pixel shader]
float4 main() : sv_target float4 main() : sv_target
{ {
int sin_out, cos_out; int sin_out, cos_out;
@ -171,5 +171,5 @@ float4 main() : sv_target
} }
[test] [test]
todo(sm>=4 & sm<6) draw quad todo(glsl | msl) draw quad
probe (0, 0) rgba (0, 0, 0, 0); probe (0, 0) rgba (0, 0, 0, 0);