More draft for descriptor sets

This commit is contained in:
Pierre Krieger 2016-02-20 13:05:44 +01:00
parent f4b4f9f8b4
commit 0fe6c0f23d
9 changed files with 162 additions and 44 deletions

View File

@ -1,5 +1,7 @@
# Vulkano
*Warning: this library breaks every five minutes for the moment.*
## [Documentation](http://tomaka.github.io/vulkano/vulkano/index.html)
This repository contains three libraries:

View File

@ -156,7 +156,7 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
format!("({}, ::std::borrow::Cow::Borrowed(\"{}\"))", loc, name)
}).collect::<Vec<_>>().join(", ");
let t = format!("::vulkano::shader::VertexShaderEntryPoint<({input})>",
let t = format!("::vulkano::shader::VertexShaderEntryPoint<({input}), Layout>", // FIXME:
input = input);
let f = format!("vertex_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as *const _), vec![{}])", attributes);
(t, f)
@ -236,7 +236,42 @@ fn write_descriptor_sets(doc: &parse::Spirv) -> String {
};
}
return "".to_owned();
return r#"
#[derive(Default)]
pub struct Set1;
unsafe impl ::vulkano::descriptor_set::DescriptorSetDesc for Set1 {
fn descriptors(&self) -> Vec<::vulkano::descriptor_set::DescriptorDesc> {
vec![
::vulkano::descriptor_set::DescriptorDesc {
binding: 0,
ty: ::vulkano::descriptor_set::DescriptorType::UniformBuffer,
count: 1,
stages: ::vulkano::descriptor_set::ShaderStages::all_graphics(),
}
]
}
}
#[derive(Default)]
pub struct Layout;
unsafe impl ::vulkano::descriptor_set::PipelineLayoutDesc for Layout {
type DescriptorSets = ::std::sync::Arc<::vulkano::descriptor_set::DescriptorSet<Set1>>;
type DescriptorSetLayouts = ::std::sync::Arc<::vulkano::descriptor_set::DescriptorSetLayout<Set1>>;
type PushConstants = ();
fn decode_descriptor_set_layouts(&self, layouts: Self::DescriptorSetLayouts)
-> Vec<::std::sync::Arc<::vulkano::descriptor_set::AbstractDescriptorSetLayout>>
{
vec![
layouts
]
}
}
"#.to_owned();
}
fn type_from_id(doc: &parse::Spirv, searched: u32) -> String {

View File

@ -87,7 +87,19 @@ fn main() {
}
}.unwrap();
let pipeline: Arc<vulkano::pipeline::GraphicsPipeline<Arc<vulkano::buffer::Buffer<[Vertex; 3], _>>>> = {
let descriptor_pool = vulkano::descriptor_set::DescriptorPool::new(&device).unwrap();
let (pipeline_layout, set) = {
let layout1 = vulkano::descriptor_set::DescriptorSetLayout::new(&device, Default::default()).unwrap();
let pipeline_layout = vulkano::descriptor_set::PipelineLayout::new(&device, Default::default(), layout1.clone()).unwrap();
let set1 = vulkano::descriptor_set::DescriptorSet::new(&descriptor_pool, &layout1).unwrap();
(pipeline_layout, set1)
};
let pipeline: Arc<vulkano::pipeline::GraphicsPipeline<Arc<vulkano::buffer::Buffer<[Vertex; 3], _>>, _>> = {
let ia = vulkano::pipeline::input_assembly::InputAssembly {
topology: vulkano::pipeline::input_assembly::PrimitiveTopology::TriangleList,
primitive_restart_enable: false,
@ -116,13 +128,16 @@ fn main() {
vulkano::pipeline::GraphicsPipeline::new(&device, &vs.main_entry_point(), &ia, &viewports,
&raster, &ms, &blend, &fs.main_entry_point(),
&renderpass.subpass(0).unwrap()).unwrap()
&pipeline_layout, &renderpass.subpass(0).unwrap())
.unwrap()
};
let framebuffers = images.iter().map(|image| {
vulkano::framebuffer::Framebuffer::new(&renderpass, (1244, 699, 1), image).unwrap()
}).collect::<Vec<_>>();
let command_buffers = framebuffers.iter().map(|framebuffer| {
vulkano::command_buffer::PrimaryCommandBufferBuilder::new(&cb_pool).unwrap()
.draw_inline(&renderpass, &framebuffer, [0.0, 0.0, 1.0, 1.0])

View File

@ -5,6 +5,10 @@
layout(location = 0) in vec2 position;
uniform Data {
mat4 worldview;
} uniforms;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
gl_Position = uniforms.worldview * vec4(position, 0.0, 1.0);
}

View File

@ -262,7 +262,7 @@ impl InnerCommandBufferBuilder {
/// Calls `vkCmdDraw`.
// FIXME: push constants
pub unsafe fn draw<V: 'static>(mut self, pipeline: &Arc<GraphicsPipeline<V>>,
pub unsafe fn draw<V: 'static, L: 'static>(mut self, pipeline: &Arc<GraphicsPipeline<V, L>>,
vertices: V, dynamic: &DynamicState) -> InnerCommandBufferBuilder
where V: MultiVertex
{
@ -284,7 +284,7 @@ impl InnerCommandBufferBuilder {
self
}
fn bind_gfx_pipeline_state<V: 'static>(&mut self, pipeline: &Arc<GraphicsPipeline<V>>,
fn bind_gfx_pipeline_state<V: 'static, L: 'static>(&mut self, pipeline: &Arc<GraphicsPipeline<V, L>>,
dynamic: &DynamicState)
{
let vk = self.device.pointers();

View File

@ -197,9 +197,9 @@ pub struct PrimaryCommandBufferBuilderInlineDraw {
impl PrimaryCommandBufferBuilderInlineDraw {
/// Calls `vkCmdDraw`.
// FIXME: push constants
pub fn draw<V>(self, pipeline: &Arc<GraphicsPipeline<V>>,
vertices: V, dynamic: &DynamicState) -> PrimaryCommandBufferBuilderInlineDraw
where V: MultiVertex + 'static
pub fn draw<V, L>(self, pipeline: &Arc<GraphicsPipeline<V, L>>,
vertices: V, dynamic: &DynamicState) -> PrimaryCommandBufferBuilderInlineDraw
where V: MultiVertex + 'static, L: 'static
{
unsafe {
PrimaryCommandBufferBuilderInlineDraw {

View File

@ -16,6 +16,9 @@
//!
//!
// FIXME: all destructors are missing
use std::mem;
use std::ptr;
use std::sync::Arc;
@ -93,6 +96,34 @@ pub struct ShaderStages {
pub compute: bool,
}
impl ShaderStages {
/// Creates a `ShaderStages` struct will all graphics stages set to `true`.
#[inline]
pub fn all_graphics() -> ShaderStages {
ShaderStages {
vertex: true,
tessellation_control: true,
tessellation_evaluation: true,
geometry: true,
fragment: true,
compute: false,
}
}
/// Creates a `ShaderStages` struct will the compute stage set to `true`.
#[inline]
pub fn compute() -> ShaderStages {
ShaderStages {
vertex: false,
tessellation_control: false,
tessellation_evaluation: false,
geometry: false,
fragment: false,
compute: true,
}
}
}
impl Into<vk::ShaderStageFlags> for ShaderStages {
#[inline]
fn into(self) -> vk::ShaderStageFlags {
@ -313,8 +344,51 @@ impl<P> PipelineLayout<P> where P: PipelineLayoutDesc {
}
}
impl<P> VulkanObject for PipelineLayout<P> {
type Object = vk::PipelineLayout;
#[inline]
fn internal_object(&self) -> vk::PipelineLayout {
self.layout
}
}
pub struct DescriptorPool {
pool: vk::DescriptorPool,
device: Arc<Device>,
}
impl DescriptorPool {
pub fn new(device: &Arc<Device>) -> Result<Arc<DescriptorPool>, OomError> {
let vk = device.pointers();
// FIXME: arbitrary
let pool_sizes = vec![
vk::DescriptorPoolSize {
ty: vk::DESCRIPTOR_TYPE_UNIFORM_BUFFER,
descriptorCount: 10,
}
];
let pool = unsafe {
let infos = vk::DescriptorPoolCreateInfo {
sType: vk::STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
pNext: ptr::null(),
flags: 0, // TODO:
maxSets: 100, // TODO: let user choose
poolSizeCount: pool_sizes.len() as u32,
pPoolSizes: pool_sizes.as_ptr(),
};
let mut output = mem::uninitialized();
try!(check_errors(vk.CreateDescriptorPool(device.internal_object(), &infos,
ptr::null(), &mut output)));
output
};
Ok(Arc::new(DescriptorPool {
pool: pool,
device: device.clone(),
}))
}
}

View File

@ -4,6 +4,8 @@ use std::ptr;
use std::sync::Arc;
use device::Device;
use descriptor_set::PipelineLayout;
use descriptor_set::PipelineLayoutDesc;
use framebuffer::Subpass;
use shader::FragmentShaderEntryPoint;
use shader::VertexShaderEntryPoint;
@ -26,9 +28,10 @@ use pipeline::viewport::ViewportsState;
///
/// The template parameter contains the descriptor set to use with this pipeline, and the
/// renderpass layout.
pub struct GraphicsPipeline<MultiVertex> {
pub struct GraphicsPipeline<MultiVertex, Layout> {
device: Arc<Device>,
pipeline: vk::Pipeline,
layout: Arc<PipelineLayout<Layout>>,
dynamic_line_width: bool,
dynamic_viewport: bool,
@ -39,8 +42,8 @@ pub struct GraphicsPipeline<MultiVertex> {
marker: PhantomData<(MultiVertex,)>
}
impl<MV> GraphicsPipeline<MV>
where MV: MultiVertex
impl<MV, L> GraphicsPipeline<MV, L>
where MV: MultiVertex, L: PipelineLayoutDesc
{
/// Builds a new graphics pipeline object.
///
@ -51,11 +54,12 @@ impl<MV> GraphicsPipeline<MV>
/// - Panicks if the `sample_shading` parameter of `multisample` is not between 0.0 and 1.0.
///
// TODO: check all the device's limits
pub fn new<V, F, R>(device: &Arc<Device>, vertex_shader: &VertexShaderEntryPoint<V>,
pub fn new<V, F, R>(device: &Arc<Device>, vertex_shader: &VertexShaderEntryPoint<V, L>,
input_assembly: &InputAssembly, viewport: &ViewportsState,
raster: &Rasterization, multisample: &Multisample, blend: &Blend,
fragment_shader: &FragmentShaderEntryPoint<F>, render_pass: &Subpass<R>)
-> Result<Arc<GraphicsPipeline<MV>>, OomError>
fragment_shader: &FragmentShaderEntryPoint<F>,
layout: &Arc<PipelineLayout<L>>, render_pass: &Subpass<R>)
-> Result<Arc<GraphicsPipeline<MV, L>>, OomError>
{
let vk = device.pointers();
@ -250,23 +254,6 @@ impl<MV> GraphicsPipeline<MV>
pDynamicStates: dynamic_states.as_ptr(),
};
// FIXME: hack with leaking pipeline layout
let layout = {
let infos = vk::PipelineLayoutCreateInfo {
sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
pNext: ptr::null(),
flags: 0,
setLayoutCount: 0,
pSetLayouts: ptr::null(),
pushConstantRangeCount: 0,
pPushConstantRanges: ptr::null(),
};
let mut out = mem::uninitialized();
try!(check_errors(vk.CreatePipelineLayout(device.internal_object(), &infos,
ptr::null(), &mut out)));
out
};
let infos = vk::GraphicsPipelineCreateInfo {
sType: vk::STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
pNext: ptr::null(),
@ -282,7 +269,7 @@ impl<MV> GraphicsPipeline<MV>
pDepthStencilState: &depth_stencil,
pColorBlendState: &blend,
pDynamicState: &dynamic_states,
layout: layout, // FIXME:
layout: layout.internal_object(),
renderPass: render_pass.renderpass().internal_object(),
subpass: render_pass.index(),
basePipelineHandle: 0, // TODO:
@ -298,6 +285,7 @@ impl<MV> GraphicsPipeline<MV>
Ok(Arc::new(GraphicsPipeline {
device: device.clone(),
pipeline: pipeline,
layout: layout.clone(),
dynamic_line_width: raster.line_width.is_none(),
dynamic_viewport: viewport.dynamic_viewports(),
@ -310,7 +298,7 @@ impl<MV> GraphicsPipeline<MV>
}
}
impl<MultiVertex> GraphicsPipeline<MultiVertex> {
impl<MultiVertex, Layout> GraphicsPipeline<MultiVertex, Layout> {
/// Returns true if the line width used by this pipeline is dynamic.
#[inline]
pub fn has_dynamic_line_width(&self) -> bool {
@ -318,10 +306,10 @@ impl<MultiVertex> GraphicsPipeline<MultiVertex> {
}
}
impl<MultiVertex> GenericPipeline for GraphicsPipeline<MultiVertex> {
impl<MultiVertex, Layout> GenericPipeline for GraphicsPipeline<MultiVertex, Layout> {
}
impl<MultiVertex> VulkanObject for GraphicsPipeline<MultiVertex> {
impl<MultiVertex, Layout> VulkanObject for GraphicsPipeline<MultiVertex, Layout> {
type Object = vk::Pipeline;
#[inline]
@ -330,7 +318,7 @@ impl<MultiVertex> VulkanObject for GraphicsPipeline<MultiVertex> {
}
}
impl<MultiVertex> Drop for GraphicsPipeline<MultiVertex> {
impl<MultiVertex, Layout> Drop for GraphicsPipeline<MultiVertex, Layout> {
#[inline]
fn drop(&mut self) {
unsafe {

View File

@ -58,9 +58,9 @@ impl ShaderModule {
}))
}
pub unsafe fn vertex_shader_entry_point<'a, V>(&'a self, name: &'a CStr,
attributes: Vec<(u32, Cow<'static, str>)>)
-> VertexShaderEntryPoint<'a, V>
pub unsafe fn vertex_shader_entry_point<'a, V, L>(&'a self, name: &'a CStr,
attributes: Vec<(u32, Cow<'static, str>)>)
-> VertexShaderEntryPoint<'a, V, L>
{
VertexShaderEntryPoint {
module: self,
@ -112,14 +112,14 @@ impl Drop for ShaderModule {
}
}
pub struct VertexShaderEntryPoint<'a, V> {
pub struct VertexShaderEntryPoint<'a, V, L> {
module: &'a ShaderModule,
name: &'a CStr,
marker: PhantomData<V>,
marker: PhantomData<(V, L)>,
attributes: Vec<(u32, Cow<'static, str>)>,
}
impl<'a, V> VertexShaderEntryPoint<'a, V> {
impl<'a, V, L> VertexShaderEntryPoint<'a, V, L> {
#[inline]
pub fn module(&self) -> &'a ShaderModule {
self.module