Skip to content
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

Refactor vulkano-shaders and support HLSL #2568

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add lang option to vulkano_shaders::shader! and update documentation
interacsion committed Sep 15, 2024
commit 075e9812d89c7384d7cc31a2284755dfc95122a0
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -130,7 +130,7 @@ of unreleased and breaking changes in `master`
This repository contains four libraries:

- `vulkano` is the main one.
- `vulkano-shaders` provides the `shader!` macro for compiling glsl shaders.
- `vulkano-shaders` provides the `shader!` macro for compiling shaders.
- `vulkano-util` provides a variety of utility functions to streamline certain common operations such as device and swapchain creation.
- `vulkano-win` provides a safe link between vulkano and the `winit` library which can create
a window to render to.
12 changes: 9 additions & 3 deletions vulkano-shaders/src/codegen.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ use heck::ToSnakeCase;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub use shaderc::{CompilationArtifact, IncludeType, ResolvedInclude, ShaderKind};
use shaderc::{CompileOptions, Compiler, EnvVersion, TargetEnv};
use shaderc::{CompileOptions, Compiler, EnvVersion, SourceLanguage, TargetEnv};
use std::{
cell::RefCell,
fs,
@@ -145,10 +145,13 @@ pub(super) fn compile(
shader_kind: ShaderKind,
) -> Result<(CompilationArtifact, Vec<String>), String> {
let includes = RefCell::new(Vec::new());
let compiler = Compiler::new().ok_or("failed to create GLSL compiler")?;
let compiler = Compiler::new().ok_or("failed to create shader compiler")?;
let mut compile_options =
CompileOptions::new().ok_or("failed to initialize compile options")?;

let source_language = input.source_language.unwrap_or(SourceLanguage::GLSL);
compile_options.set_source_language(source_language);

compile_options.set_target_env(
TargetEnv::Vulkan,
input.vulkan_version.unwrap_or(EnvVersion::Vulkan1_0) as u32,
@@ -160,7 +163,10 @@ pub(super) fn compile(

let root_source_path = path.as_deref().unwrap_or(
// An arbitrary placeholder file name for embedded shaders.
"shader.glsl",
match source_language {
SourceLanguage::GLSL => "shader.glsl",
SourceLanguage::HLSL => "shader.hlsl",
},
);

// Specify the file resolution callback for the `#include` directive.
35 changes: 28 additions & 7 deletions vulkano-shaders/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The procedural macro for vulkano's shader system.
//! Manages the compile-time compilation of GLSL into SPIR-V and generation of associated Rust
//! code.
//! Manages the compile-time compilation of shader code into SPIR-V and generation of associated
//! Rust code.
//!
//! # Basic usage
//!
@@ -89,8 +89,8 @@
//!
//! ## `ty: "..."`
//!
//! This defines what shader type the given GLSL source will be compiled into. The type can be any
//! of the following:
//! This defines what shader type the shader source will be compiled into. The type can be any of
//! the following:
//!
//! - `vertex`
//! - `tess_ctrl`
@@ -111,12 +111,12 @@
//!
//! ## `src: "..."`
//!
//! Provides the raw GLSL source to be compiled in the form of a string. Cannot be used in
//! Provides the raw shader source to be compiled in the form of a string. Cannot be used in
//! conjunction with the `path` or `bytes` field.
//!
//! ## `path: "..."`
//!
//! Provides the path to the GLSL source to be compiled, relative to your `Cargo.toml`. Cannot be
//! Provides the path to the shader source to be compiled, relative to your `Cargo.toml`. Cannot be
//! used in conjunction with the `src` or `bytes` field.
//!
//! ## `bytes: "..."`
@@ -163,6 +163,11 @@
//! Adds the given macro definitions to the pre-processor. This is equivalent to passing the
//! `-DNAME=VALUE` argument on the command line.
//!
//! ## `lang: "..."`
//!
//! Provides the language of the shader source. Must be either `glsl` or `hlsl` (defaults to
//! `glsl`).
//!
//! ## `vulkan_version: "major.minor"` and `spirv_version: "major.minor"`
//!
//! Sets the Vulkan and SPIR-V versions to compile into, respectively. These map directly to the
@@ -230,7 +235,7 @@ use crate::codegen::ShaderKind;
use ahash::HashMap;
use proc_macro2::{Span, TokenStream};
use quote::quote;
use shaderc::{EnvVersion, SpirvVersion};
use shaderc::{EnvVersion, SourceLanguage, SpirvVersion};
use std::{
env, fs, mem,
path::{Path, PathBuf},
@@ -380,6 +385,7 @@ struct MacroInput {
include_directories: Vec<PathBuf>,
macro_defines: Vec<(String, String)>,
shaders: HashMap<String, (Option<ShaderKind>, SourceKind)>,
source_language: Option<SourceLanguage>,
spirv_version: Option<SpirvVersion>,
vulkan_version: Option<EnvVersion>,
generate_structs: bool,
@@ -393,6 +399,7 @@ impl MacroInput {
fn empty() -> Self {
MacroInput {
root_path_env: None,
source_language: None,
include_directories: Vec::new(),
macro_defines: Vec::new(),
shaders: HashMap::default(),
@@ -411,6 +418,7 @@ impl Parse for MacroInput {
let root = env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into());

let mut root_path_env = None;
let mut source_language = None;
let mut include_directories = Vec::new();
let mut macro_defines = Vec::new();
let mut shaders = HashMap::default();
@@ -619,6 +627,18 @@ impl Parse for MacroInput {
}
}
}
"lang" => {
let lit = input.parse::<LitStr>()?;
if source_language.is_some() {
bail!(lit, "field `lang` is already defined");
}

source_language = Some(match lit.value().as_str() {
"glsl" => SourceLanguage::GLSL,
"hlsl" => SourceLanguage::HLSL,
lang => bail!(lit, "expected `glsl` or `hlsl`, found `{lang}`"),
})
}
"vulkan_version" => {
let lit = input.parse::<LitStr>()?;
if vulkan_version.is_some() {
@@ -755,6 +775,7 @@ impl Parse for MacroInput {
(key, (shader_kind, shader_source.unwrap()))
})
.collect(),
source_language,
vulkan_version,
spirv_version,
generate_structs: generate_structs.unwrap_or(true),