Skip to content

Commit cabb19b

Browse files
committed
buffer: adjust ash to use buffers
1 parent abc9299 commit cabb19b

File tree

24 files changed

+582
-78
lines changed

24 files changed

+582
-78
lines changed

Cargo.lock

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[workspace]
22
members = [
3-
"graphics/mygraphics",
4-
"graphics/mygraphics-shaders",
5-
"xtask",
3+
"graphics/mygraphics",
4+
"graphics/mygraphics-shaders",
5+
"xtask",
66
]
77
resolver = "3"
88

@@ -20,6 +20,7 @@ unexpected_cfgs = { level = "allow", check-cfg = ['cfg(target_arch, values("spir
2020
# API
2121
ash = "0.38"
2222
ash-window = "0.13"
23+
gpu-allocator = { version = "0.28.0", default-features = false, features = ["std", "vulkan"] }
2324
wgpu = { version = "27.0.1", default-features = false, features = ["std", "parking_lot", "vulkan", "vulkan-portability", "spirv", "wgsl"] }
2425
pollster = "0.4.0"
2526

generated/graphics/ash/cargo-gpu/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ unexpected_cfgs = { level = "allow", check-cfg = ['cfg(target_arch, values("spir
1919
# API
2020
ash = "0.38"
2121
ash-window = "0.13"
22+
gpu-allocator = { version = "0.28.0", default-features = false, features = ["std", "vulkan"] }
2223

2324
# rust-gpu
2425
cargo-gpu = { git = "https://github.com/Rust-GPU/cargo-gpu", rev = "bb74342b90066ce8b7d50ba8e058df356a54acf4" }

generated/graphics/ash/cargo-gpu/mygraphics/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mygraphics-shaders = { path = "../mygraphics-shaders" }
1717
# API
1818
ash.workspace = true
1919
ash-window.workspace = true
20+
gpu-allocator.workspace = true
2021

2122
# other
2223
raw-window-handle.workspace = true

generated/graphics/ash/cargo-gpu/mygraphics/src/ash_renderer/device.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use anyhow::{Context, anyhow};
22
use ash::{ext, khr, vk};
3+
use gpu_allocator::vulkan::{Allocator, AllocatorCreateDesc};
34
use std::borrow::Cow;
45
use std::ffi::{CStr, c_char};
56
use std::ops::Deref;
6-
use std::sync::Arc;
7+
use std::sync::{Arc, Mutex, MutexGuard};
78

89
/// Central struct containing the Vulkan instance and device, among others
910
pub struct MyDevice {
@@ -13,6 +14,7 @@ pub struct MyDevice {
1314
pub device: ash::Device,
1415
pub main_queue_family: u32,
1516
pub main_queue: vk::Queue,
17+
allocator: Option<Mutex<Allocator>>,
1618
pub debug_ext_instance: ext::debug_utils::Instance,
1719
pub debug_ext_device: ext::debug_utils::Device,
1820
pub surface_ext: khr::surface::Instance,
@@ -134,6 +136,15 @@ impl MyDevice {
134136
.context("create_device")?;
135137
let main_queue = device.get_device_queue(main_queue_family, 0);
136138

139+
let allocator = Allocator::new(&AllocatorCreateDesc {
140+
instance: instance.clone(),
141+
device: device.clone(),
142+
physical_device,
143+
debug_settings: Default::default(),
144+
buffer_device_address: false,
145+
allocation_sizes: Default::default(),
146+
})?;
147+
137148
Ok(Arc::new(Self {
138149
debug_ext_device: ext::debug_utils::Device::new(&instance, &device),
139150
surface_ext: khr::surface::Instance::new(&entry, &instance),
@@ -144,16 +155,22 @@ impl MyDevice {
144155
device,
145156
main_queue_family,
146157
main_queue,
158+
allocator: Some(Mutex::new(allocator)),
147159
debug_ext_instance: debug_instance,
148160
debug_callback,
149161
}))
150162
}
151163
}
164+
165+
pub fn borrow_allocator(&self) -> MutexGuard<'_, Allocator> {
166+
self.allocator.as_ref().unwrap().lock().unwrap()
167+
}
152168
}
153169

154170
impl Drop for MyDevice {
155171
fn drop(&mut self) {
156172
unsafe {
173+
drop(self.allocator.take());
157174
self.debug_ext_instance
158175
.destroy_debug_utils_messenger(self.debug_callback, None);
159176
self.device.destroy_device(None);
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use crate::ash_renderer::device::MyDevice;
2+
use ash::vk;
3+
use std::sync::Arc;
4+
5+
pub struct GlobalDescriptorSetLayout {
6+
pub device: Arc<MyDevice>,
7+
pub layout: vk::DescriptorSetLayout,
8+
}
9+
10+
impl GlobalDescriptorSetLayout {
11+
pub fn new(device: Arc<MyDevice>) -> anyhow::Result<Arc<Self>> {
12+
unsafe {
13+
Ok(Arc::new(Self {
14+
layout: device.create_descriptor_set_layout(
15+
&vk::DescriptorSetLayoutCreateInfo::default().bindings(&[
16+
vk::DescriptorSetLayoutBinding::default()
17+
.binding(0)
18+
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
19+
.stage_flags(vk::ShaderStageFlags::ALL_GRAPHICS)
20+
.descriptor_count(1),
21+
]),
22+
None,
23+
)?,
24+
device,
25+
}))
26+
}
27+
}
28+
}
29+
30+
impl Drop for GlobalDescriptorSetLayout {
31+
fn drop(&mut self) {
32+
unsafe {
33+
self.device.destroy_descriptor_set_layout(self.layout, None);
34+
}
35+
}
36+
}
37+
38+
/// This implementation of descriptor sets is kept simple on purpose, even at the cost of being quite inefficient.
39+
/// Don't use this as a reference on how it should be done!
40+
pub struct GlobalDescriptorSet {
41+
pub layout: Arc<GlobalDescriptorSetLayout>,
42+
pub pool: vk::DescriptorPool,
43+
pub set: vk::DescriptorSet,
44+
}
45+
46+
impl GlobalDescriptorSet {
47+
/// # Safety
48+
/// * `shader_constants` must not be dropped before `GlobalDescriptorSet` is dropped
49+
/// * you must only drop this `GlobalDescriptorSet` when it is unused, e.g. by GPU execution
50+
pub unsafe fn new(
51+
layout: &Arc<GlobalDescriptorSetLayout>,
52+
shader_constants: vk::Buffer,
53+
) -> anyhow::Result<Self> {
54+
unsafe {
55+
let device = &layout.device;
56+
let pool = device.create_descriptor_pool(
57+
&vk::DescriptorPoolCreateInfo::default()
58+
.pool_sizes(&[vk::DescriptorPoolSize::default()
59+
.ty(vk::DescriptorType::STORAGE_BUFFER)
60+
.descriptor_count(1)])
61+
.max_sets(1),
62+
None,
63+
)?;
64+
let set = device.allocate_descriptor_sets(
65+
&vk::DescriptorSetAllocateInfo::default()
66+
.descriptor_pool(pool)
67+
.set_layouts(&[layout.layout]),
68+
)?[0];
69+
device.update_descriptor_sets(
70+
&[vk::WriteDescriptorSet::default()
71+
.dst_set(set)
72+
.dst_binding(0)
73+
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
74+
.descriptor_count(1)
75+
.buffer_info(&[vk::DescriptorBufferInfo::default()
76+
.buffer(shader_constants)
77+
.offset(0)
78+
.range(vk::WHOLE_SIZE)])],
79+
&[],
80+
);
81+
Ok(Self {
82+
layout: layout.clone(),
83+
pool,
84+
set,
85+
})
86+
}
87+
}
88+
}
89+
90+
impl Drop for GlobalDescriptorSet {
91+
fn drop(&mut self) {
92+
let device = &self.layout.device;
93+
unsafe {
94+
device
95+
.reset_descriptor_pool(self.pool, vk::DescriptorPoolResetFlags::empty())
96+
.ok();
97+
device.destroy_descriptor_pool(self.pool, None);
98+
}
99+
}
100+
}

generated/graphics/ash/cargo-gpu/mygraphics/src/ash_renderer/mod.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::ash_renderer::device::MyDevice;
2-
use crate::ash_renderer::render_pipeline::MyRenderPipelineManager;
32
use crate::ash_renderer::renderer::MyRenderer;
43
use crate::ash_renderer::swapchain::MySwapchainManager;
54
use crate::util::enable_debug_layer;
@@ -13,6 +12,7 @@ use winit::{
1312
};
1413

1514
pub mod device;
15+
pub mod global_descriptor_set;
1616
pub mod render_pipeline;
1717
pub mod renderer;
1818
pub mod single_command_buffer;
@@ -36,24 +36,20 @@ pub fn main() -> anyhow::Result<()> {
3636
let extensions = ash_window::enumerate_required_extensions(window.display_handle()?.as_raw())?;
3737
let device = MyDevice::new(extensions, enable_debug_layer())?;
3838
let mut swapchain = MySwapchainManager::new(device.clone(), window)?;
39-
let mut renderer = MyRenderer::new(MyRenderPipelineManager::new(
40-
device.clone(),
41-
swapchain.surface_format.format,
42-
get_shaders()?,
43-
)?)?;
39+
let mut renderer = MyRenderer::new(device.clone(), swapchain.surface_format.format)?;
4440

4541
let start = std::time::Instant::now();
4642
let mut event_handler =
4743
move |event: Event<_>, event_loop_window_target: &ActiveEventLoop| match event {
4844
Event::AboutToWait => swapchain.render(|frame| {
4945
let extent = frame.extent;
50-
let push_constants = ShaderConstants {
46+
let shader_constants = ShaderConstants {
5147
width: extent.width,
5248
height: extent.height,
5349
time: start.elapsed().as_secs_f32(),
5450
};
5551

56-
renderer.render_frame(frame, push_constants)?;
52+
renderer.render_frame(frame, &shader_constants)?;
5753
Ok(())
5854
}),
5955
Event::WindowEvent { event, .. } => {

generated/graphics/ash/cargo-gpu/mygraphics/src/ash_renderer/render_pipeline.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use crate::ash_renderer::device::MyDevice;
2+
use crate::ash_renderer::global_descriptor_set::{GlobalDescriptorSet, GlobalDescriptorSetLayout};
23
use anyhow::Context;
34
use ash::vk;
4-
use mygraphics_shaders::ShaderConstants;
55
use std::sync::Arc;
66

77
/// Manages the creation and recreation of [`MyRenderPipeline`], whenever new shader code ([`Self::set_shader_code`])
88
/// is submitted
99
pub struct MyRenderPipelineManager {
1010
pub device: Arc<MyDevice>,
11+
global_descriptor_set_layout: Arc<GlobalDescriptorSetLayout>,
1112
color_out_format: vk::Format,
1213
shader_code: Vec<u32>,
1314
pipeline: Option<MyRenderPipeline>,
@@ -22,11 +23,13 @@ pub struct MyRenderPipeline {
2223
impl MyRenderPipelineManager {
2324
pub fn new(
2425
device: Arc<MyDevice>,
26+
global_descriptor_set_layout: Arc<GlobalDescriptorSetLayout>,
2527
color_out_format: vk::Format,
2628
shader_code: Vec<u32>,
2729
) -> anyhow::Result<Self> {
2830
Ok(Self {
2931
device,
32+
global_descriptor_set_layout,
3033
color_out_format,
3134
shader_code,
3235
pipeline: None,
@@ -63,12 +66,8 @@ impl MyRenderPipelineManager {
6366
)?;
6467

6568
let pipeline_layout = self.device.create_pipeline_layout(
66-
&vk::PipelineLayoutCreateInfo::default().push_constant_ranges(&[
67-
vk::PushConstantRange::default()
68-
.offset(0)
69-
.size(size_of::<ShaderConstants>() as u32)
70-
.stage_flags(vk::ShaderStageFlags::ALL),
71-
]),
69+
&vk::PipelineLayoutCreateInfo::default()
70+
.set_layouts(&[self.global_descriptor_set_layout.layout]),
7271
None,
7372
)?;
7473

@@ -177,7 +176,7 @@ impl MyRenderPipeline {
177176
cmd: vk::CommandBuffer,
178177
color_out: vk::ImageView,
179178
extent: vk::Extent2D,
180-
push_constants: ShaderConstants,
179+
global_descriptor_set: &GlobalDescriptorSet,
181180
) -> anyhow::Result<()> {
182181
unsafe {
183182
let render_area = vk::Rect2D {
@@ -216,12 +215,13 @@ impl MyRenderPipeline {
216215
}],
217216
);
218217
device.cmd_set_scissor(cmd, 0, &[render_area]);
219-
device.cmd_push_constants(
218+
device.cmd_bind_descriptor_sets(
220219
cmd,
220+
vk::PipelineBindPoint::GRAPHICS,
221221
self.pipeline_layout,
222-
vk::ShaderStageFlags::ALL,
223222
0,
224-
bytemuck::bytes_of(&push_constants),
223+
&[global_descriptor_set.set],
224+
&[],
225225
);
226226
device.cmd_draw(cmd, 3, 1, 0, 0);
227227
device.cmd_end_rendering(cmd);

0 commit comments

Comments
 (0)