mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/hlsl: Support interlocked operations on non-indexed 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
@@ -2383,6 +2383,19 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index)
|
||||||
|
{
|
||||||
|
if (index->val.node->type == HLSL_IR_LOAD)
|
||||||
|
{
|
||||||
|
struct hlsl_ir_load *load = hlsl_ir_load(index->val.node);
|
||||||
|
return load->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index->val.node->type == HLSL_IR_INDEX)
|
||||||
|
return hlsl_index_chain_has_tgsm_access(hlsl_ir_index(index->val.node));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val,
|
static 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)
|
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1712,6 +1712,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls
|
|||||||
bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index);
|
bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index);
|
||||||
bool hlsl_index_is_resource_access(struct hlsl_ir_index *index);
|
bool hlsl_index_is_resource_access(struct hlsl_ir_index *index);
|
||||||
bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index);
|
bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index);
|
||||||
|
bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index);
|
||||||
|
|
||||||
struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
|
struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
|
||||||
const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count,
|
const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count,
|
||||||
|
|||||||
@@ -5063,13 +5063,25 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op
|
|||||||
|
|
||||||
if (hlsl_deref_get_type(ctx, &dst_deref)->class != HLSL_CLASS_UAV)
|
if (hlsl_deref_get_type(ctx, &dst_deref)->class != HLSL_CLASS_UAV)
|
||||||
{
|
{
|
||||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements.");
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
|
"Interlocked targets must be UAV or groupshared elements.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (lhs->type == HLSL_IR_INDEX && hlsl_index_chain_has_tgsm_access(hlsl_ir_index(lhs)))
|
||||||
|
{
|
||||||
|
hlsl_fixme(ctx, loc, "Interlocked operations on indexed groupshared elements.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (lhs->type == HLSL_IR_LOAD && (hlsl_ir_load(lhs)->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED))
|
||||||
|
{
|
||||||
|
hlsl_init_simple_deref_from_var(&dst_deref, hlsl_ir_load(lhs)->src.var);
|
||||||
|
coords = hlsl_block_add_uint_constant(ctx, params->instrs, 0, loc);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements.");
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
|
"Interlocked targets must be UAV or groupshared elements.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3537,10 +3537,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
|
|||||||
{
|
{
|
||||||
struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr);
|
struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr);
|
||||||
|
|
||||||
if (!interlocked->dst.var->is_uniform)
|
if (!interlocked->dst.var->is_uniform && !interlocked->dst.var->is_tgsm)
|
||||||
{
|
{
|
||||||
hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF,
|
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, &interlocked->dst) == DEREF_VALIDATION_NOT_CONSTANT)
|
else if (validate_component_index_range_from_deref(ctx, &interlocked->dst) == DEREF_VALIDATION_NOT_CONSTANT)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ size (raw_buffer, 4)
|
|||||||
|
|
||||||
1 0 0 0
|
1 0 0 0
|
||||||
|
|
||||||
[compute shader todo]
|
[compute shader]
|
||||||
RWByteAddressBuffer u : register(u1);
|
RWByteAddressBuffer u : register(u1);
|
||||||
groupshared uint m;
|
groupshared uint m;
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ void main(uint local_idx : SV_GroupIndex, uint group_id : SV_GroupID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
[test]
|
[test]
|
||||||
todo(sm<6 | msl) dispatch 4 1 1
|
todo(glsl | msl) dispatch 4 1 1
|
||||||
probe uav 1 (0) u32(0)
|
probe uav 1 (0) u32(0)
|
||||||
probe uav 1 (1) u32(33)
|
probe uav 1 (1) u32(33)
|
||||||
probe uav 1 (2) u32(66)
|
probe uav 1 (2) u32(66)
|
||||||
@@ -112,7 +112,7 @@ size (raw_buffer, 4)
|
|||||||
|
|
||||||
1 0 0 0
|
1 0 0 0
|
||||||
|
|
||||||
[compute shader todo]
|
[compute shader]
|
||||||
RWByteAddressBuffer u : register(u1);
|
RWByteAddressBuffer u : register(u1);
|
||||||
groupshared int m;
|
groupshared int m;
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ void main(uint local_idx : SV_GroupIndex, uint group_id : SV_GroupID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
[test]
|
[test]
|
||||||
todo(sm<6 | msl) dispatch 4 1 1
|
todo(glsl | msl) dispatch 4 1 1
|
||||||
probe uav 1 (0) i32(0)
|
probe uav 1 (0) i32(0)
|
||||||
probe uav 1 (1) i32(-31)
|
probe uav 1 (1) i32(-31)
|
||||||
probe uav 1 (2) i32(-62)
|
probe uav 1 (2) i32(-62)
|
||||||
@@ -216,7 +216,7 @@ size (raw_buffer, 1)
|
|||||||
|
|
||||||
0
|
0
|
||||||
|
|
||||||
[compute shader todo]
|
[compute shader]
|
||||||
RWByteAddressBuffer u : register(u1);
|
RWByteAddressBuffer u : register(u1);
|
||||||
groupshared uint m;
|
groupshared uint m;
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ void main(uint local_idx : SV_GroupIndex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
[test]
|
[test]
|
||||||
todo(sm<6 | msl) dispatch 1 1 1
|
todo(glsl | msl) dispatch 1 1 1
|
||||||
probe uav 1 (0) u32(39)
|
probe uav 1 (0) u32(39)
|
||||||
|
|
||||||
[uav 0]
|
[uav 0]
|
||||||
|
|||||||
Reference in New Issue
Block a user