From: Francisco Casas fcasas@codeweavers.com
While a deref's data type can be computed from the variable's data type as long as the deref is still represented as a path (as we did with hlsl_deref_get_type()), we need the deref.data_type field for when the deref is represented as an offset.
While we could get rid of it in the future, if we manage to transform the HLSL IR instructions directly to VSIR withot requiring lowering the derefs to their offset representation, this would take a while.
So, this patch makes the deref.data_type field available during the whole lifetime of the deref. Which makes deref.data_type easier to understand (since it can be used anytime now) and we no longer have to call hlsl_deref_get_type(). --- libs/vkd3d-shader/hlsl.c | 39 ++++++++++++++++++++++---------- libs/vkd3d-shader/hlsl.h | 7 +++--- libs/vkd3d-shader/hlsl_codegen.c | 4 ++-- 3 files changed, 33 insertions(+), 17 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 09580970..52766671 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -503,6 +503,8 @@ static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hl deref->path_len = path_len; deref->offset.node = NULL;
+ deref->data_type = NULL; + if (path_len == 0) { deref->path = NULL; @@ -519,6 +521,17 @@ static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hl return true; }
+void hlsl_deref_compute_data_type(struct hlsl_ctx *ctx, struct hlsl_deref *deref) +{ + struct hlsl_type *type = deref->var->data_type; + unsigned int i; + + for (i = 0; i < deref->path_len; ++i) + type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node); + + deref->data_type = type; +} + bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain) { struct hlsl_ir_index *index; @@ -581,23 +594,14 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d } assert(deref->path_len == load->src.path_len + chain_len);
+ hlsl_deref_compute_data_type(ctx, deref); + return true; }
struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) { - struct hlsl_type *type; - unsigned int i; - - assert(deref); - - if (deref->offset.node) - return deref->data_type; - - type = deref->var->data_type; - for (i = 0; i < deref->path_len; ++i) - type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node); - return type; + return deref->data_type; }
/* Initializes a deref from another deref (prefix) and a component index. @@ -646,6 +650,8 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl
assert(deref_path_len == deref->path_len);
+ deref->data_type = path_type; + return true; }
@@ -1110,6 +1116,8 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc for (i = 0; i < deref->path_len; ++i) hlsl_src_from_node(&deref->path[i], other->path[i].node);
+ deref->data_type = other->data_type; + return true; }
@@ -1132,6 +1140,7 @@ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_va { memset(deref, 0, sizeof(*deref)); deref->var = var; + deref->data_type = var->data_type; }
static void init_node(struct hlsl_ir_node *node, enum hlsl_ir_node_type type, @@ -1174,6 +1183,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls hlsl_src_from_node(&store->lhs.path[i], lhs->path[i].node); if (idx) hlsl_src_from_node(&store->lhs.path[lhs->path_len], idx); + hlsl_deref_compute_data_type(ctx, &store->lhs);
hlsl_src_from_node(&store->rhs, rhs);
@@ -1351,6 +1361,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl hlsl_src_from_node(&load->src.path[i], deref->path[i].node); if (idx) hlsl_src_from_node(&load->src.path[deref->path_len], idx); + hlsl_deref_compute_data_type(ctx, &load->src);
return load; } @@ -1365,6 +1376,8 @@ struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hls
tmp_deref = *deref; tmp_deref.path_len = deref->path_len - 1; + hlsl_deref_compute_data_type(ctx, &tmp_deref); + return hlsl_new_load_index(ctx, &tmp_deref, NULL, loc); }
@@ -1613,6 +1626,8 @@ static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map, for (i = 0; i < src->path_len; ++i) hlsl_src_from_node(&dst->path[i], map_instr(map, src->path[i].node));
+ dst->data_type = src->data_type; + return true; }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 04e681a9..5bc59add 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -615,10 +615,10 @@ struct hlsl_deref * components, within the pertaining regset), from the start of the variable, of the part * referenced. * The path is lowered to this single offset -- whose value may vary between SM1 and SM4 -- - * before writing the bytecode. - * Since the type information cannot longer be retrieved from the offset alone, the type is - * stored in the data_type field. */ + * before writing the bytecode. */ struct hlsl_src offset; + + /* Type of the part of the variable referenced by this deref. */ struct hlsl_type *data_type; };
@@ -1247,6 +1247,7 @@ unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask); unsigned int hlsl_swizzle_from_writemask(unsigned int writemask);
struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); +void hlsl_deref_compute_data_type(struct hlsl_ctx *ctx, struct hlsl_deref *deref); bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *start, unsigned int *count); bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 132f44a2..023f2e8d 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -146,8 +146,6 @@ static bool replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der return true; }
- deref->data_type = type; - if (!(offset = new_offset_instr_from_deref(ctx, &block, deref, &instr->loc))) return false; list_move_before(&instr->entry, &block.instrs); @@ -2181,6 +2179,8 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
hlsl_copy_deref(ctx, &load->sampler, &load->resource); load->resource.var = var; + hlsl_deref_compute_data_type(ctx, &load->resource); + assert(hlsl_deref_get_type(ctx, &load->resource)->base_type == HLSL_TYPE_TEXTURE); assert(hlsl_deref_get_type(ctx, &load->sampler)->base_type == HLSL_TYPE_SAMPLER);