push constants

master
Tom Gowan 6 years ago
parent f3346e48bb
commit 2c5747a52f

@ -62,17 +62,22 @@ unsafe impl PipelineLayoutDesc for FragLayout {
.and_then(|s|s.get(&binding)) .and_then(|s|s.get(&binding))
.map(|desc| { .map(|desc| {
let mut desc = desc.clone(); let mut desc = desc.clone();
dbg!(&self.stages);
desc.stages = self.stages.clone(); desc.stages = self.stages.clone();
desc desc
}) })
} }
fn num_push_constants_ranges(&self) -> usize { fn num_push_constants_ranges(&self) -> usize {
0 self.layout_data.num_constants
} }
fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> { fn push_constants_range(&self, num: usize) -> Option<PipelineLayoutDescPcRange> {
None self.layout_data.pc_ranges.get(num)
.map(|desc| {
let mut desc = desc.clone();
desc.stages = self.stages.clone();
desc
})
} }
} }

@ -1,11 +1,12 @@
use crate::sr; use crate::layouts::*;
use crate::srvk::{SpirvTy,DescriptorDescInfo}; use crate::sr;
use std::borrow::Cow; use crate::srvk::{DescriptorDescInfo, SpirvTy};
use crate::vk::pipeline::shader::ShaderInterfaceDefEntry;
use crate::vk::descriptor::descriptor::*; use crate::vk::descriptor::descriptor::*;
use std::collections::HashMap; use crate::vk::descriptor::pipeline_layout::PipelineLayoutDescPcRange;
use crate::vk::pipeline::shader::ShaderInterfaceDefEntry;
use crate::CompiledShaders; use crate::CompiledShaders;
use crate::layouts::*; use std::borrow::Cow;
use std::collections::HashMap;
pub struct ShaderInterfaces { pub struct ShaderInterfaces {
pub inputs: Vec<ShaderInterfaceDefEntry>, pub inputs: Vec<ShaderInterfaceDefEntry>,
@ -17,27 +18,37 @@ pub struct LayoutData {
pub num_sets: usize, pub num_sets: usize,
pub num_bindings: HashMap<usize, usize>, pub num_bindings: HashMap<usize, usize>,
pub descriptions: HashMap<usize, HashMap<usize, DescriptorDesc>>, pub descriptions: HashMap<usize, HashMap<usize, DescriptorDesc>>,
pub num_constants: usize,
pub pc_ranges: Vec<PipelineLayoutDescPcRange>,
} }
pub fn create_entry(shaders: &CompiledShaders) -> Entry { pub fn create_entry(shaders: &CompiledShaders) -> Entry {
let vertex_interfaces = create_interfaces(&shaders.vertex); let vertex_interfaces = create_interfaces(&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{ inputs: fragment_interfaces.inputs }; let frag_input = FragInput {
let frag_output = FragOutput{ outputs: fragment_interfaces.outputs }; inputs: fragment_interfaces.inputs,
};
let frag_output = FragOutput {
outputs: fragment_interfaces.outputs,
};
let frag_layout = FragLayout { let frag_layout = FragLayout {
stages: ShaderStages { stages: ShaderStages {
fragment: true, fragment: true,
..ShaderStages::none() ..ShaderStages::none()
}, },
layout_data: fragment_layout, layout_data: fragment_layout,
}; };
let vert_input = VertInput{ inputs: vertex_interfaces.inputs }; let vert_input = VertInput {
let vert_output = VertOutput{ outputs: vertex_interfaces.outputs }; inputs: vertex_interfaces.inputs,
};
let vert_output = VertOutput {
outputs: vertex_interfaces.outputs,
};
let vert_layout = VertLayout(ShaderStages { let vert_layout = VertLayout(ShaderStages {
vertex: true, vertex: true,
..ShaderStages::none() ..ShaderStages::none()
}); });
Entry { Entry {
frag_input, frag_input,
frag_output, frag_output,
@ -46,7 +57,6 @@ pub fn create_entry(shaders: &CompiledShaders) -> Entry {
frag_layout, frag_layout,
vert_layout, vert_layout,
} }
} }
fn create_interfaces(data: &[u32]) -> ShaderInterfaces { fn create_interfaces(data: &[u32]) -> ShaderInterfaces {
@ -94,7 +104,8 @@ fn create_interfaces(data: &[u32]) -> ShaderInterfaces {
fn create_layouts(data: &[u32]) -> LayoutData { fn create_layouts(data: &[u32]) -> LayoutData {
sr::ShaderModule::load_u32_data(data) sr::ShaderModule::load_u32_data(data)
.map(|m| { .map(|m| {
m.enumerate_descriptor_sets(None) let (num_sets, num_bindings, descriptions) = m
.enumerate_descriptor_sets(None)
.map(|sets| { .map(|sets| {
let num_sets = sets.len(); let num_sets = sets.len();
let num_bindings = sets let num_bindings = sets
@ -107,9 +118,11 @@ fn create_layouts(data: &[u32]) -> LayoutData {
let descriptions = sets let descriptions = sets
.iter() .iter()
.map(|i| { .map(|i| {
let desc = i.bindings.iter() let desc = i
.bindings
.iter()
.map(|b| { .map(|b| {
let info = DescriptorDescInfo{ let info = DescriptorDescInfo {
descriptor_type: b.descriptor_type, descriptor_type: b.descriptor_type,
image: b.image, image: b.image,
}; };
@ -125,18 +138,35 @@ fn create_layouts(data: &[u32]) -> LayoutData {
}; };
(b.binding as usize, d) (b.binding as usize, d)
}) })
.collect::<HashMap<usize, DescriptorDesc>>(); .collect::<HashMap<usize, DescriptorDesc>>();
(i.set as usize, desc) (i.set as usize, desc)
}) })
.collect::<HashMap<usize, HashMap<usize, DescriptorDesc>>>(); .collect::<HashMap<usize, HashMap<usize, DescriptorDesc>>>();
LayoutData { (num_sets, num_bindings, descriptions)
num_sets,
num_bindings,
descriptions,
}
}) })
.expect("Failed to pass outputs") .expect("Failed to pass descriptors");
let (num_constants, pc_ranges) = m
.enumerate_push_constant_blocks(None)
.map(|constants| {
let num_constants = constants.len();
let pc_ranges = constants
.iter()
.map(|pc| PipelineLayoutDescPcRange {
offset: pc.offset as usize,
size: pc.size as usize,
stages: ShaderStages::all(),
})
.collect::<Vec<PipelineLayoutDescPcRange>>();
(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") .expect("failed to load module")
} }

@ -0,0 +1,11 @@
#version 450
layout(location = 0) out vec4 f_color;
layout(push_constant) uniform PushConstantData {
float time;
} pc;
void main() {
f_color = vec4(pc.time, 0.5, 1.0, 1.0);
}

@ -0,0 +1,10 @@
#version 450
layout(location = 0) in vec2 position;
void main() {
vec2 p = position;
p.x += 0.2;
gl_Position = vec4(p, 0.0, 1.0);
}

@ -5,9 +5,9 @@ use std::borrow::Cow;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use vulkano::descriptor::descriptor::*; use vulkano::descriptor::descriptor::*;
use vulkano::descriptor::pipeline_layout::{PipelineLayoutDesc, PipelineLayoutDescPcRange};
use vulkano::format::*; use vulkano::format::*;
use vulkano::pipeline::shader::ShaderInterfaceDefEntry; use vulkano::pipeline::shader::ShaderInterfaceDefEntry;
use vulkano::descriptor::pipeline_layout::PipelineLayoutDesc;
fn setup() { fn setup() {
color_backtrace::install(); color_backtrace::install();
@ -32,9 +32,9 @@ fn difference(e: &str, t: &str) -> String {
.join("\n") .join("\n")
} }
fn descriptor_layout<T>(desc: &T) -> String fn descriptor_layout<T>(desc: &T) -> String
where where
T: PipelineLayoutDesc, T: PipelineLayoutDesc,
{ {
let num_sets = desc.num_sets(); let num_sets = desc.num_sets();
let mut r = format!("{:?}", num_sets); let mut r = format!("{:?}", num_sets);
@ -68,6 +68,15 @@ where
shade_runner::parse(&shader) shade_runner::parse(&shader)
} }
fn do_test<T>(a: &T, b: &T)
where
T: std::fmt::Debug,
{
let a = format!("{:?}", a);
let b = format!("{:?}", b);
assert_eq!(&a, &b, "\n\nDifference: {}", difference(&a, &b));
}
#[test] #[test]
fn test_shade1() { fn test_shade1() {
setup(); setup();
@ -89,6 +98,8 @@ fn test_shade1() {
num_sets: 0, num_sets: 0,
num_bindings: HashMap::new(), num_bindings: HashMap::new(),
descriptions: HashMap::new(), descriptions: HashMap::new(),
num_constants: 0,
pc_ranges: Vec::new(),
}, },
}, },
vert_input: VertInput { vert_input: VertInput {
@ -107,14 +118,7 @@ fn test_shade1() {
}), }),
}; };
let entry = parse("vert1.glsl", "frag1.glsl"); let entry = parse("vert1.glsl", "frag1.glsl");
let entry = format!("{:?}", entry); do_test(&entry, &target);
let target = format!("{:?}", target);
assert_eq!(
&entry,
&target,
"\n\nDifference: {}",
difference(&entry, &target)
);
} }
#[test] #[test]
@ -156,6 +160,8 @@ fn test_shade2() {
num_sets: 0, num_sets: 0,
num_bindings: HashMap::new(), num_bindings: HashMap::new(),
descriptions: HashMap::new(), descriptions: HashMap::new(),
num_constants: 0,
pc_ranges: Vec::new(),
}, },
}, },
vert_input: VertInput { vert_input: VertInput {
@ -190,14 +196,7 @@ fn test_shade2() {
}), }),
}; };
let entry = parse("vert2.glsl", "frag2.glsl"); let entry = parse("vert2.glsl", "frag2.glsl");
let entry = format!("{:?}", entry); do_test(&entry, &target);
let target = format!("{:?}", target);
assert_eq!(
&entry,
&target,
"\n\nDifference: {}",
difference(&entry, &target)
);
} }
#[test] #[test]
@ -245,6 +244,8 @@ fn test_shade3() {
)] )]
.into_iter() .into_iter()
.collect(), .collect(),
num_constants: 0,
pc_ranges: Vec::new(),
}, },
}, },
vert_input: VertInput { vert_input: VertInput {
@ -267,21 +268,70 @@ fn test_shade3() {
do_test(&entry.frag_output, &target.frag_output); do_test(&entry.frag_output, &target.frag_output);
do_test(&entry.vert_input, &target.vert_input); do_test(&entry.vert_input, &target.vert_input);
do_test(&entry.vert_output, &target.vert_output); do_test(&entry.vert_output, &target.vert_output);
do_test(&descriptor_layout(&entry.frag_layout), &descriptor_layout(&target.frag_layout)); do_test(
do_test(&descriptor_layout(&entry.vert_layout), &descriptor_layout(&target.vert_layout)); &descriptor_layout(&entry.frag_layout),
&descriptor_layout(&target.frag_layout),
);
do_test(
&descriptor_layout(&entry.vert_layout),
&descriptor_layout(&target.vert_layout),
);
} }
fn do_test<T>(a: &T, b: &T) #[test]
where fn test_shade4() {
T: std::fmt::Debug, setup();
{ let target = Entry {
let a = format!("{:?}", a); frag_input: FragInput { inputs: Vec::new() },
let b = format!("{:?}", b); frag_output: FragOutput {
assert_eq!( outputs: vec![ShaderInterfaceDefEntry {
&a, location: 0..1,
&b, format: Format::R32G32B32A32Sfloat,
"\n\nDifference: {}", name: Some(Cow::Borrowed("f_color")),
difference(&a, &b) }],
},
frag_layout: FragLayout {
stages: ShaderStages {
fragment: true,
..ShaderStages::none()
},
layout_data: LayoutData {
num_sets: 0,
num_bindings: HashMap::new(),
descriptions: HashMap::new(),
num_constants: 1,
pc_ranges: vec![PipelineLayoutDescPcRange {
offset: 0,
size: 16,
stages: ShaderStages {
fragment: true,
..ShaderStages::none()
},
}],
},
},
vert_input: VertInput {
inputs: vec![ShaderInterfaceDefEntry {
location: 0..1,
format: Format::R32G32Sfloat,
name: Some(Cow::Borrowed("position")),
}],
},
vert_output: VertOutput {
outputs: Vec::new(),
},
vert_layout: VertLayout(ShaderStages {
vertex: true,
..ShaderStages::none()
}),
};
let entry = parse("vert4.glsl", "frag4.glsl");
do_test(&entry.frag_input, &target.frag_input);
do_test(&entry.frag_output, &target.frag_output);
do_test(&entry.vert_input, &target.vert_input);
do_test(&entry.vert_output, &target.vert_output);
do_test(
&descriptor_layout(&entry.frag_layout),
&descriptor_layout(&target.frag_layout),
); );
} }

Loading…
Cancel
Save