mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/hlsl: Support stores to raw groupshared variables.
This commit is contained in:
Notes:
Henri Verbeet
2025-08-05 16:40:26 +02:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1605
@@ -2112,9 +2112,9 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h
|
||||
return append_new_instr(ctx, block, &load->node);
|
||||
}
|
||||
|
||||
static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type,
|
||||
const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value,
|
||||
const struct vkd3d_shader_location *loc)
|
||||
static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx,
|
||||
enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
|
||||
struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_resource_store *store;
|
||||
|
||||
@@ -2122,6 +2122,7 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h
|
||||
return NULL;
|
||||
init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc);
|
||||
store->store_type = type;
|
||||
store->writemask = writemask;
|
||||
|
||||
hlsl_copy_deref(ctx, &store->resource, resource);
|
||||
hlsl_src_from_node(&store->coords, coords);
|
||||
@@ -2131,9 +2132,9 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h
|
||||
|
||||
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||
enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
|
||||
struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
|
||||
struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc));
|
||||
append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc));
|
||||
}
|
||||
|
||||
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count,
|
||||
@@ -2674,6 +2675,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx,
|
||||
return NULL;
|
||||
init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc);
|
||||
dst->store_type = src->store_type;
|
||||
dst->writemask = src->writemask;
|
||||
if (!clone_deref(ctx, map, &dst->resource, &src->resource))
|
||||
{
|
||||
vkd3d_free(dst);
|
||||
@@ -3824,7 +3826,8 @@ 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)
|
||||
static void dump_ir_resource_store(struct hlsl_ctx *ctx,
|
||||
struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store)
|
||||
{
|
||||
static const char *const type_names[] =
|
||||
{
|
||||
@@ -3836,6 +3839,8 @@ static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const str
|
||||
VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names));
|
||||
vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]);
|
||||
dump_deref(buffer, &store->resource);
|
||||
if (store->writemask != VKD3DSP_WRITEMASK_ALL && type_is_single_reg(hlsl_deref_get_type(ctx, &store->resource)))
|
||||
vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask));
|
||||
if (store->coords.node)
|
||||
{
|
||||
vkd3d_string_buffer_printf(buffer, ", coords = ");
|
||||
@@ -4048,7 +4053,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
|
||||
break;
|
||||
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr));
|
||||
dump_ir_resource_store(ctx, buffer, hlsl_ir_resource_store(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_STRING_CONSTANT:
|
||||
|
@@ -911,6 +911,7 @@ struct hlsl_ir_resource_store
|
||||
enum hlsl_resource_store_type store_type;
|
||||
struct hlsl_deref resource;
|
||||
struct hlsl_src coords, value;
|
||||
uint8_t writemask;
|
||||
};
|
||||
|
||||
struct hlsl_ir_store
|
||||
@@ -1587,7 +1588,7 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h
|
||||
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
|
||||
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||
enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
|
||||
struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||
struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc);
|
||||
void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||
|
@@ -2117,7 +2117,8 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
|
||||
VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
||||
VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count);
|
||||
|
||||
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc);
|
||||
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE,
|
||||
&resource_deref, coords, rhs, writemask, &lhs->loc);
|
||||
hlsl_cleanup_deref(&resource_deref);
|
||||
}
|
||||
else if (matrix_writemask)
|
||||
@@ -6300,6 +6301,7 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block
|
||||
struct hlsl_ir_node *offset, *rhs;
|
||||
struct hlsl_deref resource_deref;
|
||||
unsigned int value_dim;
|
||||
uint32_t writemask;
|
||||
|
||||
if (params->args_count != 2)
|
||||
{
|
||||
@@ -6321,11 +6323,12 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block
|
||||
hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc);
|
||||
rhs = add_implicit_conversion(ctx, block, params->args[1],
|
||||
hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc);
|
||||
writemask = vkd3d_write_mask_from_component_count(value_dim);
|
||||
|
||||
if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object))
|
||||
return false;
|
||||
|
||||
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc);
|
||||
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, writemask, loc);
|
||||
hlsl_cleanup_deref(&resource_deref);
|
||||
|
||||
return true;
|
||||
@@ -6350,7 +6353,7 @@ static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *b
|
||||
if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc)))
|
||||
return false;
|
||||
|
||||
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc);
|
||||
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, 0, loc);
|
||||
hlsl_cleanup_deref(&so_deref);
|
||||
|
||||
return true;
|
||||
@@ -6371,7 +6374,7 @@ static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_bl
|
||||
if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object))
|
||||
return false;
|
||||
|
||||
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc);
|
||||
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, 0, loc);
|
||||
hlsl_cleanup_deref(&so_deref);
|
||||
|
||||
return true;
|
||||
|
@@ -1610,6 +1610,38 @@ static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Lowers stores to TGSMs to resource stores. */
|
||||
static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
||||
{
|
||||
struct hlsl_ir_store *store;
|
||||
struct hlsl_ir_node *coords;
|
||||
struct hlsl_deref res_deref;
|
||||
struct hlsl_deref *deref;
|
||||
|
||||
if (instr->type != HLSL_IR_STORE)
|
||||
return false;
|
||||
store = hlsl_ir_store(instr);
|
||||
deref = &store->lhs;
|
||||
|
||||
if (!deref->var->is_tgsm)
|
||||
return false;
|
||||
|
||||
if (deref->path_len)
|
||||
{
|
||||
hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM.");
|
||||
return false;
|
||||
}
|
||||
|
||||
hlsl_init_simple_deref_from_var(&res_deref, deref->var);
|
||||
coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc);
|
||||
|
||||
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref,
|
||||
coords, store->rhs.node, store->writemask, &instr->loc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Allocate a unique, ordered index to each instruction, which will be used for
|
||||
* copy propagation and computing liveness ranges.
|
||||
* Index 0 means unused, so start at 1. */
|
||||
@@ -3475,10 +3507,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
|
||||
{
|
||||
struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr);
|
||||
|
||||
if (!store->resource.var->is_uniform)
|
||||
if (!store->resource.var->is_uniform && !store->resource.var->is_tgsm)
|
||||
{
|
||||
hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF,
|
||||
"Accessed resource must have a single uniform source.");
|
||||
"Accessed resource must have a single uniform or groupshared source.");
|
||||
}
|
||||
else if (validate_component_index_range_from_deref(ctx, &store->resource) == DEREF_VALIDATION_NOT_CONSTANT)
|
||||
{
|
||||
@@ -11204,11 +11236,7 @@ static bool sm4_generate_vsir_instr_store(struct hlsl_ctx *ctx,
|
||||
struct vkd3d_shader_src_param *src_param;
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
|
||||
if (store->lhs.var->is_tgsm)
|
||||
{
|
||||
hlsl_fixme(ctx, &instr->loc, "Store to groupshared variable.");
|
||||
return false;
|
||||
}
|
||||
VKD3D_ASSERT(!store->lhs.var->is_tgsm);
|
||||
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1)))
|
||||
return false;
|
||||
@@ -11289,8 +11317,8 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx,
|
||||
struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &store->resource);
|
||||
struct hlsl_ir_node *coords = store->coords.node, *value = store->value.node;
|
||||
struct hlsl_ir_node *instr = &store->node;
|
||||
bool tgsm = store->resource.var->is_tgsm;
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
unsigned int writemask;
|
||||
|
||||
if (store->store_type != HLSL_RESOURCE_STORE)
|
||||
{
|
||||
@@ -11317,9 +11345,9 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!store->resource.var->is_uniform)
|
||||
if (!store->resource.var->is_uniform && !tgsm)
|
||||
{
|
||||
hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable.");
|
||||
hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform non-groupshared resource variable.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11329,14 +11357,19 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
|
||||
if (tgsm && !hlsl_is_numeric_type(resource_type))
|
||||
{
|
||||
hlsl_fixme(ctx, &store->node.loc, "Store to structured TGSM.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tgsm || resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
|
||||
{
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_STORE_RAW, 1, 2)))
|
||||
return false;
|
||||
|
||||
writemask = vkd3d_write_mask_from_component_count(value->data_type->e.numeric.dimx);
|
||||
if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program,
|
||||
&ins->dst[0], &store->resource, &instr->loc, writemask))
|
||||
if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, &ins->dst[0],
|
||||
&store->resource, &instr->loc, store->writemask))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -13955,6 +13988,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v
|
||||
lower_ir(ctx, lower_index_loads, body);
|
||||
|
||||
lower_ir(ctx, lower_tgsm_loads, body);
|
||||
lower_ir(ctx, lower_tgsm_stores, body);
|
||||
|
||||
if (entry_func->return_var)
|
||||
{
|
||||
|
@@ -280,7 +280,7 @@ size (raw_buffer, 8)
|
||||
0xf000f 0xf000f 0xf000f 0xf000f
|
||||
0xf000f 0xf000f 0xf000f 0xf000f
|
||||
|
||||
[compute shader todo]
|
||||
[compute shader]
|
||||
RWByteAddressBuffer u : register(u0);
|
||||
groupshared min16uint m;
|
||||
|
||||
@@ -305,7 +305,7 @@ void main(uint local_idx : SV_GroupIndex, uint group_id : SV_GroupID)
|
||||
}
|
||||
|
||||
[test]
|
||||
todo(sm<6 | msl) dispatch 2 1 1
|
||||
todo(glsl | msl) dispatch 2 1 1
|
||||
probe uav 0 (0) u32(0x14321)
|
||||
probe uav 0 (1) u32(0x14321)
|
||||
probe uav 0 (2) u32(0x14321)
|
||||
|
Reference in New Issue
Block a user