GPU: Push Constants #89553

Closed
opened 2021-06-30 12:22:40 +02:00 by Jeroen Bakker · 6 comments
Member

Add the concept of push constants to GPUShader(Interface)
Branch: temp-gpu-push-constants.

What are push constants?

Push constants have been introduced with vulkan and the main difference with uniform buffers are that they are transported inside the command buffer and not bound. A shader can only have a single push constant (struct). Per shader stage the offset can be changed.

There is a minimum (specification) and maximum (physical device property) that should be respected.

GLSL example

layout(push_constant) uniform BlockName {
        int member1;
        float member2;
        ...
} InstanceName; // optional instance name

... = InstanceName.member2; // read a push constant

In openGL this could be written as a UBO

layout(std140) uniform BlockName {
        int member1;
        float member2;
        ...
} InstanceName; // optional instance name

... = InstanceName.member2; // read a push constant

Alternatives

Alternative1: Cross compilation using macros
Cross compilation can be done with a simple macro

- define LAYOUT_PUSH_CONSTANT layout(push_constant)
- define LAYOUT_PUSH_CONSTANT layout(std140)

challenge is that we still need to indetify the push constant in the shader interface for the API. if it is handled as a regular uniform there would be differences when using OpenGL vs Vulkan.

Alternative2: Source parsing.

Using a preprocessor we could detect the push constant and retrieve the needed information. For OpenGL we need the name for locating the binding. This could be written as a string parser.

Alternative3: Source parsing using GLSLANG.

For this case the source parsing could be done by the glslang. this library is already included in the shaderc lib that we want to use for SpirV compilation.

The biggest challenge is that we still need to rewrite the Vulkan GLSL to OpenGL GLSL. This could be done by walking the AST like (https://github.com/KhronosGroup/glslang/blob/master/glslang/MachineIndependent/intermOut.cpp) but that leads to different source code and reduces traceability.

TODO
Both doesn't seem active, but do what we want using AST.

Conclusion

I prefer to use Alternative2 as is a solution that works. Both 1 and 3 are limited and would need alternative 2 to fix their short comings.

The result of the parser would be passed to the ShaderInterface the shader interface can check if a uniform is actually a push constant and register it as a push constant.

Usages:

  • builtin uniforms can be partially moved to push constants. Shaders only uses a small subset of the builtin uniforms (largest internally = 61 floats/244 bytes MODEL, MVP, CLIPPLANES, COLOR, SRGB_TRANSFORM)

NOTE: On Linux/Mesa the maxPushConstatsSize = 128 bytes.

Add the concept of push constants to GPUShader(Interface) Branch: `temp-gpu-push-constants`. **What are push constants?** Push constants have been introduced with vulkan and the main difference with uniform buffers are that they are transported inside the command buffer and not bound. A shader can only have a single push constant (struct). Per shader stage the offset can be changed. There is a minimum (specification) and maximum (physical device property) that should be respected. **GLSL example** ``` layout(push_constant) uniform BlockName { int member1; float member2; ... } InstanceName; // optional instance name ... = InstanceName.member2; // read a push constant ``` In openGL this could be written as a UBO ``` layout(std140) uniform BlockName { int member1; float member2; ... } InstanceName; // optional instance name ... = InstanceName.member2; // read a push constant ``` **Alternatives** **Alternative1: Cross compilation using macros** Cross compilation can be done with a simple macro ``` - define LAYOUT_PUSH_CONSTANT layout(push_constant) - define LAYOUT_PUSH_CONSTANT layout(std140) ``` challenge is that we still need to indetify the push constant in the shader interface for the API. if it is handled as a regular uniform there would be differences when using OpenGL vs Vulkan. **Alternative2: Source parsing.** Using a preprocessor we could detect the push constant and retrieve the needed information. For OpenGL we need the name for locating the binding. This could be written as a string parser. **Alternative3: Source parsing using GLSLANG.** For this case the source parsing could be done by the glslang. this library is already included in the shaderc lib that we want to use for SpirV compilation. The biggest challenge is that we still need to rewrite the Vulkan GLSL to OpenGL GLSL. This could be done by walking the AST like (https://github.com/KhronosGroup/glslang/blob/master/glslang/MachineIndependent/intermOut.cpp) but that leads to different source code and reduces traceability. **TODO** Both doesn't seem active, but do what we want using AST. - [ ] https://github.com/graphitemaster/glsl-parser - [ ] https://github.com/Shirakumo/glsl-toolkit **Conclusion** I prefer to use Alternative2 as is a solution that works. Both 1 and 3 are limited and would need alternative 2 to fix their short comings. The result of the parser would be passed to the ShaderInterface the shader interface can check if a uniform is actually a push constant and register it as a push constant. Usages: - builtin uniforms can be partially moved to push constants. Shaders only uses a small subset of the builtin uniforms (largest internally = 61 floats/244 bytes MODEL, MVP, CLIPPLANES, COLOR, SRGB_TRANSFORM) NOTE: On Linux/Mesa the maxPushConstatsSize = 128 bytes.
Jeroen Bakker self-assigned this 2021-06-30 12:22:40 +02:00
Author
Member

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Author
Member

Added subscriber: @Jeroen-Bakker

Added subscriber: @Jeroen-Bakker

Added subscriber: @2046411367

Added subscriber: @2046411367

Added subscriber: @dodo-2

Added subscriber: @dodo-2
Author
Member

Changed status from 'Confirmed' to: 'Archived'

Changed status from 'Confirmed' to: 'Archived'
Author
Member

Replaced by GPUShaderCreateInfo

Replaced by GPUShaderCreateInfo
Sign in to join this conversation.
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: blender/blender#89553
No description provided.