mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/hlsl: Use hlsl_ir_index for array and record access.
From this point on, it is no longer true that only hlsl_ir_loads can return objects, because an object can also come from chain of hlsl_ir_indexes that ends in an hlsl_ir_load. The lower_index_loads pass takes care of lowering all hlsl_ir_indexes into hlsl_ir_loads. For this reason, hlsl_resource_load_params now expects both the resource as the sampler to be just an hlsl_ir_node pointer instead of a pointer to a more specific hlsl_ir_load.
This commit is contained in:
committed by
Alexandre Julliard
parent
741c9e5893
commit
5c285adc6b
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
@@ -438,6 +438,71 @@ static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hl
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
struct hlsl_ir_load *load;
|
||||
unsigned int chain_len, i;
|
||||
struct hlsl_ir_node *ptr;
|
||||
|
||||
deref->path = NULL;
|
||||
deref->path_len = 0;
|
||||
deref->offset.node = NULL;
|
||||
|
||||
assert(chain);
|
||||
if (chain->type == HLSL_IR_INDEX)
|
||||
assert(!hlsl_index_is_noncontiguous(hlsl_ir_index(chain)));
|
||||
|
||||
/* Find the length of the index chain */
|
||||
chain_len = 0;
|
||||
ptr = chain;
|
||||
while (ptr->type == HLSL_IR_INDEX)
|
||||
{
|
||||
index = hlsl_ir_index(ptr);
|
||||
|
||||
chain_len++;
|
||||
ptr = index->val.node;
|
||||
}
|
||||
|
||||
if (ptr->type != HLSL_IR_LOAD)
|
||||
{
|
||||
hlsl_error(ctx, &chain->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid l-value.");
|
||||
return false;
|
||||
}
|
||||
load = hlsl_ir_load(ptr);
|
||||
|
||||
if (!init_deref(ctx, deref, load->src.var, load->src.path_len + chain_len))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < load->src.path_len; ++i)
|
||||
hlsl_src_from_node(&deref->path[i], load->src.path[i].node);
|
||||
|
||||
chain_len = 0;
|
||||
ptr = chain;
|
||||
while (ptr->type == HLSL_IR_INDEX)
|
||||
{
|
||||
unsigned int p = deref->path_len - 1 - chain_len;
|
||||
|
||||
index = hlsl_ir_index(ptr);
|
||||
if (hlsl_index_is_noncontiguous(index))
|
||||
{
|
||||
hlsl_src_from_node(&deref->path[p], deref->path[p + 1].node);
|
||||
hlsl_src_remove(&deref->path[p + 1]);
|
||||
hlsl_src_from_node(&deref->path[p + 1], index->idx.node);
|
||||
}
|
||||
else
|
||||
{
|
||||
hlsl_src_from_node(&deref->path[p], index->idx.node);
|
||||
}
|
||||
|
||||
chain_len++;
|
||||
ptr = index->val.node;
|
||||
}
|
||||
assert(deref->path_len == load->src.path_len + chain_len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_deref *deref)
|
||||
{
|
||||
struct hlsl_type *type;
|
||||
@@ -1232,17 +1297,23 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx,
|
||||
return NULL;
|
||||
init_node(&load->node, HLSL_IR_RESOURCE_LOAD, params->format, loc);
|
||||
load->load_type = params->type;
|
||||
if (!hlsl_copy_deref(ctx, &load->resource, ¶ms->resource))
|
||||
|
||||
if (!hlsl_init_deref_from_index_chain(ctx, &load->resource, params->resource))
|
||||
{
|
||||
vkd3d_free(load);
|
||||
return NULL;
|
||||
}
|
||||
if (!hlsl_copy_deref(ctx, &load->sampler, ¶ms->sampler))
|
||||
|
||||
if (params->sampler)
|
||||
{
|
||||
hlsl_cleanup_deref(&load->resource);
|
||||
vkd3d_free(load);
|
||||
return NULL;
|
||||
if (!hlsl_init_deref_from_index_chain(ctx, &load->sampler, params->sampler))
|
||||
{
|
||||
hlsl_cleanup_deref(&load->resource);
|
||||
vkd3d_free(load);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
hlsl_src_from_node(&load->coords, params->coords);
|
||||
hlsl_src_from_node(&load->texel_offset, params->texel_offset);
|
||||
hlsl_src_from_node(&load->lod, params->lod);
|
||||
@@ -1281,6 +1352,13 @@ struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned
|
||||
return swizzle;
|
||||
}
|
||||
|
||||
bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index)
|
||||
{
|
||||
struct hlsl_type *type = index->val.node->data_type;
|
||||
|
||||
return type->class == HLSL_CLASS_MATRIX && !hlsl_type_is_row_major(type);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user