SPIR-V Storage Class for GLSL Workgroup Shared Memory

In graphics and compute APIs utilizing SPIR-V, memory management relies on strictly defined storage classes that dictate scope, lifetime, and access permissions. This article explains the specific SPIR-V storage class assigned to GLSL workgroup shared variables, detailing how shader compilers translate the GLSL shared qualifier into SPIR-V intermediate representation and the operational semantics associated with this memory space.

The Workgroup Storage Class

When compiling OpenGL Shading Language (GLSL) to SPIR-V, variables declared with the shared storage qualifier are assigned the Workgroup storage class.

In a GLSL compute shader, a declaration such as:

shared float localBuffer[64];

is translated by SPIR-V compilers (such as glslang) into an OpVariable instruction using a pointer type parameterized with the Workgroup storage class:

%float = OpTypeFloat 32
%uint = OpTypeInt 32 0
%uint_64 = OpConstant %uint 64
%_arr_float_uint_64 = OpTypeArray %float %uint_64
%_ptr_Workgroup_arr = OpTypePointer Workgroup %_arr_float_uint_64
%localBuffer = OpVariable %_ptr_Workgroup_arr Workgroup

Architectural Characteristics of Workgroup Memory

The Workgroup storage class introduces specific architectural rules within the SPIR-V execution model:

  • Visibility and Scope: Memory allocated under the Workgroup storage class is shared across all invocations within a single workgroup. Invocations in different workgroups cannot access or observe modifications made to this memory.
  • Lifetime: The allocation persists only for the execution duration of the individual workgroup. Once all invocations in the workgroup complete, the memory is discarded.
  • Hardware Mapping: On modern GPUs, Workgroup variables typically map directly to on-chip Local Data Share (LDS) or shared memory, offering significantly lower latency and higher bandwidth compared to global device memory.
  • Synchronization: Because multiple invocations read and write to the same Workgroup addresses concurrently, access must be synchronized using barriers (OpControlBarrier) configured with the WorkgroupMemory semantics mask to prevent data races.