Is your feature request related to a problem? Please describe.
I've noticed that wgpu doesn't provide any way to enable sample shading. As I can see in the wgpu-core code, hal::pso::Multisampling is always created with sample_shading set to None.
Describe the solution you'd like
I'm not sure about the best solution API-wise here. In the telegram chat, @kvark has suggested that it's possible to detect whether to enable sample shading by a shader itself if I got it correctly. I'm curious to hear how exactly this can be implemented.
Describe alternatives you've considered
Initially, I considered that it's something possible to add to RenderPipelineDescriptor itself. I guess that would require to change sample_count field to accept a descriptor(?) containing the related VkPipelineMultisampleStateCreateInfo data. That would be a breaking change though.
Thank you for filing!
wgpu already has to introspect shaders in order to validate them (in case of WGSL), and to validate the shader interface (i.e. that pipeline description is compatible with the shader). In this particular case, we should probably follow D3D model, where sample shading frequency is automatically enabled if one of the following is detected to be statically used by the fragment entry point:
Would it make sense to provide an API to enable sample shading if a user can't modify a fragment shader? In Vulkan I can just do multisampling.sampleShadingEnable = VK_TRUE without having to touch a shader. I believe it's best if a shader isn't aware whether it's used with sample shading or not in case it's not essential for the shader program itself. It would also help to avoid recompiling shaders if a user wants to play around with different sample settings.
For example, OpenGL Programming Guide suggests the following motivation:
If you can鈥檛 modify a fragment shader to use the sample keyword (e.g.,
you鈥檙e creating a library that accepts shaders created by another
programmer), you can have OpenGL do sample shading by passing
GL_SAMPLE_SHADING to glEnable(). This will cause unmodified
fragment shader in variables to be interpolated to sample locations
automatically.
http://www.csc.villanova.edu/~mdamian/Textbooks/opengl_programming_guide_8th_edition.pdf
Another question: is it possible to reflect such settings as minSampleShading in a shader? If it's something that we want to allow users to control, I guess it should be a concern as well.
And the last one: not sure whether it matters and is feasible, but I guess the API way would also make it possible to allow controlling sample shading in application runtime (game settings).
Since we have to be portable over Vulkan, Metal, and D3D, we don't have a luxury of enabling it manually. In D3D the rules are set for us. If we make it explicit, and the user says "no sample shading" but the shader expects it, then we have a problem that D3D would show a non-portable behavior.
I believe it's best if a shader isn't aware whether it's used with sample shading or not in case it's not essential for the shader program itself.
How do you think the shading frequency is going to be observable? Are you talking about the scenario where the shader uses "sample" interpolation qualifier, but the host side can force it to still run at pixel frequency?
is it possible to reflect such settings as minSampleShading in a shader
I don't think the shaders would know about this rate in any way.
In D3D the rules are set for us. If we make it explicit, and the user says "no sample shading" but the shader expects it, then we have a problem that D3D would show a non-portable behaviour.
Oh, I see. I didn't know that supersampling can be controlled only within a shader in D3D. Thanks for explaining.
How do you think the shading frequency is going to be observable? Are you talking about the scenario where the shader uses "sample" interpolation qualifier, but the host side can force it to still run at pixel frequency?
Well, I just saw that both Vulkan and OpenGL seem to provide such an option, so I thought it's something worth bringing up. I didn't have any particular scenario in mind.
If the only portable way is to allow enabling sample shading only via a shader, that's the way to go I guess.
If your use case is indeed "shader uses "sample" interpolation qualifier, but the host side can force it to still run at pixel frequency" like I asked, then technically we can still do it semi-explicitly. I.e. if the pipeline is created with "pixel" frequency, then we could go through all the fragment shader interpolation qualifiers and change "sample" -> "linear". Then, we could for example trigger an error if the shader uses sample_index built-in... But this all is more complicated than just deriving the usage in the first place, so we should consider it after we get the basic scheme working.