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 mvp;
|
||||
pub mod transform;
|
||||
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 vulkano::Validated;
|
||||
use vulkano::buffer::{
|
||||
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::shader::ShaderStages;
|
||||
use vulkano::{Validated, VulkanError};
|
||||
|
||||
use crate::core::render::primitives::AsBindableDescriptorSet;
|
||||
|
||||
#[derive(BufferContents, Clone, Copy)]
|
||||
#[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, EncodableLayout};
|
||||
use image::DynamicImage;
|
||||
use vulkano::{
|
||||
Validated, VulkanError,
|
||||
buffer::{Buffer, BufferCreateInfo, BufferUsage},
|
||||
command_buffer::{AutoCommandBufferBuilder, CopyBufferToImageInfo, PrimaryAutoCommandBuffer},
|
||||
descriptor_set::{
|
||||
DescriptorSet, WriteDescriptorSet,
|
||||
allocator::StandardDescriptorSetAllocator,
|
||||
layout::{DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorType},
|
||||
},
|
||||
device::Device,
|
||||
format::Format,
|
||||
image::{
|
||||
|
@ -13,8 +18,11 @@ use vulkano::{
|
|||
view::ImageView,
|
||||
},
|
||||
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
|
||||
shader::ShaderStages,
|
||||
};
|
||||
|
||||
use crate::core::render::primitives::AsBindableDescriptorSet;
|
||||
|
||||
pub struct Texture {
|
||||
texture: Arc<ImageView>,
|
||||
sampler: Arc<Sampler>,
|
||||
|
@ -30,7 +38,7 @@ impl Texture {
|
|||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||
path: &str,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, Box<dyn Error>> {
|
||||
let _span = tracing::info_span!("texture_load_from_file", path = path);
|
||||
|
||||
let bytes = std::fs::read(path)?;
|
||||
|
@ -42,7 +50,7 @@ impl Texture {
|
|||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||
bytes: &[u8],
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, Box<dyn Error>> {
|
||||
let image = image::load_from_memory(bytes)?;
|
||||
Self::from_dynamic_image(device, memory_allocator, builder, image)
|
||||
}
|
||||
|
@ -52,7 +60,7 @@ impl Texture {
|
|||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||
image: DynamicImage,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, Box<dyn Error>> {
|
||||
let _span = tracing::info_span!("texture_from_dynamic_image");
|
||||
|
||||
let image_data = image.to_rgba8();
|
||||
|
@ -121,3 +129,40 @@ impl Texture {
|
|||
&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::{
|
||||
primitives::{mvp::Mvp, transform::TransformRaw, vertex::Vertex3D},
|
||||
primitives::{AsBindableDescriptorSet, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D},
|
||||
texture::Texture,
|
||||
};
|
||||
|
||||
|
@ -130,29 +130,8 @@ impl Square {
|
|||
PipelineShaderStageCreateInfo::new(fs),
|
||||
];
|
||||
|
||||
let vertex_bindings = BTreeMap::<u32, DescriptorSetLayoutBinding>::from_iter([(
|
||||
0,
|
||||
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_bindings = Mvp::as_descriptor_set_layout_bindings();
|
||||
let texture_bindings = Texture::as_descriptor_set_layout_bindings();
|
||||
|
||||
let vertex_descriptor_set_layout = DescriptorSetLayoutCreateInfo {
|
||||
bindings: vertex_bindings,
|
||||
|
@ -160,7 +139,7 @@ impl Square {
|
|||
};
|
||||
|
||||
let fragment_descriptor_set_layout = DescriptorSetLayoutCreateInfo {
|
||||
bindings: fragment_bindings,
|
||||
bindings: texture_bindings,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
@ -220,22 +199,11 @@ impl Square {
|
|||
) -> Result<(), Box<dyn Error>> {
|
||||
let layouts = self.pipeline.layout().set_layouts();
|
||||
|
||||
let uniform_descriptor_set = DescriptorSet::new(
|
||||
descriptor_set_allocator.clone(),
|
||||
layouts[0].clone(),
|
||||
[WriteDescriptorSet::buffer(0, mvp_uniform.clone())],
|
||||
[],
|
||||
)?;
|
||||
let uniform_descriptor_set =
|
||||
Mvp::as_descriptor_set(descriptor_set_allocator, &layouts[0], mvp_uniform)?;
|
||||
|
||||
let texture_descriptor_set = DescriptorSet::new(
|
||||
descriptor_set_allocator.clone(),
|
||||
layouts[1].clone(),
|
||||
[
|
||||
WriteDescriptorSet::sampler(0, texture.get_sampler().clone()),
|
||||
WriteDescriptorSet::image_view(1, texture.get_texture().clone()),
|
||||
],
|
||||
[],
|
||||
)?;
|
||||
let texture_descriptor_set =
|
||||
Texture::as_descriptor_set(descriptor_set_allocator, &layouts[1], texture)?;
|
||||
|
||||
command_buffer.bind_pipeline_graphics(self.pipeline.clone())?;
|
||||
command_buffer.bind_descriptor_sets(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue