vkd3d-shader/hlsl: Introduce hlsl_ir_index.

This node type is intended for use during parse-time.

While we parse an indexing expression such as "a[3]", we don't know if
it will end up as part of an expression (in which case it must be folded
into a load) or it is for the lhs of a store (in which case it must be
folded into the store's deref).
This commit is contained in:
Francisco Casas 2023-02-24 16:39:56 -03:00 committed by Alexandre Julliard
parent 8cd3defe0d
commit 741c9e5893
Notes: Alexandre Julliard 2023-04-13 23:20:40 +02:00
Approved-by: Zebediah Figura (@zfigura)
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/124
4 changed files with 85 additions and 0 deletions

View File

@ -1281,6 +1281,28 @@ struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned
return swizzle;
}
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_type *type = val->data_type;
struct hlsl_ir_index *index;
if (!(index = hlsl_alloc(ctx, sizeof(*index))))
return NULL;
if (type->class == HLSL_CLASS_OBJECT)
type = type->e.resource_format;
else if (type->class == HLSL_CLASS_MATRIX)
type = hlsl_get_vector_type(ctx, type->base_type, type->dimx);
else
type = hlsl_get_element_type_from_path_index(ctx, type, idx);
init_node(&index->node, HLSL_IR_INDEX, type, loc);
hlsl_src_from_node(&index->val, val);
hlsl_src_from_node(&index->idx, idx);
return &index->node;
}
struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc)
{
struct hlsl_ir_jump *jump;
@ -1540,6 +1562,17 @@ static struct hlsl_ir_node *clone_swizzle(struct hlsl_ctx *ctx,
return &dst->node;
}
static struct hlsl_ir_node *clone_index(struct hlsl_ctx *ctx, struct clone_instr_map *map,
struct hlsl_ir_index *src)
{
struct hlsl_ir_node *dst;
if (!(dst = hlsl_new_index(ctx, map_instr(map, src->val.node), map_instr(map, src->idx.node),
&src->node.loc)))
return NULL;
return dst;
}
static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
struct clone_instr_map *map, const struct hlsl_ir_node *instr)
{
@ -1557,6 +1590,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
case HLSL_IR_IF:
return clone_if(ctx, map, hlsl_ir_if(instr));
case HLSL_IR_INDEX:
return clone_index(ctx, map, hlsl_ir_index(instr));
case HLSL_IR_JUMP:
return clone_jump(ctx, hlsl_ir_jump(instr));
@ -1946,6 +1982,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
"HLSL_IR_CONSTANT",
"HLSL_IR_EXPR",
"HLSL_IR_IF",
"HLSL_IR_INDEX",
"HLSL_IR_LOAD",
"HLSL_IR_LOOP",
"HLSL_IR_JUMP",
@ -2324,6 +2361,14 @@ static void dump_ir_swizzle(struct vkd3d_string_buffer *buffer, const struct hls
}
}
static void dump_ir_index(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_index *index)
{
dump_src(buffer, &index->val);
vkd3d_string_buffer_printf(buffer, "[idx:");
dump_src(buffer, &index->idx);
vkd3d_string_buffer_printf(buffer, "]");
}
static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_node *instr)
{
if (instr->index)
@ -2351,6 +2396,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
dump_ir_if(ctx, buffer, hlsl_ir_if(instr));
break;
case HLSL_IR_INDEX:
dump_ir_index(buffer, hlsl_ir_index(instr));
break;
case HLSL_IR_JUMP:
dump_ir_jump(buffer, hlsl_ir_jump(instr));
break;
@ -2525,6 +2574,13 @@ static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle)
vkd3d_free(swizzle);
}
static void free_ir_index(struct hlsl_ir_index *index)
{
hlsl_src_remove(&index->val);
hlsl_src_remove(&index->idx);
vkd3d_free(index);
}
void hlsl_free_instr(struct hlsl_ir_node *node)
{
assert(list_empty(&node->uses));
@ -2547,6 +2603,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
free_ir_if(hlsl_ir_if(node));
break;
case HLSL_IR_INDEX:
free_ir_index(hlsl_ir_index(node));
break;
case HLSL_IR_JUMP:
free_ir_jump(hlsl_ir_jump(node));
break;

View File

@ -254,6 +254,7 @@ enum hlsl_ir_node_type
HLSL_IR_CONSTANT,
HLSL_IR_EXPR,
HLSL_IR_IF,
HLSL_IR_INDEX,
HLSL_IR_LOAD,
HLSL_IR_LOOP,
HLSL_IR_JUMP,
@ -544,6 +545,12 @@ struct hlsl_ir_swizzle
DWORD swizzle;
};
struct hlsl_ir_index
{
struct hlsl_ir_node node;
struct hlsl_src val, idx;
};
/* Reference to a variable, or a part of it (e.g. a vector within a matrix within a struct). */
struct hlsl_deref
{
@ -857,6 +864,12 @@ static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node
return CONTAINING_RECORD(node, struct hlsl_ir_swizzle, node);
}
static inline struct hlsl_ir_index *hlsl_ir_index(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_INDEX);
return CONTAINING_RECORD(node, struct hlsl_ir_index, node);
}
static inline void hlsl_block_init(struct hlsl_block *block)
{
list_init(&block->instrs);
@ -1072,6 +1085,8 @@ struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hl
struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs);
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_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc);
struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx,
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);

View File

@ -1210,6 +1210,7 @@ static unsigned int evaluate_static_expression(struct hlsl_ir_node *node)
}
case HLSL_IR_EXPR:
case HLSL_IR_INDEX:
case HLSL_IR_LOAD:
case HLSL_IR_RESOURCE_LOAD:
case HLSL_IR_SWIZZLE:

View File

@ -2200,6 +2200,7 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
{
case HLSL_IR_CONSTANT:
case HLSL_IR_EXPR:
case HLSL_IR_INDEX:
case HLSL_IR_LOAD:
case HLSL_IR_RESOURCE_LOAD:
case HLSL_IR_SWIZZLE:
@ -2440,6 +2441,14 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
swizzle->val.node->last_read = instr->index;
break;
}
case HLSL_IR_INDEX:
{
struct hlsl_ir_index *index = hlsl_ir_index(instr);
index->val.node->last_read = instr->index;
index->idx.node->last_read = instr->index;
break;
}
case HLSL_IR_CONSTANT:
case HLSL_IR_JUMP:
break;