start work on shader reflection

This commit is contained in:
Carter Anderson 2020-02-16 12:12:55 -08:00
parent dbd634b8d8
commit 8698dcea25
4 changed files with 84 additions and 5 deletions

View file

@ -22,7 +22,8 @@ erased-serde = "0.3"
type-uuid = "0.1"
shaderc = "0.6"
libloading = "0.5.2"
rspirv = "0.5.4"
# rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "baa469eae2932271174593eb066894d7a7a38439" }
spirv-reflect = "0.2.3"
bevy_derive = { path = "bevy_derive" }
bevy_transform = { path = "bevy_transform" }

View file

@ -4,6 +4,7 @@ pub mod passes;
pub mod render_graph_2;
pub mod render_resources;
pub mod shader;
pub mod shader_reflect;
mod light;
mod material;

View file

@ -1,4 +1,4 @@
use crate::asset::Handle;
use crate::{asset::Handle, render::shader_reflect::get_shader_layout};
use std::marker::Copy;
#[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
@ -68,10 +68,14 @@ impl Shader {
}
pub fn get_spirv(&self, macros: Option<&[String]>) -> Vec<u32> {
match self.source {
let result = match self.source {
ShaderSource::Spirv(ref bytes) => bytes.clone(),
ShaderSource::Glsl(ref source) => glsl_to_spirv(&source, self.stage, macros),
}
};
get_shader_layout(&result);
result
}
pub fn get_spirv_shader(&self, macros: Option<&[String]>) -> Shader {

View file

@ -0,0 +1,73 @@
use crate::render::render_graph_2::{BindGroup, UniformPropertyType, Binding, BindType};
use spirv_reflect::{
types::{ReflectDescriptorSet, ReflectTypeDescription, ReflectDescriptorBinding, ReflectDescriptorType},
ShaderModule,
};
use zerocopy::AsBytes;
// use rspirv::{binary::Parser, dr::Loader, lift::LiftContext};
// TODO: pick rspirv vs spirv-reflect
// pub fn get_shader_layout(spirv_data: &[u32]) {
// let mut loader = Loader::new(); // You can use your own consumer here.
// {
// let p = Parser::new(spirv_data.as_bytes(), &mut loader);
// p.parse().unwrap();
// }
// let module = loader.module();
// let structured = LiftContext::convert(&module).unwrap();
// println!("{:?}", structured.types);
// }
pub fn get_shader_layout(spirv_data: &[u32]) {
match ShaderModule::load_u8_data(spirv_data.as_bytes()) {
Ok(ref mut module) => {
let entry_point_name = module.get_entry_point_name();
let shader_stage = module.get_shader_stage();
println!("entry point: {}", entry_point_name);
println!("shader stage: {:?}", shader_stage);
let mut bind_groups = Vec::new();
for descriptor_set in module.enumerate_descriptor_sets(None).unwrap() {
let bind_group = reflect_bind_group(&descriptor_set);
bind_groups.push(bind_group);
}
println!(" result {:?}", &bind_groups);
println!();
}
_ => {}
}
}
fn reflect_bind_group(descriptor_set: &ReflectDescriptorSet) -> BindGroup {
println!(" set {}", descriptor_set.set);
let mut bindings = Vec::new();
for descriptor_binding in descriptor_set.bindings.iter() {
let binding = reflect_binding(descriptor_binding);
bindings.push(binding);
}
BindGroup::new(bindings)
}
fn reflect_binding(binding: &ReflectDescriptorBinding) -> Binding {
let type_description = binding.type_description.as_ref().unwrap();
let bind_type = match binding.descriptor_type {
ReflectDescriptorType::UniformBuffer => reflect_uniform(type_description),
_ => panic!("unsupported bind type {:?}", binding.descriptor_type),
};
// println!(" {:?}", binding);
Binding{
bind_type: bind_type,
name: type_description.type_name.to_string()
}
}
fn reflect_uniform(binding: &ReflectTypeDescription) -> BindType {
BindType::Uniform {
dynamic: false,
properties: Vec::new()
}
}