|
|
@ -1,3 +1,4 @@
|
|
|
|
|
|
|
|
use crate::error::Error;
|
|
|
|
use crate::layouts::*;
|
|
|
|
use crate::layouts::*;
|
|
|
|
use crate::sr;
|
|
|
|
use crate::sr;
|
|
|
|
use crate::srvk::{DescriptorDescInfo, SpirvTy};
|
|
|
|
use crate::srvk::{DescriptorDescInfo, SpirvTy};
|
|
|
@ -7,6 +8,7 @@ use crate::vk::pipeline::shader::ShaderInterfaceDefEntry;
|
|
|
|
use crate::CompiledShaders;
|
|
|
|
use crate::CompiledShaders;
|
|
|
|
use std::borrow::Cow;
|
|
|
|
use std::borrow::Cow;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
use std::convert::TryFrom;
|
|
|
|
|
|
|
|
|
|
|
|
pub struct ShaderInterfaces {
|
|
|
|
pub struct ShaderInterfaces {
|
|
|
|
pub inputs: Vec<ShaderInterfaceDefEntry>,
|
|
|
|
pub inputs: Vec<ShaderInterfaceDefEntry>,
|
|
|
@ -22,11 +24,11 @@ pub struct LayoutData {
|
|
|
|
pub pc_ranges: Vec<PipelineLayoutDescPcRange>,
|
|
|
|
pub pc_ranges: Vec<PipelineLayoutDescPcRange>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn create_entry(shaders: &CompiledShaders) -> Entry {
|
|
|
|
pub fn create_entry(shaders: &CompiledShaders) -> Result<Entry, Error> {
|
|
|
|
let vertex_interfaces = create_interfaces(&shaders.vertex);
|
|
|
|
let vertex_interfaces = create_interfaces(&shaders.vertex)?;
|
|
|
|
let vertex_layout = create_layouts(&shaders.vertex);
|
|
|
|
let vertex_layout = create_layouts(&shaders.vertex)?;
|
|
|
|
let fragment_interfaces = create_interfaces(&shaders.fragment);
|
|
|
|
let fragment_interfaces = create_interfaces(&shaders.fragment)?;
|
|
|
|
let fragment_layout = create_layouts(&shaders.fragment);
|
|
|
|
let fragment_layout = create_layouts(&shaders.fragment)?;
|
|
|
|
let frag_input = FragInput {
|
|
|
|
let frag_input = FragInput {
|
|
|
|
inputs: fragment_interfaces.inputs,
|
|
|
|
inputs: fragment_interfaces.inputs,
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -53,71 +55,70 @@ pub fn create_entry(shaders: &CompiledShaders) -> Entry {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
layout_data: vertex_layout,
|
|
|
|
layout_data: vertex_layout,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
Entry {
|
|
|
|
Ok(Entry {
|
|
|
|
frag_input,
|
|
|
|
frag_input,
|
|
|
|
frag_output,
|
|
|
|
frag_output,
|
|
|
|
vert_input,
|
|
|
|
vert_input,
|
|
|
|
vert_output,
|
|
|
|
vert_output,
|
|
|
|
frag_layout,
|
|
|
|
frag_layout,
|
|
|
|
vert_layout,
|
|
|
|
vert_layout,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn create_interfaces(data: &[u32]) -> ShaderInterfaces {
|
|
|
|
fn create_interfaces(data: &[u32]) -> Result<ShaderInterfaces, Error> {
|
|
|
|
sr::ShaderModule::load_u32_data(data)
|
|
|
|
sr::ShaderModule::load_u32_data(data)
|
|
|
|
|
|
|
|
.map_err(|e| Error::LoadingData(e.to_string()))
|
|
|
|
.map(|m| {
|
|
|
|
.map(|m| {
|
|
|
|
let inputs = m
|
|
|
|
let inputs = m
|
|
|
|
.enumerate_input_variables(None)
|
|
|
|
.enumerate_input_variables(None)
|
|
|
|
.map(|inputs| {
|
|
|
|
.map_err(|e| Error::LoadingData(e.to_string()))
|
|
|
|
|
|
|
|
.and_then(|inputs| {
|
|
|
|
inputs
|
|
|
|
inputs
|
|
|
|
.iter()
|
|
|
|
.iter()
|
|
|
|
.filter(|i| {
|
|
|
|
.filter(|i| {
|
|
|
|
!i.decoration_flags
|
|
|
|
!i.decoration_flags
|
|
|
|
.contains(sr::types::ReflectDecorationFlags::BUILT_IN)
|
|
|
|
.contains(sr::types::ReflectDecorationFlags::BUILT_IN)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.map(|i| ShaderInterfaceDefEntry {
|
|
|
|
.map(|i| Ok(ShaderInterfaceDefEntry {
|
|
|
|
location: i.location..(i.location + 1),
|
|
|
|
location: i.location..(i.location + 1),
|
|
|
|
format: SpirvTy::from(i.format).inner(),
|
|
|
|
format: SpirvTy::try_from(i.format)?.inner(),
|
|
|
|
name: Some(Cow::from(i.name.clone())),
|
|
|
|
name: Some(Cow::from(i.name.clone())),
|
|
|
|
})
|
|
|
|
}))
|
|
|
|
.collect::<Vec<ShaderInterfaceDefEntry>>()
|
|
|
|
.collect::<Result<Vec<ShaderInterfaceDefEntry>, _>>()
|
|
|
|
})
|
|
|
|
});
|
|
|
|
.expect("Failed to pass inputs");
|
|
|
|
|
|
|
|
let outputs = m
|
|
|
|
let outputs = m
|
|
|
|
.enumerate_output_variables(None)
|
|
|
|
.enumerate_output_variables(None)
|
|
|
|
.map(|outputs| {
|
|
|
|
.map_err(|e| Error::LoadingData(e.to_string()))
|
|
|
|
|
|
|
|
.and_then(|outputs| {
|
|
|
|
outputs
|
|
|
|
outputs
|
|
|
|
.iter()
|
|
|
|
.iter()
|
|
|
|
.filter(|i| {
|
|
|
|
.filter(|i| {
|
|
|
|
!i.decoration_flags
|
|
|
|
!i.decoration_flags
|
|
|
|
.contains(sr::types::ReflectDecorationFlags::BUILT_IN)
|
|
|
|
.contains(sr::types::ReflectDecorationFlags::BUILT_IN)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.map(|i| ShaderInterfaceDefEntry {
|
|
|
|
.map(|i| Ok(ShaderInterfaceDefEntry {
|
|
|
|
location: i.location..(i.location + 1),
|
|
|
|
location: i.location..(i.location + 1),
|
|
|
|
format: SpirvTy::from(i.format).inner(),
|
|
|
|
format: SpirvTy::try_from(i.format)?.inner(),
|
|
|
|
name: Some(Cow::from(i.name.clone())),
|
|
|
|
name: Some(Cow::from(i.name.clone())),
|
|
|
|
})
|
|
|
|
}))
|
|
|
|
.collect::<Vec<ShaderInterfaceDefEntry>>()
|
|
|
|
.collect::<Result<Vec<ShaderInterfaceDefEntry>, _>>()
|
|
|
|
})
|
|
|
|
});
|
|
|
|
.expect("Failed to pass outputs");
|
|
|
|
inputs.and_then(|inputs| outputs.map(|outputs| ShaderInterfaces { inputs, outputs } ))
|
|
|
|
ShaderInterfaces { inputs, outputs }
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.expect("failed to load module")
|
|
|
|
.and_then(|t| t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn create_layouts(data: &[u32]) -> LayoutData {
|
|
|
|
fn create_layouts(data: &[u32]) -> Result<LayoutData, Error> {
|
|
|
|
sr::ShaderModule::load_u32_data(data)
|
|
|
|
sr::ShaderModule::load_u32_data(data)
|
|
|
|
.map(|m| {
|
|
|
|
.map(|m| {
|
|
|
|
let (num_sets, num_bindings, descriptions) = m
|
|
|
|
let descs: Result<_, Error> = m
|
|
|
|
.enumerate_descriptor_sets(None)
|
|
|
|
.enumerate_descriptor_sets(None)
|
|
|
|
.map(|sets| {
|
|
|
|
.map_err(|e| Error::LoadingData(e.to_string()))
|
|
|
|
|
|
|
|
.and_then(|sets| {
|
|
|
|
let num_sets = sets.len();
|
|
|
|
let num_sets = sets.len();
|
|
|
|
let num_bindings = sets
|
|
|
|
let num_bindings = sets
|
|
|
|
.iter()
|
|
|
|
.iter()
|
|
|
|
.map(|i| {
|
|
|
|
.map(|i| (i.set as usize, i.bindings.len()))
|
|
|
|
dbg!(&i);
|
|
|
|
|
|
|
|
(i.set as usize, i.bindings.len())
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.collect::<HashMap<usize, usize>>();
|
|
|
|
.collect::<HashMap<usize, usize>>();
|
|
|
|
let descriptions = sets
|
|
|
|
let descriptions = sets
|
|
|
|
.iter()
|
|
|
|
.iter()
|
|
|
@ -130,7 +131,7 @@ fn create_layouts(data: &[u32]) -> LayoutData {
|
|
|
|
descriptor_type: b.descriptor_type,
|
|
|
|
descriptor_type: b.descriptor_type,
|
|
|
|
image: b.image,
|
|
|
|
image: b.image,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let ty = SpirvTy::<DescriptorDescTy>::from(info).inner();
|
|
|
|
let ty = SpirvTy::<DescriptorDescTy>::try_from(info)?.inner();
|
|
|
|
let stages = ShaderStages::none();
|
|
|
|
let stages = ShaderStages::none();
|
|
|
|
let d = DescriptorDesc {
|
|
|
|
let d = DescriptorDesc {
|
|
|
|
ty,
|
|
|
|
ty,
|
|
|
@ -140,17 +141,17 @@ fn create_layouts(data: &[u32]) -> LayoutData {
|
|
|
|
// it's correct
|
|
|
|
// it's correct
|
|
|
|
readonly: true,
|
|
|
|
readonly: true,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
(b.binding as usize, d)
|
|
|
|
Ok((b.binding as usize, d))
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.collect::<HashMap<usize, DescriptorDesc>>();
|
|
|
|
.collect::<Result<HashMap<usize, DescriptorDesc>, Error>>();
|
|
|
|
(i.set as usize, desc)
|
|
|
|
desc.and_then(|d| Ok((i.set as usize, d)))
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.collect::<HashMap<usize, HashMap<usize, DescriptorDesc>>>();
|
|
|
|
.collect::<Result<HashMap<usize, _>, Error>>();
|
|
|
|
(num_sets, num_bindings, descriptions)
|
|
|
|
descriptions.map(|d| (num_sets, num_bindings, d))
|
|
|
|
})
|
|
|
|
});
|
|
|
|
.expect("Failed to pass descriptors");
|
|
|
|
let pcs = m
|
|
|
|
let (num_constants, pc_ranges) = m
|
|
|
|
|
|
|
|
.enumerate_push_constant_blocks(None)
|
|
|
|
.enumerate_push_constant_blocks(None)
|
|
|
|
|
|
|
|
.map_err(|e| Error::LoadingData(e.to_string()))
|
|
|
|
.map(|constants| {
|
|
|
|
.map(|constants| {
|
|
|
|
let num_constants = constants.len();
|
|
|
|
let num_constants = constants.len();
|
|
|
|
let pc_ranges = constants
|
|
|
|
let pc_ranges = constants
|
|
|
@ -162,15 +163,17 @@ fn create_layouts(data: &[u32]) -> LayoutData {
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.collect::<Vec<PipelineLayoutDescPcRange>>();
|
|
|
|
.collect::<Vec<PipelineLayoutDescPcRange>>();
|
|
|
|
(num_constants, pc_ranges)
|
|
|
|
(num_constants, pc_ranges)
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
descs.and_then(|(num_sets, num_bindings, descriptions)| {
|
|
|
|
|
|
|
|
pcs.map(|(num_constants, pc_ranges)| LayoutData {
|
|
|
|
|
|
|
|
num_sets,
|
|
|
|
|
|
|
|
num_bindings,
|
|
|
|
|
|
|
|
descriptions,
|
|
|
|
|
|
|
|
num_constants,
|
|
|
|
|
|
|
|
pc_ranges,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.expect("Failed to pass push constants");
|
|
|
|
})
|
|
|
|
LayoutData {
|
|
|
|
|
|
|
|
num_sets,
|
|
|
|
|
|
|
|
num_bindings,
|
|
|
|
|
|
|
|
descriptions,
|
|
|
|
|
|
|
|
num_constants,
|
|
|
|
|
|
|
|
pc_ranges,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.expect("failed to load module")
|
|
|
|
.map_err(|e| Error::LoadingData(e.to_string()))
|
|
|
|
|
|
|
|
.and_then(|t| t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|