From 7b2da82718b2c33a63a84762c9f990a12f3923f6 Mon Sep 17 00:00:00 2001 From: Michael Hills Date: Wed, 2 Sep 2020 04:06:15 +1000 Subject: [PATCH] iOS: use shaderc-rs for glsl to spirv compilation (#324) --- crates/bevy_render/Cargo.toml | 12 ++++++-- crates/bevy_render/src/shader/shader.rs | 39 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index c3a9b8111413e..623c8f69c4ccd 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -32,16 +32,16 @@ image = { version = "0.23", default-features = false } log = { version = "0.4", features = ["release_max_level_info"] } uuid = { version = "0.8", features = ["v4", "serde"] } serde = { version = "1", features = ["derive"] } -bitflags = "1.0" +bitflags = "1.2.1" smallvec = "1.4.0" # TODO: replace once_cell with std equivalent if/when this lands: https://github.com/rust-lang/rfcs/pull/2788 once_cell = "1.4.0" -downcast-rs = "1.1.1" +downcast-rs = "1.2.0" thiserror = "1.0" anyhow = "1.0" hex = "0.4.2" hexasphere = "1.0.0" -parking_lot = "0.10" +parking_lot = "0.11.0" [dependencies.naga] # Temporarily git, either get kvark to publish a new version, or mirror @@ -53,6 +53,12 @@ features = ["glsl-new", "spirv"] [dev-dependencies] pretty_assertions = "0.6.1" +# [target.'cfg(not(target_os = "ios"))'.dependencies] +# bevy-glsl-to-spirv = "0.1.7" + +# [target.'cfg(target_os = "ios")'.dependencies] +# shaderc = "0.6.2" + [features] # default = ["bevy-glsl-to-spirv", "spirv-reflect"] default = ["naga-glsl", "naga-reflect"] diff --git a/crates/bevy_render/src/shader/shader.rs b/crates/bevy_render/src/shader/shader.rs index da450c3322513..f76990b2e8477 100644 --- a/crates/bevy_render/src/shader/shader.rs +++ b/crates/bevy_render/src/shader/shader.rs @@ -37,6 +37,7 @@ impl Into for ShaderStage { } } +#[cfg(not(target_os = "ios"))] fn glsl_to_spirv( glsl_source: &str, stage: ShaderStage, @@ -80,6 +81,44 @@ fn glsl_to_spirv( } } +#[cfg(target_os = "ios")] +impl Into for ShaderStage { + fn into(self) -> shaderc::ShaderKind { + match self { + ShaderStage::Vertex => shaderc::ShaderKind::Vertex, + ShaderStage::Fragment => shaderc::ShaderKind::Fragment, + ShaderStage::Compute => shaderc::ShaderKind::Compute, + } + } +} + +#[cfg(target_os = "ios")] +fn glsl_to_spirv( + glsl_source: &str, + stage: ShaderStage, + shader_defs: Option<&[String]>, +) -> Vec { + let mut compiler = shaderc::Compiler::new().unwrap(); + let mut options = shaderc::CompileOptions::new().unwrap(); + if let Some(shader_defs) = shader_defs { + for def in shader_defs.iter() { + options.add_macro_definition(def, None); + } + } + + let binary_result = compiler + .compile_into_spirv( + glsl_source, + stage.into(), + "shader.glsl", + "main", + Some(&options), + ) + .unwrap(); + + binary_result.as_binary().to_vec() +} + fn bytes_to_words(bytes: &[u8]) -> Vec { let mut words = Vec::new(); for bytes4 in bytes.chunks(4) {