render: Add AsBindableDescriptorSet
This commit is contained in:
parent
b7bc6478e2
commit
5539381f46
4 changed files with 115 additions and 47 deletions
|
@ -1,4 +1,25 @@
|
||||||
|
use std::{collections::BTreeMap, sync::Arc};
|
||||||
|
|
||||||
|
use vulkano::{
|
||||||
|
Validated, VulkanError,
|
||||||
|
descriptor_set::{
|
||||||
|
DescriptorSet,
|
||||||
|
allocator::StandardDescriptorSetAllocator,
|
||||||
|
layout::{DescriptorSetLayout, DescriptorSetLayoutBinding},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
pub mod mvp;
|
pub mod mvp;
|
||||||
pub mod transform;
|
pub mod transform;
|
||||||
pub mod vertex;
|
pub mod vertex;
|
||||||
|
|
||||||
|
pub trait AsBindableDescriptorSet<T> {
|
||||||
|
fn as_descriptor_set_layout_bindings() -> BTreeMap<u32, DescriptorSetLayoutBinding>;
|
||||||
|
|
||||||
|
fn as_descriptor_set(
|
||||||
|
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
||||||
|
layout: &Arc<DescriptorSetLayout>,
|
||||||
|
data: &T,
|
||||||
|
) -> Result<Arc<DescriptorSet>, Validated<VulkanError>>;
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
|
use std::collections::BTreeMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use vulkano::Validated;
|
|
||||||
use vulkano::buffer::{
|
use vulkano::buffer::{
|
||||||
AllocateBufferError, Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer,
|
AllocateBufferError, Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer,
|
||||||
};
|
};
|
||||||
|
use vulkano::descriptor_set::allocator::StandardDescriptorSetAllocator;
|
||||||
|
use vulkano::descriptor_set::layout::{
|
||||||
|
DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorType,
|
||||||
|
};
|
||||||
|
use vulkano::descriptor_set::{DescriptorSet, WriteDescriptorSet};
|
||||||
use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator};
|
use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator};
|
||||||
|
use vulkano::shader::ShaderStages;
|
||||||
|
use vulkano::{Validated, VulkanError};
|
||||||
|
|
||||||
|
use crate::core::render::primitives::AsBindableDescriptorSet;
|
||||||
|
|
||||||
#[derive(BufferContents, Clone, Copy)]
|
#[derive(BufferContents, Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -34,3 +43,28 @@ impl Mvp {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsBindableDescriptorSet<Subbuffer<[Mvp]>> for Mvp {
|
||||||
|
fn as_descriptor_set_layout_bindings() -> BTreeMap<u32, DescriptorSetLayoutBinding> {
|
||||||
|
BTreeMap::<u32, DescriptorSetLayoutBinding>::from_iter([(
|
||||||
|
0,
|
||||||
|
DescriptorSetLayoutBinding {
|
||||||
|
stages: ShaderStages::VERTEX,
|
||||||
|
..DescriptorSetLayoutBinding::descriptor_type(DescriptorType::UniformBuffer)
|
||||||
|
},
|
||||||
|
)])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_descriptor_set(
|
||||||
|
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
||||||
|
layout: &Arc<DescriptorSetLayout>,
|
||||||
|
data: &Subbuffer<[Mvp]>,
|
||||||
|
) -> Result<Arc<DescriptorSet>, Validated<VulkanError>> {
|
||||||
|
DescriptorSet::new(
|
||||||
|
descriptor_set_allocator.clone(),
|
||||||
|
layout.clone(),
|
||||||
|
[WriteDescriptorSet::buffer(0, data.clone())],
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
use std::{path::Path, sync::Arc};
|
use std::{collections::BTreeMap, error::Error, sync::Arc};
|
||||||
|
|
||||||
use anyhow::Error;
|
use image::DynamicImage;
|
||||||
use image::{DynamicImage, EncodableLayout};
|
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
|
Validated, VulkanError,
|
||||||
buffer::{Buffer, BufferCreateInfo, BufferUsage},
|
buffer::{Buffer, BufferCreateInfo, BufferUsage},
|
||||||
command_buffer::{AutoCommandBufferBuilder, CopyBufferToImageInfo, PrimaryAutoCommandBuffer},
|
command_buffer::{AutoCommandBufferBuilder, CopyBufferToImageInfo, PrimaryAutoCommandBuffer},
|
||||||
|
descriptor_set::{
|
||||||
|
DescriptorSet, WriteDescriptorSet,
|
||||||
|
allocator::StandardDescriptorSetAllocator,
|
||||||
|
layout::{DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorType},
|
||||||
|
},
|
||||||
device::Device,
|
device::Device,
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
|
@ -13,8 +18,11 @@ use vulkano::{
|
||||||
view::ImageView,
|
view::ImageView,
|
||||||
},
|
},
|
||||||
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
|
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
|
||||||
|
shader::ShaderStages,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::core::render::primitives::AsBindableDescriptorSet;
|
||||||
|
|
||||||
pub struct Texture {
|
pub struct Texture {
|
||||||
texture: Arc<ImageView>,
|
texture: Arc<ImageView>,
|
||||||
sampler: Arc<Sampler>,
|
sampler: Arc<Sampler>,
|
||||||
|
@ -30,7 +38,7 @@ impl Texture {
|
||||||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||||
path: &str,
|
path: &str,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Box<dyn Error>> {
|
||||||
let _span = tracing::info_span!("texture_load_from_file", path = path);
|
let _span = tracing::info_span!("texture_load_from_file", path = path);
|
||||||
|
|
||||||
let bytes = std::fs::read(path)?;
|
let bytes = std::fs::read(path)?;
|
||||||
|
@ -42,7 +50,7 @@ impl Texture {
|
||||||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Box<dyn Error>> {
|
||||||
let image = image::load_from_memory(bytes)?;
|
let image = image::load_from_memory(bytes)?;
|
||||||
Self::from_dynamic_image(device, memory_allocator, builder, image)
|
Self::from_dynamic_image(device, memory_allocator, builder, image)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +60,7 @@ impl Texture {
|
||||||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||||
image: DynamicImage,
|
image: DynamicImage,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Box<dyn Error>> {
|
||||||
let _span = tracing::info_span!("texture_from_dynamic_image");
|
let _span = tracing::info_span!("texture_from_dynamic_image");
|
||||||
|
|
||||||
let image_data = image.to_rgba8();
|
let image_data = image.to_rgba8();
|
||||||
|
@ -121,3 +129,40 @@ impl Texture {
|
||||||
&self.sampler
|
&self.sampler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsBindableDescriptorSet<Texture> for Texture {
|
||||||
|
fn as_descriptor_set_layout_bindings() -> BTreeMap<u32, DescriptorSetLayoutBinding> {
|
||||||
|
BTreeMap::<u32, DescriptorSetLayoutBinding>::from_iter([
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
DescriptorSetLayoutBinding {
|
||||||
|
stages: ShaderStages::FRAGMENT,
|
||||||
|
..DescriptorSetLayoutBinding::descriptor_type(DescriptorType::Sampler)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
1,
|
||||||
|
DescriptorSetLayoutBinding {
|
||||||
|
stages: ShaderStages::FRAGMENT,
|
||||||
|
..DescriptorSetLayoutBinding::descriptor_type(DescriptorType::SampledImage)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_descriptor_set(
|
||||||
|
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
||||||
|
layout: &Arc<DescriptorSetLayout>,
|
||||||
|
data: &Texture,
|
||||||
|
) -> Result<Arc<DescriptorSet>, Validated<VulkanError>> {
|
||||||
|
DescriptorSet::new(
|
||||||
|
descriptor_set_allocator.clone(),
|
||||||
|
layout.clone(),
|
||||||
|
[
|
||||||
|
WriteDescriptorSet::sampler(0, data.sampler.clone()),
|
||||||
|
WriteDescriptorSet::image_view(1, data.texture.clone()),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ use vulkano::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::core::render::{
|
use crate::core::render::{
|
||||||
primitives::{mvp::Mvp, transform::TransformRaw, vertex::Vertex3D},
|
primitives::{AsBindableDescriptorSet, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,29 +130,8 @@ impl Square {
|
||||||
PipelineShaderStageCreateInfo::new(fs),
|
PipelineShaderStageCreateInfo::new(fs),
|
||||||
];
|
];
|
||||||
|
|
||||||
let vertex_bindings = BTreeMap::<u32, DescriptorSetLayoutBinding>::from_iter([(
|
let vertex_bindings = Mvp::as_descriptor_set_layout_bindings();
|
||||||
0,
|
let texture_bindings = Texture::as_descriptor_set_layout_bindings();
|
||||||
DescriptorSetLayoutBinding {
|
|
||||||
stages: ShaderStages::VERTEX,
|
|
||||||
..DescriptorSetLayoutBinding::descriptor_type(DescriptorType::UniformBuffer)
|
|
||||||
},
|
|
||||||
)]);
|
|
||||||
let fragment_bindings = BTreeMap::<u32, DescriptorSetLayoutBinding>::from_iter([
|
|
||||||
(
|
|
||||||
0,
|
|
||||||
DescriptorSetLayoutBinding {
|
|
||||||
stages: ShaderStages::FRAGMENT,
|
|
||||||
..DescriptorSetLayoutBinding::descriptor_type(DescriptorType::Sampler)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
1,
|
|
||||||
DescriptorSetLayoutBinding {
|
|
||||||
stages: ShaderStages::FRAGMENT,
|
|
||||||
..DescriptorSetLayoutBinding::descriptor_type(DescriptorType::SampledImage)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
let vertex_descriptor_set_layout = DescriptorSetLayoutCreateInfo {
|
let vertex_descriptor_set_layout = DescriptorSetLayoutCreateInfo {
|
||||||
bindings: vertex_bindings,
|
bindings: vertex_bindings,
|
||||||
|
@ -160,7 +139,7 @@ impl Square {
|
||||||
};
|
};
|
||||||
|
|
||||||
let fragment_descriptor_set_layout = DescriptorSetLayoutCreateInfo {
|
let fragment_descriptor_set_layout = DescriptorSetLayoutCreateInfo {
|
||||||
bindings: fragment_bindings,
|
bindings: texture_bindings,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -220,22 +199,11 @@ impl Square {
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let layouts = self.pipeline.layout().set_layouts();
|
let layouts = self.pipeline.layout().set_layouts();
|
||||||
|
|
||||||
let uniform_descriptor_set = DescriptorSet::new(
|
let uniform_descriptor_set =
|
||||||
descriptor_set_allocator.clone(),
|
Mvp::as_descriptor_set(descriptor_set_allocator, &layouts[0], mvp_uniform)?;
|
||||||
layouts[0].clone(),
|
|
||||||
[WriteDescriptorSet::buffer(0, mvp_uniform.clone())],
|
|
||||||
[],
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let texture_descriptor_set = DescriptorSet::new(
|
let texture_descriptor_set =
|
||||||
descriptor_set_allocator.clone(),
|
Texture::as_descriptor_set(descriptor_set_allocator, &layouts[1], texture)?;
|
||||||
layouts[1].clone(),
|
|
||||||
[
|
|
||||||
WriteDescriptorSet::sampler(0, texture.get_sampler().clone()),
|
|
||||||
WriteDescriptorSet::image_view(1, texture.get_texture().clone()),
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
)?;
|
|
||||||
|
|
||||||
command_buffer.bind_pipeline_graphics(self.pipeline.clone())?;
|
command_buffer.bind_pipeline_graphics(self.pipeline.clone())?;
|
||||||
command_buffer.bind_descriptor_sets(
|
command_buffer.bind_descriptor_sets(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue