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) {}
|
||||
}
|
||||
|
||||
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) {
|
||||
// No resource access, but affects the pipeline state
|
||||
}
|
||||
|
|
@ -331,7 +331,7 @@ impl Command for BindPipeline {
|
|||
let dev = &cmd.device().raw;
|
||||
|
||||
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 UpdateBuffer {}
|
||||
|
||||
impl InsideRenderPass for BindPipeline {}
|
||||
impl OutsideRenderPass for BindPipeline {}
|
||||
impl InsideRenderPass for BindPipeline<'_> {}
|
||||
impl OutsideRenderPass for BindPipeline<'_> {}
|
||||
impl InsideRenderPass for BindVertexBuffers {}
|
||||
impl OutsideRenderPass for BindVertexBuffers {}
|
||||
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,
|
||||
num_commands: u32,
|
||||
|
||||
_pd: PhantomData<&'cmd ()>,
|
||||
_pd: PhantomData<fn(&'cmd ())>,
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
|
@ -156,7 +156,7 @@ impl<'cmd> CommandList<'cmd> {
|
|||
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)]
|
||||
struct Packed<C> {
|
||||
meta: CommandMeta,
|
||||
|
|
|
|||
Loading…
Reference in a new issue