mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
update shader include resolution to fix issues with windows (#1248)
This commit is contained in:
parent
ea8fed21f6
commit
901993b390
@ -5,6 +5,8 @@
|
|||||||
- Update MacOS dependencies metal to 0.17 and cocoa to 0.19
|
- Update MacOS dependencies metal to 0.17 and cocoa to 0.19
|
||||||
- Added dynamic stencil elements to `DynamicState`
|
- Added dynamic stencil elements to `DynamicState`
|
||||||
- Fixed `ImageDimensions::mipmap_dimensions` and `max_mipmaps` in cases where the original size is not a power of two.
|
- Fixed `ImageDimensions::mipmap_dimensions` and `max_mipmaps` in cases where the original size is not a power of two.
|
||||||
|
- Shader includes now work on Windows.
|
||||||
|
- **Breaking Change** Shader include directories passed to the `shader!` macro are now relative to the crates `Cargo.toml`
|
||||||
|
|
||||||
# Version 0.14.0 (2019-08-17)
|
# Version 0.14.0 (2019-08-17)
|
||||||
|
|
||||||
|
@ -23,68 +23,66 @@ use vulkano::sync;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// TODO: Disabled because it fails on windows
|
let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
|
||||||
//
|
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||||
// let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
|
let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap();
|
||||||
// let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
|
let (device, mut queues) = Device::new(physical, physical.supported_features(),
|
||||||
// let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap();
|
&DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
|
||||||
// let (device, mut queues) = Device::new(physical, physical.supported_features(),
|
let queue = queues.next().unwrap();
|
||||||
// &DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
|
|
||||||
// let queue = queues.next().unwrap();
|
println!("Device initialized");
|
||||||
//
|
|
||||||
// println!("Device initialized");
|
let pipeline = Arc::new({
|
||||||
//
|
mod cs {
|
||||||
// let pipeline = Arc::new({
|
vulkano_shaders::shader!{
|
||||||
// mod cs {
|
ty: "compute",
|
||||||
// vulkano_shaders::shader!{
|
// We declare what directories to search for when using the `#include <...>`
|
||||||
// ty: "compute",
|
// syntax. Specified directories have descending priorities based on their order.
|
||||||
// // We declare what directories to search for when using the `#include <...>`
|
include: [ "src/bin/shader-include/standard-shaders" ],
|
||||||
// // syntax. Specified directories have descending priorities based on their order.
|
src: "
|
||||||
// include: [ "examples/src/bin/shader-include/standard-shaders" ],
|
#version 450
|
||||||
// src: "
|
// Substitutes this line with the contents of the file `common.glsl` found in one of the standard
|
||||||
//#version 450
|
// `include` directories specified above.
|
||||||
//// Substitutes this line with the contents of the file `common.glsl` found in one of the standard
|
// Note, that relative inclusion (`#include \"...\"`), although it falls back to standard
|
||||||
//// `include` directories specified above.
|
// inclusion, should not be used for **embedded** shader source, as it may be misleading and/or
|
||||||
//// Note, that relative inclusion (`#include \"...\"`), although it falls back to standard
|
// confusing.
|
||||||
//// inclusion, should not be used for **embedded** shader source, as it may be misleading and/or
|
#include <common.glsl>
|
||||||
//// confusing.
|
|
||||||
//#include <common.glsl>
|
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
|
||||||
//
|
|
||||||
//layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
|
layout(set = 0, binding = 0) buffer Data {
|
||||||
//
|
uint data[];
|
||||||
//layout(set = 0, binding = 0) buffer Data {
|
} data;
|
||||||
// uint data[];
|
|
||||||
//} data;
|
void main() {
|
||||||
//
|
uint idx = gl_GlobalInvocationID.x;
|
||||||
//void main() {
|
data.data[idx] = multiply_by_12(data.data[idx]);
|
||||||
// uint idx = gl_GlobalInvocationID.x;
|
}"
|
||||||
// data.data[idx] = multiply_by_12(data.data[idx]);
|
}
|
||||||
//}"
|
}
|
||||||
// }
|
let shader = cs::Shader::load(device.clone()).unwrap();
|
||||||
// }
|
ComputePipeline::new(device.clone(), &shader.main_entry_point(), &()).unwrap()
|
||||||
// let shader = cs::Shader::load(device.clone()).unwrap();
|
});
|
||||||
// ComputePipeline::new(device.clone(), &shader.main_entry_point(), &()).unwrap()
|
|
||||||
// });
|
let data_buffer = {
|
||||||
//
|
let data_iter = (0 .. 65536u32).map(|n| n);
|
||||||
// let data_buffer = {
|
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
|
||||||
// let data_iter = (0 .. 65536u32).map(|n| n);
|
};
|
||||||
// CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
|
let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0)
|
||||||
// };
|
.add_buffer(data_buffer.clone()).unwrap()
|
||||||
// let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0)
|
.build().unwrap()
|
||||||
// .add_buffer(data_buffer.clone()).unwrap()
|
);
|
||||||
// .build().unwrap()
|
let command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap()
|
||||||
// );
|
.dispatch([1024, 1, 1], pipeline.clone(), set.clone(), ()).unwrap()
|
||||||
// let command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap()
|
.build().unwrap();
|
||||||
// .dispatch([1024, 1, 1], pipeline.clone(), set.clone(), ()).unwrap()
|
let future = sync::now(device.clone())
|
||||||
// .build().unwrap();
|
.then_execute(queue.clone(), command_buffer).unwrap()
|
||||||
// let future = sync::now(device.clone())
|
.then_signal_fence_and_flush().unwrap();
|
||||||
// .then_execute(queue.clone(), command_buffer).unwrap()
|
|
||||||
// .then_signal_fence_and_flush().unwrap();
|
future.wait(None).unwrap();
|
||||||
//
|
|
||||||
// future.wait(None).unwrap();
|
let data_buffer_content = data_buffer.read().unwrap();
|
||||||
//
|
for n in 0 .. 65536u32 {
|
||||||
// let data_buffer_content = data_buffer.read().unwrap();
|
assert_eq!(data_buffer_content[n as usize], n * 12);
|
||||||
// for n in 0 .. 65536u32 {
|
}
|
||||||
// assert_eq!(data_buffer_content[n as usize], n * 12);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@ -29,14 +29,14 @@ use crate::read_file_to_string;
|
|||||||
|
|
||||||
fn include_callback(requested_source_path_raw: &str, directive_type: IncludeType,
|
fn include_callback(requested_source_path_raw: &str, directive_type: IncludeType,
|
||||||
contained_within_path_raw: &str, recursion_depth: usize,
|
contained_within_path_raw: &str, recursion_depth: usize,
|
||||||
include_directories: &[String], root_source_has_path: bool) -> Result<ResolvedInclude, String> {
|
include_directories: &[impl AsRef<Path>], root_source_has_path: bool,
|
||||||
|
base_path: &impl AsRef<Path>) -> Result<ResolvedInclude, String> {
|
||||||
let file_to_include = match directive_type {
|
let file_to_include = match directive_type {
|
||||||
IncludeType::Relative => {
|
IncludeType::Relative => {
|
||||||
let requested_source_path = Path::new(requested_source_path_raw);
|
let requested_source_path = Path::new(requested_source_path_raw);
|
||||||
|
|
||||||
// Is embedded current shader source embedded within a rust macro?
|
// Is embedded current shader source embedded within a rust macro?
|
||||||
// If so, abort.
|
// If so, abort unless absolute path.
|
||||||
if !root_source_has_path && recursion_depth == 1 {
|
if !root_source_has_path && recursion_depth == 1 && !requested_source_path.is_absolute() {
|
||||||
let requested_source_name = requested_source_path.file_name()
|
let requested_source_name = requested_source_path.file_name()
|
||||||
.expect("Could not get the name of the requested source file.")
|
.expect("Could not get the name of the requested source file.")
|
||||||
.to_string_lossy();
|
.to_string_lossy();
|
||||||
@ -51,18 +51,21 @@ fn include_callback(requested_source_path_raw: &str, directive_type: IncludeType
|
|||||||
requested_source_name, requested_source_directory));
|
requested_source_name, requested_source_directory));
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent_of_current_source = Path::new(contained_within_path_raw).parent()
|
let mut resolved_path = if recursion_depth == 1 {
|
||||||
.unwrap_or_else(|| panic!("The file `{}` does not reside in a directory. This is \
|
Path::new(contained_within_path_raw).parent().map(|parent| base_path.as_ref().join(parent))
|
||||||
an implementation error.",
|
} else {
|
||||||
contained_within_path_raw));
|
Path::new(contained_within_path_raw).parent().map(|parent| parent.to_owned())
|
||||||
let resolved_requested_source_path = parent_of_current_source.join(requested_source_path);
|
}.unwrap_or_else(|| panic!("The file `{}` does not reside in a directory. This is \
|
||||||
|
an implementation error.",
|
||||||
|
contained_within_path_raw));
|
||||||
|
resolved_path.push(requested_source_path);
|
||||||
|
|
||||||
if !resolved_requested_source_path.is_file() {
|
if !resolved_path.is_file() {
|
||||||
return Err(format!("Invalid inclusion path `{}`, the path does not point to a file.",
|
return Err(format!("Invalid inclusion path `{}`, the path does not point to a file.",
|
||||||
requested_source_path_raw));
|
requested_source_path_raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
resolved_requested_source_path
|
resolved_path
|
||||||
},
|
},
|
||||||
IncludeType::Standard => {
|
IncludeType::Standard => {
|
||||||
let requested_source_path = Path::new(requested_source_path_raw);
|
let requested_source_path = Path::new(requested_source_path_raw);
|
||||||
@ -78,58 +81,35 @@ fn include_callback(requested_source_path_raw: &str, directive_type: IncludeType
|
|||||||
requested_source_path_raw));
|
requested_source_path_raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut found_requested_source_path = None;
|
let found_requested_source_path = include_directories.iter().map(|include_directory| include_directory.as_ref().join(requested_source_path)).find(
|
||||||
|
|resolved_requested_source_path| resolved_requested_source_path.is_file()
|
||||||
|
);
|
||||||
|
|
||||||
for include_directory in include_directories {
|
if let Some(found_requested_source_path) = found_requested_source_path {
|
||||||
let include_directory_path = Path::new(include_directory).canonicalize()
|
found_requested_source_path
|
||||||
.unwrap_or_else(|_| panic!("Invalid standard shader inclusion directory `{}`.",
|
} else {
|
||||||
include_directory));
|
|
||||||
let resolved_requested_source_path_rel = include_directory_path
|
|
||||||
.join(requested_source_path);
|
|
||||||
let resolved_requested_source_path = resolved_requested_source_path_rel
|
|
||||||
.canonicalize()
|
|
||||||
.map_err(|_| format!("Invalid inclusion path `{}`.",
|
|
||||||
resolved_requested_source_path_rel.to_string_lossy()))?;
|
|
||||||
|
|
||||||
if !resolved_requested_source_path.starts_with(include_directory_path) {
|
|
||||||
return Err(format!("Cannot use `..` with inclusion from standard directories \
|
|
||||||
(`#include <...>`), try using `#include \"...\"` instead. \
|
|
||||||
Requested path: {}", requested_source_path.to_string_lossy()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if resolved_requested_source_path.is_file() {
|
|
||||||
found_requested_source_path = Some(resolved_requested_source_path);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if found_requested_source_path.is_none() {
|
|
||||||
return Err(format!("Could not include the file `{}` from any include directories.",
|
return Err(format!("Could not include the file `{}` from any include directories.",
|
||||||
requested_source_path_raw));
|
requested_source_path_raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
found_requested_source_path.unwrap()
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let canonical_file_to_include = file_to_include.canonicalize()
|
let file_to_include_string = file_to_include.to_str()
|
||||||
.unwrap_or_else(|_| file_to_include);
|
|
||||||
let canonical_file_to_include_string = canonical_file_to_include.to_str()
|
|
||||||
.expect("Could not stringify the file to be included. Make sure the path consists of \
|
.expect("Could not stringify the file to be included. Make sure the path consists of \
|
||||||
valid unicode characters.")
|
valid unicode characters.")
|
||||||
.to_string();
|
.to_string();
|
||||||
let content = read_file_to_string(canonical_file_to_include.as_path())
|
let content = read_file_to_string(file_to_include.as_path())
|
||||||
.map_err(|_| format!("Could not read the contents of file `{}` to be included in the \
|
.map_err(|_| format!("Could not read the contents of file `{}` to be included in the \
|
||||||
shader source.",
|
shader source.",
|
||||||
&canonical_file_to_include_string))?;
|
&file_to_include_string))?;
|
||||||
|
|
||||||
Ok(ResolvedInclude {
|
Ok(ResolvedInclude {
|
||||||
resolved_name: canonical_file_to_include_string,
|
resolved_name: file_to_include_string,
|
||||||
content,
|
content,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(path: Option<String>, code: &str, ty: ShaderKind, include_directories: &[String]) -> Result<CompilationArtifact, String> {
|
pub fn compile(path: Option<String>, base_path: &impl AsRef<Path>, code: &str, ty: ShaderKind, include_directories: &[impl AsRef<Path>]) -> Result<CompilationArtifact, String> {
|
||||||
let mut compiler = Compiler::new().ok_or("failed to create GLSL compiler")?;
|
let mut compiler = Compiler::new().ok_or("failed to create GLSL compiler")?;
|
||||||
let mut compile_options = CompileOptions::new()
|
let mut compile_options = CompileOptions::new()
|
||||||
.ok_or("failed to initialize compile option")?;
|
.ok_or("failed to initialize compile option")?;
|
||||||
@ -144,7 +124,7 @@ pub fn compile(path: Option<String>, code: &str, ty: ShaderKind, include_directo
|
|||||||
compile_options.set_include_callback(|requested_source_path, directive_type,
|
compile_options.set_include_callback(|requested_source_path, directive_type,
|
||||||
contained_within_path, recursion_depth| {
|
contained_within_path, recursion_depth| {
|
||||||
include_callback(requested_source_path, directive_type, contained_within_path,
|
include_callback(requested_source_path, directive_type, contained_within_path,
|
||||||
recursion_depth, include_directories, path.is_some())
|
recursion_depth, include_directories, path.is_some(), base_path)
|
||||||
});
|
});
|
||||||
|
|
||||||
let content = compiler
|
let content = compiler
|
||||||
@ -374,6 +354,7 @@ fn capability_name(cap: &Capability) -> Option<&'static str> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bad_alignment() {
|
fn test_bad_alignment() {
|
||||||
@ -383,7 +364,8 @@ mod tests {
|
|||||||
// byte, but in a rust [[f32;3];2], the second element starts on the
|
// byte, but in a rust [[f32;3];2], the second element starts on the
|
||||||
// 12th byte. Since we can't generate code for these types, we should
|
// 12th byte. Since we can't generate code for these types, we should
|
||||||
// create an error instead of generating incorrect code.
|
// create an error instead of generating incorrect code.
|
||||||
let comp = compile(None, "
|
let includes: [PathBuf;0] = [];
|
||||||
|
let comp = compile(None, &Path::new(""), "
|
||||||
#version 450
|
#version 450
|
||||||
struct MyStruct {
|
struct MyStruct {
|
||||||
vec3 vs[2];
|
vec3 vs[2];
|
||||||
@ -392,14 +374,15 @@ mod tests {
|
|||||||
MyStruct s;
|
MyStruct s;
|
||||||
};
|
};
|
||||||
void main() {}
|
void main() {}
|
||||||
", ShaderKind::Vertex, &[]).unwrap();
|
", ShaderKind::Vertex, &includes).unwrap();
|
||||||
let doc = parse::parse_spirv(comp.as_binary()).unwrap();
|
let doc = parse::parse_spirv(comp.as_binary()).unwrap();
|
||||||
let res = std::panic::catch_unwind(|| structs::write_structs(&doc));
|
let res = std::panic::catch_unwind(|| structs::write_structs(&doc));
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_trivial_alignment() {
|
fn test_trivial_alignment() {
|
||||||
let comp = compile(None, "
|
let includes: [PathBuf;0] = [];
|
||||||
|
let comp = compile(None, &Path::new(""), "
|
||||||
#version 450
|
#version 450
|
||||||
struct MyStruct {
|
struct MyStruct {
|
||||||
vec4 vs[2];
|
vec4 vs[2];
|
||||||
@ -408,7 +391,7 @@ mod tests {
|
|||||||
MyStruct s;
|
MyStruct s;
|
||||||
};
|
};
|
||||||
void main() {}
|
void main() {}
|
||||||
", ShaderKind::Vertex, &[]).unwrap();
|
", ShaderKind::Vertex, &includes).unwrap();
|
||||||
let doc = parse::parse_spirv(comp.as_binary()).unwrap();
|
let doc = parse::parse_spirv(comp.as_binary()).unwrap();
|
||||||
structs::write_structs(&doc);
|
structs::write_structs(&doc);
|
||||||
}
|
}
|
||||||
@ -416,7 +399,8 @@ mod tests {
|
|||||||
fn test_wrap_alignment() {
|
fn test_wrap_alignment() {
|
||||||
// This is a workaround suggested in the case of test_bad_alignment,
|
// This is a workaround suggested in the case of test_bad_alignment,
|
||||||
// so we should make sure it works.
|
// so we should make sure it works.
|
||||||
let comp = compile(None, "
|
let includes: [PathBuf;0] = [];
|
||||||
|
let comp = compile(None, &Path::new(""), "
|
||||||
#version 450
|
#version 450
|
||||||
struct Vec3Wrap {
|
struct Vec3Wrap {
|
||||||
vec3 v;
|
vec3 v;
|
||||||
@ -428,8 +412,48 @@ mod tests {
|
|||||||
MyStruct s;
|
MyStruct s;
|
||||||
};
|
};
|
||||||
void main() {}
|
void main() {}
|
||||||
", ShaderKind::Vertex, &[]).unwrap();
|
", ShaderKind::Vertex, &includes).unwrap();
|
||||||
let doc = parse::parse_spirv(comp.as_binary()).unwrap();
|
let doc = parse::parse_spirv(comp.as_binary()).unwrap();
|
||||||
structs::write_structs(&doc);
|
structs::write_structs(&doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_include_resolution() {
|
||||||
|
let root_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
let empty_includes: [PathBuf;0] = [];
|
||||||
|
let _compile_relative = compile(Some(String::from("tests/include_test.glsl")), &root_path, "
|
||||||
|
#version 450
|
||||||
|
#include \"include_dir_a/target_a.glsl\"
|
||||||
|
#include \"include_dir_b/target_b.glsl\"
|
||||||
|
void main() {}
|
||||||
|
", ShaderKind::Vertex, &empty_includes).expect("Cannot resolve include files");
|
||||||
|
|
||||||
|
let _compile_include_paths = compile(Some(String::from("tests/include_test.glsl")), &root_path, "
|
||||||
|
#version 450
|
||||||
|
#include <target_a.glsl>
|
||||||
|
#include <target_b.glsl>
|
||||||
|
void main() {}
|
||||||
|
", ShaderKind::Vertex,&[root_path.join("tests/include_dir_a"), root_path.join("tests/include_dir_b")]).expect("Cannot resolve include files");
|
||||||
|
|
||||||
|
let _compile_include_paths_with_relative = compile(Some(String::from("tests/include_test.glsl")), &root_path, "
|
||||||
|
#version 450
|
||||||
|
#include <target_a.glsl>
|
||||||
|
#include <../include_dir_b/target_b.glsl>
|
||||||
|
void main() {}
|
||||||
|
", ShaderKind::Vertex,&[root_path.join("tests/include_dir_a")]).expect("Cannot resolve include files");
|
||||||
|
|
||||||
|
let absolute_path = root_path.join("tests/include_dir_a/target_a.glsl");
|
||||||
|
let absolute_path_str = absolute_path.to_str().expect("Cannot run tests in a folder with non unicode characters");
|
||||||
|
let _compile_absolute_path = compile(Some(String::from("tests/include_test.glsl")), &root_path, &format!("
|
||||||
|
#version 450
|
||||||
|
#include \"{}\"
|
||||||
|
void main() {{}}
|
||||||
|
", absolute_path_str), ShaderKind::Vertex, &empty_includes).expect("Cannot resolve include files");
|
||||||
|
|
||||||
|
let _compile_recursive = compile(Some(String::from("tests/include_test.glsl")), &root_path, "
|
||||||
|
#version 450
|
||||||
|
#include <target_c.glsl>
|
||||||
|
void main() {}
|
||||||
|
", ShaderKind::Vertex,&[root_path.join("tests/include_dir_b"), root_path.join("tests/include_dir_c")]).expect("Cannot resolve include files");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,8 @@
|
|||||||
//! ## `include: ["...", "...", ..., "..."]`
|
//! ## `include: ["...", "...", ..., "..."]`
|
||||||
//!
|
//!
|
||||||
//! Specifies the standard include directories to be searched through when using the
|
//! Specifies the standard include directories to be searched through when using the
|
||||||
//! `#include <...>` directive within a shader source.
|
//! `#include <...>` directive within a shader source. Include directories can be absolute
|
||||||
|
//! or relative to `Cargo.toml`.
|
||||||
//! If `path` was specified, relative paths can also be used (`#include "..."`), without the need
|
//! If `path` was specified, relative paths can also be used (`#include "..."`), without the need
|
||||||
//! to specify one or more standard include directories. Relative paths are relative to the
|
//! to specify one or more standard include directories. Relative paths are relative to the
|
||||||
//! directory, which contains the source file the `#include "..."` directive is declared in.
|
//! directory, which contains the source file the `#include "..."` directive is declared in.
|
||||||
@ -287,12 +288,13 @@ pub(self) fn read_file_to_string(full_path: &Path) -> IoResult<String> {
|
|||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn shader(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn shader(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let input = parse_macro_input!(input as MacroInput);
|
let input = parse_macro_input!(input as MacroInput);
|
||||||
|
let root = env::var("CARGO_MANIFEST_DIR").unwrap_or(".".into());
|
||||||
|
let root_path = Path::new(&root);
|
||||||
|
|
||||||
let (path, source_code) = match input.source_kind {
|
let (path, source_code) = match input.source_kind {
|
||||||
SourceKind::Src(source) => (None, source),
|
SourceKind::Src(source) => (None, source),
|
||||||
SourceKind::Path(path) => (Some(path.clone()), {
|
SourceKind::Path(path) => (Some(path.clone()), {
|
||||||
let root = env::var("CARGO_MANIFEST_DIR").unwrap_or(".".into());
|
let full_path = root_path.join(&path);
|
||||||
let full_path = Path::new(&root).join(&path);
|
|
||||||
|
|
||||||
if full_path.is_file() {
|
if full_path.is_file() {
|
||||||
read_file_to_string(&full_path)
|
read_file_to_string(&full_path)
|
||||||
@ -303,6 +305,13 @@ pub fn shader(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let content = codegen::compile(path, &source_code, input.shader_kind, &input.include_directories).unwrap();
|
let include_paths = input.include_directories.iter().map(|include_directory| {
|
||||||
|
let include_path = Path::new(include_directory);
|
||||||
|
let mut full_include_path = root_path.to_owned();
|
||||||
|
full_include_path.push(include_path);
|
||||||
|
full_include_path
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let content = codegen::compile(path, &root_path, &source_code, input.shader_kind, &include_paths).unwrap();
|
||||||
codegen::reflect("Shader", content.as_binary(), input.dump).unwrap().into()
|
codegen::reflect("Shader", content.as_binary(), input.dump).unwrap().into()
|
||||||
}
|
}
|
||||||
|
0
vulkano-shaders/tests/include_dir_a/target_a.glsl
Normal file
0
vulkano-shaders/tests/include_dir_a/target_a.glsl
Normal file
0
vulkano-shaders/tests/include_dir_b/target_b.glsl
Normal file
0
vulkano-shaders/tests/include_dir_b/target_b.glsl
Normal file
2
vulkano-shaders/tests/include_dir_c/target_c.glsl
Normal file
2
vulkano-shaders/tests/include_dir_c/target_c.glsl
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#include "../include_dir_a/target_a.glsl"
|
||||||
|
#include <target_b.glsl>
|
Loading…
Reference in New Issue
Block a user