Skip to content

Commit 2c32b6b

Browse files
Merge pull request KhronosGroup#2449 from KhronosGroup/glsl-atomic-fixes
GLSL: Fix some issues with atomics
2 parents 6a62df6 + b220e53 commit 2c32b6b

File tree

7 files changed

+132
-5
lines changed

7 files changed

+132
-5
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#version 450
2+
#extension GL_EXT_buffer_reference2 : require
3+
#extension GL_EXT_buffer_reference_uvec2 : require
4+
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
5+
6+
layout(buffer_reference) buffer uintPointer;
7+
layout(buffer_reference, buffer_reference_align = 4) buffer uintPointer
8+
{
9+
uint value;
10+
};
11+
12+
layout(push_constant, std430) uniform Registers
13+
{
14+
uvec2 va;
15+
} _6;
16+
17+
void main()
18+
{
19+
uint _24 = atomicMax(uintPointer(_6.va).value, 10u);
20+
}
21+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#version 450
2+
#if defined(GL_ARB_gpu_shader_int64)
3+
#extension GL_ARB_gpu_shader_int64 : require
4+
#elif defined(GL_NV_gpu_shader5)
5+
#extension GL_NV_gpu_shader5 : require
6+
#else
7+
#error No extension available for 64-bit integers.
8+
#endif
9+
#extension GL_EXT_shader_atomic_int64 : require
10+
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
11+
12+
layout(binding = 0, std430) buffer SSBO
13+
{
14+
uint64_t v;
15+
} _9;
16+
17+
void main()
18+
{
19+
uint64_t _18 = atomicMax(_9.v, 10ul);
20+
}
21+

reference/shaders-no-opt/vulkan/comp/image-64bit.vk.nocompat.comp.vk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#error No extension available for 64-bit integers.
66
#endif
77
#extension GL_EXT_shader_image_int64 : require
8+
#extension GL_EXT_shader_atomic_int64 : require
89
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
910

1011
layout(set = 0, binding = 0, r64ui) uniform u64image2D uimg;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; SPIR-V
2+
; Version: 1.0
3+
; Generator: Khronos Glslang Reference Front End; 11
4+
; Bound: 25
5+
; Schema: 0
6+
OpCapability Shader
7+
OpCapability PhysicalStorageBufferAddresses
8+
OpExtension "SPV_KHR_physical_storage_buffer"
9+
%1 = OpExtInstImport "GLSL.std.450"
10+
OpMemoryModel PhysicalStorageBuffer64 GLSL450
11+
OpEntryPoint GLCompute %main "main"
12+
OpExecutionMode %main LocalSize 1 1 1
13+
OpSource GLSL 450
14+
OpSourceExtension "GL_EXT_buffer_reference"
15+
OpSourceExtension "GL_EXT_buffer_reference_uvec2"
16+
OpName %main "main"
17+
OpName %Registers "Registers"
18+
OpMemberName %Registers 0 "va"
19+
OpName %_ ""
20+
OpDecorate %Registers Block
21+
OpMemberDecorate %Registers 0 Offset 0
22+
%void = OpTypeVoid
23+
%3 = OpTypeFunction %void
24+
%uint = OpTypeInt 32 0
25+
%v2uint = OpTypeVector %uint 2
26+
%Registers = OpTypeStruct %v2uint
27+
%_ptr_PushConstant_Registers = OpTypePointer PushConstant %Registers
28+
%_ = OpVariable %_ptr_PushConstant_Registers PushConstant
29+
%int = OpTypeInt 32 1
30+
%int_0 = OpConstant %int 0
31+
%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint
32+
%_ptr_PhysicalStorageBuffer_uint = OpTypePointer PhysicalStorageBuffer %uint
33+
%uint_10 = OpConstant %uint 10
34+
%uint_1 = OpConstant %uint 1
35+
%uint_0 = OpConstant %uint 0
36+
%main = OpFunction %void None %3
37+
%5 = OpLabel
38+
%14 = OpAccessChain %_ptr_PushConstant_v2uint %_ %int_0
39+
%15 = OpLoad %v2uint %14
40+
%18 = OpBitcast %_ptr_PhysicalStorageBuffer_uint %15
41+
%24 = OpAtomicUMax %uint %18 %uint_1 %uint_0 %uint_10
42+
OpReturn
43+
OpFunctionEnd
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#version 450
2+
#extension GL_EXT_shader_atomic_int64 : require
3+
#extension GL_ARB_gpu_shader_int64 : require
4+
layout(local_size_x = 1) in;
5+
6+
layout(set = 0, binding = 0) buffer SSBO
7+
{
8+
uint64_t v;
9+
};
10+
11+
void main()
12+
{
13+
atomicMax(v, 10ul);
14+
}

spirv_glsl.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5397,6 +5397,15 @@ string CompilerGLSL::to_non_uniform_aware_expression(uint32_t id)
53975397
return expr;
53985398
}
53995399

5400+
string CompilerGLSL::to_atomic_ptr_expression(uint32_t id)
5401+
{
5402+
string expr = to_non_uniform_aware_expression(id);
5403+
// If we have naked pointer to POD, we need to dereference to get the proper ".value" resolve.
5404+
if (should_dereference(id))
5405+
expr = dereference_expression(expression_type(id), expr);
5406+
return expr;
5407+
}
5408+
54005409
string CompilerGLSL::to_expression(uint32_t id, bool register_expression_read)
54015410
{
54025411
auto itr = invalid_expressions.find(id);
@@ -6999,9 +7008,12 @@ void CompilerGLSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id,
69997008
require_extension_internal("GL_EXT_shader_atomic_float");
70007009
}
70017010

7011+
if (type.basetype == SPIRType::UInt64 || type.basetype == SPIRType::Int64)
7012+
require_extension_internal("GL_EXT_shader_atomic_int64");
7013+
70027014
forced_temporaries.insert(result_id);
70037015
emit_op(result_type, result_id,
7004-
join(op, "(", to_non_uniform_aware_expression(op0), ", ",
7016+
join(op, "(", to_atomic_ptr_expression(op0), ", ",
70057017
to_unpacked_expression(op1), ")"), false);
70067018
flush_all_atomic_capable_variables();
70077019
}
@@ -13875,8 +13887,11 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
1387513887
const char *increment = unsigned_type ? "0u" : "0";
1387613888
emit_op(ops[0], ops[1],
1387713889
join(op, "(",
13878-
to_non_uniform_aware_expression(ops[2]), ", ", increment, ")"), false);
13890+
to_atomic_ptr_expression(ops[2]), ", ", increment, ")"), false);
1387913891
flush_all_atomic_capable_variables();
13892+
13893+
if (type.basetype == SPIRType::UInt64 || type.basetype == SPIRType::Int64)
13894+
require_extension_internal("GL_EXT_shader_atomic_int64");
1388013895
break;
1388113896
}
1388213897

@@ -13888,8 +13903,12 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
1388813903
// Ignore semantics for now, probably only relevant to CL.
1388913904
uint32_t val = ops[3];
1389013905
const char *op = check_atomic_image(ptr) ? "imageAtomicExchange" : "atomicExchange";
13891-
statement(op, "(", to_non_uniform_aware_expression(ptr), ", ", to_expression(val), ");");
13906+
statement(op, "(", to_atomic_ptr_expression(ptr), ", ", to_expression(val), ");");
1389213907
flush_all_atomic_capable_variables();
13908+
13909+
auto &type = expression_type(ptr);
13910+
if (type.basetype == SPIRType::UInt64 || type.basetype == SPIRType::Int64)
13911+
require_extension_internal("GL_EXT_shader_atomic_int64");
1389313912
break;
1389413913
}
1389513914

@@ -13924,7 +13943,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
1392413943
increment = "-1";
1392513944

1392613945
emit_op(ops[0], ops[1],
13927-
join(op, "(", to_non_uniform_aware_expression(ops[2]), ", ", increment, ")"), false);
13946+
join(op, "(", to_atomic_ptr_expression(ops[2]), ", ", increment, ")"), false);
13947+
13948+
if (type.basetype == SPIRType::UInt64 || type.basetype == SPIRType::Int64)
13949+
require_extension_internal("GL_EXT_shader_atomic_int64");
1392813950
}
1392913951

1393013952
flush_all_atomic_capable_variables();
@@ -13943,9 +13965,13 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
1394313965
{
1394413966
const char *op = check_atomic_image(ops[2]) ? "imageAtomicAdd" : "atomicAdd";
1394513967
forced_temporaries.insert(ops[1]);
13946-
auto expr = join(op, "(", to_non_uniform_aware_expression(ops[2]), ", -", to_enclosed_expression(ops[5]), ")");
13968+
auto expr = join(op, "(", to_atomic_ptr_expression(ops[2]), ", -", to_enclosed_expression(ops[5]), ")");
1394713969
emit_op(ops[0], ops[1], expr, should_forward(ops[2]) && should_forward(ops[5]));
1394813970
flush_all_atomic_capable_variables();
13971+
13972+
auto &type = get<SPIRType>(ops[0]);
13973+
if (type.basetype == SPIRType::UInt64 || type.basetype == SPIRType::Int64)
13974+
require_extension_internal("GL_EXT_shader_atomic_int64");
1394913975
break;
1395013976
}
1395113977

spirv_glsl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,7 @@ class CompilerGLSL : public Compiler
800800
SPIRExpression &emit_uninitialized_temporary_expression(uint32_t type, uint32_t id);
801801
void append_global_func_args(const SPIRFunction &func, uint32_t index, SmallVector<std::string> &arglist);
802802
std::string to_non_uniform_aware_expression(uint32_t id);
803+
std::string to_atomic_ptr_expression(uint32_t id);
803804
std::string to_expression(uint32_t id, bool register_expression_read = true);
804805
std::string to_composite_constructor_expression(const SPIRType &parent_type, uint32_t id, bool block_like_type);
805806
std::string to_rerolled_array_expression(const SPIRType &parent_type, const std::string &expr, const SPIRType &type);

0 commit comments

Comments
 (0)