mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
Use shaderc instead of glsl-to-spirv for shader compilation (#947)
* Use shaderc instead of glsl-to-spirv for shader compilation * added some setup notes
This commit is contained in:
parent
e3bfe4270c
commit
b507034df7
@ -13,7 +13,6 @@ stages:
|
|||||||
job1:
|
job1:
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- cargo test -v --manifest-path glsl-to-spirv/Cargo.toml
|
|
||||||
- cargo test -v --manifest-path vulkano-shaders/Cargo.toml
|
- cargo test -v --manifest-path vulkano-shaders/Cargo.toml
|
||||||
- cargo test --no-run -v --manifest-path vulkano/Cargo.toml
|
- cargo test --no-run -v --manifest-path vulkano/Cargo.toml
|
||||||
|
|
||||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
|||||||
[submodule "glsl-to-spirv/glslang"]
|
|
||||||
path = glsl-to-spirv/glslang
|
|
||||||
url = https://github.com/KhronosGroup/glslang
|
|
@ -22,7 +22,7 @@ addons:
|
|||||||
- cmake-data
|
- cmake-data
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cargo test --all -j 1
|
- travis_wait cargo test --all -j 1
|
||||||
- cd examples
|
- cd examples
|
||||||
- cargo build
|
- cargo build
|
||||||
- cd .. # this is very important or else the below `cargo publish` will fail
|
- cd .. # this is very important or else the below `cargo publish` will fail
|
||||||
@ -40,10 +40,6 @@ after_success:
|
|||||||
[ $TRAVIS_BRANCH = master ] &&
|
[ $TRAVIS_BRANCH = master ] &&
|
||||||
[ $TRAVIS_PULL_REQUEST = false ] &&
|
[ $TRAVIS_PULL_REQUEST = false ] &&
|
||||||
cargo publish --token ${CRATESIO_TOKEN} --manifest-path vulkano-win/Cargo.toml
|
cargo publish --token ${CRATESIO_TOKEN} --manifest-path vulkano-win/Cargo.toml
|
||||||
- |
|
|
||||||
[ $TRAVIS_BRANCH = master ] &&
|
|
||||||
[ $TRAVIS_PULL_REQUEST = false ] &&
|
|
||||||
cargo publish --token ${CRATESIO_TOKEN} --manifest-path glsl-to-spirv/Cargo.toml
|
|
||||||
- |
|
- |
|
||||||
[ $TRAVIS_BRANCH = master ] &&
|
[ $TRAVIS_BRANCH = master ] &&
|
||||||
[ $TRAVIS_PULL_REQUEST = false ] &&
|
[ $TRAVIS_PULL_REQUEST = false ] &&
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
- Fix instance_count when using draw_index with instance buffers
|
- Fix instance_count when using draw_index with instance buffers
|
||||||
- Added a `reinterpret` function to `BufferSlice`
|
- Added a `reinterpret` function to `BufferSlice`
|
||||||
|
|
||||||
|
- Use [google/shaderc](https://github.com/google/shaderc-rs) for shader compilation
|
||||||
|
|
||||||
# Version 0.10.0 (2018-08-10)
|
# Version 0.10.0 (2018-08-10)
|
||||||
|
|
||||||
- Use dynamically loaded `libvulkan` like on other platforms instead of linking to MoltenVK on macOS
|
- Use dynamically loaded `libvulkan` like on other platforms instead of linking to MoltenVK on macOS
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"examples",
|
"examples",
|
||||||
"glsl-to-spirv",
|
|
||||||
"vk-sys",
|
"vk-sys",
|
||||||
"vulkano",
|
"vulkano",
|
||||||
"vulkano-shaders",
|
"vulkano-shaders",
|
||||||
|
18
README.md
18
README.md
@ -51,7 +51,17 @@ To get started you are encouraged to use the following resources:
|
|||||||
examples in the repo and also a list of projects that use vulkano.
|
examples in the repo and also a list of projects that use vulkano.
|
||||||
* [docs.rs](https://docs.rs/vulkano) - Full Vulkano API documentation
|
* [docs.rs](https://docs.rs/vulkano) - Full Vulkano API documentation
|
||||||
|
|
||||||
## macOS and iOS Setup
|
## Setup
|
||||||
|
|
||||||
|
Vulkano uses [shaderc-rs](https://github.com/google/shaderc-rs) for shader compilation. In order to
|
||||||
|
build the shaderc-rs crate the following tools must be installed and available on `PATH`:
|
||||||
|
- [CMake](https://cmake.org/)
|
||||||
|
- [Python](https://www.python.org/) (works with both Python 2.x and 3.x)
|
||||||
|
|
||||||
|
These requirements can be either installed with your favourite package manager or with installers
|
||||||
|
from the projects' websites.
|
||||||
|
|
||||||
|
### macOS and iOS Specific Setup
|
||||||
|
|
||||||
Vulkan is not natively supported by macOS and iOS. However, there exists [MoltenVK](https://github.com/KhronosGroup/MoltenVK)
|
Vulkan is not natively supported by macOS and iOS. However, there exists [MoltenVK](https://github.com/KhronosGroup/MoltenVK)
|
||||||
a Vulkan implementation on top of Apple's Metal API. This allows vulkano to build and run on macOS
|
a Vulkan implementation on top of Apple's Metal API. This allows vulkano to build and run on macOS
|
||||||
@ -107,14 +117,10 @@ This repository contains six libraries:
|
|||||||
easily integrate your GLSL shaders within the rest of your source code.
|
easily integrate your GLSL shaders within the rest of your source code.
|
||||||
- `vulkano-win` provides a safe link between vulkano and the `winit` library which can create
|
- `vulkano-win` provides a safe link between vulkano and the `winit` library which can create
|
||||||
a window to render to.
|
a window to render to.
|
||||||
- `glsl-to-spirv` can compile GLSL to SPIR-V by wrapping around `glslang`. `glsl-to-spirv` is an
|
|
||||||
implementation detail that you don't need to use manually if you use vulkano.
|
|
||||||
- `vk-sys` contains raw bindings for Vulkan. You can use it even if you don't care about vulkano.
|
- `vk-sys` contains raw bindings for Vulkan. You can use it even if you don't care about vulkano.
|
||||||
|
|
||||||
Once procedural macros are stabilized in Rust, the `vulkano-shaders` and `vulkano-shader-derive`
|
Once procedural macros are stabilized in Rust, the `vulkano-shaders` and `vulkano-shader-derive`
|
||||||
crates will be merged with the `vulkano` crate. The `glsl-to-spirv` crate is an implementation
|
crates will be merged with the `vulkano` crate.
|
||||||
detail of vulkano and is not supposed to be used directly if you use vulkano. You are, however,
|
|
||||||
free to use it if you want to write an alternative to vulkano.
|
|
||||||
|
|
||||||
In order to run tests, run `cargo test --all` at the root of the repository. Make sure your Vulkan
|
In order to run tests, run `cargo test --all` at the root of the repository. Make sure your Vulkan
|
||||||
driver is up to date before doing so.
|
driver is up to date before doing so.
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "glsl-to-spirv"
|
|
||||||
version = "0.1.7"
|
|
||||||
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>", "The vulkano contributors"]
|
|
||||||
repository = "https://github.com/vulkano-rs/vulkano"
|
|
||||||
description = "Deprecated. Use shaderc-rs instead."
|
|
||||||
license = "MIT/Apache-2.0"
|
|
||||||
build = "build/build.rs"
|
|
||||||
categories = ["rendering::graphics-api"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tempfile = "3"
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
cmake = "0.1.27"
|
|
||||||
sha2 = "0.7"
|
|
@ -1,44 +0,0 @@
|
|||||||
extern crate cmake;
|
|
||||||
extern crate sha2;
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
use sha2::{Sha256, Digest};
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("cargo:rerun-if-changed=build/glslangValidator.exe");
|
|
||||||
|
|
||||||
let target = env::var("TARGET").unwrap();
|
|
||||||
let out_file = Path::new(&env::var("OUT_DIR").unwrap()).join("glslang_validator");
|
|
||||||
|
|
||||||
let path = if target.contains("windows") {
|
|
||||||
const SHA256SUM: &'static str =
|
|
||||||
"90b377479fb137f4ac69460d5f5cdc54cd23bace5eb6e6812516fdfa693b25cf";
|
|
||||||
let path = Path::new("build/glslangValidator.exe").to_owned();
|
|
||||||
let content = fs::read(&path).expect("failed to open executable");
|
|
||||||
let mut hasher = Sha256::default();
|
|
||||||
hasher.input(&content);
|
|
||||||
let result = hasher.result();
|
|
||||||
let sha256sum = format!("{:x}", result);
|
|
||||||
assert_eq!(sha256sum, SHA256SUM, "glslangValidator.exe checksum failed");
|
|
||||||
path
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Try to initialize submodules. Don't care if it fails, since this code also runs for
|
|
||||||
// the crates.io package.
|
|
||||||
let _ = Command::new("git")
|
|
||||||
.arg("submodule")
|
|
||||||
.arg("update")
|
|
||||||
.arg("--init")
|
|
||||||
.status();
|
|
||||||
cmake::build("glslang");
|
|
||||||
Path::new(&env::var("OUT_DIR").unwrap())
|
|
||||||
.join("bin")
|
|
||||||
.join("glslangValidator")
|
|
||||||
};
|
|
||||||
|
|
||||||
fs::copy(&path, &out_file).expect("failed to copy executable");
|
|
||||||
}
|
|
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
Subproject commit 4fbb8cb45e144ff63383b48fb1d3244522602438
|
|
@ -1 +0,0 @@
|
|||||||
This crate is deprecated please use [shaderc-rs](https://github.com/google/shaderc-rs) instead.
|
|
@ -1,76 +0,0 @@
|
|||||||
// Copyright (c) 2016 The vulkano developers
|
|
||||||
// Licensed under the Apache License, Version 2.0
|
|
||||||
// <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
|
|
||||||
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
|
||||||
// at your option. All files in the project carrying such
|
|
||||||
// notice may not be copied, modified, or distributed except
|
|
||||||
// according to those terms.
|
|
||||||
|
|
||||||
extern crate tempfile;
|
|
||||||
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
pub type SpirvOutput = File;
|
|
||||||
|
|
||||||
pub fn compile(code: &str, ty: ShaderType) -> Result<SpirvOutput, String> {
|
|
||||||
compile_inner(Some((code, ty)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Eventually the API will look like this, with an iterator for multiple shader stages.
|
|
||||||
// However for the moment GLSLang doesn't like that, so we only pass one shader at a time.
|
|
||||||
fn compile_inner<'a, I>(shaders: I) -> Result<SpirvOutput, String>
|
|
||||||
where I: IntoIterator<Item = (&'a str, ShaderType)>
|
|
||||||
{
|
|
||||||
let temp_dir = tempfile::tempdir().unwrap();
|
|
||||||
let output_file = temp_dir.path().join("compilation_output.spv");
|
|
||||||
|
|
||||||
let mut command = Command::new(concat!(env!("OUT_DIR"), "/glslang_validator"));
|
|
||||||
command.arg("-V");
|
|
||||||
command.arg("-l");
|
|
||||||
command.arg("-o").arg(&output_file);
|
|
||||||
|
|
||||||
for (num, (source, ty)) in shaders.into_iter().enumerate() {
|
|
||||||
let extension = match ty {
|
|
||||||
ShaderType::Vertex => ".vert",
|
|
||||||
ShaderType::Fragment => ".frag",
|
|
||||||
ShaderType::Geometry => ".geom",
|
|
||||||
ShaderType::TessellationControl => ".tesc",
|
|
||||||
ShaderType::TessellationEvaluation => ".tese",
|
|
||||||
ShaderType::Compute => ".comp",
|
|
||||||
};
|
|
||||||
|
|
||||||
let file_path = temp_dir.path().join(format!("{}{}", num, extension));
|
|
||||||
File::create(&file_path)
|
|
||||||
.unwrap()
|
|
||||||
.write_all(source.as_bytes())
|
|
||||||
.unwrap();
|
|
||||||
command.arg(file_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
let output = command
|
|
||||||
.output()
|
|
||||||
.expect("Failed to execute glslangValidator");
|
|
||||||
|
|
||||||
if output.status.success() {
|
|
||||||
let spirv_output = File::open(output_file).expect("failed to open SPIR-V output file");
|
|
||||||
return Ok(spirv_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
let error1 = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let error2 = String::from_utf8_lossy(&output.stderr);
|
|
||||||
return Err(error1.into_owned() + &error2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Type of shader.
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum ShaderType {
|
|
||||||
Vertex,
|
|
||||||
Fragment,
|
|
||||||
Geometry,
|
|
||||||
TessellationControl,
|
|
||||||
TessellationEvaluation,
|
|
||||||
Compute,
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
// Copyright (c) 2016 The vulkano developers
|
|
||||||
// Licensed under the Apache License, Version 2.0
|
|
||||||
// <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
|
|
||||||
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
|
||||||
// at your option. All files in the project carrying such
|
|
||||||
// notice may not be copied, modified, or distributed except
|
|
||||||
// according to those terms.
|
|
||||||
|
|
||||||
extern crate glsl_to_spirv;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test1() {
|
|
||||||
let shader = r#"
|
|
||||||
#version 330
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 f_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
f_color = vec4(1.0);
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
glsl_to_spirv::compile(shader, glsl_to_spirv::ShaderType::Fragment).unwrap();
|
|
||||||
}
|
|
@ -13,7 +13,6 @@ name = "vulkano_shader_derive"
|
|||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glsl-to-spirv = { version = "0.1.6", path = "../glsl-to-spirv" }
|
|
||||||
syn = "0.14"
|
syn = "0.14"
|
||||||
vulkano-shaders = { version = "0.10", path = "../vulkano-shaders" }
|
vulkano-shaders = { version = "0.10", path = "../vulkano-shaders" }
|
||||||
|
|
||||||
|
@ -155,7 +155,6 @@
|
|||||||
//! [SpecializationConstants]: https://docs.rs/vulkano/*/vulkano/pipeline/shader/trait.SpecializationConstants.html
|
//! [SpecializationConstants]: https://docs.rs/vulkano/*/vulkano/pipeline/shader/trait.SpecializationConstants.html
|
||||||
//! [pipeline]: https://docs.rs/vulkano/*/vulkano/pipeline/index.html
|
//! [pipeline]: https://docs.rs/vulkano/*/vulkano/pipeline/index.html
|
||||||
|
|
||||||
extern crate glsl_to_spirv;
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
extern crate syn;
|
extern crate syn;
|
||||||
extern crate vulkano_shaders;
|
extern crate vulkano_shaders;
|
||||||
@ -235,19 +234,18 @@ pub fn derive(input: TokenStream) -> TokenStream {
|
|||||||
}).next().expect("Can't find `ty` attribute ; put #[ty = \"vertex\"] for example.");
|
}).next().expect("Can't find `ty` attribute ; put #[ty = \"vertex\"] for example.");
|
||||||
|
|
||||||
let ty = match &ty_str[..] {
|
let ty = match &ty_str[..] {
|
||||||
"vertex" => glsl_to_spirv::ShaderType::Vertex,
|
"vertex" => vulkano_shaders::ShaderKind::Vertex,
|
||||||
"fragment" => glsl_to_spirv::ShaderType::Fragment,
|
"fragment" => vulkano_shaders::ShaderKind::Fragment,
|
||||||
"geometry" => glsl_to_spirv::ShaderType::Geometry,
|
"geometry" => vulkano_shaders::ShaderKind::Geometry,
|
||||||
"tess_ctrl" => glsl_to_spirv::ShaderType::TessellationControl,
|
"tess_ctrl" => vulkano_shaders::ShaderKind::TessControl,
|
||||||
"tess_eval" => glsl_to_spirv::ShaderType::TessellationEvaluation,
|
"tess_eval" => vulkano_shaders::ShaderKind::TessEvaluation,
|
||||||
"compute" => glsl_to_spirv::ShaderType::Compute,
|
"compute" => vulkano_shaders::ShaderKind::Compute,
|
||||||
_ => panic!("Unexpected shader type ; valid values: vertex, fragment, geometry, tess_ctrl, tess_eval, compute")
|
_ => panic!("Unexpected shader type ; valid values: vertex, fragment, geometry, tess_ctrl, tess_eval, compute")
|
||||||
};
|
};
|
||||||
|
let content = vulkano_shaders::compile(&source_code, ty).unwrap();
|
||||||
let spirv_data = match glsl_to_spirv::compile(&source_code, ty) {
|
|
||||||
Ok(compiled) => compiled,
|
vulkano_shaders::reflect("Shader", content.as_binary())
|
||||||
Err(message) => panic!("{}\nfailed to compile shader", message),
|
.unwrap()
|
||||||
};
|
.parse()
|
||||||
|
.unwrap()
|
||||||
vulkano_shaders::reflect("Shader", spirv_data).unwrap().parse().unwrap()
|
|
||||||
}
|
}
|
||||||
|
@ -9,4 +9,4 @@ documentation = "http://tomaka.github.io/vulkano/vulkano/index.html"
|
|||||||
categories = ["rendering::graphics-api"]
|
categories = ["rendering::graphics-api"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glsl-to-spirv = { version = "0.1.6", path = "../glsl-to-spirv" }
|
shaderc = "0.3"
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
// notice may not be copied, modified, or distributed except
|
// notice may not be copied, modified, or distributed except
|
||||||
// according to those terms.
|
// according to those terms.
|
||||||
|
|
||||||
extern crate glsl_to_spirv;
|
|
||||||
extern crate vulkano_shaders;
|
extern crate vulkano_shaders;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -40,7 +39,7 @@ void main() {
|
|||||||
|
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let content = glsl_to_spirv::compile(shader, glsl_to_spirv::ShaderType::Fragment).unwrap();
|
let content = vulkano_shaders::compile(shader, vulkano_shaders::ShaderKind::Fragment).unwrap();
|
||||||
let output = vulkano_shaders::reflect("Shader", content).unwrap();
|
let output = vulkano_shaders::reflect("Shader", content.as_binary()).unwrap();
|
||||||
println!("{}", output);
|
println!("{}", output);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
// notice may not be copied, modified, or distributed except
|
// notice may not be copied, modified, or distributed except
|
||||||
// according to those terms.
|
// according to those terms.
|
||||||
|
|
||||||
extern crate glsl_to_spirv;
|
extern crate shaderc;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@ -17,7 +17,9 @@ use std::io::Read;
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
pub use glsl_to_spirv::ShaderType;
|
use shaderc::{Compiler, CompileOptions};
|
||||||
|
|
||||||
|
pub use shaderc::{CompilationArtifact, ShaderKind};
|
||||||
pub use parse::ParseError;
|
pub use parse::ParseError;
|
||||||
|
|
||||||
mod descriptor_sets;
|
mod descriptor_sets;
|
||||||
@ -28,7 +30,7 @@ mod spec_consts;
|
|||||||
mod structs;
|
mod structs;
|
||||||
|
|
||||||
pub fn build_glsl_shaders<'a, I>(shaders: I)
|
pub fn build_glsl_shaders<'a, I>(shaders: I)
|
||||||
where I: IntoIterator<Item = (&'a str, ShaderType)>
|
where I: IntoIterator<Item = (&'a str, ShaderKind)>
|
||||||
{
|
{
|
||||||
let destination = env::var("OUT_DIR").unwrap();
|
let destination = env::var("OUT_DIR").unwrap();
|
||||||
let destination = Path::new(&destination);
|
let destination = Path::new(&destination);
|
||||||
@ -55,23 +57,25 @@ pub fn build_glsl_shaders<'a, I>(shaders: I)
|
|||||||
let mut file_output = File::create(&destination.join("shaders").join(shader))
|
let mut file_output = File::create(&destination.join("shaders").join(shader))
|
||||||
.expect("failed to open shader output");
|
.expect("failed to open shader output");
|
||||||
|
|
||||||
let content = match glsl_to_spirv::compile(&shader_content, ty) {
|
let content = compile(&shader_content, ty).unwrap();
|
||||||
Ok(compiled) => compiled,
|
let output = reflect("Shader", content.as_binary()).unwrap();
|
||||||
Err(message) => panic!("{}\nfailed to compile shader", message),
|
|
||||||
};
|
|
||||||
let output = reflect("Shader", content).unwrap();
|
|
||||||
write!(file_output, "{}", output).unwrap();
|
write!(file_output, "{}", output).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reflect<R>(name: &str, mut spirv: R) -> Result<String, Error>
|
pub fn compile(code: &str, ty: ShaderKind) -> Result<CompilationArtifact, String> {
|
||||||
where R: Read
|
let mut compiler = Compiler::new().ok_or("failed to create GLSL compiler")?;
|
||||||
{
|
let compile_options = CompileOptions::new().ok_or("failed to initialize compile option")?;
|
||||||
let mut data = Vec::new();
|
|
||||||
spirv.read_to_end(&mut data)?;
|
|
||||||
|
|
||||||
// now parsing the document
|
let content = compiler
|
||||||
let doc = parse::parse_spirv(&data)?;
|
.compile_into_spirv(&code, ty, "shader.glsl", "main", Some(&compile_options))
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
Ok(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reflect(name: &str, spirv: &[u32]) -> Result<String, Error> {
|
||||||
|
let doc = parse::parse_spirv(spirv)?;
|
||||||
|
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
output.push_str(
|
output.push_str(
|
||||||
@ -118,8 +122,8 @@ pub fn reflect<R>(name: &str, mut spirv: R) -> Result<String, Error>
|
|||||||
|
|
||||||
{
|
{
|
||||||
// contains the data that was passed as input to this function
|
// contains the data that was passed as input to this function
|
||||||
let spirv_data = data.iter()
|
let spirv_words = spirv.iter()
|
||||||
.map(|&byte| byte.to_string())
|
.map(|&word| word.to_string())
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
|
|
||||||
@ -162,10 +166,10 @@ impl {name} {{
|
|||||||
output.push_str(&format!(
|
output.push_str(&format!(
|
||||||
r#"
|
r#"
|
||||||
unsafe {{
|
unsafe {{
|
||||||
let data = [{spirv_data}];
|
let words = [{spirv_words}];
|
||||||
|
|
||||||
Ok({name} {{
|
Ok({name} {{
|
||||||
shader: try!(::vulkano::pipeline::shader::ShaderModule::new(device, &data))
|
shader: try!(::vulkano::pipeline::shader::ShaderModule::from_words(device, &words))
|
||||||
}})
|
}})
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
@ -178,7 +182,7 @@ impl {name} {{
|
|||||||
}}
|
}}
|
||||||
"#,
|
"#,
|
||||||
name = name,
|
name = name,
|
||||||
spirv_data = spirv_data
|
spirv_words = spirv_words
|
||||||
));
|
));
|
||||||
|
|
||||||
// writing one method for each entry point of this module
|
// writing one method for each entry point of this module
|
||||||
|
@ -9,43 +9,8 @@
|
|||||||
|
|
||||||
use enums::*;
|
use enums::*;
|
||||||
|
|
||||||
/// Parses a SPIR-V document.
|
/// Parses a SPIR-V document from a list of words.
|
||||||
pub fn parse_spirv(data: &[u8]) -> Result<Spirv, ParseError> {
|
pub fn parse_spirv(i: &[u32]) -> Result<Spirv, ParseError> {
|
||||||
if data.len() < 20 {
|
|
||||||
return Err(ParseError::MissingHeader);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to determine whether we are in big endian order or little endian order depending
|
|
||||||
// on the magic number at the start of the file
|
|
||||||
let data = if data[0] == 0x07 && data[1] == 0x23 && data[2] == 0x02 && data[3] == 0x03 {
|
|
||||||
// big endian
|
|
||||||
data.chunks(4)
|
|
||||||
.map(|c| {
|
|
||||||
((c[0] as u32) << 24) | ((c[1] as u32) << 16) | ((c[2] as u32) << 8) |
|
|
||||||
c[3] as u32
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
|
|
||||||
} else if data[3] == 0x07 && data[2] == 0x23 && data[1] == 0x02 && data[0] == 0x03 {
|
|
||||||
// little endian
|
|
||||||
data.chunks(4)
|
|
||||||
.map(|c| {
|
|
||||||
((c[3] as u32) << 24) | ((c[2] as u32) << 16) | ((c[1] as u32) << 8) |
|
|
||||||
c[0] as u32
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return Err(ParseError::MissingHeader);
|
|
||||||
};
|
|
||||||
|
|
||||||
parse_u32s(&data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parses a SPIR-V document from a list of u32s.
|
|
||||||
///
|
|
||||||
/// Endianness has already been handled.
|
|
||||||
fn parse_u32s(i: &[u32]) -> Result<Spirv, ParseError> {
|
|
||||||
if i.len() < 5 {
|
if i.len() < 5 {
|
||||||
return Err(ParseError::MissingHeader);
|
return Err(ParseError::MissingHeader);
|
||||||
}
|
}
|
||||||
@ -399,6 +364,12 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
let data = include_bytes!("../tests/frag.spv");
|
let data = include_bytes!("../tests/frag.spv");
|
||||||
parse::parse_spirv(data).unwrap();
|
let insts: Vec<_> = data.chunks(4)
|
||||||
|
.map(|c| {
|
||||||
|
((c[3] as u32) << 24) | ((c[2] as u32) << 16) | ((c[1] as u32) << 8) | c[0] as u32
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
parse::parse_spirv(&insts).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user