diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 3e26fc0dc..319907227 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2383,6 +2383,19 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index) 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, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) { diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 199329039..34c63cd33 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -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_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, const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2de7e81f6..66582e884 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -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) { - 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; } } + 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 { - 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; } diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 1fbf96cdf..168aa56ea 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -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); - 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, - "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) { diff --git a/tests/hlsl/tgsm.shader_test b/tests/hlsl/tgsm.shader_test index e1f6284d6..28a133208 100644 --- a/tests/hlsl/tgsm.shader_test +++ b/tests/hlsl/tgsm.shader_test @@ -82,7 +82,7 @@ size (raw_buffer, 4) 1 0 0 0 -[compute shader todo] +[compute shader] RWByteAddressBuffer u : register(u1); groupshared uint m; @@ -99,7 +99,7 @@ void main(uint local_idx : SV_GroupIndex, uint group_id : SV_GroupID) } [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 (1) u32(33) probe uav 1 (2) u32(66) @@ -112,7 +112,7 @@ size (raw_buffer, 4) 1 0 0 0 -[compute shader todo] +[compute shader] RWByteAddressBuffer u : register(u1); groupshared int m; @@ -129,7 +129,7 @@ void main(uint local_idx : SV_GroupIndex, uint group_id : SV_GroupID) } [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 (1) i32(-31) probe uav 1 (2) i32(-62) @@ -216,7 +216,7 @@ size (raw_buffer, 1) 0 -[compute shader todo] +[compute shader] RWByteAddressBuffer u : register(u1); groupshared uint m; @@ -234,7 +234,7 @@ void main(uint local_idx : SV_GroupIndex) } [test] -todo(sm<6 | msl) dispatch 1 1 1 +todo(glsl | msl) dispatch 1 1 1 probe uav 1 (0) u32(39) [uav 0]