From c29a6f7dd22e33ccd41428aff3b70afcc217f767 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Sun, 16 Feb 2020 20:35:44 -0800 Subject: [PATCH] more shader reflection --- src/render/render_graph_2/pipeline_layout.rs | 4 +- .../render_graph_2/pipelines/forward/mod.rs | 15 ++++- src/render/shader_reflect.rs | 65 +++++++++++++++++-- 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/render/render_graph_2/pipeline_layout.rs b/src/render/render_graph_2/pipeline_layout.rs index 1b93734b4b..7a2ee6379f 100644 --- a/src/render/render_graph_2/pipeline_layout.rs +++ b/src/render/render_graph_2/pipeline_layout.rs @@ -96,7 +96,7 @@ pub enum UniformPropertyType { Vec3, Vec4, Mat4, - Struct(Vec), + Struct(Vec), Array(Box, usize), } @@ -111,7 +111,7 @@ impl UniformPropertyType { UniformPropertyType::Mat4 => 4 * 4 * 4, UniformPropertyType::Struct(properties) => properties .iter() - .map(|p| p.get_size()) + .map(|p| p.property_type.get_size()) .fold(0, |total, size| total + size), UniformPropertyType::Array(property, length) => property.get_size() * *length as u64, } diff --git a/src/render/render_graph_2/pipelines/forward/mod.rs b/src/render/render_graph_2/pipelines/forward/mod.rs index bc35106057..c903a56e10 100644 --- a/src/render/render_graph_2/pipelines/forward/mod.rs +++ b/src/render/render_graph_2/pipelines/forward/mod.rs @@ -45,9 +45,18 @@ impl ForwardPipelineBuilder for RenderGraphBuilder { name: "SceneLights".to_string(), property_type: UniformPropertyType::Array( Box::new(UniformPropertyType::Struct(vec![ - UniformPropertyType::Mat4, // proj - UniformPropertyType::Vec4, // pos - UniformPropertyType::Vec4, // color + UniformProperty { + name: "proj".to_string(), + property_type: UniformPropertyType::Mat4, + }, + UniformProperty { + name: "pos".to_string(), + property_type: UniformPropertyType::Vec4, + }, + UniformProperty { + name: "color".to_string(), + property_type: UniformPropertyType::Vec4, + }, ])), 10, // max lights ), diff --git a/src/render/shader_reflect.rs b/src/render/shader_reflect.rs index c08c10be13..01a65ce3c5 100644 --- a/src/render/shader_reflect.rs +++ b/src/render/shader_reflect.rs @@ -1,6 +1,6 @@ -use crate::render::render_graph_2::{BindGroup, UniformPropertyType, Binding, BindType}; +use crate::render::render_graph_2::{BindGroup, UniformPropertyType, Binding, BindType, UniformProperty}; use spirv_reflect::{ - types::{ReflectDescriptorSet, ReflectTypeDescription, ReflectDescriptorBinding, ReflectDescriptorType}, + types::{ReflectDescriptorSet, ReflectTypeDescription, ReflectDescriptorBinding, ReflectDescriptorType, ReflectTypeFlags}, ShaderModule, }; use zerocopy::AsBytes; @@ -54,7 +54,10 @@ fn reflect_bind_group(descriptor_set: &ReflectDescriptorSet) -> BindGroup { 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), + ReflectDescriptorType::UniformBuffer => BindType::Uniform { + dynamic: false, + properties: vec![reflect_uniform(type_description)], + }, _ => panic!("unsupported bind type {:?}", binding.descriptor_type), }; @@ -65,9 +68,57 @@ fn reflect_binding(binding: &ReflectDescriptorBinding) -> Binding { } } -fn reflect_uniform(binding: &ReflectTypeDescription) -> BindType { - BindType::Uniform { - dynamic: false, - properties: Vec::new() +#[derive(Debug)] +enum NumberType { + Int, + UInt, + Float, +} + +fn reflect_uniform(type_description: &ReflectTypeDescription) -> UniformProperty { + let uniform_property_type = if type_description.type_flags.contains(ReflectTypeFlags::STRUCT) { + reflect_uniform_struct(type_description) + } else { + reflect_uniform_numeric(type_description) + }; + + UniformProperty { + name: type_description.type_name.to_string(), + property_type: uniform_property_type, + } +} + +fn reflect_uniform_struct(type_description: &ReflectTypeDescription) -> UniformPropertyType { + println!("reflecting struct"); + let mut properties = Vec::new(); + for member in type_description.members.iter() { + properties.push(reflect_uniform(member)); + } + + UniformPropertyType::Struct(properties) +} + +fn reflect_uniform_numeric(type_description: &ReflectTypeDescription) -> UniformPropertyType { + let traits = &type_description.traits; + let number_type = if type_description.type_flags.contains(ReflectTypeFlags::INT) { + match traits.numeric.scalar.signedness { + 0 => NumberType::UInt, + 1 => NumberType::Int, + signedness => panic!("unexpected signedness {}", signedness) + } + } else if type_description.type_flags.contains(ReflectTypeFlags::FLOAT) { + NumberType::Float + } else { + panic!("unexpected type flag {:?}", type_description.type_flags); + }; + + // TODO: handle scalar width here + + match (number_type, traits.numeric.vector.component_count) { + (NumberType::Int, 1) => UniformPropertyType::Int, + (NumberType::Float, 3) => UniformPropertyType::Vec3, + (NumberType::Float, 4) => UniformPropertyType::Vec4, + (NumberType::UInt, 4) => UniformPropertyType::UVec4, + (number_type, component_count) => panic!("unexpected uniform property format {:?} {}", number_type, component_count), } }