mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/hlsl: Parse loop and unroll loop attributes.
Based on a patch by Nikolay Sivov. Co-authored-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
parent
323f53bd7d
commit
5bc56d43bb
Notes:
Henri Verbeet
2024-07-11 00:40:50 +02:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/786
@ -1810,7 +1810,8 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type
|
||||
}
|
||||
|
||||
struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx,
|
||||
struct hlsl_block *block, const struct vkd3d_shader_location *loc)
|
||||
struct hlsl_block *block, enum hlsl_ir_loop_unroll_type unroll_type,
|
||||
unsigned int unroll_limit, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_loop *loop;
|
||||
|
||||
@ -1819,6 +1820,9 @@ struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx,
|
||||
init_node(&loop->node, HLSL_IR_LOOP, NULL, loc);
|
||||
hlsl_block_init(&loop->body);
|
||||
hlsl_block_add_block(&loop->body, block);
|
||||
|
||||
loop->unroll_type = unroll_type;
|
||||
loop->unroll_limit = unroll_limit;
|
||||
return &loop->node;
|
||||
}
|
||||
|
||||
@ -1980,7 +1984,7 @@ static struct hlsl_ir_node *clone_loop(struct hlsl_ctx *ctx, struct clone_instr_
|
||||
if (!clone_block(ctx, &body, &src->body, map))
|
||||
return NULL;
|
||||
|
||||
if (!(dst = hlsl_new_loop(ctx, &body, &src->node.loc)))
|
||||
if (!(dst = hlsl_new_loop(ctx, &body, src->unroll_type, src->unroll_limit, &src->node.loc)))
|
||||
{
|
||||
hlsl_block_cleanup(&body);
|
||||
return NULL;
|
||||
|
@ -602,12 +602,21 @@ struct hlsl_ir_if
|
||||
struct hlsl_block else_block;
|
||||
};
|
||||
|
||||
enum hlsl_ir_loop_unroll_type
|
||||
{
|
||||
HLSL_IR_LOOP_UNROLL,
|
||||
HLSL_IR_LOOP_FORCE_UNROLL,
|
||||
HLSL_IR_LOOP_FORCE_LOOP
|
||||
};
|
||||
|
||||
struct hlsl_ir_loop
|
||||
{
|
||||
struct hlsl_ir_node node;
|
||||
/* loop condition is stored in the body (as "if (!condition) break;") */
|
||||
struct hlsl_block body;
|
||||
unsigned int next_index; /* liveness index of the end of the loop */
|
||||
unsigned int unroll_limit;
|
||||
enum hlsl_ir_loop_unroll_type unroll_type;
|
||||
};
|
||||
|
||||
struct hlsl_ir_switch_case
|
||||
@ -1390,7 +1399,7 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index);
|
||||
struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val,
|
||||
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx,
|
||||
struct hlsl_block *block, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_block *block, enum hlsl_ir_loop_unroll_type unroll_type, unsigned int unroll_limit, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
|
||||
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource,
|
||||
|
@ -655,8 +655,9 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type,
|
||||
const struct parse_attribute_list *attributes, struct hlsl_block *init, struct hlsl_block *cond,
|
||||
struct hlsl_block *iter, struct hlsl_block *body, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
enum hlsl_ir_loop_unroll_type unroll_type = HLSL_IR_LOOP_UNROLL;
|
||||
unsigned int i, unroll_limit = 0;
|
||||
struct hlsl_ir_node *loop;
|
||||
unsigned int i;
|
||||
|
||||
if (attribute_list_has_duplicates(attributes))
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Found duplicate attribute.");
|
||||
@ -669,18 +670,29 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type,
|
||||
const struct hlsl_attribute *attr = attributes->attrs[i];
|
||||
if (!strcmp(attr->name, "unroll"))
|
||||
{
|
||||
if (attr->args_count)
|
||||
if (attr->args_count > 1)
|
||||
{
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "Unroll attribute with iteration count.");
|
||||
hlsl_warning(ctx, &attr->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE,
|
||||
"Ignoring 'unroll' attribute with more than 1 argument.");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
||||
if (attr->args_count == 1)
|
||||
{
|
||||
hlsl_warning(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "Loop unrolling is not implemented.");
|
||||
struct hlsl_block expr;
|
||||
hlsl_block_init(&expr);
|
||||
if (!hlsl_clone_block(ctx, &expr, &attr->instrs))
|
||||
return NULL;
|
||||
|
||||
unroll_limit = evaluate_static_expression_as_uint(ctx, &expr, loc);
|
||||
hlsl_block_cleanup(&expr);
|
||||
}
|
||||
|
||||
unroll_type = HLSL_IR_LOOP_FORCE_UNROLL;
|
||||
}
|
||||
else if (!strcmp(attr->name, "loop"))
|
||||
{
|
||||
/* TODO: this attribute will be used to disable unrolling, once it's implememented. */
|
||||
unroll_type = HLSL_IR_LOOP_FORCE_LOOP;
|
||||
}
|
||||
else if (!strcmp(attr->name, "fastopt")
|
||||
|| !strcmp(attr->name, "allow_uav_condition"))
|
||||
@ -709,7 +721,7 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type,
|
||||
else
|
||||
list_move_head(&body->instrs, &cond->instrs);
|
||||
|
||||
if (!(loop = hlsl_new_loop(ctx, body, loc)))
|
||||
if (!(loop = hlsl_new_loop(ctx, body, unroll_type, unroll_limit, loc)))
|
||||
goto oom;
|
||||
hlsl_block_add_instr(init, loop);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user