From cf52f73a0cba3a9464d5e4b672e494a2bb9ef96b Mon Sep 17 00:00:00 2001 From: ZhiqianXia Date: Mon, 12 Jul 2021 16:57:25 +0800 Subject: [PATCH] Atomic memory function can only be used for shader storage block member or shared variable. Signed-off-by: ZhiqianXia --- Test/atomicAdd.comp | 19 ++ Test/baseResults/atomicAdd.comp.out | 87 +++++ .../spv.atomicAdd.bufferReference.comp.out | 304 ++++++++++++++++++ Test/spv.atomicAdd.bufferReference.comp | 50 +++ glslang/MachineIndependent/Intermediate.cpp | 8 +- glslang/MachineIndependent/ParseHelper.cpp | 8 + .../MachineIndependent/localintermediate.h | 2 +- gtests/AST.FromFile.cpp | 1 + gtests/Spv.FromFile.cpp | 1 + 9 files changed, 478 insertions(+), 2 deletions(-) create mode 100644 Test/atomicAdd.comp create mode 100644 Test/baseResults/atomicAdd.comp.out create mode 100644 Test/baseResults/spv.atomicAdd.bufferReference.comp.out create mode 100644 Test/spv.atomicAdd.bufferReference.comp diff --git a/Test/atomicAdd.comp b/Test/atomicAdd.comp new file mode 100644 index 00000000..27dfa13b --- /dev/null +++ b/Test/atomicAdd.comp @@ -0,0 +1,19 @@ +#version 320 es +layout(local_size_x = 1) in; + +struct structType{ + int y[3]; +}; + +layout(std430) buffer t2 { + structType f; +} t; + +buffer coherent Buffer { int x; }; +int z; + +void main() { + atomicAdd(x, 1); + atomicAdd(t.f.y[1], 1); + atomicAdd(z, 1); +} \ No newline at end of file diff --git a/Test/baseResults/atomicAdd.comp.out b/Test/baseResults/atomicAdd.comp.out new file mode 100644 index 00000000..6752a713 --- /dev/null +++ b/Test/baseResults/atomicAdd.comp.out @@ -0,0 +1,87 @@ +atomicAdd.comp +ERROR: 0:18: 'atomicAdd' : Atomic memory function can only be used for shader storage block member or shared variable. +ERROR: 1 compilation errors. No code generated. + + +Shader version: 320 +local_size = (1, 1, 1) +ERROR: node is still EOpNull! +0:15 Function Definition: main( ( global void) +0:15 Function Parameters: +0:16 Sequence +0:16 AtomicAdd ( global highp int) +0:16 x: direct index for structure (layout( column_major shared) coherent buffer highp int) +0:16 'anon@0' (layout( column_major shared) coherent buffer block{layout( column_major shared) coherent buffer highp int x}) +0:16 Constant: +0:16 0 (const uint) +0:16 Constant: +0:16 1 (const int) +0:17 AtomicAdd ( global highp int) +0:17 direct index (layout( std430) temp highp int) +0:17 y: direct index for structure (layout( std430) global 3-element array of highp int) +0:17 f: direct index for structure (layout( column_major std430 offset=0) buffer structure{layout( std430) global 3-element array of highp int y}) +0:17 't' (layout( column_major std430) buffer block{layout( column_major std430 offset=0) buffer structure{layout( std430) global 3-element array of highp int y} f}) +0:17 Constant: +0:17 0 (const int) +0:17 Constant: +0:17 0 (const int) +0:17 Constant: +0:17 1 (const int) +0:17 Constant: +0:17 1 (const int) +0:18 AtomicAdd ( global highp int) +0:18 'z' ( global highp int) +0:18 Constant: +0:18 1 (const int) +0:? Linker Objects +0:? 'gl_WorkGroupSize' ( const highp 3-component vector of uint WorkGroupSize) +0:? 1 (const uint) +0:? 1 (const uint) +0:? 1 (const uint) +0:? 't' (layout( column_major std430) buffer block{layout( column_major std430 offset=0) buffer structure{layout( std430) global 3-element array of highp int y} f}) +0:? 'anon@0' (layout( column_major shared) coherent buffer block{layout( column_major shared) coherent buffer highp int x}) +0:? 'z' ( global highp int) + + +Linked compute stage: + + +Shader version: 320 +local_size = (1, 1, 1) +ERROR: node is still EOpNull! +0:15 Function Definition: main( ( global void) +0:15 Function Parameters: +0:16 Sequence +0:16 AtomicAdd ( global highp int) +0:16 x: direct index for structure (layout( column_major shared) coherent buffer highp int) +0:16 'anon@0' (layout( column_major shared) coherent buffer block{layout( column_major shared) coherent buffer highp int x}) +0:16 Constant: +0:16 0 (const uint) +0:16 Constant: +0:16 1 (const int) +0:17 AtomicAdd ( global highp int) +0:17 direct index (layout( std430) temp highp int) +0:17 y: direct index for structure (layout( std430) global 3-element array of highp int) +0:17 f: direct index for structure (layout( column_major std430 offset=0) buffer structure{layout( std430) global 3-element array of highp int y}) +0:17 't' (layout( column_major std430) buffer block{layout( column_major std430 offset=0) buffer structure{layout( std430) global 3-element array of highp int y} f}) +0:17 Constant: +0:17 0 (const int) +0:17 Constant: +0:17 0 (const int) +0:17 Constant: +0:17 1 (const int) +0:17 Constant: +0:17 1 (const int) +0:18 AtomicAdd ( global highp int) +0:18 'z' ( global highp int) +0:18 Constant: +0:18 1 (const int) +0:? Linker Objects +0:? 'gl_WorkGroupSize' ( const highp 3-component vector of uint WorkGroupSize) +0:? 1 (const uint) +0:? 1 (const uint) +0:? 1 (const uint) +0:? 't' (layout( column_major std430) buffer block{layout( column_major std430 offset=0) buffer structure{layout( std430) global 3-element array of highp int y} f}) +0:? 'anon@0' (layout( column_major shared) coherent buffer block{layout( column_major shared) coherent buffer highp int x}) +0:? 'z' ( global highp int) + diff --git a/Test/baseResults/spv.atomicAdd.bufferReference.comp.out b/Test/baseResults/spv.atomicAdd.bufferReference.comp.out new file mode 100644 index 00000000..9ecc7425 --- /dev/null +++ b/Test/baseResults/spv.atomicAdd.bufferReference.comp.out @@ -0,0 +1,304 @@ +spv.atomicAdd.bufferReference.comp +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 188 + + Capability Shader + Capability VulkanMemoryModelKHR + Capability VulkanMemoryModelDeviceScopeKHR + Capability PhysicalStorageBufferAddressesEXT + Extension "SPV_KHR_physical_storage_buffer" + Extension "SPV_KHR_storage_buffer_storage_class" + Extension "SPV_KHR_vulkan_memory_model" + 1: ExtInstImport "GLSL.std.450" + MemoryModel PhysicalStorageBuffer64EXT VulkanKHR + EntryPoint GLCompute 4 "main" 37 81 133 + ExecutionMode 4 LocalSize 1 1 1 + Source GLSL 450 + SourceExtension "GL_ARB_gpu_shader_int64" + SourceExtension "GL_EXT_buffer_reference" + SourceExtension "GL_KHR_memory_scope_semantics" + SourceExtension "GL_KHR_shader_subgroup_ballot" + SourceExtension "GL_KHR_shader_subgroup_basic" + SourceExtension "GL_KHR_shader_subgroup_shuffle" + Name 4 "main" + Name 8 "pass" + Name 10 "skip" + Name 13 "sharedSkip" + Name 18 "PayloadRef" + MemberName 18(PayloadRef) 0 "x" + Name 20 "payload" + Name 22 "PC" + MemberName 22(PC) 0 "payloadref" + MemberName 22(PC) 1 "guard" + Name 24 "GuardRef" + MemberName 24(GuardRef) 0 "x" + Name 26 "" + Name 34 "globalId" + Name 37 "gl_GlobalInvocationID" + Name 42 "partnerGlobalId" + Name 43 "DIM" + Name 44 "NUM_WORKGROUP_EACH_DIM" + Name 54 "bufferCoord" + Name 66 "partnerBufferCoord" + Name 75 "imageCoord" + Name 77 "partnerImageCoord" + Name 79 "globalId00" + Name 81 "gl_WorkGroupID" + Name 86 "partnerGlobalId00" + Name 95 "bufferCoord00" + Name 104 "partnerBufferCoord00" + Name 113 "imageCoord00" + Name 115 "partnerImageCoord00" + Name 133 "gl_LocalInvocationID" + Name 163 "r" + Name 179 "Fail" + MemberName 179(Fail) 0 "x" + Name 181 "fail" + Decorate 17 ArrayStride 4 + MemberDecorate 18(PayloadRef) 0 Offset 0 + Decorate 18(PayloadRef) Block + Decorate 20(payload) DecorationAliasedPointerEXT + MemberDecorate 22(PC) 0 Offset 0 + MemberDecorate 22(PC) 1 Offset 8 + Decorate 22(PC) Block + Decorate 23 ArrayStride 4 + MemberDecorate 24(GuardRef) 0 Offset 0 + Decorate 24(GuardRef) Block + Decorate 37(gl_GlobalInvocationID) BuiltIn GlobalInvocationId + Decorate 43(DIM) SpecId 0 + Decorate 44(NUM_WORKGROUP_EACH_DIM) SpecId 1 + Decorate 81(gl_WorkGroupID) BuiltIn WorkgroupId + Decorate 133(gl_LocalInvocationID) BuiltIn LocalInvocationId + Decorate 178 ArrayStride 4 + MemberDecorate 179(Fail) 0 Offset 0 + Decorate 179(Fail) Block + Decorate 181(fail) DescriptorSet 0 + Decorate 181(fail) Binding 2 + Decorate 185 SpecId 0 + Decorate 186 SpecId 0 + Decorate 187 BuiltIn WorkgroupSize + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeBool + 7: TypePointer Function 6(bool) + 9: 6(bool) ConstantTrue + 11: 6(bool) ConstantFalse + 12: TypePointer Workgroup 6(bool) + 13(sharedSkip): 12(ptr) Variable Workgroup + 14: TypeInt 32 0 + 15: 14(int) Constant 2 + TypeForwardPointer 16 PhysicalStorageBufferEXT + 17: TypeRuntimeArray 14(int) + 18(PayloadRef): TypeStruct 17 + 16: TypePointer PhysicalStorageBufferEXT 18(PayloadRef) + 19: TypePointer Function 16(ptr) + TypeForwardPointer 21 PhysicalStorageBufferEXT + 22(PC): TypeStruct 16(ptr) 21 + 23: TypeRuntimeArray 14(int) + 24(GuardRef): TypeStruct 23 + 21: TypePointer PhysicalStorageBufferEXT 24(GuardRef) + 25: TypePointer PushConstant 22(PC) + 26: 25(ptr) Variable PushConstant + 27: TypeInt 32 1 + 28: 27(int) Constant 0 + 29: TypePointer PushConstant 16(ptr) + 32: TypeVector 27(int) 2 + 33: TypePointer Function 32(ivec2) + 35: TypeVector 14(int) 3 + 36: TypePointer Input 35(ivec3) +37(gl_GlobalInvocationID): 36(ptr) Variable Input + 38: TypeVector 14(int) 2 + 43(DIM): 27(int) SpecConstant 1 +44(NUM_WORKGROUP_EACH_DIM): 27(int) SpecConstant 1 + 45: 27(int) SpecConstantOp 132 43(DIM) 44(NUM_WORKGROUP_EACH_DIM) + 46: 27(int) Constant 1 + 47: 27(int) SpecConstantOp 130 45 46 + 48: 32(ivec2) SpecConstantComposite 47 47 + 53: TypePointer Function 14(int) + 55: 14(int) Constant 1 + 56: TypePointer Function 27(int) + 61: 14(int) Constant 0 + 80: 32(ivec2) SpecConstantComposite 43(DIM) 43(DIM) +81(gl_WorkGroupID): 36(ptr) Variable Input + 87: 32(ivec2) SpecConstantComposite 43(DIM) 43(DIM) + 88: 27(int) SpecConstantOp 130 44(NUM_WORKGROUP_EACH_DIM) 46 + 89: 32(ivec2) SpecConstantComposite 88 88 + 122: TypePointer PhysicalStorageBufferEXT 14(int) + 125: 27(int) Constant 31 + 129: 27(int) Constant 2 + 130: 27(int) Constant 320 + 131: 27(int) Constant 8200 + 132: 14(int) Constant 8520 +133(gl_LocalInvocationID): 36(ptr) Variable Input + 136: 38(ivec2) ConstantComposite 61 61 + 137: TypeVector 6(bool) 2 + 142: TypePointer PushConstant 21(ptr) + 147: 27(int) Constant 64 + 148: 27(int) Constant 8196 + 149: 14(int) Constant 5 + 150: 14(int) Constant 8260 + 155: 27(int) Constant 16386 + 156: 14(int) Constant 16450 + 160: 27(int) Constant 16392 + 161: 14(int) Constant 16712 + 178: TypeRuntimeArray 14(int) + 179(Fail): TypeStruct 178 + 180: TypePointer StorageBuffer 179(Fail) + 181(fail): 180(ptr) Variable StorageBuffer + 183: TypePointer StorageBuffer 14(int) + 185: 14(int) SpecConstant 1 + 186: 14(int) SpecConstant 1 + 187: 35(ivec3) SpecConstantComposite 185 186 55 + 4(main): 2 Function None 3 + 5: Label + 8(pass): 7(ptr) Variable Function + 10(skip): 7(ptr) Variable Function + 20(payload): 19(ptr) Variable Function + 34(globalId): 33(ptr) Variable Function +42(partnerGlobalId): 33(ptr) Variable Function + 54(bufferCoord): 53(ptr) Variable Function +66(partnerBufferCoord): 53(ptr) Variable Function + 75(imageCoord): 33(ptr) Variable Function +77(partnerImageCoord): 33(ptr) Variable Function + 79(globalId00): 33(ptr) Variable Function +86(partnerGlobalId00): 33(ptr) Variable Function +95(bufferCoord00): 53(ptr) Variable Function +104(partnerBufferCoord00): 53(ptr) Variable Function +113(imageCoord00): 33(ptr) Variable Function +115(partnerImageCoord00): 33(ptr) Variable Function + 163(r): 53(ptr) Variable Function + Store 8(pass) 9 + Store 10(skip) 11 + Store 13(sharedSkip) 11 MakePointerAvailableKHR NonPrivatePointerKHR 15 + 30: 29(ptr) AccessChain 26 28 + 31: 16(ptr) Load 30 + Store 20(payload) 31 + 39: 35(ivec3) Load 37(gl_GlobalInvocationID) + 40: 38(ivec2) VectorShuffle 39 39 0 1 + 41: 32(ivec2) Bitcast 40 + Store 34(globalId) 41 + 49: 35(ivec3) Load 37(gl_GlobalInvocationID) + 50: 38(ivec2) VectorShuffle 49 49 0 1 + 51: 32(ivec2) Bitcast 50 + 52: 32(ivec2) ISub 48 51 + Store 42(partnerGlobalId) 52 + 57: 56(ptr) AccessChain 34(globalId) 55 + 58: 27(int) Load 57 + 59: 27(int) IMul 58 43(DIM) + 60: 27(int) IMul 59 44(NUM_WORKGROUP_EACH_DIM) + 62: 56(ptr) AccessChain 34(globalId) 61 + 63: 27(int) Load 62 + 64: 27(int) IAdd 60 63 + 65: 14(int) Bitcast 64 + Store 54(bufferCoord) 65 + 67: 56(ptr) AccessChain 42(partnerGlobalId) 55 + 68: 27(int) Load 67 + 69: 27(int) IMul 68 43(DIM) + 70: 27(int) IMul 69 44(NUM_WORKGROUP_EACH_DIM) + 71: 56(ptr) AccessChain 42(partnerGlobalId) 61 + 72: 27(int) Load 71 + 73: 27(int) IAdd 70 72 + 74: 14(int) Bitcast 73 + Store 66(partnerBufferCoord) 74 + 76: 32(ivec2) Load 34(globalId) + Store 75(imageCoord) 76 + 78: 32(ivec2) Load 42(partnerGlobalId) + Store 77(partnerImageCoord) 78 + 82: 35(ivec3) Load 81(gl_WorkGroupID) + 83: 38(ivec2) VectorShuffle 82 82 0 1 + 84: 32(ivec2) Bitcast 83 + 85: 32(ivec2) IMul 80 84 + Store 79(globalId00) 85 + 90: 35(ivec3) Load 81(gl_WorkGroupID) + 91: 38(ivec2) VectorShuffle 90 90 0 1 + 92: 32(ivec2) Bitcast 91 + 93: 32(ivec2) ISub 89 92 + 94: 32(ivec2) IMul 87 93 + Store 86(partnerGlobalId00) 94 + 96: 56(ptr) AccessChain 79(globalId00) 55 + 97: 27(int) Load 96 + 98: 27(int) IMul 97 43(DIM) + 99: 27(int) IMul 98 44(NUM_WORKGROUP_EACH_DIM) + 100: 56(ptr) AccessChain 79(globalId00) 61 + 101: 27(int) Load 100 + 102: 27(int) IAdd 99 101 + 103: 14(int) Bitcast 102 + Store 95(bufferCoord00) 103 + 105: 56(ptr) AccessChain 86(partnerGlobalId00) 55 + 106: 27(int) Load 105 + 107: 27(int) IMul 106 43(DIM) + 108: 27(int) IMul 107 44(NUM_WORKGROUP_EACH_DIM) + 109: 56(ptr) AccessChain 86(partnerGlobalId00) 61 + 110: 27(int) Load 109 + 111: 27(int) IAdd 108 110 + 112: 14(int) Bitcast 111 + Store 104(partnerBufferCoord00) 112 + 114: 32(ivec2) Load 79(globalId00) + Store 113(imageCoord00) 114 + 116: 32(ivec2) Load 86(partnerGlobalId00) + Store 115(partnerImageCoord00) 116 + 117: 16(ptr) Load 20(payload) + 118: 14(int) Load 54(bufferCoord) + 119: 14(int) Load 54(bufferCoord) + 120: 16(ptr) Load 20(payload) + 121: 14(int) Load 66(partnerBufferCoord) + 123: 122(ptr) AccessChain 120 28 121 + 124: 14(int) Load 123 Aligned NonPrivatePointerKHR 4 + 126: 14(int) ShiftRightLogical 124 125 + 127: 14(int) IAdd 119 126 + 128: 122(ptr) AccessChain 117 28 118 + Store 128 127 Aligned NonPrivatePointerKHR 4 + ControlBarrier 15 15 132 + 134: 35(ivec3) Load 133(gl_LocalInvocationID) + 135: 38(ivec2) VectorShuffle 134 134 0 1 + 138: 137(bvec2) IEqual 135 136 + 139: 6(bool) All 138 + SelectionMerge 141 None + BranchConditional 139 140 141 + 140: Label + 143: 142(ptr) AccessChain 26 46 + 144: 21(ptr) Load 143 + 145: 14(int) Load 54(bufferCoord) + 146: 122(ptr) AccessChain 144 28 145 + AtomicStore 146 46 150 55 + 151: 142(ptr) AccessChain 26 46 + 152: 21(ptr) Load 151 + 153: 14(int) Load 104(partnerBufferCoord00) + 154: 122(ptr) AccessChain 152 28 153 + 157: 14(int) AtomicLoad 154 46 156 + 158: 6(bool) IEqual 157 61 + Store 10(skip) 158 + 159: 6(bool) Load 10(skip) + Store 13(sharedSkip) 159 MakePointerAvailableKHR NonPrivatePointerKHR 15 + Branch 141 + 141: Label + ControlBarrier 15 15 161 + 162: 6(bool) Load 13(sharedSkip) MakePointerVisibleKHR NonPrivatePointerKHR 15 + Store 10(skip) 162 + 164: 16(ptr) Load 20(payload) + 165: 14(int) Load 66(partnerBufferCoord) + 166: 122(ptr) AccessChain 164 28 165 + 167: 14(int) Load 166 Aligned NonPrivatePointerKHR 4 + Store 163(r) 167 + 168: 6(bool) Load 10(skip) + 169: 6(bool) LogicalNot 168 + SelectionMerge 171 None + BranchConditional 169 170 171 + 170: Label + 172: 14(int) Load 163(r) + 173: 14(int) Load 66(partnerBufferCoord) + 174: 6(bool) INotEqual 172 173 + Branch 171 + 171: Label + 175: 6(bool) Phi 169 141 174 170 + SelectionMerge 177 None + BranchConditional 175 176 177 + 176: Label + 182: 14(int) Load 54(bufferCoord) + 184: 183(ptr) AccessChain 181(fail) 28 182 + Store 184 55 + Branch 177 + 177: Label + Return + FunctionEnd diff --git a/Test/spv.atomicAdd.bufferReference.comp b/Test/spv.atomicAdd.bufferReference.comp new file mode 100644 index 00000000..fdd031d0 --- /dev/null +++ b/Test/spv.atomicAdd.bufferReference.comp @@ -0,0 +1,50 @@ +#version 450 core +#pragma use_vulkan_memory_model +#extension GL_KHR_shader_subgroup_basic : enable +#extension GL_KHR_shader_subgroup_shuffle : enable +#extension GL_KHR_shader_subgroup_ballot : enable +#extension GL_KHR_memory_scope_semantics : enable +#extension GL_ARB_gpu_shader_int64 : enable +#extension GL_EXT_buffer_reference : enable +// DIM/NUM_WORKGROUP_EACH_DIM overriden by spec constants +layout(constant_id = 0) const int DIM = 1; +layout(constant_id = 1) const int NUM_WORKGROUP_EACH_DIM = 1; +shared bool sharedSkip; +layout(local_size_x_id = 0, local_size_y_id = 0, local_size_z = 1) in; +layout(buffer_reference) buffer PayloadRef { uint x[]; }; +layout(buffer_reference) buffer GuardRef { uint x[]; }; +layout(set=0, binding=2) buffer Fail { uint x[]; } fail; +layout (push_constant, std430) uniform PC { + layout(offset = 0) PayloadRef payloadref; +layout(offset = 8) GuardRef guard; +}; +void main() +{ + bool pass = true; + bool skip = false; + sharedSkip = false; + nonprivate PayloadRef payload = payloadref; + ivec2 globalId = ivec2(gl_GlobalInvocationID.xy); + ivec2 partnerGlobalId = ivec2(DIM*NUM_WORKGROUP_EACH_DIM-1) - ivec2(gl_GlobalInvocationID.xy); + uint bufferCoord = globalId.y * DIM*NUM_WORKGROUP_EACH_DIM + globalId.x; + uint partnerBufferCoord = partnerGlobalId.y * DIM*NUM_WORKGROUP_EACH_DIM + partnerGlobalId.x; + ivec2 imageCoord = globalId; + ivec2 partnerImageCoord = partnerGlobalId; + ivec2 globalId00 = ivec2(DIM) * ivec2(gl_WorkGroupID.xy); + ivec2 partnerGlobalId00 = ivec2(DIM) * (ivec2(NUM_WORKGROUP_EACH_DIM-1) - ivec2(gl_WorkGroupID.xy)); + uint bufferCoord00 = globalId00.y * DIM*NUM_WORKGROUP_EACH_DIM + globalId00.x; + uint partnerBufferCoord00 = partnerGlobalId00.y * DIM*NUM_WORKGROUP_EACH_DIM + partnerGlobalId00.x; + ivec2 imageCoord00 = globalId00; + ivec2 partnerImageCoord00 = partnerGlobalId00; + payload.x[bufferCoord] = bufferCoord + (payload.x[partnerBufferCoord]>>31); + controlBarrier(gl_ScopeWorkgroup, gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquireRelease | gl_SemanticsMakeAvailable); + if (all(equal(gl_LocalInvocationID.xy, ivec2(0,0)))) { + atomicStore(guard.x[bufferCoord], uint(1u), gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease | gl_SemanticsMakeAvailable); + skip = atomicLoad(guard.x[partnerBufferCoord00], gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire | gl_SemanticsMakeVisible) == 0; + sharedSkip = skip; + } + controlBarrier(gl_ScopeWorkgroup, gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquireRelease | gl_SemanticsMakeVisible); + skip = sharedSkip; + uint r = payload.x[partnerBufferCoord]; + if (!skip && r != uint(partnerBufferCoord)) { fail.x[bufferCoord] = 1; } +} \ No newline at end of file diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index d1123d4a..08494f82 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -2676,7 +2676,11 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors& selecto // 'swizzleOkay' says whether or not it is okay to consider a swizzle // a valid part of the dereference chain. // -const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay) +// 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node. +// +// + +const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk) { do { const TIntermBinary* binary = node->getAsBinaryNode(); @@ -2694,6 +2698,8 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool return nullptr; } node = node->getAsBinaryNode()->getLeft(); + if (bufferReferenceOk && node->isReference()) + return node; } while (true); } diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index c2b9edcf..d2ad355f 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -2409,6 +2409,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan arg0->getType().isFloatingDomain()) { requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str()); } + + const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true); + const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr; + const TQualifier& qualifier = (refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier(); + if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer) + error(loc,"Atomic memory function can only be used for shader storage block member or shared variable.", + fnCandidate.getName().c_str(), ""); + break; } diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 5cc9930a..37a78397 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -538,7 +538,7 @@ public: TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors& fields, const TSourceLoc&); // Tree ops - static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay); + static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false); // Linkage related void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); diff --git a/gtests/AST.FromFile.cpp b/gtests/AST.FromFile.cpp index 77f0aafb..cedd558e 100644 --- a/gtests/AST.FromFile.cpp +++ b/gtests/AST.FromFile.cpp @@ -282,6 +282,7 @@ INSTANTIATE_TEST_SUITE_P( "terminate.vert", "negativeWorkGroupSize.comp", "textureoffset_sampler2darrayshadow.vert", + "atomicAdd.comp", })), FileNameAsCustomTestSuffix ); diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 20683a68..1abd9b78 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -465,6 +465,7 @@ INSTANTIATE_TEST_SUITE_P( "spv.smBuiltins.frag", "spv.builtin.PrimitiveShadingRateEXT.vert", "spv.builtin.ShadingRateEXT.frag", + "spv.atomicAdd.bufferReference.comp" })), FileNameAsCustomTestSuffix );