From 2c25e3de58232e8da1ff4562967bf59a4d645e16 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 30 Dec 2024 21:34:05 +0100 Subject: [PATCH 1/2] wip bevy0.15 ; not working --- Cargo.lock | 106 +++++-- crates/compiler/Cargo.toml | 3 + crates/compiler/src/backend_v0_15/mod.rs | 214 +++++++++++++ crates/compiler/src/backend_v0_15/to_wgsl.rs | 307 +++++++++++++++++++ crates/compiler/src/backend_v0_15/util.rs | 111 +++++++ crates/compiler/src/lib.rs | 9 + crates/docs/src/lib.rs | 3 + crates/generator/src/lib.rs | 7 +- crates/make/Cargo.toml | 1 + crates/make/src/main.rs | 209 ++++++++----- 10 files changed, 870 insertions(+), 100 deletions(-) create mode 100644 crates/compiler/src/backend_v0_15/mod.rs create mode 100644 crates/compiler/src/backend_v0_15/to_wgsl.rs create mode 100644 crates/compiler/src/backend_v0_15/util.rs diff --git a/Cargo.lock b/Cargo.lock index ddc1bee..6d4c5a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,7 +118,16 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "bit-vec", + "bit-vec 0.6.3", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec 0.8.0", ] [[package]] @@ -127,6 +136,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitflags" version = "1.3.2" @@ -198,6 +213,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -220,10 +241,12 @@ dependencies = [ "naga 0.14.1", "naga 0.19.2", "naga 0.20.0", + "naga 23.1.0", "naga_oil 0.10.1", "naga_oil 0.11.0", "naga_oil 0.13.0", "naga_oil 0.14.0", + "naga_oil 0.16.0", "naga_oil 0.8.2", "regex", "reqwest", @@ -683,7 +706,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbcc2e0513220fd2b598e6068608d4462db20322c0e77e47f6f488dfcfc279cb" dependencies = [ - "bit-set", + "bit-set 0.5.3", "bitflags 1.3.2", "codespan-reporting", "hexf-parse", @@ -703,7 +726,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1ceaaa4eedaece7e4ec08c55c640ba03dbb73fb812a6570a59bcf1930d0f70e" dependencies = [ - "bit-set", + "bit-set 0.5.3", "bitflags 2.6.0", "codespan-reporting", "hexf-parse", @@ -723,7 +746,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cd05939c491da968a42986204b7431678be21fdcd4b10cc84997ba130ada5a4" dependencies = [ - "bit-set", + "bit-set 0.5.3", "bitflags 2.6.0", "codespan-reporting", "hexf-parse", @@ -743,7 +766,7 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50e3524642f53d9af419ab5e8dd29d3ba155708267667c2f3f06c88c9e130843" dependencies = [ - "bit-set", + "bit-set 0.5.3", "bitflags 2.6.0", "codespan-reporting", "hexf-parse", @@ -764,7 +787,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e536ae46fcab0876853bd4a632ede5df4b1c2527a58f6c5a4150fe86be858231" dependencies = [ "arrayvec", - "bit-set", + "bit-set 0.5.3", "bitflags 2.6.0", "codespan-reporting", "hexf-parse", @@ -778,13 +801,34 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "naga" +version = "23.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "364f94bc34f61332abebe8cad6f6cd82a5b65cff22c828d05d0968911462ca4f" +dependencies = [ + "arrayvec", + "bit-set 0.8.0", + "bitflags 2.6.0", + "cfg_aliases", + "codespan-reporting", + "hexf-parse", + "indexmap 2.1.0", + "log", + "pp-rs", + "rustc-hash", + "termcolor", + "thiserror", + "unicode-xid", +] + [[package]] name = "naga_oil" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8be942a5c21c58b9b0bf4d9b99db3634ddb7a916f8e1d1d0b71820cc4150e56b" dependencies = [ - "bit-set", + "bit-set 0.5.3", "codespan-reporting", "data-encoding", "indexmap 1.9.3", @@ -804,7 +848,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ac54c77b3529887f9668d3dd81e955e58f252b31a333f836e3548c06460b958" dependencies = [ - "bit-set", + "bit-set 0.5.3", "codespan-reporting", "data-encoding", "indexmap 1.9.3", @@ -824,7 +868,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fff3f369dd665ee365daeab786466a6f70ff53e4a95a76117363b1077e1b0492" dependencies = [ - "bit-set", + "bit-set 0.5.3", "codespan-reporting", "data-encoding", "indexmap 2.1.0", @@ -844,7 +888,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ea62ae0f2787456afca7209ca180522b41f00cbe159ee369eba1e07d365cd1" dependencies = [ - "bit-set", + "bit-set 0.5.3", "codespan-reporting", "data-encoding", "indexmap 2.1.0", @@ -864,7 +908,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "275d9720a7338eedac966141089232514c84d76a246a58ef501af88c5edf402f" dependencies = [ - "bit-set", + "bit-set 0.5.3", "codespan-reporting", "data-encoding", "indexmap 2.1.0", @@ -878,6 +922,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "naga_oil" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ea1f080bb359927cd5404d0af1e5e6758f4f2d82ecfbebb0a0c434764e40f1" +dependencies = [ + "bit-set 0.5.3", + "codespan-reporting", + "data-encoding", + "indexmap 2.1.0", + "naga 23.1.0", + "once_cell", + "regex", + "regex-syntax 0.8.2", + "rustc-hash", + "thiserror", + "tracing", + "unicode-ident", +] + [[package]] name = "native-tls" version = "0.2.11" @@ -1019,9 +1083,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -1278,9 +1342,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.61" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", @@ -1343,18 +1407,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -1497,9 +1561,9 @@ checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "url" diff --git a/crates/compiler/Cargo.toml b/crates/compiler/Cargo.toml index b23ac37..d53918d 100644 --- a/crates/compiler/Cargo.toml +++ b/crates/compiler/Cargo.toml @@ -13,12 +13,14 @@ tar = "0.4.40" flate2 = "1.0.28" regex = "1.10.2" +naga_oil_v0_16 = { package = "naga_oil", version = "0.16.0", optional = true } naga_oil_v0_14 = { package = "naga_oil", version = "0.14.0", optional = true } naga_oil_v0_13 = { package = "naga_oil", version = "0.13.0", optional = true } naga_oil_v0_11 = { package = "naga_oil", version = "0.11.0", optional = true } naga_oil_v0_10 = { package = "naga_oil", version = "0.10.1", optional = true } naga_oil_v0_08 = { package = "naga_oil", version = "0.8.2", optional = true } +naga_v23_1 = { package = "naga", version = "23.1.0", optional = true } naga_v0_20 = { package = "naga", version = "0.20.0", optional = true } naga_v0_19 = { package = "naga", version = "0.19.2", optional = true } naga_v0_14 = { package = "naga", version = "0.14.1", optional = true } @@ -28,6 +30,7 @@ naga_v0_12 = { package = "naga", version = "0.12.3", optional = true } [features] default = [] +backend_v0_15 = ["dep:naga_oil_v0_16", "dep:naga_v23_1"] # bevy 0.15.x backend_v0_14 = ["dep:naga_oil_v0_14", "dep:naga_v0_20"] # bevy 0.14.x backend_v0_13 = ["dep:naga_oil_v0_13", "dep:naga_v0_19"] # bevy 0.13.x backend_v0_11 = ["dep:naga_oil_v0_11", "dep:naga_v0_14"] # ... diff --git a/crates/compiler/src/backend_v0_15/mod.rs b/crates/compiler/src/backend_v0_15/mod.rs new file mode 100644 index 0000000..d43962b --- /dev/null +++ b/crates/compiler/src/backend_v0_15/mod.rs @@ -0,0 +1,214 @@ +mod to_wgsl; +mod util; + +use naga_oil_v0_16 as naga_oil; +use naga_v23_1 as naga; + +use crate::{common, download::ShaderSource}; +use docs::*; +use naga::TypeInner; +use naga_oil::compose::{ + self, ComposableModuleDescriptor, Composer, ImportDefinition, NagaModuleDescriptor, + ShaderLanguage, +}; +use std::collections::HashMap; +use to_wgsl::build_ty; +use util::{build_address_space, build_binding, build_expression, build_resource_binding}; + +const NAGA_OIL_DECORATION_PRE: &str = "X_naga_oil_mod_X"; +const NAGA_OIL_DECORATION_POST: &str = "X"; + +pub fn compile( + root_crate_name: &str, + root_crate_version: Version, + shader_def_values: IndexMap, + shader_sources: Vec, +) -> Result> { + let (shaders, mut composer) = compile_shaders(shader_sources)?; + + let mut doc = common::doc_new( + root_crate_name.to_string(), + root_crate_version, + shader_def_values.clone(), + ); + + for (import_path, shader) in &shaders { + let (module_path, module) = common::find_or_create_module(&mut doc, import_path); + + module + .shader_defs + .extend(shader.source.shader_defs.iter().cloned()); + module.source_url = Some(shader.source.docsrs_url.clone()); + + let desc = NagaModuleDescriptor { + source: &shader.source.source, + shader_defs: shader_def_values + .iter() + .map(|(key, value)| { + ( + key.clone(), + match *value { + ShaderDefValue::Bool(value) => compose::ShaderDefValue::Bool(value), + ShaderDefValue::Int(value) => compose::ShaderDefValue::Int(value), + ShaderDefValue::UInt(value) => compose::ShaderDefValue::UInt(value), + }, + ) + }) + .collect(), + ..Default::default() + }; + let naga_module = composer.make_naga_module(desc)?; + let gctx = naga_module.to_ctx(); + + let mut def_paths = HashMap::new(); + for import in &shader.imports { + let module_path = import + .import + .split("::") + .map(str::to_owned) + .collect::>(); + for item in &import.items { + def_paths.insert(item.clone(), module_path.clone()); + } + } + for (_handle, ty) in naga_module.types.iter() { + if !contains_pre(ty.name.as_deref()) { + if let TypeInner::Struct { .. } = &ty.inner { + if let Some(name) = &ty.name { + def_paths.insert(name.clone(), module_path.clone()); + } + } + } + } + + for (_handle, constant) in naga_module.constants.iter() { + if !contains_pre(constant.name.as_deref()) { + module.constants.push(Constant { + name: Ident::from(constant.name.clone()), + ty: build_ty(&naga_module.types[constant.ty], gctx, &def_paths), + init: build_expression(&naga_module.global_expressions[constant.init]), + }); + } + } + + for (_handle, var) in naga_module.global_variables.iter() { + if !contains_pre(var.name.as_deref()) { + module.global_variables.push(GlobalVariable { + name: Ident::from(var.name.clone()), + space: build_address_space(&var.space), + binding: var.binding.as_ref().map(build_resource_binding), + ty: build_ty(&naga_module.types[var.ty], gctx, &def_paths), + init: var + .init + .map(|init| build_expression(&naga_module.global_expressions[init])), + }); + } + } + + for (_handle, ty) in naga_module.types.iter() { + if !contains_pre(ty.name.as_deref()) { + if let TypeInner::Struct { members, .. } = &ty.inner { + module.structs.push(Struct { + name: Ident::from(ty.name.clone()), + members: members + .iter() + .map(|member| StructMember { + name: Ident::from(member.name.clone()), + ty: build_ty(&naga_module.types[member.ty], gctx, &def_paths), + binding: member.binding.as_ref().map(build_binding), + }) + .collect(), + }); + } + } + } + + for (_handle, function) in naga_module.functions.iter() { + if !contains_pre(function.name.as_deref()) { + module.functions.push(Function { + name: Ident::from(function.name.clone()), + arguments: function + .arguments + .iter() + .map(|arg| FunctionArgument { + name: Ident::from(arg.name.clone()), + ty: build_ty(&naga_module.types[arg.ty], gctx, &def_paths), + binding: arg.binding.as_ref().map(build_binding), + }) + .collect(), + ret: function + .result + .as_ref() + .map(|res| build_ty(&naga_module.types[res.ty], gctx, &def_paths)), + }); + } + } + } + + Ok(doc) +} + +fn contains_pre(name: Option<&str>) -> bool { + name.map(|name| name.contains(NAGA_OIL_DECORATION_PRE)) + .unwrap_or(false) +} + +struct Shader { + source: ShaderSource, + imports: Vec, + defines: HashMap, +} + +fn compile_shaders( + shader_sources: Vec, +) -> Result<(HashMap, Composer), Box> { + let mut composer = Composer::default(); + let mut shaders = HashMap::new(); + + for shader_source in shader_sources { + let (import_path, imports, defines) = compose::get_preprocessor_data(&shader_source.source); + if let Some(import_path) = import_path { + shaders.insert( + import_path, + Shader { + source: shader_source, + imports, + defines, + }, + ); + } + } + + fn add_to_composer( + composer: &mut Composer, + name: &str, + shaders: &HashMap, + ) -> Result<(), Box> { + if !composer.contains_module(name) { + let this = match shaders.get(name) { + Some(this) => this, + None => return Err(format!("shader not found: {}", name).into()), + }; + + for import in &this.imports { + add_to_composer(composer, &import.import, shaders)?; + } + + composer.add_composable_module(ComposableModuleDescriptor { + source: &this.source.source, + file_path: &this.source.path.to_string_lossy(), + language: ShaderLanguage::Wgsl, + additional_imports: Default::default(), + shader_defs: this.defines.clone(), + as_name: None, + })?; + } + + Ok(()) + } + for name in shaders.keys() { + add_to_composer(&mut composer, name, &shaders)?; + } + + Ok((shaders, composer)) +} diff --git a/crates/compiler/src/backend_v0_15/to_wgsl.rs b/crates/compiler/src/backend_v0_15/to_wgsl.rs new file mode 100644 index 0000000..498664f --- /dev/null +++ b/crates/compiler/src/backend_v0_15/to_wgsl.rs @@ -0,0 +1,307 @@ +use super::naga::{self, proc::GlobalCtx, Scalar, TypeInner}; +use super::{NAGA_OIL_DECORATION_POST, NAGA_OIL_DECORATION_PRE}; +use std::collections::HashMap; + +pub fn build_ty( + ty: &naga::Type, + gctx: GlobalCtx, + def_paths: &HashMap>, +) -> docs::Type { + match &ty.name { + Some(name) => { + let pre_pos = name.find(NAGA_OIL_DECORATION_PRE); + let ends_with_post = name.ends_with(NAGA_OIL_DECORATION_POST); + + let name = match (pre_pos, ends_with_post) { + (Some(pre_pos), true) => name[..pre_pos].to_string(), + _ => name.clone(), + }; + let def_path = def_paths.get(&name).cloned(); + docs::Type::Named { name, def_path } + } + None => build_ty_inner(&ty.inner, gctx, def_paths), + } +} + +// Copy-pasted and adapted from: naga-0.19.2 + +pub fn build_ty_inner( + type_inner: &TypeInner, + gctx: GlobalCtx, + def_paths: &HashMap>, +) -> docs::Type { + let name = match *type_inner { + TypeInner::Vector { size, scalar } => { + format!("vec{}<{}>", vector_size_str(size), scalar_kind_str(scalar),) + } + TypeInner::Sampler { comparison: false } => "sampler".to_string(), + TypeInner::Sampler { comparison: true } => "sampler_comparison".to_string(), + TypeInner::Image { + dim, + arrayed, + class, + } => { + // More about texture types: https://gpuweb.github.io/gpuweb/wgsl/#sampled-texture-type + use naga::ImageClass as Ic; + + let dim_str = image_dimension_str(dim); + let arrayed_str = if arrayed { "_array" } else { "" }; + let (class_str, multisampled_str, format_str, storage_str) = match class { + Ic::Sampled { kind, multi } => ( + "", + if multi { "multisampled_" } else { "" }, + scalar_kind_str(naga::Scalar { kind, width: 4 }), + "", + ), + Ic::Depth { multi } => ("depth_", if multi { "multisampled_" } else { "" }, "", ""), + Ic::Storage { format, access } => ( + "storage_", + "", + storage_format_str(format), + if access.contains(naga::StorageAccess::LOAD | naga::StorageAccess::STORE) { + ",read_write" + } else if access.contains(naga::StorageAccess::LOAD) { + ",read" + } else { + ",write" + }, + ), + }; + let mut out = format!("texture_{class_str}{multisampled_str}{dim_str}{arrayed_str}"); + + if !format_str.is_empty() { + out += &format!("<{format_str}{storage_str}>"); + } + + out + } + TypeInner::Scalar(scalar) => scalar_kind_str(scalar).to_string(), + TypeInner::Atomic(scalar) => { + format!("atomic<{}>", scalar_kind_str(scalar)) + } + TypeInner::Array { + base, + size, + stride: _, + } => { + // More info https://gpuweb.github.io/gpuweb/wgsl/#array-types + // array -- Constant array + // array -- Dynamic array + let member_type = &gctx.types[base]; + return match size { + naga::ArraySize::Constant(size) => docs::Type::ArrayConstant( + Box::new(build_ty(member_type, gctx, def_paths)), + Some(size.get()), + ), + naga::ArraySize::Dynamic => { + docs::Type::ArrayDynamic(Box::new(build_ty(member_type, gctx, def_paths))) + } + }; + } + TypeInner::BindingArray { base, size } => { + // More info https://github.com/gpuweb/gpuweb/issues/2105 + let member_type = &gctx.types[base]; + return match size { + naga::ArraySize::Constant(size) => docs::Type::BindingArrayConstant( + Box::new(build_ty(member_type, gctx, def_paths)), + Some(size.get()), + ), + naga::ArraySize::Dynamic => docs::Type::BindingArrayDynamic(Box::new(build_ty( + member_type, + gctx, + def_paths, + ))), + }; + } + TypeInner::Matrix { + columns, + rows, + scalar, + } => { + format!( + "mat{}x{}<{}>", + vector_size_str(columns), + vector_size_str(rows), + scalar_kind_str(scalar) + ) + } + TypeInner::Pointer { base, space } => { + let (address, maybe_access) = address_space_str(space); + // Everything but `AddressSpace::Handle` gives us a `address` name, but + // Naga IR never produces pointers to handles, so it doesn't matter much + // how we write such a type. Just write it as the base type alone. + let base = build_ty(&gctx.types[base], gctx, def_paths); + return match address { + Some(address) => docs::Type::PointerWithAddressSpace { + base: Box::new(base), + address_space: address, + maybe_access, + }, + None => base, + }; + } + TypeInner::ValuePointer { + size, + scalar, + space, + } => { + let (address, maybe_access) = address_space_str(space); + let base = docs::Type::Named { + name: match size { + Some(size) => { + format!("vec{}<{}>", vector_size_str(size), scalar_kind_str(scalar)) + } + None => scalar_kind_str(scalar).to_string(), + }, + def_path: None, + }; + return match address { + Some(address) => docs::Type::PointerWithAddressSpace { + base: Box::new(base), + address_space: address, + maybe_access, + }, + None => base, + }; + } + TypeInner::AccelerationStructure => "acceleration_structure".to_string(), + TypeInner::Struct { .. } => { + // TODO: Actually output the struct? + "struct".to_string() + } + TypeInner::RayQuery { .. } => { + // TODO: ??? + "ray_query".to_string() + } + }; + + let def_path = def_paths.get(&name).cloned(); + docs::Type::Named { name, def_path } +} + +const fn vector_size_str(size: naga::VectorSize) -> &'static str { + match size { + naga::VectorSize::Bi => "2", + naga::VectorSize::Tri => "3", + naga::VectorSize::Quad => "4", + } +} + +const fn image_dimension_str(dim: naga::ImageDimension) -> &'static str { + use naga::ImageDimension as IDim; + + match dim { + IDim::D1 => "1d", + IDim::D2 => "2d", + IDim::D3 => "3d", + IDim::Cube => "cube", + } +} + +const fn scalar_kind_str(scalar: naga::Scalar) -> &'static str { + use naga::ScalarKind as Sk; + + match scalar { + Scalar { + kind: Sk::Float, + width: 8, + } => "f64", + Scalar { + kind: Sk::Float, + width: 4, + } => "f32", + Scalar { + kind: Sk::Sint, + width: 4, + } => "i32", + Scalar { + kind: Sk::Uint, + width: 4, + } => "u32", + Scalar { + kind: Sk::Sint, + width: 8, + } => "i64", + Scalar { + kind: Sk::Uint, + width: 8, + } => "u64", + Scalar { + kind: Sk::Bool, + width: 1, + } => "bool", + _ => unreachable!(), + } +} + +const fn storage_format_str(format: naga::StorageFormat) -> &'static str { + use naga::StorageFormat as Sf; + + match format { + Sf::R8Unorm => "r8unorm", + Sf::R8Snorm => "r8snorm", + Sf::R8Uint => "r8uint", + Sf::R8Sint => "r8sint", + Sf::R16Uint => "r16uint", + Sf::R16Sint => "r16sint", + Sf::R16Float => "r16float", + Sf::Rg8Unorm => "rg8unorm", + Sf::Rg8Snorm => "rg8snorm", + Sf::Rg8Uint => "rg8uint", + Sf::Rg8Sint => "rg8sint", + Sf::R32Uint => "r32uint", + Sf::R32Sint => "r32sint", + Sf::R32Float => "r32float", + Sf::Rg16Uint => "rg16uint", + Sf::Rg16Sint => "rg16sint", + Sf::Rg16Float => "rg16float", + Sf::Rgba8Unorm => "rgba8unorm", + Sf::Rgba8Snorm => "rgba8snorm", + Sf::Rgba8Uint => "rgba8uint", + Sf::Rgba8Sint => "rgba8sint", + Sf::Bgra8Unorm => "bgra8unorm", + Sf::Rgb10a2Uint => "rgb10a2uint", + Sf::Rgb10a2Unorm => "rgb10a2unorm", + Sf::Rg11b10Ufloat => "rg11b10ufloat", + Sf::Rg32Uint => "rg32uint", + Sf::Rg32Sint => "rg32sint", + Sf::Rg32Float => "rg32float", + Sf::Rgba16Uint => "rgba16uint", + Sf::Rgba16Sint => "rgba16sint", + Sf::Rgba16Float => "rgba16float", + Sf::Rgba32Uint => "rgba32uint", + Sf::Rgba32Sint => "rgba32sint", + Sf::Rgba32Float => "rgba32float", + Sf::R16Unorm => "r16unorm", + Sf::R16Snorm => "r16snorm", + Sf::Rg16Unorm => "rg16unorm", + Sf::Rg16Snorm => "rg16snorm", + Sf::Rgba16Unorm => "rgba16unorm", + Sf::Rgba16Snorm => "rgba16snorm", + } +} + +const fn address_space_str( + space: naga::AddressSpace, +) -> (Option<&'static str>, Option<&'static str>) { + use naga::AddressSpace as As; + + ( + Some(match space { + As::Private => "private", + As::Uniform => "uniform", + As::Storage { access } => { + if access.contains(naga::StorageAccess::STORE) { + return (Some("storage"), Some("read_write")); + } else { + "storage" + } + } + As::PushConstant => "push_constant", + As::WorkGroup => "workgroup", + As::Handle => return (None, None), + As::Function => "function", + }), + None, + ) +} diff --git a/crates/compiler/src/backend_v0_15/util.rs b/crates/compiler/src/backend_v0_15/util.rs new file mode 100644 index 0000000..ecc049f --- /dev/null +++ b/crates/compiler/src/backend_v0_15/util.rs @@ -0,0 +1,111 @@ +use super::naga; +use docs::{ + AddressSpace, Binding, BuiltIn, Expression, Interpolation, Literal, ResourceBinding, Sampling, +}; + +pub fn build_expression(expression: &naga::Expression) -> Expression { + match expression { + naga::Expression::Literal(lit) => Expression::Literal(match *lit { + naga::Literal::F64(v) => Literal::F64(v), + naga::Literal::F32(v) => Literal::F32(v), + naga::Literal::U32(v) => Literal::U32(v), + naga::Literal::I32(v) => Literal::I32(v), + naga::Literal::Bool(v) => Literal::Bool(v), + naga::Literal::I64(v) => Literal::I64(v), + naga::Literal::U64(v) => Literal::U64(v), + naga::Literal::AbstractInt(v) => Literal::AbstractInt(v), + naga::Literal::AbstractFloat(v) => Literal::AbstractFloat(v), + }), + _ => Expression::Unknown, + } +} + +pub fn build_resource_binding(binding: &naga::ResourceBinding) -> ResourceBinding { + ResourceBinding { + group: binding.group, + binding: binding.binding, + } +} + +pub fn build_address_space(address_space: &naga::AddressSpace) -> AddressSpace { + match address_space { + naga::AddressSpace::Function => AddressSpace::Function, + naga::AddressSpace::Private => AddressSpace::Private, + naga::AddressSpace::WorkGroup => AddressSpace::WorkGroup, + naga::AddressSpace::Uniform => AddressSpace::Uniform, + naga::AddressSpace::Storage { access } => AddressSpace::Storage { + load: access.contains(naga::StorageAccess::LOAD), + store: access.contains(naga::StorageAccess::STORE), + }, + naga::AddressSpace::Handle => AddressSpace::Handle, + naga::AddressSpace::PushConstant => AddressSpace::PushConstant, + } +} + +pub fn build_binding(binding: &naga::Binding) -> Binding { + match binding { + naga::Binding::BuiltIn(builtin) => Binding::BuiltIn(build_builtin(builtin)), + naga::Binding::Location { + location, + second_blend_source, + interpolation, + sampling, + } => Binding::Location { + location: *location, + second_blend_source: *second_blend_source, + interpolation: interpolation.as_ref().map(build_interpolation), + sampling: sampling.as_ref().map(build_sampling), + }, + } +} + +pub fn build_builtin(builtin: &naga::BuiltIn) -> BuiltIn { + match builtin { + naga::BuiltIn::Position { invariant } => BuiltIn::Position { + invariant: *invariant, + }, + naga::BuiltIn::ViewIndex => BuiltIn::ViewIndex, + naga::BuiltIn::BaseInstance => BuiltIn::BaseInstance, + naga::BuiltIn::BaseVertex => BuiltIn::BaseVertex, + naga::BuiltIn::ClipDistance => BuiltIn::ClipDistance, + naga::BuiltIn::CullDistance => BuiltIn::CullDistance, + naga::BuiltIn::InstanceIndex => BuiltIn::InstanceIndex, + naga::BuiltIn::PointSize => BuiltIn::PointSize, + naga::BuiltIn::VertexIndex => BuiltIn::VertexIndex, + naga::BuiltIn::FragDepth => BuiltIn::FragDepth, + naga::BuiltIn::PointCoord => BuiltIn::PointCoord, + naga::BuiltIn::FrontFacing => BuiltIn::FrontFacing, + naga::BuiltIn::PrimitiveIndex => BuiltIn::PrimitiveIndex, + naga::BuiltIn::SampleIndex => BuiltIn::SampleIndex, + naga::BuiltIn::SampleMask => BuiltIn::SampleMask, + naga::BuiltIn::GlobalInvocationId => BuiltIn::GlobalInvocationId, + naga::BuiltIn::LocalInvocationId => BuiltIn::LocalInvocationId, + naga::BuiltIn::LocalInvocationIndex => BuiltIn::LocalInvocationIndex, + naga::BuiltIn::WorkGroupId => BuiltIn::WorkGroupId, + naga::BuiltIn::WorkGroupSize => BuiltIn::WorkGroupSize, + naga::BuiltIn::NumWorkGroups => BuiltIn::NumWorkGroups, + naga::BuiltIn::NumSubgroups => BuiltIn::NumSubgroups, + naga::BuiltIn::SubgroupId => BuiltIn::SubgroupId, + naga::BuiltIn::SubgroupSize => BuiltIn::SubgroupSize, + naga::BuiltIn::SubgroupInvocationId => BuiltIn::SubgroupInvocationId, + naga::BuiltIn::DrawID => BuiltIn::DrawID, + } +} + +pub fn build_interpolation(interpolation: &naga::Interpolation) -> Interpolation { + match interpolation { + naga::Interpolation::Perspective => Interpolation::Perspective, + naga::Interpolation::Linear => Interpolation::Linear, + naga::Interpolation::Flat => Interpolation::Flat, + } +} + +pub fn build_sampling(sampling: &naga::Sampling) -> Sampling { + match sampling { + naga::Sampling::Center => Sampling::Center, + naga::Sampling::Centroid => Sampling::Centroid, + naga::Sampling::Sample => Sampling::Sample, + naga_v23_1::Sampling::First => Sampling::First, + naga_v23_1::Sampling::Either => Sampling::Either, + } +} diff --git a/crates/compiler/src/lib.rs b/crates/compiler/src/lib.rs index 0807007..0b54f33 100644 --- a/crates/compiler/src/lib.rs +++ b/crates/compiler/src/lib.rs @@ -2,6 +2,9 @@ mod common; mod download; mod post_process; +#[cfg(feature = "backend_v0_15")] +mod backend_v0_15; + #[cfg(feature = "backend_v0_14")] mod backend_v0_14; @@ -23,6 +26,8 @@ use std::path::Path; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum CompilerBackend { + #[cfg(feature = "backend_v0_15")] + V0_15, #[cfg(feature = "backend_v0_14")] V0_14, #[cfg(feature = "backend_v0_13")] @@ -38,6 +43,8 @@ pub enum CompilerBackend { impl CompilerBackend { fn naga_oil_minor(self) -> u64 { match self { + #[cfg(feature = "backend_v0_15")] + CompilerBackend::V0_15 => 16, #[cfg(feature = "backend_v0_14")] CompilerBackend::V0_14 => 14, #[cfg(feature = "backend_v0_13")] @@ -70,6 +77,8 @@ pub fn compile( // CompileFn type is necessary to avoid compiler error if no backend is enabled let compile: CompileFn = match backend { + #[cfg(feature = "backend_v0_15")] + CompilerBackend::V0_15 => backend_v0_15::compile, #[cfg(feature = "backend_v0_14")] CompilerBackend::V0_14 => backend_v0_14::compile, #[cfg(feature = "backend_v0_13")] diff --git a/crates/docs/src/lib.rs b/crates/docs/src/lib.rs index 6325dd2..1855cb8 100644 --- a/crates/docs/src/lib.rs +++ b/crates/docs/src/lib.rs @@ -235,6 +235,7 @@ pub enum BuiltIn { SubgroupId, SubgroupSize, SubgroupInvocationId, + DrawID, } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -249,4 +250,6 @@ pub enum Sampling { Center, Centroid, Sample, + First, + Either, } diff --git a/crates/generator/src/lib.rs b/crates/generator/src/lib.rs index abc797e..bfda535 100644 --- a/crates/generator/src/lib.rs +++ b/crates/generator/src/lib.rs @@ -442,9 +442,8 @@ fn builtin_str(built_in: &BuiltIn) -> Result<&'static str, Box { - return Err(format!("unsupported built-in: {:?}", built_in).into()) - } + | BuiltIn::WorkGroupSize + | BuiltIn::DrawID => return Err(format!("unsupported built-in: {:?}", built_in).into()), }) } @@ -461,5 +460,7 @@ const fn sampling_str(sampling: Sampling) -> &'static str { Sampling::Center => "", Sampling::Centroid => "centroid", Sampling::Sample => "sample", + Sampling::First => "First", + Sampling::Either => "Either", } } diff --git a/crates/make/Cargo.toml b/crates/make/Cargo.toml index 6212bff..8cd63ab 100644 --- a/crates/make/Cargo.toml +++ b/crates/make/Cargo.toml @@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] docs = { path = "../docs" } compiler = { path = "../compiler", features = [ + "backend_v0_15", "backend_v0_14", "backend_v0_13", "backend_v0_11", diff --git a/crates/make/src/main.rs b/crates/make/src/main.rs index 324a377..3cee580 100644 --- a/crates/make/src/main.rs +++ b/crates/make/src/main.rs @@ -7,84 +7,92 @@ fn main() -> Result<(), Box> { let docs = vec![ compiler::compile( "bevy", - Version::new(0, 14, 0), + Version::new(0, 15, 0), |name| name.starts_with("bevy"), - shader_def_values_0_14(), + shader_def_values_0_15(), cache_path, - compiler::CompilerBackend::V0_14, - )?, - compiler::compile( - "bevy", - Version::new(0, 13, 2), - |name| name.starts_with("bevy"), - shader_def_values_0_13(), - cache_path, - compiler::CompilerBackend::V0_13, - )?, - compiler::compile( - "bevy", - Version::new(0, 13, 1), - |name| name.starts_with("bevy"), - shader_def_values_0_13(), - cache_path, - compiler::CompilerBackend::V0_13, - )?, - compiler::compile( - "bevy", - Version::new(0, 13, 0), - |name| name.starts_with("bevy"), - shader_def_values_0_13(), - cache_path, - compiler::CompilerBackend::V0_13, - )?, - compiler::compile( - "bevy", - Version::new(0, 12, 1), - |name| name.starts_with("bevy"), - shader_def_values_0_12(), - cache_path, - compiler::CompilerBackend::V0_10, - )?, - compiler::compile( - "bevy", - Version::new(0, 12, 0), - |name| name.starts_with("bevy"), - shader_def_values_0_12(), - cache_path, - compiler::CompilerBackend::V0_10, - )?, - compiler::compile( - "bevy", - Version::new(0, 11, 3), - |name| name.starts_with("bevy"), - shader_def_values_0_11(), - cache_path, - compiler::CompilerBackend::V0_08, - )?, - compiler::compile( - "bevy", - Version::new(0, 11, 2), - |name| name.starts_with("bevy"), - shader_def_values_0_11(), - cache_path, - compiler::CompilerBackend::V0_08, - )?, - compiler::compile( - "bevy", - Version::new(0, 11, 1), - |name| name.starts_with("bevy"), - shader_def_values_0_11(), - cache_path, - compiler::CompilerBackend::V0_08, - )?, - compiler::compile( - "bevy", - Version::new(0, 11, 0), - |name| name.starts_with("bevy"), - shader_def_values_0_11(), - cache_path, - compiler::CompilerBackend::V0_08, - )?, + compiler::CompilerBackend::V0_15, + )?, /* + compiler::compile( + "bevy", + Version::new(0, 14, 0), + |name| name.starts_with("bevy"), + shader_def_values_0_14(), + cache_path, + compiler::CompilerBackend::V0_14, + )?, + compiler::compile( + "bevy", + Version::new(0, 13, 2), + |name| name.starts_with("bevy"), + shader_def_values_0_13(), + cache_path, + compiler::CompilerBackend::V0_13, + )?, + compiler::compile( + "bevy", + Version::new(0, 13, 1), + |name| name.starts_with("bevy"), + shader_def_values_0_13(), + cache_path, + compiler::CompilerBackend::V0_13, + )?, + compiler::compile( + "bevy", + Version::new(0, 13, 0), + |name| name.starts_with("bevy"), + shader_def_values_0_13(), + cache_path, + compiler::CompilerBackend::V0_13, + )?, + compiler::compile( + "bevy", + Version::new(0, 12, 1), + |name| name.starts_with("bevy"), + shader_def_values_0_12(), + cache_path, + compiler::CompilerBackend::V0_10, + )?, + compiler::compile( + "bevy", + Version::new(0, 12, 0), + |name| name.starts_with("bevy"), + shader_def_values_0_12(), + cache_path, + compiler::CompilerBackend::V0_10, + )?, + compiler::compile( + "bevy", + Version::new(0, 11, 3), + |name| name.starts_with("bevy"), + shader_def_values_0_11(), + cache_path, + compiler::CompilerBackend::V0_08, + )?, + compiler::compile( + "bevy", + Version::new(0, 11, 2), + |name| name.starts_with("bevy"), + shader_def_values_0_11(), + cache_path, + compiler::CompilerBackend::V0_08, + )?, + compiler::compile( + "bevy", + Version::new(0, 11, 1), + |name| name.starts_with("bevy"), + shader_def_values_0_11(), + cache_path, + compiler::CompilerBackend::V0_08, + )?, + compiler::compile( + "bevy", + Version::new(0, 11, 0), + |name| name.starts_with("bevy"), + shader_def_values_0_11(), + cache_path, + compiler::CompilerBackend::V0_08, + )?,*/ ]; // Generate docs @@ -95,6 +103,55 @@ fn main() -> Result<(), Box> { Ok(()) } +// TODO: Check list for bevy 0.15 +fn shader_def_values_0_15() -> IndexMap { + use ShaderDefValue::*; + + [ + // From 0.14: + ("AVAILABLE_STORAGE_BUFFER_BINDINGS", UInt(3)), + ("BLEND_MULTIPLY", Bool(true)), + ("BLEND_PREMULTIPLIED_ALPHA", Bool(true)), + ("DEFERRED_PREPASS", Bool(true)), + ("DEPTH_PREPASS", Bool(true)), + ("ENVIRONMENT_MAP", Bool(true)), + ("IRRADIANCE_VOLUME", Bool(true)), + ("IRRADIANCE_VOLUMES_ARE_USABLE", Bool(true)), + ("LIGHTMAP", Bool(true)), + ("MAX_CASCADES_PER_LIGHT", UInt(4)), + ("MAX_DIRECTIONAL_LIGHTS", UInt(10)), + ("MORPH_TARGETS", Bool(true)), + ("MOTION_VECTOR_PREPASS", Bool(true)), + // ("MULTISAMPLED", Bool(true)), causes error from 0.14. + ("NORMAL_PREPASS", Bool(true)), + ("NORMAL_PREPASS_OR_DEFERRED_PREPASS", Bool(true)), + ("PBR_TRANSMISSION_TEXTURES_SUPPORTED", Bool(true)), + ("PREPASS_FRAGMENT", Bool(true)), + ("PREPASS_PIPELINE", Bool(true)), + ("SKINNED", Bool(true)), + ("STANDARD_MATERIAL_CLEARCOAT", Bool(true)), + ("STANDARD_MATERIAL_DIFFUSE_TRANSMISSION", Bool(true)), + ("STANDARD_MATERIAL_NORMAL_MAP", Bool(true)), + ("STANDARD_MATERIAL_SPECULAR_TRANSMISSION", Bool(true)), + ("TONEMAPPING_LUT_SAMPLER_BINDING_INDEX", UInt(20)), + ("TONEMAPPING_LUT_TEXTURE_BINDING_INDEX", UInt(20)), + ("TONEMAP_METHOD_TONY_MC_MAPFACE", Bool(true)), + ("VERTEX_COLORS", Bool(true)), + ("VERTEX_NORMALS", Bool(true)), + ("VERTEX_OUTPUT_INSTANCE_INDEX", Bool(true)), + ("VERTEX_POSITIONS", Bool(true)), + ("VERTEX_TANGENTS", Bool(true)), + ("VERTEX_UVS", Bool(true)), + ("VERTEX_UVS_A", Bool(true)), + ("VERTEX_UVS_B", Bool(true)), + // New for 0.15 + ("DIRECTIONAL_LIGHT_SHADOW_MAP_DEBUG_CASCADES", Bool(true)), + ] + .into_iter() + .map(|(key, value)| (key.to_string(), value)) + .collect() +} + // TODO: More shader defs available on 0.14 fn shader_def_values_0_14() -> IndexMap { use ShaderDefValue::*; From bc0cdc2b4d20a0a6bbac4a60a39fb2d8b648100a Mon Sep 17 00:00:00 2001 From: Jannik Obermann Date: Sun, 5 Jan 2025 18:41:06 +0100 Subject: [PATCH 2/2] Update for bevy 0.15 --- crates/compiler/Cargo.toml | 2 +- .../{backend_v0_15 => backend_v0_16}/mod.rs | 0 .../to_wgsl.rs | 2 +- .../{backend_v0_15 => backend_v0_16}/util.rs | 0 crates/compiler/src/download.rs | 46 ++-- crates/compiler/src/lib.rs | 16 +- crates/generator/src/lib.rs | 4 +- crates/make/Cargo.toml | 2 +- crates/make/src/main.rs | 196 ++++++++++-------- 9 files changed, 149 insertions(+), 119 deletions(-) rename crates/compiler/src/{backend_v0_15 => backend_v0_16}/mod.rs (100%) rename crates/compiler/src/{backend_v0_15 => backend_v0_16}/to_wgsl.rs (99%) rename crates/compiler/src/{backend_v0_15 => backend_v0_16}/util.rs (100%) diff --git a/crates/compiler/Cargo.toml b/crates/compiler/Cargo.toml index d53918d..4c85663 100644 --- a/crates/compiler/Cargo.toml +++ b/crates/compiler/Cargo.toml @@ -30,7 +30,7 @@ naga_v0_12 = { package = "naga", version = "0.12.3", optional = true } [features] default = [] -backend_v0_15 = ["dep:naga_oil_v0_16", "dep:naga_v23_1"] # bevy 0.15.x +backend_v0_16 = ["dep:naga_oil_v0_16", "dep:naga_v23_1"] # bevy 0.15.x backend_v0_14 = ["dep:naga_oil_v0_14", "dep:naga_v0_20"] # bevy 0.14.x backend_v0_13 = ["dep:naga_oil_v0_13", "dep:naga_v0_19"] # bevy 0.13.x backend_v0_11 = ["dep:naga_oil_v0_11", "dep:naga_v0_14"] # ... diff --git a/crates/compiler/src/backend_v0_15/mod.rs b/crates/compiler/src/backend_v0_16/mod.rs similarity index 100% rename from crates/compiler/src/backend_v0_15/mod.rs rename to crates/compiler/src/backend_v0_16/mod.rs diff --git a/crates/compiler/src/backend_v0_15/to_wgsl.rs b/crates/compiler/src/backend_v0_16/to_wgsl.rs similarity index 99% rename from crates/compiler/src/backend_v0_15/to_wgsl.rs rename to crates/compiler/src/backend_v0_16/to_wgsl.rs index 498664f..0300d2d 100644 --- a/crates/compiler/src/backend_v0_15/to_wgsl.rs +++ b/crates/compiler/src/backend_v0_16/to_wgsl.rs @@ -262,7 +262,7 @@ const fn storage_format_str(format: naga::StorageFormat) -> &'static str { Sf::Bgra8Unorm => "bgra8unorm", Sf::Rgb10a2Uint => "rgb10a2uint", Sf::Rgb10a2Unorm => "rgb10a2unorm", - Sf::Rg11b10Ufloat => "rg11b10ufloat", + Sf::Rg11b10Ufloat => "rg11b10float", Sf::Rg32Uint => "rg32uint", Sf::Rg32Sint => "rg32sint", Sf::Rg32Float => "rg32float", diff --git a/crates/compiler/src/backend_v0_15/util.rs b/crates/compiler/src/backend_v0_16/util.rs similarity index 100% rename from crates/compiler/src/backend_v0_15/util.rs rename to crates/compiler/src/backend_v0_16/util.rs diff --git a/crates/compiler/src/download.rs b/crates/compiler/src/download.rs index 7b84158..27f21a1 100644 --- a/crates/compiler/src/download.rs +++ b/crates/compiler/src/download.rs @@ -1,5 +1,5 @@ use crate::CompilerBackend; -use cargo_metadata::MetadataCommand; +use cargo_metadata::{MetadataCommand, Package}; use docs::Version; use regex::Regex; use reqwest::blocking::Client; @@ -74,24 +74,7 @@ pub fn download_shaders( url }; - // Fixes: https://github.com/bevyengine/bevy/issues/14139 - let code = r#"fn hsv_to_rgb(hsv: vec3) -> vec3 { - let n = vec3(5.0, 3.0, 1.0); - let k = (n + hsv.x / FRAC_PI_3) % 6.0; - return hsv.z - hsv.z * hsv.y * max(vec3(0.0), min(k, min(4.0 - k, vec3(1.0)))); -}"#; - let source = if source.contains(code) { - source.replace( - code, - r#"fn hsv_to_rgb(x: f32, y: f32, z: f32) -> vec3 { - let n = vec3(5.0, 3.0, 1.0); - let k = (n + x / FRAC_PI_3) % 6.0; - return z - z * y * max(vec3(0.0), min(k, min(4.0 - k, vec3(1.0)))); -}"#, - ) - } else { - source - }; + let source = fix_bevy_14139(source, package); shaders.push(ShaderSource { path, @@ -198,3 +181,28 @@ fn find_defs(source: &str) -> HashSet { defs } + +// Fixes: https://github.com/bevyengine/bevy/issues/14139 +fn fix_bevy_14139(source: String, package: &Package) -> String { + if !(package.name == "bevy_render" && package.version == Version::new(0, 14, 0)) { + return source; + } + + let code = r#"fn hsv_to_rgb(hsv: vec3) -> vec3 { + let n = vec3(5.0, 3.0, 1.0); + let k = (n + hsv.x / FRAC_PI_3) % 6.0; + return hsv.z - hsv.z * hsv.y * max(vec3(0.0), min(k, min(4.0 - k, vec3(1.0)))); +}"#; + if source.contains(code) { + source.replace( + code, + r#"fn hsv_to_rgb(x: f32, y: f32, z: f32) -> vec3 { + let n = vec3(5.0, 3.0, 1.0); + let k = (n + x / FRAC_PI_3) % 6.0; + return z - z * y * max(vec3(0.0), min(k, min(4.0 - k, vec3(1.0)))); +}"#, + ) + } else { + source + } +} diff --git a/crates/compiler/src/lib.rs b/crates/compiler/src/lib.rs index 0b54f33..ce08059 100644 --- a/crates/compiler/src/lib.rs +++ b/crates/compiler/src/lib.rs @@ -2,8 +2,8 @@ mod common; mod download; mod post_process; -#[cfg(feature = "backend_v0_15")] -mod backend_v0_15; +#[cfg(feature = "backend_v0_16")] +mod backend_v0_16; #[cfg(feature = "backend_v0_14")] mod backend_v0_14; @@ -26,8 +26,8 @@ use std::path::Path; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum CompilerBackend { - #[cfg(feature = "backend_v0_15")] - V0_15, + #[cfg(feature = "backend_v0_16")] + V0_16, #[cfg(feature = "backend_v0_14")] V0_14, #[cfg(feature = "backend_v0_13")] @@ -43,8 +43,8 @@ pub enum CompilerBackend { impl CompilerBackend { fn naga_oil_minor(self) -> u64 { match self { - #[cfg(feature = "backend_v0_15")] - CompilerBackend::V0_15 => 16, + #[cfg(feature = "backend_v0_16")] + CompilerBackend::V0_16 => 16, #[cfg(feature = "backend_v0_14")] CompilerBackend::V0_14 => 14, #[cfg(feature = "backend_v0_13")] @@ -77,8 +77,8 @@ pub fn compile( // CompileFn type is necessary to avoid compiler error if no backend is enabled let compile: CompileFn = match backend { - #[cfg(feature = "backend_v0_15")] - CompilerBackend::V0_15 => backend_v0_15::compile, + #[cfg(feature = "backend_v0_16")] + CompilerBackend::V0_16 => backend_v0_16::compile, #[cfg(feature = "backend_v0_14")] CompilerBackend::V0_14 => backend_v0_14::compile, #[cfg(feature = "backend_v0_13")] diff --git a/crates/generator/src/lib.rs b/crates/generator/src/lib.rs index bfda535..17715cb 100644 --- a/crates/generator/src/lib.rs +++ b/crates/generator/src/lib.rs @@ -460,7 +460,7 @@ const fn sampling_str(sampling: Sampling) -> &'static str { Sampling::Center => "", Sampling::Centroid => "centroid", Sampling::Sample => "sample", - Sampling::First => "First", - Sampling::Either => "Either", + Sampling::First => "first", + Sampling::Either => "either", } } diff --git a/crates/make/Cargo.toml b/crates/make/Cargo.toml index 8cd63ab..ea94871 100644 --- a/crates/make/Cargo.toml +++ b/crates/make/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] docs = { path = "../docs" } compiler = { path = "../compiler", features = [ - "backend_v0_15", + "backend_v0_16", "backend_v0_14", "backend_v0_13", "backend_v0_11", diff --git a/crates/make/src/main.rs b/crates/make/src/main.rs index 3cee580..3f4ab12 100644 --- a/crates/make/src/main.rs +++ b/crates/make/src/main.rs @@ -5,94 +5,118 @@ fn main() -> Result<(), Box> { // Compile docs let cache_path = Path::new("target/shader_docs_cache"); let docs = vec![ + compiler::compile( + "bevy", + Version::new(0, 15, 1), + |name| name.starts_with("bevy"), + shader_def_values_0_15(), + cache_path, + compiler::CompilerBackend::V0_16, + )?, compiler::compile( "bevy", Version::new(0, 15, 0), |name| name.starts_with("bevy"), shader_def_values_0_15(), cache_path, - compiler::CompilerBackend::V0_15, - )?, /* - compiler::compile( - "bevy", - Version::new(0, 14, 0), - |name| name.starts_with("bevy"), - shader_def_values_0_14(), - cache_path, - compiler::CompilerBackend::V0_14, - )?, - compiler::compile( - "bevy", - Version::new(0, 13, 2), - |name| name.starts_with("bevy"), - shader_def_values_0_13(), - cache_path, - compiler::CompilerBackend::V0_13, - )?, - compiler::compile( - "bevy", - Version::new(0, 13, 1), - |name| name.starts_with("bevy"), - shader_def_values_0_13(), - cache_path, - compiler::CompilerBackend::V0_13, - )?, - compiler::compile( - "bevy", - Version::new(0, 13, 0), - |name| name.starts_with("bevy"), - shader_def_values_0_13(), - cache_path, - compiler::CompilerBackend::V0_13, - )?, - compiler::compile( - "bevy", - Version::new(0, 12, 1), - |name| name.starts_with("bevy"), - shader_def_values_0_12(), - cache_path, - compiler::CompilerBackend::V0_10, - )?, - compiler::compile( - "bevy", - Version::new(0, 12, 0), - |name| name.starts_with("bevy"), - shader_def_values_0_12(), - cache_path, - compiler::CompilerBackend::V0_10, - )?, - compiler::compile( - "bevy", - Version::new(0, 11, 3), - |name| name.starts_with("bevy"), - shader_def_values_0_11(), - cache_path, - compiler::CompilerBackend::V0_08, - )?, - compiler::compile( - "bevy", - Version::new(0, 11, 2), - |name| name.starts_with("bevy"), - shader_def_values_0_11(), - cache_path, - compiler::CompilerBackend::V0_08, - )?, - compiler::compile( - "bevy", - Version::new(0, 11, 1), - |name| name.starts_with("bevy"), - shader_def_values_0_11(), - cache_path, - compiler::CompilerBackend::V0_08, - )?, - compiler::compile( - "bevy", - Version::new(0, 11, 0), - |name| name.starts_with("bevy"), - shader_def_values_0_11(), - cache_path, - compiler::CompilerBackend::V0_08, - )?,*/ + compiler::CompilerBackend::V0_16, + )?, + compiler::compile( + "bevy", + Version::new(0, 14, 2), + |name| name.starts_with("bevy"), + shader_def_values_0_14(), + cache_path, + compiler::CompilerBackend::V0_14, + )?, + compiler::compile( + "bevy", + Version::new(0, 14, 1), + |name| name.starts_with("bevy"), + shader_def_values_0_14(), + cache_path, + compiler::CompilerBackend::V0_14, + )?, + compiler::compile( + "bevy", + Version::new(0, 14, 0), + |name| name.starts_with("bevy"), + shader_def_values_0_14(), + cache_path, + compiler::CompilerBackend::V0_14, + )?, + compiler::compile( + "bevy", + Version::new(0, 13, 2), + |name| name.starts_with("bevy"), + shader_def_values_0_13(), + cache_path, + compiler::CompilerBackend::V0_13, + )?, + compiler::compile( + "bevy", + Version::new(0, 13, 1), + |name| name.starts_with("bevy"), + shader_def_values_0_13(), + cache_path, + compiler::CompilerBackend::V0_13, + )?, + compiler::compile( + "bevy", + Version::new(0, 13, 0), + |name| name.starts_with("bevy"), + shader_def_values_0_13(), + cache_path, + compiler::CompilerBackend::V0_13, + )?, + compiler::compile( + "bevy", + Version::new(0, 12, 1), + |name| name.starts_with("bevy"), + shader_def_values_0_12(), + cache_path, + compiler::CompilerBackend::V0_10, + )?, + compiler::compile( + "bevy", + Version::new(0, 12, 0), + |name| name.starts_with("bevy"), + shader_def_values_0_12(), + cache_path, + compiler::CompilerBackend::V0_10, + )?, + compiler::compile( + "bevy", + Version::new(0, 11, 3), + |name| name.starts_with("bevy"), + shader_def_values_0_11(), + cache_path, + compiler::CompilerBackend::V0_08, + )?, + compiler::compile( + "bevy", + Version::new(0, 11, 2), + |name| name.starts_with("bevy"), + shader_def_values_0_11(), + cache_path, + compiler::CompilerBackend::V0_08, + )?, + compiler::compile( + "bevy", + Version::new(0, 11, 1), + |name| name.starts_with("bevy"), + shader_def_values_0_11(), + cache_path, + compiler::CompilerBackend::V0_08, + )?, + compiler::compile( + "bevy", + Version::new(0, 11, 0), + |name| name.starts_with("bevy"), + shader_def_values_0_11(), + cache_path, + compiler::CompilerBackend::V0_08, + )?, ]; // Generate docs @@ -103,17 +127,17 @@ fn main() -> Result<(), Box> { Ok(()) } -// TODO: Check list for bevy 0.15 +// TODO: More shader defs available on 0.15 fn shader_def_values_0_15() -> IndexMap { use ShaderDefValue::*; [ - // From 0.14: ("AVAILABLE_STORAGE_BUFFER_BINDINGS", UInt(3)), ("BLEND_MULTIPLY", Bool(true)), ("BLEND_PREMULTIPLIED_ALPHA", Bool(true)), ("DEFERRED_PREPASS", Bool(true)), ("DEPTH_PREPASS", Bool(true)), + ("DIRECTIONAL_LIGHT_SHADOW_MAP_DEBUG_CASCADES", Bool(true)), ("ENVIRONMENT_MAP", Bool(true)), ("IRRADIANCE_VOLUME", Bool(true)), ("IRRADIANCE_VOLUMES_ARE_USABLE", Bool(true)), @@ -122,7 +146,7 @@ fn shader_def_values_0_15() -> IndexMap { ("MAX_DIRECTIONAL_LIGHTS", UInt(10)), ("MORPH_TARGETS", Bool(true)), ("MOTION_VECTOR_PREPASS", Bool(true)), - // ("MULTISAMPLED", Bool(true)), causes error from 0.14. + // ("MULTISAMPLED", Bool(true)), causes error ("NORMAL_PREPASS", Bool(true)), ("NORMAL_PREPASS_OR_DEFERRED_PREPASS", Bool(true)), ("PBR_TRANSMISSION_TEXTURES_SUPPORTED", Bool(true)), @@ -144,8 +168,6 @@ fn shader_def_values_0_15() -> IndexMap { ("VERTEX_UVS", Bool(true)), ("VERTEX_UVS_A", Bool(true)), ("VERTEX_UVS_B", Bool(true)), - // New for 0.15 - ("DIRECTIONAL_LIGHT_SHADOW_MAP_DEBUG_CASCADES", Bool(true)), ] .into_iter() .map(|(key, value)| (key.to_string(), value))