-
Notifications
You must be signed in to change notification settings - Fork 570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support generating shader code to load vertices #2204
base: main
Are you sure you want to change the base?
Conversation
adbb14b
to
e4954df
Compare
Keep it C++11. What are the real gains from using C++14 here? Min-spec is MSVC 2013 / GCC 4.8 (although GCC 4 CI is dead, so not sure if that builds anymore ...)
No dependency on external headers is acceptable. It's fine to document that the MSLFormat is an alias of VkFormat to make client code easier to write.
As long as this only occurs in shaders that use the special magic vertex loader and it doesn't cause actual real-world harm, I wouldn't care too much.
Just drop sRGB VBO support in MoltenVK. It's meaningless, and it seems it's the only one that exposes it.
What is the end-game for supporting extended_dynamic_state1 (core in 1.3 I think), which allows custom stride?
Given how massive it is, it's probably fine to keep it in a separate file. |
If by custom stride, you mean dynamic state stride, as of Metal 3.1 (this year's release), Metal now supports it. Work on |
Mainly better constexpr support
Done
Probably use the stride=0 handling for struct generation, declare vertex buffers as Edit: Actually, it seems that while
Guess I'd better implement it here |
cc6d5d9
to
0999521
Compare
Okay dynamic strides should be implemented, I indexed the stride buffer based on binding number, but maybe we should compress it to include only the bindings declared in the layout? |
94b7455
to
3a1cac2
Compare
So, getting back to this after a long time. I've been dreading to stare at this PR. 1700 lines just to load vertices is arguably pretty nuts. I cannot maintain or understand this code. The proposed MSL changes lately have been increasingly invasive and it's reaching the breaking point where I want to just outright reject the changes, but that's probably not acceptable. What is the end-game here? Is the plan to emit mesh shaders from vertex/geom/tess? Using mesh shaders for pure VS pipelines isn't very useful. What would that look like in practice? Another 3000 lines of hacks in SPIRV-Cross? I don't think adding increasingly more complex transforms to SPIRV-Cross is the right approach. Large-scale rewriting of code should stay in the IR domain I think. Ideally, we'd have done tessellation that way. Essentially, my main concern boils down to: Is there a path forward where SPIRV-Cross does not have to absorb all this complexity to work around Metal issues? |
Other options maybe worth entertaining/discussing off-line is handing over long-term maintainership of the MSL backend to CW/MoltenVK if these things must land SPIRV-Cross upstream. |
6bc56a5
to
5fad5d1
Compare
For vertex loading, I think making a SPIR-V vertex loader generator would be harder than making an MSL one, and making a SPIR-V generator whose code translates to performant MSL code would be even harder than that. For reference, the generated MSL code currently uses the following things that don't translate well from SPIR-V to MSL:
Doing the GS-mesh shader conversion might work fine over SPIR-V, but then it would want to call into either an MSL shader vertex loader or the MSL compute attribute binding system that tessellation shaders currently use, which wouldn't really be available to a shader that was generated outside of SPIRV-Cross. Maybe the best solution here would be to make SPIRV-Cross more friendly to being used to mix SPIR-V and the target language. e.g. if MoltenVK could do the SPIR-V equivalent of |
With the current spec, SRGB and UNORM are identical, making SRGB useless
5fad5d1
to
127ef5d
Compare
This seems like a good idea. SPIR-V spec has
Other options is to use the non-semantic extensions or define a special SPIRV-Cross ExtInst that can be used to add arbitrary calls. Maybe something simple like MoltenVK doing very light massage of the SPIR-V to add some wrap calls, SPIRV-Cross can just thunk the call and then all implementation detail that I shouldn't have to think or reason about is left to the API user.
That works too. When emitting functions, it should just be a matter of checking if there's a replacement string for that particular function body and it can be copy-pasted in, although using function declarations without a body seems more appropriate to me. |
I don't know exactly what the solution would look like, but iteration on smaller proof of concepts first seems like the way to go and it can grow from there. |
I've created #2229 to focus discussion on options and cost-benefits on this topic. |
Any chance to push this forward? |
Working on it |
Implementing vertex pipelines on mesh shaders will require shader code to load vertices, and what better way to make sure that code actually works properly than to implement it for use with anything so you can regression test CTS over it?
As a bonus, MoltenVK currently has a bunch of workarounds for Vulkan things that Metal doesn't support (read past stride, 0-divisor, etc), some of which are incredibly hacky. This removes the need for all of those, replacing them with a single "needs shader vertex loader" check: KhronosGroup/MoltenVK#2029.
Supports nearly every reasonable VkFormat, because why not
CTS status
int(char_array[0])
loads the equivalent ofint(reinterpret_cast<const device short&>(char_array[0]))
). The code only generates arrays when vertex data is indexed past its stride, so this bug only affects us for code that loads single-byte types from buffers indexed past their stride with single-byte alignment, so given the age of 10.13, I'm considering this too obscure to bother adding a workaround, but if you think it's important, I can try.Outstanding issues / questions:
Is it okay to bump the compiler requirement to C++14, or should I make this work with C++11?Now C++11Should I keep everything in one file (e.g. before eafb97f) or is a separate file fine? Also, preferences for single massive function vs multiple smaller ones called in succession (also e.g. before eafb97f)?Keeping separate fileI duplicated VkFormat and VkVertexInputRate under slightly different names due to the lack of vulkan headers. Would it be better to just add vulkan headers as a dependency, or would that run into issues with fighting over whose vulkan headers to include when using SPIRV-cross as a dependency in a project that also uses vulkan headers?Left separateLeft as-isbuild_implicit_builtins
runs very early and seems to be the only thing that can easily generate definitions of builtin variables. We don't actually know what builtins we'll need until afteradd_interface_block(StorageClassInput)
is called, at which pointbuild_implicit_builtins
has already run. For now, I'm just adding anything we might potentially need inbuild_implicit_builtins
, which leads to a lot of unusedgl_BaseVertex
andgl_BaseInstance
in many shaders, is there a better solution / should I be trying to refactor this (and if so, do you have any recommendations on how)?SRGB types are handled identically to UNORM as per Handling of SRGB vertex formats is confusing Vulkan-Docs#2214, should I temporarily disable support of SRGB types until that gets resolved?SRGB removed