[Feature Request] [SPIR-V] Suport the vk::per_primitive attribute
Is your feature request related to a problem? Please describe.
Mesh shaders can output per-vertex and/or per-primitive variables. In HLSL the vertices and the primitives keywords are used to distinguish between the two but these keywords are only supported in mesh shaders and not in pixel shaders. DX12 is fine with that because it relies on linking (using semantic names) at PSO creation time. This is not how Vulkan works. Vulkan needs the PerPrimitiveEXT decoration in fragment shaders as well. From a first glance it doesn't seem possible to have per-primitive variables DXC/HLSL when targeting SPIRV.
Describe the solution you'd like
Maybe it's better to add support for a vk::per_primitive attribute that can tag the whole struct. This attribute will add the PerPrimitiveEXT decoration to all the members of the struct.
Describe alternatives you've considered Using SPIRV intrinsics it's possible to add the required decoration:
struct PerPrim {
[[vk::ext_decorate(5271)]] float4 a : A;
[[vk::ext_decorate(5271)]] float4 b : B;
};
[[vk::ext_extension("SPV_EXT_mesh_shader")]] [[vk::ext_capability(5283)]] float4 PSMain(PerPrim ....) {...}
The solution is somewhat annoying because the decoration has to go to each member and extra stuff need to be added to the entry point.
Additional context N/A
I wonder if we could just adjust DXC to accept the existing "primitives" and "vertices" decorations in a pixel shader? It doesn't seem like it would be harmful to allow them for DXIL, particularly if DX ever ends up going down the route of breaking up monolithic PSOs. That would need input from the core HLSL and DX teams though.
@pow2clk @llvm-beanz What do you think of @Tobski's idea? That was my first thought as well. I don't like having the outputs of the mesh shader and the inputs of the pixel shader having different attributes that will mean the same thing.
It could then be ignored by the DXIL backend. If we do it, we should try to target HLSL202X.
I've discussed this with others. We decided not to reuse the primitives keyword because it our use will be more general. That keyword only applies to structures, and not to fields. It is not easy to implement an attribute that applies to a parameter only in one case, and on both a parameter or field in another.
We decided to have a Vulkan specific attribute that can be applied where we want it. It should only be used for pixel shader inputs, and it can be placed on:
- [ ] fields of a struct that is the type of an input.
- [ ] on a scalar input parameter itself
- [ ] on a struct parameter where it will apply to every member of the struct.
Also, this was already address in the VK_EXT_mesh_shader extension, where an attribute [[vk::perprimitive]] was suppose to be added to HLSL. However, this was never implemented.