Add glsl-to-spirv library

This commit is contained in:
Pierre Krieger 2016-01-31 13:10:41 +01:00
parent 66d55cad0a
commit f2da9331f2
7 changed files with 136 additions and 0 deletions

2
glsl-to-spirv/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
Cargo.lock

8
glsl-to-spirv/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "glsl-to-spirv"
version = "0.1.0"
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
build = "build/build.rs"
[dependencies]
tempdir = "0.3.4"

View File

@ -0,0 +1,25 @@
use std::env;
use std::fs;
use std::path::Path;
fn main() {
println!("cargo:rerun-if-changed=build/glslangValidator");
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") {
Path::new("build/glslangValidator.exe")
} else if target.contains("linux") {
Path::new("build/glslangValidator")
} else {
panic!("The platform `{}` is not supported", target);
};
if let Err(_) = fs::hard_link(&path, &out_file) {
fs::copy(&path, &out_file).unwrap();
}
//fs::set_permissions(&out_file, std::io::USER_EXEC).unwrap();
}

Binary file not shown.

Binary file not shown.

55
glsl-to-spirv/src/lib.rs Normal file
View File

@ -0,0 +1,55 @@
extern crate tempdir;
use std::fs::File;
use std::io::Write;
use std::process::Command;
pub type SpirvOutput = File;
pub fn compile<'a, I>(shaders: I) -> Result<SpirvOutput, String>
where I: IntoIterator<Item = (&'a str, ShaderType)>
{
let temp_dir = tempdir::TempDir::new("glslang-compile").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 error = String::from_utf8(output.stdout).expect("output of glsl compiler is not UTF-8");
return Err(error);
}
/// Type of shader.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ShaderType {
Vertex,
Fragment,
Geometry,
TessellationControl,
TessellationEvaluation,
Compute,
}

View File

@ -0,0 +1,46 @@
extern crate glsl_to_spirv;
#[test]
fn test1() {
let shader = r#"
#version 330
out vec4 f_color;
void main() {
f_color = vec4(1.0);
}
"#;
glsl_to_spirv::compile(Some((shader, glsl_to_spirv::ShaderType::Fragment))).unwrap();
}
#[test]
fn test2() {
let vertex = r#"
#version 330
in vec2 i_position;
out vec2 v_texcoords;
void main() {
v_texcoords = i_position;
gl_Position = vec4(i_position, 0.0, 1.0);
}
"#;
let fragment = r#"
#version 330
out vec4 f_color;
void main() {
f_color = vec4(1.0);
}
"#;
glsl_to_spirv::compile([
(vertex, glsl_to_spirv::ShaderType::Vertex),
(fragment, glsl_to_spirv::ShaderType::Fragment)
].iter().cloned()).unwrap();
}