Split record_render_commands and bind_commands

This commit is contained in:
Florian RICHER 2025-06-08 16:42:22 +02:00
parent 078e9daba9
commit f91c0792b2
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
6 changed files with 83 additions and 85 deletions

View file

@ -1,26 +1,61 @@
use std::{error::Error, sync::Arc};
use vulkano::{
buffer::Subbuffer,
command_buffer::{
AutoCommandBufferBuilder, PrimaryAutoCommandBuffer, RenderPassBeginInfo, SubpassBeginInfo,
SubpassEndInfo,
},
buffer::{IndexBuffer, Subbuffer},
command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer},
descriptor_set::allocator::StandardDescriptorSetAllocator,
pipeline::GraphicsPipeline,
render_pass::{Framebuffer, RenderPass},
};
pub trait AsRecordable<T> {
fn record_render_commands(
pub trait AsRecordable<T, V, MI, I>
where
MI: Into<IndexBuffer> + Clone,
{
fn record_bind_commands(
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
pipeline: &Arc<GraphicsPipeline>,
data: &T,
mesh: &impl AsRenderableMesh<V, MI>,
instances: &impl AsRenderableMeshInstance<I>,
extra_data: &T,
) -> Result<(), Box<dyn Error>>;
fn record_draw_commands(
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
mesh: &impl AsRenderableMesh<V, MI>,
instances: &impl AsRenderableMeshInstance<I>,
) -> Result<(), Box<dyn Error>> {
match mesh.index_buffer() {
Some(index_buffer) => {
builder.bind_index_buffer(index_buffer.clone())?;
unsafe {
builder.draw_indexed(
mesh.index_count(),
instances.instance_count(),
mesh.first_index(),
mesh.vertex_offset(),
instances.first_instance(),
)?;
}
}
None => unsafe {
builder.draw(
mesh.vertex_count(),
instances.instance_count(),
mesh.first_vertex(),
instances.first_instance(),
)?;
},
}
Ok(())
}
}
pub trait AsRenderableMesh<V, I> {
pub trait AsRenderableMesh<V, I>
where
I: Into<IndexBuffer> + Clone,
{
fn vertex_buffer(&self) -> &Subbuffer<[V]>;
fn vertex_count(&self) -> u32;
@ -33,7 +68,7 @@ pub trait AsRenderableMesh<V, I> {
0
}
fn index_buffer(&self) -> Option<&Subbuffer<[I]>> {
fn index_buffer(&self) -> Option<&I> {
None
}
@ -44,41 +79,14 @@ pub trait AsRenderableMesh<V, I> {
fn first_index(&self) -> u32 {
0
}
}
fn index_offset(&self) -> i32 {
pub trait AsRenderableMeshInstance<T> {
fn instance_buffer(&self) -> &Subbuffer<[T]>;
fn instance_count(&self) -> u32;
fn first_instance(&self) -> u32 {
0
}
}
pub trait AsRenderPassRecordable<T> {
fn begin_render_pass(
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
_render_pass: &Arc<RenderPass>,
framebuffer: &Arc<Framebuffer>,
clear_values: Vec<Option<vulkano::format::ClearValue>>,
) -> Result<(), Box<dyn Error>> {
builder.begin_render_pass(
RenderPassBeginInfo {
clear_values,
..RenderPassBeginInfo::framebuffer(framebuffer.clone())
},
SubpassBeginInfo {
contents: vulkano::command_buffer::SubpassContents::Inline,
..Default::default()
},
)?;
Ok(())
}
fn end_render_pass(
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
) -> Result<(), Box<dyn Error>> {
builder.end_render_pass(SubpassEndInfo::default())?;
Ok(())
}
fn record_render_pass_commands(
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
data: &T,
) -> Result<(), Box<dyn Error>>;
}

View file

@ -19,7 +19,7 @@ pub mod vertex;
pub mod resource;
pub use buffer::{AsBindableBuffer, AsIndexBuffer, AsUniformBuffer, AsVertexBuffer};
pub use command::{AsRecordable, AsRenderableMesh};
pub use command::{AsRecordable, AsRenderableMesh, AsRenderableMeshInstance};
pub trait AsBindableDescriptorSet<T> {
fn as_descriptor_set_layout_bindings() -> BTreeMap<u32, DescriptorSetLayoutBinding>;

View file

@ -10,6 +10,8 @@ use vulkano::{
use crate::core::render::primitives::{AsBindableBuffer, AsVertexBuffer};
use super::command::AsRenderableMeshInstance;
#[derive(Debug, Clone)]
pub struct Transform {
pub position: Vec3,
@ -161,3 +163,13 @@ impl AsBindableBuffer<TransformRaw> for TransformRaw {
}
impl AsVertexBuffer<TransformRaw> for TransformRaw {}
impl AsRenderableMeshInstance<TransformRaw> for Subbuffer<[TransformRaw]> {
fn instance_buffer(&self) -> &Subbuffer<[TransformRaw]> {
self
}
fn instance_count(&self) -> u32 {
self.len() as u32
}
}

View file

@ -44,7 +44,7 @@ impl Square {
}
}
impl AsRenderableMesh<Vertex3D, u32> for Square {
impl AsRenderableMesh<Vertex3D, Subbuffer<[u32]>> for Square {
fn vertex_buffer(&self) -> &Subbuffer<[Vertex3D]> {
&self.vertex_buffer
}

View file

@ -28,20 +28,15 @@ use vulkano::{
use crate::core::render::{
primitives::{
AsBindableDescriptorSet, AsRecordable, AsRenderableMesh, mvp::Mvp, transform::TransformRaw,
vertex::Vertex3D,
AsBindableDescriptorSet, AsRecordable, AsRenderableMesh, AsRenderableMeshInstance,
mvp::Mvp, transform::TransformRaw, vertex::Vertex3D,
},
texture::Texture,
};
pub struct SimplePipelineRenderData<'a, T>
where
T: AsRenderableMesh<Vertex3D, u32>,
{
pub mesh: &'a T,
pub struct SimplePipelineRenderData<'a> {
pub mvp_uniform: &'a Subbuffer<[Mvp]>,
pub texture: &'a Texture,
pub instances: &'a Subbuffer<[TransformRaw]>,
}
pub struct SimplePipeline {
@ -130,14 +125,16 @@ impl SimplePipeline {
}
}
impl<'a, T: AsRenderableMesh<Vertex3D, u32>> AsRecordable<SimplePipelineRenderData<'a, T>>
impl<'a> AsRecordable<SimplePipelineRenderData<'a>, Vertex3D, Subbuffer<[u32]>, TransformRaw>
for SimplePipeline
{
fn record_render_commands(
fn record_bind_commands(
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
pipeline: &Arc<GraphicsPipeline>,
data: &SimplePipelineRenderData<'a, T>,
mesh: &impl AsRenderableMesh<Vertex3D, Subbuffer<[u32]>>,
instances: &impl AsRenderableMeshInstance<TransformRaw>,
data: &SimplePipelineRenderData<'a>,
) -> Result<(), Box<dyn Error>> {
let layouts = pipeline.layout().set_layouts();
@ -158,32 +155,12 @@ impl<'a, T: AsRenderableMesh<Vertex3D, u32>> AsRecordable<SimplePipelineRenderDa
builder.bind_vertex_buffers(
0,
(data.mesh.vertex_buffer().clone(), data.instances.clone()),
(
mesh.vertex_buffer().clone(),
instances.instance_buffer().clone(),
),
)?;
match data.mesh.index_buffer() {
Some(index_buffer) => {
builder.bind_index_buffer(index_buffer.clone())?;
unsafe {
builder.draw_indexed(
data.mesh.index_count(),
data.instances.len() as u32,
data.mesh.first_index(),
data.mesh.vertex_offset(),
0,
)?;
}
}
None => unsafe {
builder.draw(
data.mesh.vertex_count(),
data.instances.len() as u32,
data.mesh.first_vertex(),
0,
)?;
},
}
Ok(())
}
}

View file

@ -206,17 +206,18 @@ impl Scene for MainScene {
let transform_uniform =
Transform::create_buffer(&app_context.memory_allocator, &state.instances)?;
SimplePipeline::record_render_commands(
SimplePipeline::record_bind_commands(
&mut builder,
&app_context.descriptor_set_allocator,
state.simple_pipeline.pipeline(),
&state.square,
&transform_uniform,
&SimplePipelineRenderData {
mesh: &state.square,
mvp_uniform: &camera_uniform,
texture: &state.texture,
instances: &transform_uniform,
},
)?;
SimplePipeline::record_draw_commands(&mut builder, &state.square, &transform_uniform)?;
RenderPassManager::end_rendering(&mut builder)?;