Compare commits
No commits in common. "8ccdfad42a16a4a8486855cf63f9e70bca0ac4a7" and "933b4a5979cda996ef4dafab2693488f3a89fd0d" have entirely different histories.
8ccdfad42a
...
933b4a5979
|
|
@ -319,9 +319,9 @@ impl Command for EndRendering {
|
||||||
fn apply(self, _recorder: &mut CommandRecorder) {}
|
fn apply(self, _recorder: &mut CommandRecorder) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BindPipeline(pub vk::Pipeline, pub vk::PipelineBindPoint);
|
pub struct BindPipeline<'cmd>(pub &'cmd Pipeline);
|
||||||
|
|
||||||
impl Command for BindPipeline {
|
impl<'cmd> Command for BindPipeline<'cmd> {
|
||||||
fn side_effects(&self, _map: SideEffectMap) {
|
fn side_effects(&self, _map: SideEffectMap) {
|
||||||
// No resource access, but affects the pipeline state
|
// No resource access, but affects the pipeline state
|
||||||
}
|
}
|
||||||
|
|
@ -331,7 +331,7 @@ impl Command for BindPipeline {
|
||||||
let dev = &cmd.device().raw;
|
let dev = &cmd.device().raw;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
dev.cmd_bind_pipeline(cmd.raw(), self.1, self.0);
|
dev.cmd_bind_pipeline(cmd.raw(), self.0.bind_point(), self.0.raw());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -602,8 +602,8 @@ impl<T: Resource, U: Resource> OutsideRenderPass for Copy<T, U> {}
|
||||||
impl OutsideRenderPass for ClearTexture {}
|
impl OutsideRenderPass for ClearTexture {}
|
||||||
impl OutsideRenderPass for UpdateBuffer {}
|
impl OutsideRenderPass for UpdateBuffer {}
|
||||||
|
|
||||||
impl InsideRenderPass for BindPipeline {}
|
impl InsideRenderPass for BindPipeline<'_> {}
|
||||||
impl OutsideRenderPass for BindPipeline {}
|
impl OutsideRenderPass for BindPipeline<'_> {}
|
||||||
impl InsideRenderPass for BindVertexBuffers {}
|
impl InsideRenderPass for BindVertexBuffers {}
|
||||||
impl OutsideRenderPass for BindVertexBuffers {}
|
impl OutsideRenderPass for BindVertexBuffers {}
|
||||||
impl InsideRenderPass for BindIndexBuffer {}
|
impl InsideRenderPass for BindIndexBuffer {}
|
||||||
|
|
|
||||||
|
|
@ -1,315 +0,0 @@
|
||||||
use std::{cell::UnsafeCell, collections::BTreeMap, marker::PhantomData};
|
|
||||||
|
|
||||||
use ash::vk;
|
|
||||||
use derive_more::derive::{Deref, DerefMut};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
buffers, images,
|
|
||||||
render_graph::{
|
|
||||||
recorder::CommandList,
|
|
||||||
resources::{self, ResourceId},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct GraphResourceRegistry {
|
|
||||||
images: BTreeMap<ResourceId, UnsafeCell<images::Image>>,
|
|
||||||
views: BTreeMap<ResourceId, UnsafeCell<images::ImageView>>,
|
|
||||||
buffers: BTreeMap<ResourceId, UnsafeCell<buffers::Buffer>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deref, DerefMut)]
|
|
||||||
struct StagingBuffer<'a> {
|
|
||||||
id: ResourceId,
|
|
||||||
#[deref]
|
|
||||||
#[deref_mut]
|
|
||||||
buffer: &'a mut buffers::Buffer,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deref, DerefMut)]
|
|
||||||
struct Buffer<'a> {
|
|
||||||
id: ResourceId,
|
|
||||||
#[deref]
|
|
||||||
#[deref_mut]
|
|
||||||
buffer: &'a mut buffers::Buffer,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GraphBuilder<'r> {
|
|
||||||
_pd: PhantomData<fn(&'r ())>,
|
|
||||||
}
|
|
||||||
impl<'r> GraphBuilder<'r> {
|
|
||||||
fn make_command_list<'cmd>(&self) -> CommandList<'cmd> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
fn make_staging_buffer(&self, _size: u64) -> StagingBuffer<'r> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_buffer(
|
|
||||||
&self,
|
|
||||||
_size: u64,
|
|
||||||
_usage: vk::BufferUsageFlags,
|
|
||||||
_location: gpu_allocator::MemoryLocation,
|
|
||||||
) -> Buffer<'r> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to know which queue currently owns this buffer to be able to
|
|
||||||
// transfer it to the correct queue family when using it
|
|
||||||
fn import_buffer(&self, _buffer: buffers::Buffer, _owning_queue: Option<u32>) -> Buffer<'r> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod api_demo {
|
|
||||||
|
|
||||||
use crate::{EguiState, pipeline::Pipeline, render_graph::commands};
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
use ash::vk::{self, BufferUsageFlags};
|
|
||||||
use gpu_allocator::MemoryLocation;
|
|
||||||
use indexmap::IndexMap;
|
|
||||||
|
|
||||||
fn egui_graph<'a>(
|
|
||||||
egui_state: &mut EguiState,
|
|
||||||
draw_data: Vec<egui::ClippedPrimitive>,
|
|
||||||
builder: GraphBuilder,
|
|
||||||
render_target: ResourceId,
|
|
||||||
extent: (u32, u32),
|
|
||||||
pipeline: &'a Pipeline,
|
|
||||||
descriptor: vk::DescriptorSet,
|
|
||||||
) -> CommandList<'a> {
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
|
|
||||||
struct Vertex {
|
|
||||||
pos: glam::Vec2,
|
|
||||||
uv: glam::Vec2,
|
|
||||||
color: egui::epaint::Color32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
struct DrawCall(vk::DrawIndexedIndirectCommand);
|
|
||||||
unsafe impl bytemuck::Zeroable for DrawCall {}
|
|
||||||
unsafe impl bytemuck::Pod for DrawCall {}
|
|
||||||
|
|
||||||
let mut vertices = Vec::new();
|
|
||||||
let mut indices = Vec::new();
|
|
||||||
let mut draw_calls = Vec::new();
|
|
||||||
let mut textures = IndexMap::new();
|
|
||||||
let mut textures_indices = Vec::new();
|
|
||||||
for draw in draw_data {
|
|
||||||
let egui::epaint::Primitive::Mesh(mesh) = draw.primitive else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
draw_calls.push(DrawCall(vk::DrawIndexedIndirectCommand {
|
|
||||||
index_count: mesh.indices.len() as u32,
|
|
||||||
instance_count: 1,
|
|
||||||
first_index: indices.len() as u32,
|
|
||||||
vertex_offset: vertices.len() as i32,
|
|
||||||
first_instance: 0,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vertices.extend(mesh.vertices.iter().map(|v| Vertex {
|
|
||||||
pos: glam::vec2(v.pos.x, v.pos.y),
|
|
||||||
uv: glam::vec2(v.uv.x, v.uv.y),
|
|
||||||
color: v.color,
|
|
||||||
}));
|
|
||||||
|
|
||||||
indices.extend(mesh.indices);
|
|
||||||
let texture = egui_state.textures.get(&mesh.texture_id).cloned().unwrap();
|
|
||||||
if !textures.contains_key(&texture.id) {
|
|
||||||
textures.insert(texture.id, texture);
|
|
||||||
}
|
|
||||||
let idx = textures.get_index_of(&texture.id).unwrap();
|
|
||||||
textures_indices.push(idx as u32);
|
|
||||||
}
|
|
||||||
|
|
||||||
let vertex_size = vertices.len() * size_of::<Vertex>();
|
|
||||||
let index_size = indices.len() * size_of::<u32>();
|
|
||||||
let draw_calls_size = draw_calls.len() * size_of::<DrawCall>();
|
|
||||||
let textures_indices_size = textures_indices.len() * size_of::<u32>();
|
|
||||||
let staging_size = vertex_size + index_size + draw_calls_size + textures_indices_size;
|
|
||||||
let mut staging = builder.make_staging_buffer(staging_size as u64);
|
|
||||||
|
|
||||||
use core::io::BorrowedBuf;
|
|
||||||
let mut buf = BorrowedBuf::from(staging.map_mut().unwrap());
|
|
||||||
let mut cursor = buf.unfilled();
|
|
||||||
cursor.append(bytemuck::cast_slice(&vertices));
|
|
||||||
cursor.append(bytemuck::cast_slice(&indices));
|
|
||||||
cursor.append(bytemuck::cast_slice(&draw_calls));
|
|
||||||
cursor.append(bytemuck::cast_slice(&textures_indices));
|
|
||||||
|
|
||||||
let vertex_buffer = builder.make_buffer(
|
|
||||||
vertex_size as u64,
|
|
||||||
BufferUsageFlags::TRANSFER_DST | BufferUsageFlags::VERTEX_BUFFER,
|
|
||||||
MemoryLocation::GpuOnly,
|
|
||||||
);
|
|
||||||
let index_buffer = builder.make_buffer(
|
|
||||||
index_size as u64,
|
|
||||||
BufferUsageFlags::TRANSFER_DST | BufferUsageFlags::INDEX_BUFFER,
|
|
||||||
MemoryLocation::GpuOnly,
|
|
||||||
);
|
|
||||||
let indirect_buffer = builder.make_buffer(
|
|
||||||
draw_calls_size as u64,
|
|
||||||
BufferUsageFlags::TRANSFER_DST | BufferUsageFlags::INDIRECT_BUFFER,
|
|
||||||
MemoryLocation::GpuOnly,
|
|
||||||
);
|
|
||||||
let texture_indices = builder.make_buffer(
|
|
||||||
textures_indices_size as u64,
|
|
||||||
BufferUsageFlags::TRANSFER_DST | BufferUsageFlags::STORAGE_BUFFER,
|
|
||||||
MemoryLocation::GpuOnly,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut cmd = builder.make_command_list();
|
|
||||||
cmd.push(commands::Copy {
|
|
||||||
src: resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(staging.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: 0,
|
|
||||||
size: vertex_size as u64,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dst: resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(vertex_buffer.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: 0,
|
|
||||||
size: vertex_size as u64,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cmd.push(commands::Copy {
|
|
||||||
src: resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(staging.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: vertex_size as u64,
|
|
||||||
size: (vertex_size + index_size) as u64,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dst: resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(index_buffer.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: 0,
|
|
||||||
size: index_size as u64,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cmd.push(commands::Copy {
|
|
||||||
src: resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(staging.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: (vertex_size + index_size) as u64,
|
|
||||||
size: draw_calls_size as u64,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dst: resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(indirect_buffer.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: 0,
|
|
||||||
size: draw_calls_size as u64,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cmd.push(commands::Copy {
|
|
||||||
src: resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(staging.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: (vertex_size + index_size + draw_calls_size) as u64,
|
|
||||||
size: textures_indices_size as u64,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dst: resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(texture_indices.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: 0,
|
|
||||||
size: textures_indices_size as u64,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut pass_cmd = cmd.begin_rendering(
|
|
||||||
vec![resources::TextureRegion {
|
|
||||||
texture: resources::Texture(render_target),
|
|
||||||
range: resources::TextureRange {
|
|
||||||
aspect: vk::ImageAspectFlags::COLOR,
|
|
||||||
mip_levels: (0..).into(),
|
|
||||||
array_layers: (0..).into(),
|
|
||||||
origin: (0, 0, 0),
|
|
||||||
extent: (extent.0, extent.1, 1),
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
extent,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
|
|
||||||
pass_cmd.push(commands::SetScissor {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
width: extent.0,
|
|
||||||
height: extent.1,
|
|
||||||
});
|
|
||||||
pass_cmd.push(commands::SetViewport {
|
|
||||||
x: 0.0,
|
|
||||||
y: 0.0,
|
|
||||||
width: extent.0 as f32,
|
|
||||||
height: extent.1 as f32,
|
|
||||||
min_depth: 0.0,
|
|
||||||
max_depth: 1.0,
|
|
||||||
});
|
|
||||||
|
|
||||||
fn factory<T>() -> T {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
pass_cmd.push(commands::BindPipeline(
|
|
||||||
pipeline.raw(),
|
|
||||||
pipeline.bind_point(),
|
|
||||||
));
|
|
||||||
pass_cmd.push(commands::BindDescriptorSets {
|
|
||||||
pipeline_layout: pipeline.layout().raw(),
|
|
||||||
sets: vec![descriptor],
|
|
||||||
first_set: 0,
|
|
||||||
bind_point: vk::PipelineBindPoint::GRAPHICS,
|
|
||||||
});
|
|
||||||
pass_cmd.push(commands::PushConstants {
|
|
||||||
pipeline_layout: pipeline.layout().raw(),
|
|
||||||
stage_flags: vk::ShaderStageFlags::VERTEX,
|
|
||||||
offset: 0,
|
|
||||||
data: bytemuck::pod_collect_to_vec(
|
|
||||||
&[extent.0 as f32, extent.1 as f32].map(f32::to_bits),
|
|
||||||
),
|
|
||||||
});
|
|
||||||
pass_cmd.push(commands::Draw {
|
|
||||||
data: commands::DrawIndexedIndirectData {
|
|
||||||
indirect_buffer: resources::Buffer(indirect_buffer.id).full_slice(),
|
|
||||||
count: draw_calls.len() as u32,
|
|
||||||
stride: size_of::<DrawCall>() as u32,
|
|
||||||
},
|
|
||||||
vertex_buffers: vec![resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(vertex_buffer.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: 0,
|
|
||||||
size: vertex_size as u64,
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
index_buffer: Some((
|
|
||||||
resources::BufferSlice {
|
|
||||||
buffer: resources::Buffer(index_buffer.id),
|
|
||||||
range: resources::BufferRange {
|
|
||||||
offset: 0,
|
|
||||||
size: index_size as u64,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
commands::IndexFormat::Uint32,
|
|
||||||
)),
|
|
||||||
});
|
|
||||||
|
|
||||||
pass_cmd.finalise();
|
|
||||||
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -105,7 +105,7 @@ pub struct CommandList<'cmd> {
|
||||||
side_effects: SideEffects,
|
side_effects: SideEffects,
|
||||||
num_commands: u32,
|
num_commands: u32,
|
||||||
|
|
||||||
_pd: PhantomData<&'cmd ()>,
|
_pd: PhantomData<fn(&'cmd ())>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
@ -156,7 +156,7 @@ impl<'cmd> CommandList<'cmd> {
|
||||||
self.push_inner(command);
|
self.push_inner(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_inner<C: Command + 'cmd>(&mut self, command: C) {
|
fn push_inner<C: Command>(&mut self, command: C) {
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
struct Packed<C> {
|
struct Packed<C> {
|
||||||
meta: CommandMeta,
|
meta: CommandMeta,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue