Skip to content
Snippets Groups Projects
Commit d610a3ad authored by Francisco Casas's avatar Francisco Casas
Browse files

vkd3d-shader/hlsl: Use hlsl_ir_index for resource access.

parent 18baf467
No related branches found
Tags wine-0.9.54
No related merge requests found
......@@ -448,6 +448,8 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d
if (!chain)
return true;
assert(chain->type != HLSL_IR_INDEX || !hlsl_index_is_resource_access(hlsl_ir_index(chain)));
/* Find the length of the index chain */
chain_len = 0;
ptr = chain;
......@@ -1337,6 +1339,11 @@ bool hlsl_index_is_crooked_matrix_indexing(struct hlsl_ir_index *index)
return type->type == HLSL_CLASS_MATRIX && (hlsl_type_is_row_major(type) == index->is_column_indexing);
}
bool hlsl_index_is_resource_access(struct hlsl_ir_index *index)
{
return index->val.node->data_type->type == HLSL_CLASS_OBJECT;
}
struct hlsl_ir_index *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val,
struct hlsl_ir_node *idx, bool is_column_indexing, const struct vkd3d_shader_location *loc)
{
......
......@@ -1065,6 +1065,7 @@ struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl
const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs);
bool hlsl_index_is_crooked_matrix_indexing(struct hlsl_ir_index *index);
bool hlsl_index_is_resource_access(struct hlsl_ir_index *index);
struct hlsl_ir_index *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val,
struct hlsl_ir_node *idx, bool is_column_indexing, const struct vkd3d_shader_location *loc);
......
......@@ -712,9 +712,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h
&& (expr_type->base_type == HLSL_TYPE_TEXTURE || expr_type->base_type == HLSL_TYPE_UAV)
&& expr_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC)
{
struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD};
unsigned int dim_count = hlsl_sampler_dim_count(expr_type->sampler_dim);
struct hlsl_ir_resource_load *resource_load;
if (index_type->type > HLSL_CLASS_VECTOR || index_type->dimx != dim_count)
{
......@@ -734,13 +732,10 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h
if (!(index = add_zero_mipmap_level(ctx, instrs, index, dim_count, loc)))
return false;
load_params.format = expr_type->e.resource_format;
load_params.resource = array;
load_params.coords = index;
if (!(resource_load = hlsl_new_resource_load(ctx, &load_params, loc)))
if (!(return_index = hlsl_new_index(ctx, array, index, false, loc)))
return false;
list_add_tail(instrs, &resource_load->node.entry);
list_add_tail(instrs, &return_index->node.entry);
return true;
}
......@@ -1644,7 +1639,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
if (!(rhs = add_implicit_conversion(ctx, instrs, rhs, lhs_type, &rhs->loc)))
return NULL;
while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_RESOURCE_LOAD && lhs->type != HLSL_IR_INDEX)
while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_INDEX)
{
if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST)
{
......@@ -1681,17 +1676,19 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
}
}
if (lhs->type == HLSL_IR_RESOURCE_LOAD)
if (lhs->type == HLSL_IR_INDEX && hlsl_index_is_resource_access(hlsl_ir_index(lhs)))
{
struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(lhs);
struct hlsl_ir_node *load_coords = hlsl_ir_index(lhs)->idx.node;
struct hlsl_ir_resource_store *store;
struct hlsl_deref resource_deref;
struct hlsl_type *resource_type;
struct hlsl_ir_swizzle *coords;
unsigned int dim_count;
/* Such an lvalue was produced by an index expression. */
assert(load->load_type == HLSL_RESOURCE_LOAD);
resource_type = hlsl_deref_get_type(ctx, &load->resource);
if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, hlsl_ir_index(lhs)->val.node))
return NULL;
resource_type = hlsl_deref_get_type(ctx, &resource_deref);
assert(resource_type->type == HLSL_CLASS_OBJECT);
assert(resource_type->base_type == HLSL_TYPE_TEXTURE || resource_type->base_type == HLSL_TYPE_UAV);
......@@ -1700,22 +1697,28 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
"Read-only resources cannot be stored to.");
dim_count = hlsl_sampler_dim_count(resource_type->sampler_dim);
if (writemask != ((1u << resource_type->e.resource_format->dimx) - 1))
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK,
"Resource store expressions must write to all components.");
/* Remove the (implicit) mipmap level from the load expression. */
assert(load->coords.node->data_type->type == HLSL_CLASS_VECTOR);
assert(load->coords.node->data_type->base_type == HLSL_TYPE_UINT);
assert(load->coords.node->data_type->dimx == dim_count + 1);
if (!(coords = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dim_count, load->coords.node, &lhs->loc)))
assert(load_coords->data_type->type == HLSL_CLASS_VECTOR);
assert(load_coords->data_type->base_type == HLSL_TYPE_UINT);
assert(load_coords->data_type->dimx == dim_count + 1);
if (!(coords = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dim_count, load_coords, &lhs->loc)))
{
hlsl_cleanup_deref(&resource_deref);
return NULL;
}
list_add_tail(instrs, &coords->node.entry);
if (!(store = hlsl_new_resource_store(ctx, &load->resource, &coords->node, rhs, &lhs->loc)))
if (!(store = hlsl_new_resource_store(ctx, &resource_deref, &coords->node, rhs, &lhs->loc)))
{
hlsl_cleanup_deref(&resource_deref);
return NULL;
}
list_add_tail(instrs, &store->node.entry);
hlsl_cleanup_deref(&resource_deref);
}
else if (lhs->type == HLSL_IR_INDEX && hlsl_index_is_crooked_matrix_indexing(hlsl_ir_index(lhs)))
{
......
......@@ -735,7 +735,8 @@ static bool lower_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *
* record access before knowing if they will be used in the lhs of an assignment --in which case
* they are lowered into a deref-- or as the load of an element within a larger value.
* For the latter case, this pass takes care of lowering hlsl_ir_indexes (and index chains) into
* individual hlsl_ir_loads.
* individual hlsl_ir_loads, or individual hlsl_ir_resource_loads, in case the indexing is a
* resource access.
* It is worth noting that the generated hlsl_ir_loads don't load from a copy of the variable loaded
* at the beggining of the index chain, but from the same variable instead, because it is assumed
* that the value of the variable won't change between the the hlsl_ir_load instruction and the
......@@ -794,6 +795,22 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
return true;
}
else if (hlsl_index_is_resource_access(index))
{
struct hlsl_resource_load_params params = {0};
struct hlsl_ir_resource_load *load;
params.type = HLSL_RESOURCE_LOAD;
params.resource = index->val.node;
params.coords = index->idx.node;
params.format = index->val.node->data_type->e.resource_format;
if (!(load = hlsl_new_resource_load(ctx, &params, &instr->loc)))
return false;
list_add_before(&instr->entry, &load->node.entry);
hlsl_replace_node(instr, &load->node);
return true;
}
else
{
struct hlsl_ir_load *load;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment