Reduce Generics in pipeline rendering
This commit is contained in:
parent
90a5b5d117
commit
0174aeb60e
8 changed files with 92 additions and 76 deletions
|
@ -7,7 +7,9 @@ use vulkano::{
|
||||||
pipeline::GraphicsPipeline,
|
pipeline::GraphicsPipeline,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait AsRecordable<T, V, MI, I>
|
use super::AsDescriptorSet;
|
||||||
|
|
||||||
|
pub trait AsRecordable<V, MI, I>
|
||||||
where
|
where
|
||||||
MI: Into<IndexBuffer> + Clone,
|
MI: Into<IndexBuffer> + Clone,
|
||||||
{
|
{
|
||||||
|
@ -17,7 +19,7 @@ where
|
||||||
pipeline: &Arc<GraphicsPipeline>,
|
pipeline: &Arc<GraphicsPipeline>,
|
||||||
mesh: &impl AsRenderableMesh<V, MI>,
|
mesh: &impl AsRenderableMesh<V, MI>,
|
||||||
instances: &impl AsRenderableMeshInstance<I>,
|
instances: &impl AsRenderableMeshInstance<I>,
|
||||||
extra_data: &T,
|
descriptor_sets: Vec<Arc<dyn AsDescriptorSet>>,
|
||||||
) -> Result<(), Box<dyn Error>>;
|
) -> Result<(), Box<dyn Error>>;
|
||||||
|
|
||||||
fn record_draw_commands(
|
fn record_draw_commands(
|
||||||
|
|
22
src/core/render/primitives/descriptor_set.rs
Normal file
22
src/core/render/primitives/descriptor_set.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
use std::{collections::BTreeMap, sync::Arc};
|
||||||
|
|
||||||
|
use vulkano::{
|
||||||
|
Validated, VulkanError,
|
||||||
|
descriptor_set::{
|
||||||
|
DescriptorSet,
|
||||||
|
allocator::StandardDescriptorSetAllocator,
|
||||||
|
layout::{DescriptorSetLayout, DescriptorSetLayoutBinding},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait AsDescriptorSetLayoutBindings {
|
||||||
|
fn as_descriptor_set_layout_bindings() -> BTreeMap<u32, DescriptorSetLayoutBinding>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait AsDescriptorSet {
|
||||||
|
fn as_descriptor_set(
|
||||||
|
&self,
|
||||||
|
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
||||||
|
layout: &Arc<DescriptorSetLayout>,
|
||||||
|
) -> Result<Arc<DescriptorSet>, Validated<VulkanError>>;
|
||||||
|
}
|
|
@ -1,16 +1,6 @@
|
||||||
use std::{collections::BTreeMap, sync::Arc};
|
|
||||||
|
|
||||||
use vulkano::{
|
|
||||||
Validated, VulkanError,
|
|
||||||
descriptor_set::{
|
|
||||||
DescriptorSet,
|
|
||||||
allocator::StandardDescriptorSetAllocator,
|
|
||||||
layout::{DescriptorSetLayout, DescriptorSetLayoutBinding},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod command;
|
mod command;
|
||||||
|
mod descriptor_set;
|
||||||
|
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
pub mod mvp;
|
pub mod mvp;
|
||||||
|
@ -19,13 +9,4 @@ pub mod transform;
|
||||||
pub mod vertex;
|
pub mod vertex;
|
||||||
pub use buffer::{AsBindableBuffer, AsIndexBuffer, AsUniformBuffer, AsVertexBuffer};
|
pub use buffer::{AsBindableBuffer, AsIndexBuffer, AsUniformBuffer, AsVertexBuffer};
|
||||||
pub use command::{AsRecordable, AsRenderableMesh, AsRenderableMeshInstance};
|
pub use command::{AsRecordable, AsRenderableMesh, AsRenderableMeshInstance};
|
||||||
|
pub use descriptor_set::{AsDescriptorSet, AsDescriptorSetLayoutBindings};
|
||||||
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>>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, Standar
|
||||||
use vulkano::shader::ShaderStages;
|
use vulkano::shader::ShaderStages;
|
||||||
use vulkano::{Validated, VulkanError};
|
use vulkano::{Validated, VulkanError};
|
||||||
|
|
||||||
use crate::core::render::primitives::{AsBindableBuffer, AsBindableDescriptorSet, AsUniformBuffer};
|
use crate::core::render::primitives::{AsBindableBuffer, AsUniformBuffer};
|
||||||
|
|
||||||
|
use super::{AsDescriptorSet, AsDescriptorSetLayoutBindings};
|
||||||
|
|
||||||
#[derive(BufferContents, Clone, Copy)]
|
#[derive(BufferContents, Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -57,7 +59,7 @@ impl AsBindableBuffer<Mvp> for Mvp {
|
||||||
|
|
||||||
impl AsUniformBuffer<Mvp> for Mvp {}
|
impl AsUniformBuffer<Mvp> for Mvp {}
|
||||||
|
|
||||||
impl AsBindableDescriptorSet<Subbuffer<[Mvp]>> for Mvp {
|
impl AsDescriptorSetLayoutBindings for Mvp {
|
||||||
fn as_descriptor_set_layout_bindings() -> BTreeMap<u32, DescriptorSetLayoutBinding> {
|
fn as_descriptor_set_layout_bindings() -> BTreeMap<u32, DescriptorSetLayoutBinding> {
|
||||||
BTreeMap::<u32, DescriptorSetLayoutBinding>::from_iter([(
|
BTreeMap::<u32, DescriptorSetLayoutBinding>::from_iter([(
|
||||||
0,
|
0,
|
||||||
|
@ -67,16 +69,18 @@ impl AsBindableDescriptorSet<Subbuffer<[Mvp]>> for Mvp {
|
||||||
},
|
},
|
||||||
)])
|
)])
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsDescriptorSet for Subbuffer<[Mvp]> {
|
||||||
fn as_descriptor_set(
|
fn as_descriptor_set(
|
||||||
|
&self,
|
||||||
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
||||||
layout: &Arc<DescriptorSetLayout>,
|
layout: &Arc<DescriptorSetLayout>,
|
||||||
data: &Subbuffer<[Mvp]>,
|
|
||||||
) -> Result<Arc<DescriptorSet>, Validated<VulkanError>> {
|
) -> Result<Arc<DescriptorSet>, Validated<VulkanError>> {
|
||||||
DescriptorSet::new(
|
DescriptorSet::new(
|
||||||
descriptor_set_allocator.clone(),
|
descriptor_set_allocator.clone(),
|
||||||
layout.clone(),
|
layout.clone(),
|
||||||
[WriteDescriptorSet::buffer(0, data.clone())],
|
[WriteDescriptorSet::buffer(0, self.clone())],
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub struct TextureLoadInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TextureLoader {
|
pub struct TextureLoader {
|
||||||
loaded_textures: HashMap<String, Texture>,
|
loaded_textures: HashMap<String, Arc<Texture>>,
|
||||||
pending_textures: HashMap<String, TextureLoadInfo>,
|
pending_textures: HashMap<String, TextureLoadInfo>,
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
command_buffer_allocator: Arc<StandardCommandBufferAllocator>,
|
command_buffer_allocator: Arc<StandardCommandBufferAllocator>,
|
||||||
|
@ -102,7 +102,7 @@ impl TextureLoader {
|
||||||
)?,
|
)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
loading_textures.insert(name.clone(), texture);
|
loading_textures.insert(name.clone(), Arc::new(texture));
|
||||||
tracing::trace!("Loaded texture: {}", name);
|
tracing::trace!("Loaded texture: {}", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ impl TextureLoader {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_texture(&self, name: &str) -> Option<&Texture> {
|
pub fn get_texture(&self, name: &str) -> Option<&Arc<Texture>> {
|
||||||
self.loaded_textures.get(name)
|
self.loaded_textures.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ use vulkano::{
|
||||||
shader::ShaderStages,
|
shader::ShaderStages,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::core::render::primitives::AsBindableDescriptorSet;
|
use crate::core::render::primitives::{AsDescriptorSet, AsDescriptorSetLayoutBindings};
|
||||||
|
|
||||||
use super::TextureLoadInfo;
|
use super::TextureLoadInfo;
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ impl Texture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsBindableDescriptorSet<Texture> for Texture {
|
impl AsDescriptorSetLayoutBindings for Texture {
|
||||||
fn as_descriptor_set_layout_bindings() -> BTreeMap<u32, DescriptorSetLayoutBinding> {
|
fn as_descriptor_set_layout_bindings() -> BTreeMap<u32, DescriptorSetLayoutBinding> {
|
||||||
BTreeMap::<u32, DescriptorSetLayoutBinding>::from_iter([
|
BTreeMap::<u32, DescriptorSetLayoutBinding>::from_iter([
|
||||||
(
|
(
|
||||||
|
@ -131,18 +131,20 @@ impl AsBindableDescriptorSet<Texture> for Texture {
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsDescriptorSet for Texture {
|
||||||
fn as_descriptor_set(
|
fn as_descriptor_set(
|
||||||
|
&self,
|
||||||
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
||||||
layout: &Arc<DescriptorSetLayout>,
|
layout: &Arc<DescriptorSetLayout>,
|
||||||
data: &Texture,
|
|
||||||
) -> Result<Arc<DescriptorSet>, Validated<VulkanError>> {
|
) -> Result<Arc<DescriptorSet>, Validated<VulkanError>> {
|
||||||
DescriptorSet::new(
|
DescriptorSet::new(
|
||||||
descriptor_set_allocator.clone(),
|
descriptor_set_allocator.clone(),
|
||||||
layout.clone(),
|
layout.clone(),
|
||||||
[
|
[
|
||||||
WriteDescriptorSet::sampler(0, data.sampler.clone()),
|
WriteDescriptorSet::sampler(0, self.sampler.clone()),
|
||||||
WriteDescriptorSet::image_view(1, data.texture.clone()),
|
WriteDescriptorSet::image_view(1, self.texture.clone()),
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{error::Error, sync::Arc};
|
use std::{collections::HashMap, error::Error, sync::Arc};
|
||||||
|
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::Subbuffer,
|
buffer::Subbuffer,
|
||||||
|
@ -28,17 +28,12 @@ use vulkano::{
|
||||||
|
|
||||||
use crate::core::render::{
|
use crate::core::render::{
|
||||||
primitives::{
|
primitives::{
|
||||||
AsBindableDescriptorSet, AsRecordable, AsRenderableMesh, AsRenderableMeshInstance,
|
AsDescriptorSet, AsDescriptorSetLayoutBindings, AsRecordable, AsRenderableMesh,
|
||||||
mvp::Mvp, transform::TransformRaw, vertex::Vertex3D,
|
AsRenderableMeshInstance, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D,
|
||||||
},
|
},
|
||||||
resources::texture::Texture,
|
resources::texture::Texture,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct SimplePipelineRenderData<'a> {
|
|
||||||
pub mvp_uniform: &'a Subbuffer<[Mvp]>,
|
|
||||||
pub texture: &'a Texture,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SimplePipeline {
|
pub struct SimplePipeline {
|
||||||
pipeline: Arc<GraphicsPipeline>,
|
pipeline: Arc<GraphicsPipeline>,
|
||||||
}
|
}
|
||||||
|
@ -125,33 +120,35 @@ impl SimplePipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AsRecordable<SimplePipelineRenderData<'a>, Vertex3D, Subbuffer<[u32]>, TransformRaw>
|
impl AsRecordable<Vertex3D, Subbuffer<[u32]>, TransformRaw> for SimplePipeline {
|
||||||
for SimplePipeline
|
|
||||||
{
|
|
||||||
fn record_bind_commands(
|
fn record_bind_commands(
|
||||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||||
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
||||||
pipeline: &Arc<GraphicsPipeline>,
|
pipeline: &Arc<GraphicsPipeline>,
|
||||||
mesh: &impl AsRenderableMesh<Vertex3D, Subbuffer<[u32]>>,
|
mesh: &impl AsRenderableMesh<Vertex3D, Subbuffer<[u32]>>,
|
||||||
instances: &impl AsRenderableMeshInstance<TransformRaw>,
|
instances: &impl AsRenderableMeshInstance<TransformRaw>,
|
||||||
data: &SimplePipelineRenderData<'a>,
|
descriptor_sets: Vec<Arc<dyn AsDescriptorSet>>,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
builder.bind_pipeline_graphics(pipeline.clone())?;
|
||||||
|
|
||||||
|
if !descriptor_sets.is_empty() {
|
||||||
let layouts = pipeline.layout().set_layouts();
|
let layouts = pipeline.layout().set_layouts();
|
||||||
|
|
||||||
let uniform_descriptor_set =
|
let descriptor_sets = descriptor_sets
|
||||||
Mvp::as_descriptor_set(descriptor_set_allocator, &layouts[0], data.mvp_uniform)?;
|
.iter()
|
||||||
|
.enumerate()
|
||||||
let texture_descriptor_set =
|
.map(|(layout_index, data)| {
|
||||||
Texture::as_descriptor_set(descriptor_set_allocator, &layouts[1], data.texture)?;
|
data.as_descriptor_set(descriptor_set_allocator, &layouts[layout_index])
|
||||||
|
})
|
||||||
builder.bind_pipeline_graphics(pipeline.clone())?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
builder.bind_descriptor_sets(
|
builder.bind_descriptor_sets(
|
||||||
PipelineBindPoint::Graphics,
|
PipelineBindPoint::Graphics,
|
||||||
pipeline.layout().clone(),
|
pipeline.layout().clone(),
|
||||||
0,
|
0,
|
||||||
vec![uniform_descriptor_set, texture_descriptor_set],
|
descriptor_sets,
|
||||||
)?;
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
builder.bind_vertex_buffers(
|
builder.bind_vertex_buffers(
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::settings_scene::SettingsScene;
|
use super::settings_scene::SettingsScene;
|
||||||
use crate::core::app::DEPTH_IMAGE_ID;
|
use crate::core::app::DEPTH_IMAGE_ID;
|
||||||
use crate::core::app::context::WindowContext;
|
use crate::core::app::context::WindowContext;
|
||||||
use crate::core::app::user_event::UserEvent;
|
use crate::core::app::user_event::UserEvent;
|
||||||
use crate::core::render::primitives::AsRecordable;
|
|
||||||
use crate::core::render::primitives::camera::Camera3D;
|
use crate::core::render::primitives::camera::Camera3D;
|
||||||
use crate::core::render::primitives::transform::Transform;
|
use crate::core::render::primitives::transform::Transform;
|
||||||
|
use crate::core::render::primitives::{AsDescriptorSet, AsRecordable};
|
||||||
use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager};
|
use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager};
|
||||||
use crate::core::render::resources::meshes::{ObjMesh, SquareMesh};
|
use crate::core::render::resources::meshes::{ObjMesh, SquareMesh};
|
||||||
use crate::core::render::resources::texture::{
|
use crate::core::render::resources::texture::{TextureLoadInfo, TextureLoader, TextureSourceKind};
|
||||||
Texture, TextureLoadInfo, TextureLoader, TextureSourceKind,
|
|
||||||
};
|
|
||||||
use crate::core::scene::Scene;
|
use crate::core::scene::Scene;
|
||||||
use crate::game::assets::pipelines::simple::{SimplePipeline, SimplePipelineRenderData};
|
use crate::game::assets::pipelines::simple::SimplePipeline;
|
||||||
use egui_winit_vulkano::egui;
|
use egui_winit_vulkano::egui;
|
||||||
use glam::EulerRot;
|
use glam::EulerRot;
|
||||||
use glam::Quat;
|
use glam::Quat;
|
||||||
|
@ -21,7 +21,7 @@ use glam::Vec3;
|
||||||
use vulkano::format::Format;
|
use vulkano::format::Format;
|
||||||
use vulkano::image::sampler::{Filter, SamplerAddressMode, SamplerCreateInfo};
|
use vulkano::image::sampler::{Filter, SamplerAddressMode, SamplerCreateInfo};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract},
|
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||||
sync::GpuFuture,
|
sync::GpuFuture,
|
||||||
};
|
};
|
||||||
use winit::window::CursorGrabMode;
|
use winit::window::CursorGrabMode;
|
||||||
|
@ -250,7 +250,7 @@ impl Scene for MainScene {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create camera uniform using the actual camera
|
// Create camera uniform using the actual camera
|
||||||
let camera_uniform = state.camera.create_buffer(&app_context.memory_allocator)?;
|
let camera_uniform = Arc::new(state.camera.create_buffer(&app_context.memory_allocator)?);
|
||||||
let square_transform_uniform =
|
let square_transform_uniform =
|
||||||
Transform::create_buffer(&app_context.memory_allocator, &state.square_instances)?;
|
Transform::create_buffer(&app_context.memory_allocator, &state.square_instances)?;
|
||||||
let obj_transform_uniform =
|
let obj_transform_uniform =
|
||||||
|
@ -262,10 +262,14 @@ impl Scene for MainScene {
|
||||||
state.simple_pipeline.pipeline(),
|
state.simple_pipeline.pipeline(),
|
||||||
&state.square,
|
&state.square,
|
||||||
&square_transform_uniform,
|
&square_transform_uniform,
|
||||||
&SimplePipelineRenderData {
|
vec![
|
||||||
mvp_uniform: &camera_uniform,
|
camera_uniform.clone() as Arc<dyn AsDescriptorSet>,
|
||||||
texture: &state.texture_loader.get_texture("wooden-crate").unwrap(),
|
state
|
||||||
},
|
.texture_loader
|
||||||
|
.get_texture("wooden-crate")
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
],
|
||||||
)?;
|
)?;
|
||||||
SimplePipeline::record_draw_commands(
|
SimplePipeline::record_draw_commands(
|
||||||
&mut builder,
|
&mut builder,
|
||||||
|
@ -279,10 +283,14 @@ impl Scene for MainScene {
|
||||||
state.simple_pipeline.pipeline(),
|
state.simple_pipeline.pipeline(),
|
||||||
&state.obj,
|
&state.obj,
|
||||||
&obj_transform_uniform,
|
&obj_transform_uniform,
|
||||||
&SimplePipelineRenderData {
|
vec![
|
||||||
mvp_uniform: &camera_uniform,
|
camera_uniform.clone() as Arc<dyn AsDescriptorSet>,
|
||||||
texture: &state.texture_loader.get_texture("cube-diffuse").unwrap(),
|
state
|
||||||
},
|
.texture_loader
|
||||||
|
.get_texture("cube-diffuse")
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
],
|
||||||
)?;
|
)?;
|
||||||
SimplePipeline::record_draw_commands(&mut builder, &state.obj, &obj_transform_uniform)?;
|
SimplePipeline::record_draw_commands(&mut builder, &state.obj, &obj_transform_uniform)?;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue