PDA

View Full Version : SPIR-V consumption in OpenGL



Alfonse Reinheart
04-26-2015, 09:46 AM
OpenGL 4.6 (or 5.0 or whatever the next version is called) should be able to consume SPIR-V. This entails two changes:

1: glProgramBinary should be able to take SPIR-V. This would mean having a specific binary format enumerator for SPIR-V, which is something that ought to be simple enough. Any compilation errors can be reported via the usual method (GL_LINK_STATUS = GL_FLASE and an error message). There would not be a corresponding glGetProgramBinary for SPIR-V. Also, all SPIR-V-format programs are implicitly separable.

2: Descriptor Sets/Layouts in OpenGL.

That last one bears some explanation.

Vulkan uses descriptor layouts and sets for providing resources to shaders. This includes UBO/SSBOs, textures, and images. And SPIR-V has decorations for detailing how these in-shader resources map to descriptor layouts. Which is fine.

SPIR-V also has decorations for detailing how these in-shader resources map to OpenGL constructs: equivalents to layout(location) and layout(binding).

The last part would be sufficient for OpenGL to make use of SPIR-V. However, there would be a problem from the perspective of a front-end developer. Specifically, the front-end must know up-front whether the SPIR-V it generates will be handed to OpenGL or Vulkan.

Now certainly, SPIR-V's decorator scheme allows a single SPIR-V front-end to deliver information for both APIs; Vulkan compilers will ignore the OpenGL decorators, and OpenGL compilers will ignore the Vulkan decorators. Even so, this means that the shading language given to the front-end must provide a way for the user to specify both Vulkan descriptor layouts and OpenGL location/binding information.

By giving OpenGL descriptor layout/set functionality equivalent to Vulkan, you avoid all of that. OpenGL and Vulkan will be able to use the same scheme, and thus can take the same SPIR-V. Leave the old OpenGL decorators for backwards-compatibility, but OpenGL should be able to handle both through SPIR-V.

Naturally, this would also require changes to GLSL, to allow you to specify descriptor layout information from within GLSL. And similarly, the off-line GLSL-to-SPIR-V compiler would need to be updated to compile this code.

Now, I would suggest that a program be compiled either in descriptor set/layout mode or in context mode. So any particular program either gets all of its data from descriptor sets, or it gets all of its data from objects bound to the context (whether it would be allowed to mix such programs in a pipeline is up to you). For compiling GLSL, this would probably be some kind of in-shader specification, or a linker parameter like GL_PROGRAM_SEPARABLE. For generating programs from a SPIR-V binary, this information would be part of the format enum. Meaning that there would be two enumerators: GL_FORMAT_SPIR_V_DESCRIPTOR_SET and GL_FORMAT_SPIR_V_CONTEXT.

Note that while this suggestion would introduce descriptor sets into the OpenGL API, interacting with them should still behave in a synchronous fashion (unlike Vulkan). That is, if you change the data in a set, all previously-issued commands should be unaffected. Just like if you change the data in a buffer object with glBufferSubData.

Descriptor sets also let you effectively bring bindless textures into core OpenGL, simply by having an arbitrarily large array of textures. I seem to recall hearing that Intel hardware could handle this functionality, but was unable to implement ARB_bindless_texture for some reason.