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

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