-
Notifications
You must be signed in to change notification settings - Fork 255
Description
Is your feature request related to a problem? Please describe.
Using shader specialization constants to size global arrays doesn't work on the Mac.
We have a need in our vertex shader to size both a vertex attribute array and an array of gl_clipDistance by a defined value at shader compile time. We were using shader specialization constants to achieve this and on Linux and Windows with NVidia and AMD we seemed to have success even though the "Arrays inside a block" discussion in section "4.4.x Specialization-Constant Qualifier" of ARB_gl_spirv.txt made it sound like using specialization constants to size these array members in the shader is not supported. When we tried out the same code on the Mac we had very unreliable results and were not able to get clipping to work correctly if the vertex array or the gl_ClipDistance array was sized by a specialization constant.
Describe the solution you'd like
We would like to expand the definition of a shader compiler define in VSG to allow for an optional value to be associated with the define name. Here are several proposed solutions:
- Continue with the existing
std::stringandstd::set<std::string>interfaces for managing defines which allow client code to add valueless defines with a simple upper case string such as,"VERTEX_NORMALS". In addition to valueless defines that are currently supported, allow a define to have a"NAME=VALUE"syntax. This would allows a defined to be constructed as,"NUM_PRIMITIVE_CLIPS=3". There are several places inShaderCompiler.cppwhere the name portion of the define would need to be extracted when comparing with the list of#pragma import_defines, and when the define is expanded to the header stream. If an equal sign is found in a define it would be replaced with a space and then added to theheaderstreamjust like it is today. - Add a new type,
vsg::CompileDefine, that is used in place of thestd::stringinterface and maintain a set of defines withstd::set<vsg::CompilerDefine>. The constructor forvsg::CompileDefinewould allow for valueless or name/value construction. The changes required to VSG would be much more intrusive and we might need special handling for VSG serialization. This makes option 2 less attractive than option 1.
Describe alternatives you've considered
We attempted to use shader specialization constants but it wasn't super clear if they are even allowed to be used to size global arrays and we had inconsistent behavior on the Mac. Additionally, even on Linux and Windows with NVidia and AMD we had to make a default value for the shader constant that was the maximum array size. In the end we determined that using specialization constants for this purpose was not correct.
Additional context
We are happy to provide a pull request for review.