mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/hlsl: Parse UAV stores.
This commit is contained in:
parent
0a2aaa690e
commit
03f9d16047
Notes:
Alexandre Julliard
2022-10-31 22:39:35 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Zebediah Figura (@zfigura) Approved-by: Francisco Casas (@fcasas) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/36
@ -373,7 +373,7 @@ static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hl
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct hlsl_type *get_type_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref)
|
||||
struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_deref *deref)
|
||||
{
|
||||
struct hlsl_type *type;
|
||||
unsigned int i;
|
||||
@ -400,7 +400,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl
|
||||
list_init(&block->instrs);
|
||||
|
||||
path_len = 0;
|
||||
path_type = get_type_from_deref(ctx, prefix);
|
||||
path_type = hlsl_deref_get_type(ctx, prefix);
|
||||
path_index = index;
|
||||
while (!type_is_single_component(path_type))
|
||||
{
|
||||
@ -415,7 +415,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl
|
||||
for (i = 0; i < prefix->path_len; ++i)
|
||||
hlsl_src_from_node(&deref->path[deref_path_len++], prefix->path[i].node);
|
||||
|
||||
path_type = get_type_from_deref(ctx, prefix);
|
||||
path_type = hlsl_deref_get_type(ctx, prefix);
|
||||
path_index = index;
|
||||
while (!type_is_single_component(path_type))
|
||||
{
|
||||
@ -1045,7 +1045,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl
|
||||
|
||||
assert(!deref->offset.node);
|
||||
|
||||
type = get_type_from_deref(ctx, deref);
|
||||
type = hlsl_deref_get_type(ctx, deref);
|
||||
if (idx)
|
||||
type = hlsl_get_element_type_from_path_index(ctx, type, idx);
|
||||
|
||||
@ -1087,7 +1087,7 @@ struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b
|
||||
if (!(load = hlsl_alloc(ctx, sizeof(*load))))
|
||||
return NULL;
|
||||
|
||||
type = get_type_from_deref(ctx, deref);
|
||||
type = hlsl_deref_get_type(ctx, deref);
|
||||
comp_type = hlsl_type_get_component_type(ctx, type, comp);
|
||||
init_node(&load->node, HLSL_IR_LOAD, comp_type, loc);
|
||||
|
||||
@ -1129,6 +1129,20 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx,
|
||||
return load;
|
||||
}
|
||||
|
||||
struct hlsl_ir_resource_store *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource,
|
||||
struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_resource_store *store;
|
||||
|
||||
if (!(store = hlsl_alloc(ctx, sizeof(*store))))
|
||||
return NULL;
|
||||
init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc);
|
||||
hlsl_copy_deref(ctx, &store->resource, resource);
|
||||
hlsl_src_from_node(&store->coords, coords);
|
||||
hlsl_src_from_node(&store->value, value);
|
||||
return store;
|
||||
}
|
||||
|
||||
struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components,
|
||||
struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
@ -1511,6 +1525,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
|
||||
"HLSL_IR_LOOP",
|
||||
"HLSL_IR_JUMP",
|
||||
"HLSL_IR_RESOURCE_LOAD",
|
||||
"HLSL_IR_RESOURCE_STORE",
|
||||
"HLSL_IR_STORE",
|
||||
"HLSL_IR_SWIZZLE",
|
||||
};
|
||||
@ -1800,6 +1815,17 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
|
||||
vkd3d_string_buffer_printf(buffer, ")");
|
||||
}
|
||||
|
||||
static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store)
|
||||
{
|
||||
vkd3d_string_buffer_printf(buffer, "store_resource(resource = ");
|
||||
dump_deref(buffer, &store->resource);
|
||||
vkd3d_string_buffer_printf(buffer, ", coords = ");
|
||||
dump_src(buffer, &store->coords);
|
||||
vkd3d_string_buffer_printf(buffer, ", value = ");
|
||||
dump_src(buffer, &store->value);
|
||||
vkd3d_string_buffer_printf(buffer, ")");
|
||||
}
|
||||
|
||||
static void dump_ir_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store)
|
||||
{
|
||||
vkd3d_string_buffer_printf(buffer, "= (");
|
||||
@ -1867,6 +1893,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
|
||||
dump_ir_resource_load(buffer, hlsl_ir_resource_load(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_STORE:
|
||||
dump_ir_store(buffer, hlsl_ir_store(instr));
|
||||
break;
|
||||
@ -1992,6 +2022,14 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load)
|
||||
vkd3d_free(load);
|
||||
}
|
||||
|
||||
static void free_ir_resource_store(struct hlsl_ir_resource_store *store)
|
||||
{
|
||||
hlsl_src_remove(&store->resource.offset);
|
||||
hlsl_src_remove(&store->coords);
|
||||
hlsl_src_remove(&store->value);
|
||||
vkd3d_free(store);
|
||||
}
|
||||
|
||||
static void free_ir_store(struct hlsl_ir_store *store)
|
||||
{
|
||||
hlsl_src_remove(&store->rhs);
|
||||
@ -2039,6 +2077,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
|
||||
free_ir_resource_load(hlsl_ir_resource_load(node));
|
||||
break;
|
||||
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
free_ir_resource_store(hlsl_ir_resource_store(node));
|
||||
break;
|
||||
|
||||
case HLSL_IR_STORE:
|
||||
free_ir_store(hlsl_ir_store(node));
|
||||
break;
|
||||
|
@ -178,6 +178,7 @@ enum hlsl_ir_node_type
|
||||
HLSL_IR_LOOP,
|
||||
HLSL_IR_JUMP,
|
||||
HLSL_IR_RESOURCE_LOAD,
|
||||
HLSL_IR_RESOURCE_STORE,
|
||||
HLSL_IR_STORE,
|
||||
HLSL_IR_SWIZZLE,
|
||||
};
|
||||
@ -410,6 +411,13 @@ struct hlsl_ir_resource_load
|
||||
struct hlsl_src coords, lod, texel_offset;
|
||||
};
|
||||
|
||||
struct hlsl_ir_resource_store
|
||||
{
|
||||
struct hlsl_ir_node node;
|
||||
struct hlsl_deref resource;
|
||||
struct hlsl_src coords, value;
|
||||
};
|
||||
|
||||
struct hlsl_ir_store
|
||||
{
|
||||
struct hlsl_ir_node node;
|
||||
@ -578,6 +586,12 @@ static inline struct hlsl_ir_resource_load *hlsl_ir_resource_load(const struct h
|
||||
return CONTAINING_RECORD(node, struct hlsl_ir_resource_load, node);
|
||||
}
|
||||
|
||||
static inline struct hlsl_ir_resource_store *hlsl_ir_resource_store(const struct hlsl_ir_node *node)
|
||||
{
|
||||
assert(node->type == HLSL_IR_RESOURCE_STORE);
|
||||
return CONTAINING_RECORD(node, struct hlsl_ir_resource_store, node);
|
||||
}
|
||||
|
||||
static inline struct hlsl_ir_store *hlsl_ir_store(const struct hlsl_ir_node *node)
|
||||
{
|
||||
assert(node->type == HLSL_IR_STORE);
|
||||
@ -781,6 +795,8 @@ struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl
|
||||
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);
|
||||
struct hlsl_ir_resource_store *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource,
|
||||
struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name,
|
||||
struct hlsl_struct_field *fields, size_t field_count);
|
||||
struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components,
|
||||
@ -829,6 +845,7 @@ unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second);
|
||||
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);
|
||||
bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
|
||||
unsigned int *start, unsigned int *count);
|
||||
bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset);
|
||||
|
@ -1159,6 +1159,7 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node)
|
||||
case HLSL_IR_IF:
|
||||
case HLSL_IR_JUMP:
|
||||
case HLSL_IR_LOOP:
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
case HLSL_IR_STORE:
|
||||
WARN("Invalid node type %s.\n", hlsl_node_type_to_string(node->type));
|
||||
return 0;
|
||||
@ -1699,7 +1700,6 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
||||
enum parse_assign_op assign_op, struct hlsl_ir_node *rhs)
|
||||
{
|
||||
struct hlsl_type *lhs_type = lhs->data_type;
|
||||
struct hlsl_ir_store *store;
|
||||
struct hlsl_ir_expr *copy;
|
||||
unsigned int writemask = 0;
|
||||
|
||||
@ -1724,7 +1724,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)
|
||||
while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_RESOURCE_LOAD)
|
||||
{
|
||||
if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST)
|
||||
{
|
||||
@ -1761,9 +1761,50 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
||||
}
|
||||
}
|
||||
|
||||
if (!(store = hlsl_new_store_index(ctx, &hlsl_ir_load(lhs)->src, NULL, rhs, writemask, &rhs->loc)))
|
||||
return NULL;
|
||||
list_add_tail(instrs, &store->node.entry);
|
||||
if (lhs->type == HLSL_IR_RESOURCE_LOAD)
|
||||
{
|
||||
struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(lhs);
|
||||
struct hlsl_ir_resource_store *store;
|
||||
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);
|
||||
assert(resource_type->type == HLSL_CLASS_OBJECT);
|
||||
assert(resource_type->base_type == HLSL_TYPE_TEXTURE || resource_type->base_type == HLSL_TYPE_UAV);
|
||||
|
||||
if (resource_type->base_type != HLSL_TYPE_UAV)
|
||||
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
"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)))
|
||||
return NULL;
|
||||
list_add_tail(instrs, &coords->node.entry);
|
||||
|
||||
if (!(store = hlsl_new_resource_store(ctx, &load->resource, &coords->node, rhs, &lhs->loc)))
|
||||
return NULL;
|
||||
list_add_tail(instrs, &store->node.entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct hlsl_ir_store *store;
|
||||
|
||||
if (!(store = hlsl_new_store_index(ctx, &hlsl_ir_load(lhs)->src, NULL, rhs, writemask, &rhs->loc)))
|
||||
return NULL;
|
||||
list_add_tail(instrs, &store->node.entry);
|
||||
}
|
||||
|
||||
/* Don't use the instruction itself as a source, as this makes structure
|
||||
* splitting easier. Instead copy it here. Since we retrieve sources from
|
||||
|
@ -160,6 +160,10 @@ static bool transform_deref_paths_into_offsets(struct hlsl_ctx *ctx, struct hlsl
|
||||
replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->sampler, instr);
|
||||
return true;
|
||||
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
replace_deref_path_with_offset(ctx, &hlsl_ir_resource_store(instr)->resource, instr);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -1588,6 +1592,7 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
||||
case HLSL_IR_IF:
|
||||
case HLSL_IR_JUMP:
|
||||
case HLSL_IR_LOOP:
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1724,6 +1729,18 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
|
||||
load->lod.node->last_read = instr->index;
|
||||
break;
|
||||
}
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
{
|
||||
struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr);
|
||||
|
||||
var = store->resource.var;
|
||||
var->last_read = max(var->last_read, var_last_read);
|
||||
if (store->resource.offset.node)
|
||||
store->resource.offset.node->last_read = instr->index;
|
||||
store->coords.node->last_read = instr->index;
|
||||
store->value.node->last_read = instr->index;
|
||||
break;
|
||||
}
|
||||
case HLSL_IR_SWIZZLE:
|
||||
{
|
||||
struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(instr);
|
||||
|
Loading…
Reference in New Issue
Block a user