mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/hlsl: Generate IR for user-defined function calls.
This commit is contained in:
committed by
Alexandre Julliard
parent
30550c0831
commit
b29d3489de
Notes:
Alexandre Julliard
2023-01-13 22:23:38 +01:00
Approved-by: Francisco Casas (@fcasas) Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/47
@@ -1162,17 +1162,16 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node)
|
||||
FIXME("Unhandled type %s.\n", hlsl_node_type_to_string(node->type));
|
||||
return 0;
|
||||
|
||||
case HLSL_IR_CALL:
|
||||
case HLSL_IR_IF:
|
||||
case HLSL_IR_JUMP:
|
||||
case HLSL_IR_LOOP:
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
case HLSL_IR_STORE:
|
||||
WARN("Invalid node type %s.\n", hlsl_node_type_to_string(node->type));
|
||||
return 0;
|
||||
|
||||
default:
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static bool expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
|
||||
@@ -2851,64 +2850,129 @@ static int intrinsic_function_name_compare(const void *a, const void *b)
|
||||
}
|
||||
|
||||
static struct list *add_call(struct hlsl_ctx *ctx, const char *name,
|
||||
struct parse_initializer *params, struct vkd3d_shader_location loc)
|
||||
struct parse_initializer *args, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
const struct hlsl_ir_function_decl *decl;
|
||||
struct intrinsic_function *intrinsic;
|
||||
|
||||
if ((decl = find_function_call(ctx, name, params)))
|
||||
if ((decl = find_function_call(ctx, name, args)))
|
||||
{
|
||||
hlsl_fixme(ctx, &loc, "Call to user-defined function \"%s\".", name);
|
||||
free_parse_initializer(params);
|
||||
return NULL;
|
||||
struct hlsl_ir_node *call;
|
||||
struct hlsl_ir_var *param;
|
||||
unsigned int i;
|
||||
|
||||
assert(args->args_count == list_count(decl->parameters));
|
||||
|
||||
i = 0;
|
||||
LIST_FOR_EACH_ENTRY(param, decl->parameters, struct hlsl_ir_var, param_entry)
|
||||
{
|
||||
struct hlsl_ir_node *arg = args->args[i++];
|
||||
|
||||
if (!hlsl_types_are_equal(arg->data_type, param->data_type))
|
||||
{
|
||||
hlsl_fixme(ctx, &arg->loc, "Implicit cast of a function argument.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param->storage_modifiers & HLSL_STORAGE_IN)
|
||||
{
|
||||
struct hlsl_ir_store *store;
|
||||
|
||||
if (!(store = hlsl_new_simple_store(ctx, param, arg)))
|
||||
goto fail;
|
||||
list_add_tail(args->instrs, &store->node.entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(call = hlsl_new_call(ctx, decl, loc)))
|
||||
goto fail;
|
||||
list_add_tail(args->instrs, &call->entry);
|
||||
|
||||
i = 0;
|
||||
LIST_FOR_EACH_ENTRY(param, decl->parameters, struct hlsl_ir_var, param_entry)
|
||||
{
|
||||
struct hlsl_ir_node *arg = args->args[i++];
|
||||
|
||||
if (param->storage_modifiers & HLSL_STORAGE_OUT)
|
||||
{
|
||||
struct hlsl_ir_load *load;
|
||||
|
||||
if (arg->data_type->modifiers & HLSL_MODIFIER_CONST)
|
||||
hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST,
|
||||
"Output argument to \"%s\" is const.", decl->func->name);
|
||||
|
||||
if (!(load = hlsl_new_var_load(ctx, param, arg->loc)))
|
||||
goto fail;
|
||||
list_add_tail(args->instrs, &load->node.entry);
|
||||
|
||||
if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (decl->return_var)
|
||||
{
|
||||
struct hlsl_ir_load *load;
|
||||
|
||||
if (!(load = hlsl_new_var_load(ctx, decl->return_var, *loc)))
|
||||
goto fail;
|
||||
list_add_tail(args->instrs, &load->node.entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
|
||||
struct hlsl_ir_node *expr;
|
||||
|
||||
if (!(expr = hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc)))
|
||||
goto fail;
|
||||
list_add_tail(args->instrs, &expr->entry);
|
||||
}
|
||||
}
|
||||
else if ((intrinsic = bsearch(name, intrinsic_functions, ARRAY_SIZE(intrinsic_functions),
|
||||
sizeof(*intrinsic_functions), intrinsic_function_name_compare)))
|
||||
{
|
||||
if (intrinsic->param_count >= 0 && params->args_count != intrinsic->param_count)
|
||||
if (intrinsic->param_count >= 0 && args->args_count != intrinsic->param_count)
|
||||
{
|
||||
hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
||||
"Wrong number of arguments to function '%s': expected %u, but got %u.",
|
||||
name, intrinsic->param_count, params->args_count);
|
||||
free_parse_initializer(params);
|
||||
return NULL;
|
||||
name, intrinsic->param_count, args->args_count);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (intrinsic->check_numeric)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < params->args_count; ++i)
|
||||
for (i = 0; i < args->args_count; ++i)
|
||||
{
|
||||
if (params->args[i]->data_type->type > HLSL_CLASS_LAST_NUMERIC)
|
||||
if (args->args[i]->data_type->type > HLSL_CLASS_LAST_NUMERIC)
|
||||
{
|
||||
struct vkd3d_string_buffer *string;
|
||||
|
||||
if ((string = hlsl_type_to_string(ctx, params->args[i]->data_type)))
|
||||
hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
if ((string = hlsl_type_to_string(ctx, args->args[i]->data_type)))
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
"Wrong type for argument %u of '%s': expected a numeric type, but got '%s'.",
|
||||
i + 1, name, string->buffer);
|
||||
hlsl_release_string_buffer(ctx, string);
|
||||
free_parse_initializer(params);
|
||||
return NULL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!intrinsic->handler(ctx, params, &loc))
|
||||
{
|
||||
free_parse_initializer(params);
|
||||
return NULL;
|
||||
}
|
||||
if (!intrinsic->handler(ctx, args, loc))
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Function \"%s\" is not defined.", name);
|
||||
free_parse_initializer(params);
|
||||
return NULL;
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Function \"%s\" is not defined.", name);
|
||||
goto fail;
|
||||
}
|
||||
vkd3d_free(params->args);
|
||||
return params->instrs;
|
||||
vkd3d_free(args->args);
|
||||
return args->instrs;
|
||||
|
||||
fail:
|
||||
free_parse_initializer(args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type,
|
||||
@@ -4633,7 +4697,7 @@ primary_expr:
|
||||
}
|
||||
| var_identifier '(' func_arguments ')'
|
||||
{
|
||||
if (!($$ = add_call(ctx, $1, &$3, @1)))
|
||||
if (!($$ = add_call(ctx, $1, &$3, &@1)))
|
||||
YYABORT;
|
||||
}
|
||||
| NEW_IDENTIFIER
|
||||
|
||||
Reference in New Issue
Block a user