-
Notifications
You must be signed in to change notification settings - Fork 60
enum SpirvTargetEnv
containing all available targets
#311
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
base: main
Are you sure you want to change the base?
Conversation
bbbcf8b
to
61a51d6
Compare
326f31a
to
669460a
Compare
669460a
to
109b8c9
Compare
109b8c9
to
4be9bba
Compare
crates/spirv-builder/src/lib.rs
Outdated
@@ -490,10 +490,10 @@ impl Default for SpirvBuilder { | |||
} | |||
|
|||
impl SpirvBuilder { | |||
pub fn new(path_to_crate: impl AsRef<Path>, target: impl Into<String>) -> Self { | |||
pub fn new(path_to_crate: impl AsRef<Path>, target: SpirvTargetEnv) -> Self { |
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.
This PR introduces a significant breaking change right here that will affect everyone. I would like to change SpirvBuilder.target
to the new enum, so new users don't have to deal with strings. But this moves parsing of the target string from build()
to here, where we can't just return an error easily. The options:
- breaking change: return a Result for failed parsing, may be annoying to handle for the user
My choice:breaking change: require everyone to use the new enum directly (SpirvTargetEnv::Vulkan_1_2
) or explicitly call the parse function that may fail (SpirvTargetEnv::parse_triple("spirv-unknown-vulkan1.2")?
)- a surprise panic if parsing fails
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 not impl Into<SpirvTargetEnv>
and support &'static str
, breaking everyone who didn't specify a string?
I forget if you can mark an impl
or its methods as deprecated (or rather, if that ever results in a warning).
But honestly, enumerating the target-env explicitly is a bit silly. It would be much cooler if you can come up with a foolproof way for spirv-builder
itself to create and cache a target JSON (e.g. in the target dir, which currently we only detect based off of $OUT_DIR
, but maybe we could cheaply get "what would be the target dir used for the shader crate" out of Cargo?).
And then we presumably wouldn't even need this part of the system to care about the values at all and it can remain a string (unless that interferes with other plans ofc).
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 may have an even better idea how not to break anything: Just have SpirvBuilder.target
be Result<SpirvTargetEnv, *ParseError>
so we can forward the error to the build()
call. Then make new(..., target: impl IntoSpirvTargetEnv)
so it can accept a &str
, String
or SpirvTargetEnv
. We would only break anyone doing builder.target = Some("spirv-unknown-vulkan1.2")
which is a small minority since that only works since about 2 months or so.
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.
impl IntoSpirvTargetEnv
... so it can accept a&str
,String
or ...
I suppose one way to be 100% back-compat would be to implement IntoSpirvTargetEnv
for all types that implement Into<String>
, but that might feel wasteful, idk. Then again, some of this depends on whether we care about parsing SpirvTargetEnv
at all.
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 like that IDEs can auto-complete enum names, since they're symbols, not magic strings
match self { | ||
SpirvTargetEnv::OpenGL_4_0 => { | ||
include_str!("../target-specs/spirv-unknown-opengl4.0.json") | ||
} | ||
SpirvTargetEnv::OpenGL_4_1 => { | ||
include_str!("../target-specs/spirv-unknown-opengl4.1.json") | ||
} | ||
SpirvTargetEnv::OpenGL_4_2 => { | ||
include_str!("../target-specs/spirv-unknown-opengl4.2.json") | ||
} | ||
SpirvTargetEnv::OpenGL_4_3 => { | ||
include_str!("../target-specs/spirv-unknown-opengl4.3.json") | ||
} | ||
SpirvTargetEnv::OpenGL_4_5 => { | ||
include_str!("../target-specs/spirv-unknown-opengl4.5.json") | ||
} | ||
SpirvTargetEnv::Spv_1_0 => { | ||
include_str!("../target-specs/spirv-unknown-spv1.0.json") | ||
} | ||
SpirvTargetEnv::Spv_1_1 => { | ||
include_str!("../target-specs/spirv-unknown-spv1.1.json") | ||
} | ||
SpirvTargetEnv::Spv_1_2 => { | ||
include_str!("../target-specs/spirv-unknown-spv1.2.json") | ||
} | ||
SpirvTargetEnv::Spv_1_3 => { | ||
include_str!("../target-specs/spirv-unknown-spv1.3.json") | ||
} | ||
SpirvTargetEnv::Spv_1_4 => { | ||
include_str!("../target-specs/spirv-unknown-spv1.4.json") | ||
} | ||
SpirvTargetEnv::Spv_1_5 => { | ||
include_str!("../target-specs/spirv-unknown-spv1.5.json") | ||
} | ||
SpirvTargetEnv::Spv_1_6 => { | ||
include_str!("../target-specs/spirv-unknown-spv1.6.json") | ||
} | ||
SpirvTargetEnv::Vulkan_1_0 => { | ||
include_str!("../target-specs/spirv-unknown-vulkan1.0.json") | ||
} | ||
SpirvTargetEnv::Vulkan_1_1 => { | ||
include_str!("../target-specs/spirv-unknown-vulkan1.1.json") | ||
} | ||
SpirvTargetEnv::Vulkan_1_1_Spv_1_4 => { | ||
include_str!("../target-specs/spirv-unknown-vulkan1.1spv1.4.json") | ||
} | ||
SpirvTargetEnv::Vulkan_1_2 => { | ||
include_str!("../target-specs/spirv-unknown-vulkan1.2.json") | ||
} | ||
SpirvTargetEnv::Vulkan_1_3 => { | ||
include_str!("../target-specs/spirv-unknown-vulkan1.3.json") | ||
} | ||
SpirvTargetEnv::Vulkan_1_4 => { | ||
include_str!("../target-specs/spirv-unknown-vulkan1.4.json") | ||
} | ||
} |
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.
Quick question since we keep changing these things, since I went with JSON files to minimal deviation from previous behavior, and because they wouldn't cause spurious rebuilds (relative to the spirv-builder
version being used, since I would expect shaders to be rebuilt most of the times spirv-builder
itself is rebuilt):
Could cargo-gpu
generate the JSON file on-demand (and maybe cache it)? Especially since there's include_str!
going on here, I feel like that's already what's happening?
Because the only difference between these files is, for spirv-unknown-X
:
env
is set toX
llvm-target
is set tospirv-unknown-X
$ echo crates/rustc_codegen_spirv-target-specs/target-specs/*.json | xargs -n1 diff -U0 crates/rustc_codegen_spirv-targe
t-specs/target-specs/spirv-unknown-spv1.0.json | rg '^[\-+] ' -r '' | sed 's/: .*/: .../' | sort -u
"env": ...
"llvm-target": ...
(run this without sed 's/: .*/: .../'
to see the actual values)
They could even be generated by string interpolation, if not serde_json
, since the target env name doesn't even need escaping!
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.
cargo-gpu only needs them for the "legacy path" aka rustc_codegen_spirv
versions which did not depend on *target-specs
. And that "legacy" dependency is fixed to version 0.9 on crates, so technically these changes don't actually do anything. It just feels wrong not to adjust them as well.
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.
Sorry, I'm not 100% sure what's going on, are you saying that most of the time, the .json
files in the source tree get used?
I would actually be happier if cargo-gpu
/spirv-builder
created these from one template - I don't mind rustc_codegen_spirv-target-specs
existing (and we can release older versions of that crate, if we want, I guess?) - but its main job could be "take this target_env
string and return a JSON blob", without having the result of that templating be baked in the way it is today.
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.
Wow, I actually wrote some nice docs for what's going on: https://github.com/Rust-GPU/cargo-gpu/blob/main/crates/cargo-gpu/src/target_specs.rs
And I get that they actually don't change much, just something I didn't know / want to worry about back when I wrote this.
6bd4a1b
to
51d17b9
Compare
cargo-gpu fixup: Rust-GPU/cargo-gpu#92
List all available targets in
enum SpirvTargetEnv
and centralize parsing, to_string and target spec references there. ChangesSpirvBuilder.target
from String to the new enum and makesSpirvBuilder::new
accept both String and the new enum to reduce breakage as much as possible.