-
Notifications
You must be signed in to change notification settings - Fork 438
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
Move shader analysis to Vulkano crate, make available for runtime shaders #1747
Conversation
…able for runtime shaders
@@ -102,7 +102,7 @@ fn main() { | |||
// by default and the macro by default producing unique | |||
// structs(`MultSpecializationConstants`, `AddSpecializationConstants`) | |||
shared_constants: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you change this flag to false
, it will generate multSpecializationConstants
/addSpecializationConstants
(is it?), which is also violates naming convention.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I missed that bit. I can convert the name to CamelCase using the heck
crate that is already used by autogen.
examples/src/bin/teapot/main.rs
Outdated
@@ -301,8 +307,8 @@ fn main() { | |||
/// This method is called once during initialization, then again whenever the window is resized | |||
fn window_size_dependent_setup( | |||
device: Arc<Device>, | |||
vs: &vs::Shader, | |||
fs: &fs::Shader, | |||
vs: Arc<ShaderModule>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe pass &ShaderModule
here to avoid vs
/fs
cloning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that was a leftover from an earlier experiment I did with how the entry points should work, that I ended up abandoning. I'll fix it.
vulkano-shaders/src/codegen.rs
Outdated
@@ -775,6 +343,19 @@ mod tests { | |||
.collect() | |||
} | |||
|
|||
#[test] | |||
fn test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you give more descriptive name to this test, please? In case it fails, it would be easier to find the test code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, fixed.
vulkano/autogen/spirv_parse.rs
Outdated
.operand_kinds | ||
.iter() | ||
.filter(|operand_kind| operand_kind.category == "BitEnum") | ||
.cloned() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and in similar places perhaps cloning and twice collecting can be avoided by turning functional-style call chaining into imperative for-loop. The entire code would look shorter and will cost lesser performance and memory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean having a mut kinds_dedup
and then push
ing elements into it? I don't know if that would be any faster, and I've always specifically avoided that style in favour of collect
. My impression is that Rust is quite smart when it comes to optimising iterators, but comparing the assembly output or doing a benchmark is probably the only way to know for sure.
As for the cloning, I suppose that could be avoided, I'll see what I can do.
@@ -49,8 +50,8 @@ impl ComputePipeline { | |||
/// to add dynamic buffers or immutable samplers. | |||
pub fn new<Css, F>( | |||
device: Arc<Device>, | |||
shader: &ComputeEntryPoint, | |||
spec_constants: &Css, | |||
shader: EntryPoint, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why owned value instead of reference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed while working that GraphicsPipelineBuilder
took an owned GraphicsEntryPoint
while ComputePipeline
took a borrowed &ComputeEntryPoint
. I removed the borrow to make them both the same. They could both borrow instead, but I think that would be problematic for GraphicsPipelineBuilder
, and for performance a borrow just adds one layer of indirection.
vulkano/src/shader/mod.rs
Outdated
@@ -7,15 +7,15 @@ | |||
// notice may not be copied, modified, or distributed except | |||
// according to those terms. | |||
|
|||
//! Stage of a graphics pipeline. | |||
//! A program that is run on the GPU. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More broadly speaking on the Graphics Device
which could be in theory a CPU-backed emulator of Vulkan :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, fixed!
@Rua Thank you for your hard work! It's amazing! I only did a brief code review at this moment, left a few comments to discuss and maybe to fix. I will take a closer look later and do some tests. In addition to that I have a concern about the generated entry-point reusability. Previously the user could load the module, and then reuse it's main entry point every time they create a pipeline. WIll they be able to do the same in the new implementation, or the entry point generation in place is unavoidable? |
|
@Rua Can you fix merging conflicts, please? |
…untime-shader-parsing
Done. |
@Rua I adapted my project's code to these changes, but I'm receiving the following error:
There was no such error before, and it worked fine. If I raise the Instance version to |
Do you have the |
@Rua I just tried to enabled it(for Vulkan 1.1). And it asked to enable "khr_maintenance3"(
How so? I suppose, the Instance/Device of Vulkan 1.2 shouldn't let the user load the shader that requires Vulkan 1.2 and/or it's extensions, and explicitly specifies version 1.1. |
And if you enable the feature too, what happens then? The feature requirement is also according to spec; some extensions require a feature to be enabled when the extension is enabled.
It's not really a matter of the shader version itself as far as I can tell. Rather, the shader is compiled with certain SPIR-V capabilities and extensions enabled, and those in turn require matching features and extensions on the Vulkan device. If you look at the SPIR-V assembly code of your shader, you will see the As for the |
@Rua Sorry, what do you mean by enabling the feature? |
When you create a device, you pass in a |
@Rua Got it. Now it says that the feature is not supported. It looks very strange, because all of it works with Vulkan 1.2 and without explicitly enabling of these features and extensions. |
Anyway, I don't think this is a blocker for the PR merging. |
I think I see where the problem lies. The
However, |
Understood. ok, I thought there is something with my gpu driver. Anyway, PR is merged. Thanks for all the fixes and explanations! |
Fixes #1558, #1673. This moves most of the shader analysis code from Vulkano-shaders to the main Vulkano crate, so that it can be used for runtime-loaded shaders as well.
ShaderModule
will now analyse the code given to it by default, but it's still possible to provide the data manually if you want. This is done by Vulkano-shaders to avoid having to parse and analyse the code each time the program is run, so you don't have to pay a performance penalty for using Vulkano-shaders.The new code also checks compatibility between the shader (SPIR-V capabilities and extensions) and the device. For this, I added more code to autogen that generates checks from vk.xml, which already contains information about device requirements for each SPIR-V capability and extension.
The rest of the changes are mainly rearranging and changes of APIs to facilitate this. Shader entry points can now be retrieved at runtime via a string, based on the data collected from the shader. Vulkano-shaders generates its code a little differently.