SPIR-V OpEntryPoint: Execution Models & Interfaces

This article examines the function and significance of the OpEntryPoint instruction within SPIR-V binaries compiled from OpenGL Shading Language (GLSL). It details how OpEntryPoint establishes the execution model for a shader stage, defines the module's entry point function, and explicitly declares the interface variables used for hardware input and output communication.

What is OpEntryPoint?

In SPIR-V, a single binary module can contain multiple functions, execution paths, and even multiple shader stages. The OpEntryPoint instruction acts as the primary manifest for a specific shader's execution. It informs the graphics driver where execution begins, which pipeline stage the shader targets, and which global variables form the interface for that stage.

The standard syntax of OpEntryPoint consists of four primary components:

OpEntryPoint <Execution Model> <Entry Point ID> "<Name>" <Interface IDs...>
  • Execution Model: The hardware stage to run (e.g., Vertex, Fragment, GLCompute).
  • Entry Point ID: The SSA ID pointing to the OpFunction that serves as the entry function (typically compiled from GLSL's void main()).
  • Name: A literal string specifying the export name of the entry point (often "main").
  • Interface IDs: A list of IDs representing all global variables that make up the inputs and outputs used by this entry point.

Defining the Execution Model

When a GLSL shader is compiled into SPIR-V, the compiler converts stage directives into an explicit ExecutionModel operand inside OpEntryPoint.

Common execution models include:

  • Vertex (for vertex shaders)
  • TessellationControl and TessellationEvaluation
  • Geometry
  • Fragment (for fragment/pixel shaders)
  • GLCompute (for compute shaders)
  • Ray tracing models such as RayGenerationKHR, ClosestHitKHR, and MissKHR

By decoupling the function implementation from the execution model, SPIR-V enables modular shader construction. A single SPIR-V file can host both a vertex and a fragment entry point. The client API (such as Vulkan via VkPipelineShaderStageCreateInfo) references the entry point name and execution model to link the correct entry point to the intended pipeline stage.

Declaring the Shader Interface

The interface list in OpEntryPoint declares all global inputs and outputs associated with that execution path. This explicit declaration fulfills several roles:

  1. Static Interface Analysis: The driver can inspect the interface list without traversing the function's control flow graph. It identifies which variables must be bound to pipeline registers or fixed-function hardware (like rasterizer interpolators or framebuffers).
  2. SPIR-V Version Compatibility: In SPIR-V 1.0 through 1.3, the interface list only included variables in the Input and Output storage classes. Beginning with SPIR-V 1.4, this was expanded to include all global variables accessed by the entry point’s call tree, including Uniform, StorageBuffer, and UniformConstant (samplers and images). This guarantees complete dependency mapping per entry point.
  3. Namespace and Resource Isolation: When multiple entry points reside within the same module, each OpEntryPoint declares only the subset of global OpVariable nodes it actually touches. This prevents dead code or unused descriptor sets from interfering with stages that do not reference them.

Compilation from GLSL

When compilers like glslang process GLSL code:

  1. The GLSL void main() function is emitted as an OpFunction.
  2. Global variables declared with storage qualifiers (in, out, uniform, buffer) are allocated via OpVariable.
  3. An OpEntryPoint is generated, linking the stage defined by the GLSL source type (e.g., .vert, .frag) to the main OpFunction and listing every referenced input/output variable ID.
  4. Subsequent execution modes—such as local workgroup sizes for compute shaders or pixel center configurations for fragment shaders—are linked to this entry point via OpExecutionMode instructions targeting the same entry point function ID.

Through OpEntryPoint, the SPIR-V architecture ensures that hardware drivers can reliably determine how to set up, bind, and execute GLSL shader logic within the rendering pipeline.