mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/hlsl: Support lit() intrinsic.
This commit is contained in:
parent
02e3be811b
commit
d86db8bcbe
Notes:
Alexandre Julliard
2023-02-21 22:54:34 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Zebediah Figura (@zfigura) Approved-by: Francisco Casas (@fcasas) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/88
@ -117,6 +117,7 @@ vkd3d_shader_tests = \
|
||||
tests/hlsl-transpose.shader_test \
|
||||
tests/hlsl-vector-indexing.shader_test \
|
||||
tests/hlsl-vector-indexing-uniform.shader_test \
|
||||
tests/lit.shader_test \
|
||||
tests/logic-operations.shader_test \
|
||||
tests/majority-syntax.shader_test \
|
||||
tests/math.shader_test \
|
||||
|
@ -972,6 +972,8 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
|
||||
struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsigned int modifiers);
|
||||
const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type);
|
||||
|
||||
struct hlsl_ir_load *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *instrs,
|
||||
struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false);
|
||||
void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl);
|
||||
bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var);
|
||||
|
||||
|
@ -2667,6 +2667,111 @@ static bool intrinsic_lerp(struct hlsl_ctx *ctx,
|
||||
return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, params->args[0], mul, loc);
|
||||
}
|
||||
|
||||
static struct hlsl_ir_node * add_pow_expr(struct hlsl_ctx *ctx,
|
||||
struct list *instrs, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2,
|
||||
const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_node *log, *mul;
|
||||
|
||||
if (!(log = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_LOG2, arg1, loc)))
|
||||
return NULL;
|
||||
|
||||
if (!(mul = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_MUL, arg2, log, loc)))
|
||||
return NULL;
|
||||
|
||||
return add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_EXP2, mul, loc);
|
||||
}
|
||||
|
||||
static bool intrinsic_lit(struct hlsl_ctx *ctx,
|
||||
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_node *n_l_neg, *n_h_neg, *specular_or, *specular_pow;
|
||||
struct hlsl_ir_constant *init, *zero;
|
||||
struct hlsl_ir_node *n_l, *n_h, *m;
|
||||
struct hlsl_ir_node *diffuse;
|
||||
struct hlsl_ir_store *store;
|
||||
struct hlsl_deref var_deref;
|
||||
struct hlsl_type *ret_type;
|
||||
struct hlsl_ir_load *load;
|
||||
struct hlsl_ir_var *var;
|
||||
struct hlsl_block block;
|
||||
|
||||
if (params->args[0]->data_type->type != HLSL_CLASS_SCALAR
|
||||
|| params->args[1]->data_type->type != HLSL_CLASS_SCALAR
|
||||
|| params->args[2]->data_type->type != HLSL_CLASS_SCALAR)
|
||||
{
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Invalid argument type.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(n_l = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
||||
return false;
|
||||
|
||||
if (!(n_h = intrinsic_float_convert_arg(ctx, params, params->args[1], loc)))
|
||||
return false;
|
||||
|
||||
if (!(m = intrinsic_float_convert_arg(ctx, params, params->args[2], loc)))
|
||||
return false;
|
||||
|
||||
ret_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4);
|
||||
|
||||
if (!(var = hlsl_new_synthetic_var(ctx, "lit", ret_type, loc)))
|
||||
return false;
|
||||
hlsl_init_simple_deref_from_var(&var_deref, var);
|
||||
|
||||
if (!(init = hlsl_new_constant(ctx, ret_type, loc)))
|
||||
return false;
|
||||
init->value[0].f = 1.0f;
|
||||
init->value[1].f = 0.0f;
|
||||
init->value[2].f = 0.0f;
|
||||
init->value[3].f = 1.0f;
|
||||
list_add_tail(params->instrs, &init->node.entry);
|
||||
|
||||
if (!(store = hlsl_new_simple_store(ctx, var, &init->node)))
|
||||
return false;
|
||||
list_add_tail(params->instrs, &store->node.entry);
|
||||
|
||||
if (!(zero = hlsl_new_float_constant(ctx, 0.0f, loc)))
|
||||
return false;
|
||||
list_add_tail(params->instrs, &zero->node.entry);
|
||||
|
||||
/* Diffuse component. */
|
||||
if (!(diffuse = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, n_l, &zero->node, loc)))
|
||||
return false;
|
||||
|
||||
if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, 1, diffuse)))
|
||||
return false;
|
||||
list_move_tail(params->instrs, &block.instrs);
|
||||
|
||||
/* Specular component. */
|
||||
if (!(n_h_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS,
|
||||
n_h, &zero->node, loc)))
|
||||
return false;
|
||||
|
||||
if (!(n_l_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS,
|
||||
n_l, &zero->node, loc)))
|
||||
return false;
|
||||
|
||||
if (!(specular_or = add_binary_logical_expr(ctx, params->instrs, HLSL_OP2_LOGIC_OR, n_l_neg, n_h_neg, loc)))
|
||||
return false;
|
||||
|
||||
if (!(specular_pow = add_pow_expr(ctx, params->instrs, n_h, m, loc)))
|
||||
return false;
|
||||
|
||||
if (!(load = hlsl_add_conditional(ctx, params->instrs, specular_or, &zero->node, specular_pow)))
|
||||
return false;
|
||||
|
||||
if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, 2, &load->node)))
|
||||
return false;
|
||||
list_move_tail(params->instrs, &block.instrs);
|
||||
|
||||
if (!(load = hlsl_new_var_load(ctx, var, *loc)))
|
||||
return false;
|
||||
list_add_tail(params->instrs, &load->node.entry);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool intrinsic_max(struct hlsl_ctx *ctx,
|
||||
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
@ -2814,21 +2919,10 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx,
|
||||
static bool intrinsic_pow(struct hlsl_ctx *ctx,
|
||||
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_node *log, *exp, *mul;
|
||||
|
||||
if (!elementwise_intrinsic_float_convert_args(ctx, params, loc))
|
||||
return false;
|
||||
|
||||
if (!(log = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, params->args[0], loc)))
|
||||
return false;
|
||||
|
||||
if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[1], log, loc)))
|
||||
return false;
|
||||
|
||||
if (!(exp = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, mul, loc)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return !!add_pow_expr(ctx, params->instrs, params->args[0], params->args[1], loc);
|
||||
}
|
||||
|
||||
static bool intrinsic_reflect(struct hlsl_ctx *ctx,
|
||||
@ -3056,6 +3150,7 @@ intrinsic_functions[] =
|
||||
{"ldexp", 2, true, intrinsic_ldexp},
|
||||
{"length", 1, true, intrinsic_length},
|
||||
{"lerp", 3, true, intrinsic_lerp},
|
||||
{"lit", 3, true, intrinsic_lit},
|
||||
{"max", 2, true, intrinsic_max},
|
||||
{"min", 2, true, intrinsic_min},
|
||||
{"mul", 2, true, intrinsic_mul},
|
||||
|
@ -1865,7 +1865,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct hlsl_ir_load *add_conditional(struct hlsl_ctx *ctx, struct list *instrs,
|
||||
struct hlsl_ir_load *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *instrs,
|
||||
struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false)
|
||||
{
|
||||
struct hlsl_ir_store *store;
|
||||
@ -1962,7 +1962,7 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
||||
return false;
|
||||
list_add_before(&instr->entry, &neg->entry);
|
||||
|
||||
if (!(cond = add_conditional(ctx, &instr->entry, and, neg, &cast3->node)))
|
||||
if (!(cond = hlsl_add_conditional(ctx, &instr->entry, and, neg, &cast3->node)))
|
||||
return false;
|
||||
hlsl_replace_node(instr, &cond->node);
|
||||
|
||||
@ -2030,7 +2030,7 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
||||
return false;
|
||||
list_add_before(&instr->entry, &neg->entry);
|
||||
|
||||
if (!(cond = add_conditional(ctx, &instr->entry, and, neg, &cast3->node)))
|
||||
if (!(cond = hlsl_add_conditional(ctx, &instr->entry, and, neg, &cast3->node)))
|
||||
return false;
|
||||
hlsl_replace_node(instr, &cond->node);
|
||||
|
||||
@ -2105,7 +2105,7 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
|
||||
return false;
|
||||
list_add_before(&instr->entry, &neg2->entry);
|
||||
|
||||
if (!(cond = add_conditional(ctx, &instr->entry, ge, arg2, neg2)))
|
||||
if (!(cond = hlsl_add_conditional(ctx, &instr->entry, ge, arg2, neg2)))
|
||||
return false;
|
||||
|
||||
if (!(one = hlsl_new_constant(ctx, type, &instr->loc)))
|
||||
|
62
tests/lit.shader_test
Normal file
62
tests/lit.shader_test
Normal file
@ -0,0 +1,62 @@
|
||||
[pixel shader]
|
||||
float4 main(uniform float4 u) : sv_target
|
||||
{
|
||||
return lit(u.x, u.y, u.z);
|
||||
}
|
||||
|
||||
[test]
|
||||
uniform 0 float4 -0.1 10.0 0.0 0.0
|
||||
draw quad
|
||||
probe all rgba (1.0, 0.0, 0.0, 1.0)
|
||||
|
||||
[test]
|
||||
uniform 0 float4 1.2 -0.1 0.0 0.0
|
||||
draw quad
|
||||
probe all rgba (1.0, 1.2, 0.0, 1.0)
|
||||
|
||||
[test]
|
||||
uniform 0 float4 1.2 2.0 3.0 0.0
|
||||
draw quad
|
||||
probe all rgba (1.0, 1.2, 8.0, 1.0)
|
||||
|
||||
[pixel shader fail]
|
||||
float4 main(uniform float4 u) : sv_target
|
||||
{
|
||||
return lit(u.xy, u.y, u.z);
|
||||
}
|
||||
|
||||
[pixel shader fail]
|
||||
float4 main(uniform float4 u) : sv_target
|
||||
{
|
||||
return lit(u.x, u.xy, u.z);
|
||||
}
|
||||
|
||||
[pixel shader fail]
|
||||
float4 main(uniform float4 u) : sv_target
|
||||
{
|
||||
return lit(u.x, u.y, u.yz);
|
||||
}
|
||||
|
||||
[pixel shader fail]
|
||||
uniform float4x4 m;
|
||||
|
||||
float4 main(uniform float4 u) : sv_target
|
||||
{
|
||||
return lit(m, u.y, u.z);
|
||||
}
|
||||
|
||||
[pixel shader fail]
|
||||
uniform float4x4 m;
|
||||
|
||||
float4 main(uniform float4 u) : sv_target
|
||||
{
|
||||
return lit(u.x, m, u.z);
|
||||
}
|
||||
|
||||
[pixel shader fail]
|
||||
uniform float4x4 m;
|
||||
|
||||
float4 main(uniform float4 u) : sv_target
|
||||
{
|
||||
return lit(u.x, u.y, m);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user