Compare commits
No commits in common. "377b10cda28cef1f7362cdfdc93eba6dce490881" and "294ad3dbbd2988694cb911829f4067ec38238b96" have entirely different histories.
377b10cda2
...
294ad3dbbd
|
|
@ -1,11 +1,14 @@
|
|||
use std::borrow::Cow;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
ops::{Deref, DerefMut},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use ash::vk;
|
||||
use gpu_allocator::vulkan::AllocationScheme;
|
||||
use ash::{prelude::VkResult, vk};
|
||||
|
||||
use crate::{
|
||||
Device,
|
||||
device::{Allocation, AllocationStrategy, DeviceObject, QueueFlags},
|
||||
device::{Allocation, DeviceObject, QueueFlags},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -15,9 +18,7 @@ pub struct BufferDesc {
|
|||
pub size: u64,
|
||||
pub usage: vk::BufferUsageFlags,
|
||||
pub queue_families: QueueFlags,
|
||||
|
||||
pub mem_location: gpu_allocator::MemoryLocation,
|
||||
pub alloc_scheme: AllocationStrategy,
|
||||
}
|
||||
|
||||
impl std::hash::Hash for BufferDesc {
|
||||
|
|
@ -39,7 +40,6 @@ impl std::fmt::Debug for BufferDesc {
|
|||
.field("usage", &self.usage)
|
||||
.field("queue_families", &self.queue_families)
|
||||
.field("mem_location", &self.mem_location)
|
||||
.field("alloc_scheme", &self.alloc_scheme)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
|
@ -66,7 +66,6 @@ impl Default for BufferDesc {
|
|||
usage: Default::default(),
|
||||
queue_families: QueueFlags::empty(),
|
||||
mem_location: gpu_allocator::MemoryLocation::Unknown,
|
||||
alloc_scheme: AllocationStrategy::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -98,12 +97,7 @@ impl Buffer {
|
|||
requirements,
|
||||
location: desc.mem_location,
|
||||
linear: true,
|
||||
allocation_scheme: match desc.alloc_scheme {
|
||||
AllocationStrategy::AllocatorManaged => {
|
||||
AllocationScheme::GpuAllocatorManaged
|
||||
}
|
||||
AllocationStrategy::Dedicated => AllocationScheme::DedicatedBuffer(buffer),
|
||||
},
|
||||
allocation_scheme: gpu_allocator::vulkan::AllocationScheme::GpuAllocatorManaged,
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
|
|
@ -152,7 +146,7 @@ impl Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> vk::Buffer {
|
||||
pub fn buffer(&self) -> vk::Buffer {
|
||||
*self.buffer
|
||||
}
|
||||
pub fn len(&self) -> u64 {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ impl Drop for SingleUseCommandPool {
|
|||
impl SingleUseCommandPool {
|
||||
pub fn new(device: Device, queue: Queue) -> VkResult<Arc<Self>> {
|
||||
let pool_info = vk::CommandPoolCreateInfo::default()
|
||||
.queue_family_index(queue.family_index())
|
||||
.queue_family_index(queue.family())
|
||||
.flags(vk::CommandPoolCreateFlags::TRANSIENT);
|
||||
|
||||
let pool = unsafe { device.dev().create_command_pool(&pool_info, None)? };
|
||||
|
|
@ -110,7 +110,7 @@ impl<T: HasQueue> CommandList<T> {
|
|||
self.0[0]
|
||||
.device()
|
||||
.dev()
|
||||
.queue_submit(queue.raw(), &[info], fence.raw())
|
||||
.queue_submit(queue, &[info], fence.fence())
|
||||
})?;
|
||||
|
||||
Ok(FenceFuture::<'a>::new(fence))
|
||||
|
|
@ -257,7 +257,7 @@ impl SingleUseCommand {
|
|||
self.pool.queue().with_locked(|queue| unsafe {
|
||||
self.device()
|
||||
.dev()
|
||||
.queue_submit(queue.raw(), &[submit_info], fence)
|
||||
.queue_submit(queue, &[submit_info], fence)
|
||||
})?;
|
||||
|
||||
self.state.set_pending();
|
||||
|
|
@ -329,7 +329,7 @@ pub mod traits {
|
|||
queue.with_locked(|queue| unsafe {
|
||||
self.device()
|
||||
.dev()
|
||||
.queue_submit(queue.raw(), &[submit_info], fence.raw())
|
||||
.queue_submit(queue, &[submit_info], fence.fence())
|
||||
})?;
|
||||
|
||||
tracing::trace!("submitted queue {:?} and fence {:?}", queue, fence);
|
||||
|
|
@ -888,7 +888,7 @@ mod command_pools {
|
|||
) -> Result<CommandBufferFuture, Error> {
|
||||
let this = ManuallyDrop::new(self);
|
||||
|
||||
if queue.family_index() != this.pool.family {
|
||||
if queue.1 != this.pool.family {
|
||||
tracing::error!("attempted to submit commandbuffer to incompatible queue.");
|
||||
return Err(Error::InvalidQueueSubmission);
|
||||
}
|
||||
|
|
@ -911,7 +911,7 @@ mod command_pools {
|
|||
queue.with_locked(|queue| unsafe {
|
||||
this.device()
|
||||
.dev()
|
||||
.queue_submit(queue.raw(), &[submit_info], fence.raw())
|
||||
.queue_submit(queue, &[submit_info], fence.fence())
|
||||
})?;
|
||||
|
||||
Ok(CommandBufferFuture {
|
||||
|
|
@ -931,7 +931,7 @@ mod command_pools {
|
|||
}
|
||||
|
||||
impl CommandBufferFuture {
|
||||
pub fn block(&self) -> crate::Result<()> {
|
||||
pub fn block(&self) -> VkResult<()> {
|
||||
self.inner.block()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,18 +118,6 @@ impl DeviceHandle for GpuAllocation {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum AllocationStrategy {
|
||||
#[default]
|
||||
/// Let gpu_allocator manage the memory for this allocation, sub-allocating
|
||||
/// from larger blocks as needed.
|
||||
AllocatorManaged,
|
||||
/// Allocate a dedicated block of memory for this allocation. This is
|
||||
/// recommended for long-lived resources or resources with specific memory
|
||||
/// requirements.
|
||||
Dedicated,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Allocation {
|
||||
Owned(DeviceObject<GpuAllocation>),
|
||||
|
|
@ -156,6 +144,7 @@ impl Allocation {
|
|||
}
|
||||
|
||||
pub struct DeviceInner {
|
||||
pub(crate) alloc: vk_mem::Allocator,
|
||||
pub(crate) alloc2: Mutex<gpu_allocator::vulkan::Allocator>,
|
||||
pub(crate) raw: ash::Device,
|
||||
pub(crate) adapter: PhysicalDeviceInfo,
|
||||
|
|
@ -450,6 +439,13 @@ impl PhysicalDeviceInfo {
|
|||
|
||||
let inner = DeviceInner {
|
||||
raw: device.clone(),
|
||||
alloc: unsafe {
|
||||
vk_mem::Allocator::new(vk_mem::AllocatorCreateInfo::new(
|
||||
&instance.inner.raw,
|
||||
&device,
|
||||
self.pdev,
|
||||
))?
|
||||
},
|
||||
alloc2: Mutex::new(alloc2),
|
||||
instance: instance.clone(),
|
||||
adapter: self,
|
||||
|
|
@ -535,6 +531,9 @@ impl DeviceInner {
|
|||
pub fn sync_threadpool(&self) -> &sync::SyncThreadpool {
|
||||
&self.sync_threadpool
|
||||
}
|
||||
pub fn alloc(&self) -> &vk_mem::Allocator {
|
||||
&self.alloc
|
||||
}
|
||||
pub fn dev(&self) -> &ash::Device {
|
||||
&self.raw
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
use std::{collections::BTreeMap, sync::Arc};
|
||||
|
||||
use ash::vk;
|
||||
use gpu_allocator::MemoryLocation;
|
||||
use ash::{prelude::VkResult, vk};
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use crate::{
|
||||
EguiState,
|
||||
buffers::{Buffer, BufferDesc},
|
||||
commands::traits::CommandBufferExt,
|
||||
device::{self, AllocationStrategy},
|
||||
device::{self, DeviceOwned},
|
||||
images::{Image, ImageDesc, ImageViewDesc},
|
||||
render_graph::{
|
||||
Access, Barrier, GraphResourceDesc, GraphResourceId, PassDesc, RecordFn, RenderContext,
|
||||
|
|
@ -24,7 +23,7 @@ pub fn egui_pre_pass(
|
|||
textures: &mut crate::texture::TextureManager,
|
||||
egui_state: &mut EguiState,
|
||||
output: &egui::FullOutput,
|
||||
) -> crate::Result<()> {
|
||||
) -> VkResult<()> {
|
||||
// allocate resource ids for textures in tessellated list (imported from texture manager)
|
||||
// define accesses for resource ids
|
||||
|
||||
|
|
@ -51,8 +50,7 @@ pub fn egui_pre_pass(
|
|||
depth: 1,
|
||||
},
|
||||
usage: vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST,
|
||||
mem_location: MemoryLocation::GpuOnly,
|
||||
alloc_scheme: AllocationStrategy::Dedicated,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
|
@ -96,7 +94,10 @@ pub fn egui_pre_pass(
|
|||
size: staging_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_SRC,
|
||||
queue_families: device::QueueFlags::empty(),
|
||||
mem_location: MemoryLocation::CpuToGpu,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferHost,
|
||||
alloc_flags: vk_mem::AllocationCreateFlags::MAPPED
|
||||
| vk_mem::AllocationCreateFlags::HOST_ACCESS_SEQUENTIAL_WRITE
|
||||
| vk_mem::AllocationCreateFlags::STRATEGY_FIRST_FIT,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
|
@ -114,14 +115,14 @@ pub fn egui_pre_pass(
|
|||
},
|
||||
usage: vk::ImageUsageFlags::TRANSFER_SRC | vk::ImageUsageFlags::TRANSFER_DST,
|
||||
queue_families: device::QueueFlags::empty(),
|
||||
mem_location: MemoryLocation::GpuOnly,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
},
|
||||
)?);
|
||||
|
||||
let aliased_images = {
|
||||
tracing::trace!("mmap-ing staging buffer");
|
||||
let mut staging_map = staging_buffer.map().unwrap();
|
||||
let mut staging_map = staging_buffer.map()?;
|
||||
let mut offset = 0;
|
||||
|
||||
output
|
||||
|
|
@ -213,7 +214,7 @@ pub fn egui_pre_pass(
|
|||
let texture = textures.get(&id).and_then(|id| ctx.get_image(*id)).unwrap();
|
||||
|
||||
let image: Barrier = image_barrier(
|
||||
alias.raw(),
|
||||
alias.handle(),
|
||||
alias.format(),
|
||||
Access {
|
||||
stage: vk::PipelineStageFlags2::NONE,
|
||||
|
|
@ -236,8 +237,8 @@ pub fn egui_pre_pass(
|
|||
}
|
||||
|
||||
ctx.cmd.copy_buffer_to_image(
|
||||
staging_buffer.raw(),
|
||||
alias.raw(),
|
||||
staging_buffer.handle(),
|
||||
alias.handle(),
|
||||
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||
&[vk::BufferImageCopy {
|
||||
buffer_offset: offset as u64,
|
||||
|
|
@ -254,7 +255,7 @@ pub fn egui_pre_pass(
|
|||
);
|
||||
|
||||
let from_barrier = image_barrier(
|
||||
alias.raw(),
|
||||
alias.handle(),
|
||||
alias.format(),
|
||||
Access {
|
||||
stage: vk::PipelineStageFlags2::TRANSFER,
|
||||
|
|
@ -270,7 +271,7 @@ pub fn egui_pre_pass(
|
|||
);
|
||||
|
||||
let to_barrier = image_barrier(
|
||||
texture.raw(),
|
||||
texture.handle(),
|
||||
texture.format(),
|
||||
Access {
|
||||
stage: vk::PipelineStageFlags2::NONE,
|
||||
|
|
@ -303,9 +304,9 @@ pub fn egui_pre_pass(
|
|||
);
|
||||
}
|
||||
ctx.cmd.copy_images(
|
||||
alias.raw(),
|
||||
alias.handle(),
|
||||
vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
|
||||
texture.raw(),
|
||||
texture.handle(),
|
||||
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||
&[vk::ImageCopy {
|
||||
src_subresource: vk::ImageSubresourceLayers::default()
|
||||
|
|
@ -329,7 +330,7 @@ pub fn egui_pre_pass(
|
|||
);
|
||||
|
||||
let image: Barrier = image_barrier(
|
||||
texture.raw(),
|
||||
texture.handle(),
|
||||
texture.format(),
|
||||
Access {
|
||||
stage: vk::PipelineStageFlags2::TRANSFER,
|
||||
|
|
@ -396,7 +397,7 @@ pub fn egui_pass(
|
|||
egui: &egui::Context,
|
||||
output: egui::FullOutput,
|
||||
target: GraphResourceId,
|
||||
) -> crate::Result<Vec<texture::TextureId>> {
|
||||
) -> VkResult<Vec<texture::TextureId>> {
|
||||
let draw_data = egui.tessellate(output.shapes, output.pixels_per_point);
|
||||
|
||||
#[repr(C)]
|
||||
|
|
@ -460,13 +461,16 @@ pub fn egui_pass(
|
|||
name: Some("egui-draw-staging".into()),
|
||||
size: staging_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_SRC,
|
||||
mem_location: MemoryLocation::CpuToGpu,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferHost,
|
||||
alloc_flags: vk_mem::AllocationCreateFlags::MAPPED
|
||||
| vk_mem::AllocationCreateFlags::HOST_ACCESS_SEQUENTIAL_WRITE
|
||||
| vk_mem::AllocationCreateFlags::STRATEGY_FIRST_FIT,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
||||
{
|
||||
let map = staging.map_mut().unwrap();
|
||||
let mut map = staging.map()?;
|
||||
|
||||
let (st_vertices, rest) = map.split_at_mut(vertices_size);
|
||||
let (st_indices, st_drawcalls) = rest.split_at_mut(indices_size);
|
||||
|
|
@ -480,21 +484,21 @@ pub fn egui_pass(
|
|||
name: Some("egui-draw-vertices".into()),
|
||||
size: vertices_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::VERTEX_BUFFER,
|
||||
mem_location: MemoryLocation::GpuOnly,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
}));
|
||||
let indices = rg.add_resource(GraphResourceDesc::Buffer(BufferDesc {
|
||||
name: Some("egui-draw-indices".into()),
|
||||
size: indices_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::INDEX_BUFFER,
|
||||
mem_location: MemoryLocation::GpuOnly,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
}));
|
||||
let draw_calls = rg.add_resource(GraphResourceDesc::Buffer(BufferDesc {
|
||||
name: Some("egui-draw-draw_calls".into()),
|
||||
size: draw_calls_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::INDIRECT_BUFFER,
|
||||
mem_location: MemoryLocation::GpuOnly,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
}));
|
||||
|
||||
|
|
@ -504,14 +508,13 @@ pub fn egui_pass(
|
|||
name: Some("egui-draw-texture_ids".into()),
|
||||
size: (textures_indices.len() * size_of::<u32>()) as u64,
|
||||
usage: vk::BufferUsageFlags::STORAGE_BUFFER,
|
||||
mem_location: MemoryLocation::CpuToGpu,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
alloc_flags: vk_mem::AllocationCreateFlags::HOST_ACCESS_SEQUENTIAL_WRITE,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
{
|
||||
let map = texture_ids
|
||||
.map_mut()
|
||||
.expect("texture id buffer should be device visible");
|
||||
let mut map = texture_ids.map()?;
|
||||
map.copy_from_slice(bytemuck::cast_slice(&textures_indices));
|
||||
}
|
||||
|
||||
|
|
@ -525,20 +528,22 @@ pub fn egui_pass(
|
|||
vk::DescriptorImageInfo {
|
||||
sampler: samplers.get_sampler(entry.as_sampler_desc()).unwrap(),
|
||||
image_view: texture
|
||||
.create_view(
|
||||
ImageViewDesc::color_2d()
|
||||
.with_mip_range(0..1)
|
||||
.with_layer_range(0..1),
|
||||
)
|
||||
.unwrap()
|
||||
.raw(),
|
||||
.get_view(ImageViewDesc {
|
||||
kind: vk::ImageViewType::TYPE_2D,
|
||||
format: texture.format(),
|
||||
aspect: vk::ImageAspectFlags::COLOR,
|
||||
mip_range: (0..1).into(),
|
||||
layer_range: (0..1).into(),
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap(),
|
||||
image_layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let uniform_info = vk::DescriptorBufferInfo {
|
||||
buffer: texture_ids.raw(),
|
||||
buffer: texture_ids.buffer(),
|
||||
offset: 0,
|
||||
range: texture_ids.len(),
|
||||
};
|
||||
|
|
@ -604,8 +609,8 @@ pub fn egui_pass(
|
|||
let target = ctx.get_image(target).unwrap();
|
||||
|
||||
cmd.copy_buffers(
|
||||
staging.raw(),
|
||||
vertices.raw(),
|
||||
staging.buffer(),
|
||||
vertices.buffer(),
|
||||
&[vk::BufferCopy {
|
||||
src_offset: 0,
|
||||
dst_offset: 0,
|
||||
|
|
@ -613,8 +618,8 @@ pub fn egui_pass(
|
|||
}],
|
||||
);
|
||||
cmd.copy_buffers(
|
||||
staging.raw(),
|
||||
indices.raw(),
|
||||
staging.buffer(),
|
||||
indices.buffer(),
|
||||
&[vk::BufferCopy {
|
||||
src_offset: vertices_size as u64,
|
||||
dst_offset: 0,
|
||||
|
|
@ -622,8 +627,8 @@ pub fn egui_pass(
|
|||
}],
|
||||
);
|
||||
cmd.copy_buffers(
|
||||
staging.raw(),
|
||||
draw_calls.raw(),
|
||||
staging.buffer(),
|
||||
draw_calls.buffer(),
|
||||
&[vk::BufferCopy {
|
||||
src_offset: (vertices_size + indices_size) as u64,
|
||||
dst_offset: 0,
|
||||
|
|
@ -633,7 +638,7 @@ pub fn egui_pass(
|
|||
|
||||
let barriers = [
|
||||
buffer_barrier(
|
||||
vertices.raw(),
|
||||
vertices.handle(),
|
||||
0,
|
||||
vertices.len(),
|
||||
Access::transfer_write(),
|
||||
|
|
@ -641,7 +646,7 @@ pub fn egui_pass(
|
|||
None,
|
||||
),
|
||||
buffer_barrier(
|
||||
indices.raw(),
|
||||
indices.handle(),
|
||||
0,
|
||||
indices.len(),
|
||||
Access::transfer_write(),
|
||||
|
|
@ -649,7 +654,7 @@ pub fn egui_pass(
|
|||
None,
|
||||
),
|
||||
buffer_barrier(
|
||||
draw_calls.raw(),
|
||||
draw_calls.handle(),
|
||||
0,
|
||||
draw_calls.len(),
|
||||
Access::transfer_write(),
|
||||
|
|
@ -666,7 +671,12 @@ pub fn egui_pass(
|
|||
|
||||
let color_attachment = &vk::RenderingAttachmentInfo::default()
|
||||
.image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
|
||||
.image_view(target.create_view(ImageViewDesc::color_2d())?.raw())
|
||||
.image_view(target.get_view(ImageViewDesc {
|
||||
kind: vk::ImageViewType::TYPE_2D,
|
||||
format: target.format(),
|
||||
aspect: vk::ImageAspectFlags::COLOR,
|
||||
..Default::default()
|
||||
})?)
|
||||
.load_op(vk::AttachmentLoadOp::LOAD)
|
||||
.store_op(vk::AttachmentStoreOp::STORE);
|
||||
|
||||
|
|
@ -690,8 +700,8 @@ pub fn egui_pass(
|
|||
.height(target.height() as f32)]);
|
||||
|
||||
cmd.bind_pipeline(&pipeline);
|
||||
cmd.bind_indices(indices.raw(), 0, vk::IndexType::UINT32);
|
||||
cmd.bind_vertex_buffers(&[vertices.raw()], &[0]);
|
||||
cmd.bind_indices(indices.buffer(), 0, vk::IndexType::UINT32);
|
||||
cmd.bind_vertex_buffers(&[vertices.buffer()], &[0]);
|
||||
cmd.push_constants(
|
||||
&pipeline_layout,
|
||||
vk::ShaderStageFlags::VERTEX,
|
||||
|
|
@ -706,7 +716,7 @@ pub fn egui_pass(
|
|||
&[descriptor_set],
|
||||
);
|
||||
cmd.draw_indexed_indirect(
|
||||
draw_calls.raw(),
|
||||
draw_calls.buffer(),
|
||||
0,
|
||||
num_draw_calls as u32,
|
||||
size_of::<vk::DrawIndexedIndirectCommand>() as u32,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,21 @@
|
|||
use std::{borrow::Cow, sync::Arc};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashMap,
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
device::{Allocation, AllocationStrategy, DeviceHandle, DeviceObject, QueueFlags},
|
||||
define_device_owned_handle,
|
||||
device::{Allocation, DeviceHandle, DeviceObject, DeviceOwned, QueueFlags},
|
||||
swapchain::Swapchain,
|
||||
util::weak_vec::WeakVec,
|
||||
};
|
||||
|
||||
use super::Device;
|
||||
use ash::vk;
|
||||
use ash::{prelude::*, vk};
|
||||
use gpu_allocator::vulkan::{AllocationCreateDesc, AllocationScheme};
|
||||
use parking_lot::Mutex;
|
||||
use vk_mem::Alloc;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ImageDesc {
|
||||
|
|
@ -27,7 +33,6 @@ pub struct ImageDesc {
|
|||
pub layout: vk::ImageLayout,
|
||||
|
||||
pub mem_location: gpu_allocator::MemoryLocation,
|
||||
pub alloc_scheme: AllocationStrategy,
|
||||
}
|
||||
|
||||
impl std::hash::Hash for ImageDesc {
|
||||
|
|
@ -82,7 +87,6 @@ impl<'a> std::fmt::Debug for ImageDesc {
|
|||
.field("queue_families", &self.queue_families)
|
||||
.field("layout", &self.layout)
|
||||
.field("mem_location", &self.mem_location)
|
||||
.field("alloc_scheme", &self.alloc_scheme)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +107,6 @@ impl Default for ImageDesc {
|
|||
queue_families: QueueFlags::empty(),
|
||||
layout: vk::ImageLayout::UNDEFINED,
|
||||
mem_location: gpu_allocator::MemoryLocation::Unknown,
|
||||
alloc_scheme: AllocationStrategy::AllocatorManaged,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -165,10 +168,7 @@ impl Image {
|
|||
requirements,
|
||||
location: desc.mem_location,
|
||||
linear: desc.tiling == vk::ImageTiling::LINEAR,
|
||||
allocation_scheme: match desc.alloc_scheme {
|
||||
AllocationStrategy::AllocatorManaged => AllocationScheme::GpuAllocatorManaged,
|
||||
AllocationStrategy::Dedicated => AllocationScheme::DedicatedImage(image),
|
||||
},
|
||||
allocation_scheme: AllocationScheme::GpuAllocatorManaged,
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
|
|
@ -316,10 +316,6 @@ impl Image {
|
|||
|
||||
Ok((image, requirements))
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> vk::Image {
|
||||
self.image.image()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Image {}
|
||||
|
|
@ -363,35 +359,35 @@ impl Image {
|
|||
self.image.allocation_mut()
|
||||
}
|
||||
|
||||
// /// technically, this ImageView belongs to the image and is managed by it.
|
||||
// pub fn get_view(&self, desc: ImageViewDesc) -> VkResult<vk::ImageView> {
|
||||
// use std::collections::hash_map::Entry::*;
|
||||
// match self.views.lock().entry(desc.hash_eq_copy()) {
|
||||
// Occupied(occupied) => Ok(*occupied.get()),
|
||||
// Vacant(vacant) => {
|
||||
// let view = unsafe {
|
||||
// let create_info = vk::ImageViewCreateInfo::default()
|
||||
// .flags(desc.flags)
|
||||
// .image(self.image())
|
||||
// .view_type(vk::ImageViewType::TYPE_2D)
|
||||
// .format(desc.format)
|
||||
// .components(desc.components)
|
||||
// .subresource_range(
|
||||
// vk::ImageSubresourceRange::default()
|
||||
// .aspect_mask(desc.aspect)
|
||||
// .base_mip_level(desc.mip_range.0)
|
||||
// .level_count(desc.mip_range.count())
|
||||
// .base_array_layer(desc.layer_range.0)
|
||||
// .layer_count(desc.layer_range.count()),
|
||||
// );
|
||||
// self.device().dev().create_image_view(&create_info, None)?
|
||||
// };
|
||||
// Ok(*vacant.insert(view))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
/// technically, this ImageView belongs to the image and is managed by it.
|
||||
pub fn get_view(&self, desc: ImageViewDesc) -> VkResult<vk::ImageView> {
|
||||
use std::collections::hash_map::Entry::*;
|
||||
match self.views.lock().entry(desc.hash_eq_copy()) {
|
||||
Occupied(occupied) => Ok(*occupied.get()),
|
||||
Vacant(vacant) => {
|
||||
let view = unsafe {
|
||||
let create_info = vk::ImageViewCreateInfo::default()
|
||||
.flags(desc.flags)
|
||||
.image(self.image())
|
||||
.view_type(vk::ImageViewType::TYPE_2D)
|
||||
.format(desc.format)
|
||||
.components(desc.components)
|
||||
.subresource_range(
|
||||
vk::ImageSubresourceRange::default()
|
||||
.aspect_mask(desc.aspect)
|
||||
.base_mip_level(desc.mip_range.0)
|
||||
.level_count(desc.mip_range.count())
|
||||
.base_array_layer(desc.layer_range.0)
|
||||
.layer_count(desc.layer_range.count()),
|
||||
);
|
||||
self.device().dev().create_image_view(&create_info, None)?
|
||||
};
|
||||
Ok(*vacant.insert(view))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_view(self: &Arc<Self>, mut desc: ImageViewDesc) -> crate::Result<ImageView> {
|
||||
pub fn create_view(&self, desc: ImageViewDesc) -> crate::Result<ImageView> {
|
||||
// validate
|
||||
if !view_kind_compatible(self.desc.kind, desc.kind) {
|
||||
tracing::error!(
|
||||
|
|
@ -411,24 +407,7 @@ impl Image {
|
|||
desc.mip_range,
|
||||
self.desc.mip_levels
|
||||
);
|
||||
return Err(crate::Error::Todo(
|
||||
"image view mip range exceeds image mip levels",
|
||||
));
|
||||
}
|
||||
|
||||
if desc.format == vk::Format::UNDEFINED {
|
||||
desc.format = self.desc.format;
|
||||
}
|
||||
|
||||
if !validate_image_view_format(&self.desc, desc.format) {
|
||||
tracing::error!(
|
||||
"image view format {:?} is not compatible with image format {:?}",
|
||||
desc.format,
|
||||
self.desc.format
|
||||
);
|
||||
return Err(crate::Error::Todo(
|
||||
"image view format is not compatible with image format",
|
||||
));
|
||||
return Err(crate::Error::Unspecified);
|
||||
}
|
||||
|
||||
let create_info = vk::ImageViewCreateInfo::default()
|
||||
|
|
@ -449,22 +428,7 @@ impl Image {
|
|||
let device = self.image.device();
|
||||
let view = unsafe { device.raw.create_image_view(&create_info, None)? };
|
||||
|
||||
Ok(ImageView {
|
||||
view: DeviceObject::new(view, device.clone(), desc.name.clone()),
|
||||
desc,
|
||||
image: self.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_image_view_format(image: &ImageDesc, view_format: vk::Format) -> bool {
|
||||
let mutable = image.flags.contains(vk::ImageCreateFlags::MUTABLE_FORMAT);
|
||||
|
||||
if mutable {
|
||||
image.format == view_format
|
||||
|| FormatClass::from(image.format) == FormatClass::from(view_format)
|
||||
} else {
|
||||
image.format == view_format
|
||||
ImageView::construct(self.device().clone(), view, desc.name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -492,44 +456,7 @@ pub struct ImageViewDesc {
|
|||
}
|
||||
|
||||
impl ImageViewDesc {
|
||||
pub fn color_2d() -> Self {
|
||||
Self {
|
||||
kind: vk::ImageViewType::TYPE_2D,
|
||||
aspect: vk::ImageAspectFlags::COLOR,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_format(self, format: vk::Format) -> Self {
|
||||
Self { format, ..self }
|
||||
}
|
||||
|
||||
pub fn with_mip_range<R: core::ops::RangeBounds<u32>>(self, range: R) -> Self {
|
||||
Self {
|
||||
mip_range: range.into(),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_layer_range<R: core::ops::RangeBounds<u32>>(self, range: R) -> Self {
|
||||
Self {
|
||||
layer_range: range.into(),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_aspect(self, aspect: vk::ImageAspectFlags) -> Self {
|
||||
Self { aspect, ..self }
|
||||
}
|
||||
|
||||
pub fn with_name(self, name: impl Into<Cow<'static, str>>) -> Self {
|
||||
Self {
|
||||
name: Some(name.into()),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn hash_eq_copy(&self) -> Self {
|
||||
pub fn hash_eq_copy(&self) -> Self {
|
||||
let &Self {
|
||||
flags,
|
||||
kind,
|
||||
|
|
@ -634,15 +561,6 @@ pub struct ImageView {
|
|||
image: Arc<Image>,
|
||||
}
|
||||
|
||||
impl ImageView {
|
||||
pub fn raw(&self) -> vk::ImageView {
|
||||
*self.view
|
||||
}
|
||||
pub fn image(&self) -> &Arc<Image> {
|
||||
&self.image
|
||||
}
|
||||
}
|
||||
|
||||
impl DeviceHandle for vk::ImageView {
|
||||
unsafe fn destroy(&mut self, device: &Device) {
|
||||
unsafe {
|
||||
|
|
@ -671,487 +589,3 @@ pub const SUBRESOURCERANGE_COLOR_ALL: vk::ImageSubresourceRange = vk::ImageSubre
|
|||
base_array_layer: 0,
|
||||
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
||||
};
|
||||
|
||||
// copilot generated from spec:
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum FormatClass {
|
||||
Bits8,
|
||||
Bits16,
|
||||
Alpha8,
|
||||
Bits24,
|
||||
Bits32,
|
||||
Bits48,
|
||||
Bits64,
|
||||
Bits96,
|
||||
Bits128,
|
||||
Bits192,
|
||||
Bits256,
|
||||
|
||||
D16,
|
||||
D24,
|
||||
D32,
|
||||
S8,
|
||||
D16S8,
|
||||
D24S8,
|
||||
D32S8,
|
||||
|
||||
Bc1Rgb,
|
||||
Bc1Rgba,
|
||||
Bc2,
|
||||
Bc3,
|
||||
Bc4,
|
||||
Bc5,
|
||||
Bc6h,
|
||||
Bc7,
|
||||
|
||||
Etc2Rgb,
|
||||
Etc2Rgba,
|
||||
Etc2EacRgba,
|
||||
EacR,
|
||||
EacRg,
|
||||
|
||||
Astc4x4,
|
||||
Astc5x4,
|
||||
Astc5x5,
|
||||
Astc6x5,
|
||||
Astc6x6,
|
||||
Astc8x5,
|
||||
Astc8x6,
|
||||
Astc8x8,
|
||||
Astc10x5,
|
||||
Astc10x6,
|
||||
Astc10x8,
|
||||
Astc10x10,
|
||||
Astc12x10,
|
||||
Astc12x12,
|
||||
|
||||
YuvG8B8G8R8_422,
|
||||
YuvB8G8R8G8_422,
|
||||
|
||||
YuvG8B8R8Triplane420,
|
||||
YuvG8B8R8Biplane420,
|
||||
YuvG8B8R8Triplane422,
|
||||
YuvG8B8R8Biplane422,
|
||||
YuvG8B8R8Triplane444,
|
||||
YuvG10X6B10X6R10X6Triplane420,
|
||||
YuvG10X6B10X6R10X6Biplane420,
|
||||
YuvG10X6B10X6R10X6Triplane422,
|
||||
YuvG10X6B10X6R10X6Biplane422,
|
||||
YuvG10X6B10X6R10X6Triplane444,
|
||||
YuvG12X4B12X4R12X4Triplane420,
|
||||
YuvG12X4B12X4R12X4Biplane420,
|
||||
YuvG12X4B12X4R12X4Triplane422,
|
||||
YuvG12X4B12X4R12X4Biplane422,
|
||||
YuvG12X4B12X4R12X4Triplane444,
|
||||
YuvG16B16R16Triplane420,
|
||||
YuvG16B16R16Biplane420,
|
||||
YuvG16B16R16Triplane422,
|
||||
YuvG16B16R16Biplane422,
|
||||
YuvG16B16R16Triplane444,
|
||||
|
||||
YuvG8B8R8Biplane444,
|
||||
YuvG10X6B10X6R10X6Biplane444,
|
||||
YuvG12X4B12X4R12X4Biplane444,
|
||||
YuvG16B16R16Biplane444,
|
||||
|
||||
Bits64R10G10B10A10,
|
||||
Bits64G10B10G10R10_422,
|
||||
Bits64B10G10R10G10_422,
|
||||
Bits64R12G12B12A12,
|
||||
Bits64G12B12G12R12_422,
|
||||
Bits64B12G12R12G12_422,
|
||||
Bits64G16B16G16R16_422,
|
||||
Bits64B16G16R16G16_422,
|
||||
Bits64R14G14B14A14,
|
||||
|
||||
Pvrtc1_2bpp,
|
||||
Pvrtc1_4bpp,
|
||||
Pvrtc2_2bpp,
|
||||
Pvrtc2_4bpp,
|
||||
|
||||
Astc3x3x3,
|
||||
Astc4x3x3,
|
||||
Astc4x4x3,
|
||||
Astc4x4x4,
|
||||
Astc5x4x4,
|
||||
Astc5x5x4,
|
||||
Astc5x5x5,
|
||||
Astc6x5x5,
|
||||
Astc6x6x5,
|
||||
Astc6x6x6,
|
||||
|
||||
YuvG14X2B14X2R14X2Biplane420,
|
||||
YuvG14X2B14X2R14X2Biplane422,
|
||||
}
|
||||
|
||||
impl From<vk::Format> for FormatClass {
|
||||
fn from(format: vk::Format) -> Self {
|
||||
use vk::Format as F;
|
||||
match format {
|
||||
// 8-bit
|
||||
F::R4G4_UNORM_PACK8
|
||||
| F::R8_UNORM
|
||||
| F::R8_SNORM
|
||||
| F::R8_USCALED
|
||||
| F::R8_SSCALED
|
||||
// | F::R8_BOOL_ARM
|
||||
// | F::R8_SFLOAT_FPENCODING_FLOAT8E4M3_ARM
|
||||
// | F::R8_SFLOAT_FPENCODING_FLOAT8E5M2_ARM
|
||||
| F::R8_UINT
|
||||
| F::R8_SINT
|
||||
| F::R8_SRGB => FormatClass::Bits8,
|
||||
|
||||
// 16-bit
|
||||
F::A1B5G5R5_UNORM_PACK16_KHR
|
||||
| F::R10X6_UNORM_PACK16
|
||||
| F::R12X4_UNORM_PACK16
|
||||
| F::A4R4G4B4_UNORM_PACK16
|
||||
| F::A4B4G4R4_UNORM_PACK16
|
||||
// | F::R10X6_UINT_PACK16_ARM
|
||||
// | F::R12X4_UINT_PACK16_ARM
|
||||
// | F::R14X2_UINT_PACK16_ARM
|
||||
// | F::R14X2_UNORM_PACK16_ARM
|
||||
// | F::R16_SFLOAT_FPENCODING_BFLOAT16_ARM
|
||||
| F::R4G4B4A4_UNORM_PACK16
|
||||
| F::B4G4R4A4_UNORM_PACK16
|
||||
| F::R5G6B5_UNORM_PACK16
|
||||
| F::B5G6R5_UNORM_PACK16
|
||||
| F::R5G5B5A1_UNORM_PACK16
|
||||
| F::B5G5R5A1_UNORM_PACK16
|
||||
| F::A1R5G5B5_UNORM_PACK16
|
||||
| F::R8G8_UNORM
|
||||
| F::R8G8_SNORM
|
||||
| F::R8G8_USCALED
|
||||
| F::R8G8_SSCALED
|
||||
| F::R8G8_UINT
|
||||
| F::R8G8_SINT
|
||||
| F::R8G8_SRGB
|
||||
| F::R16_UNORM
|
||||
| F::R16_SNORM
|
||||
| F::R16_USCALED
|
||||
| F::R16_SSCALED
|
||||
| F::R16_UINT
|
||||
| F::R16_SINT
|
||||
| F::R16_SFLOAT => FormatClass::Bits16,
|
||||
|
||||
// 8-bit alpha
|
||||
F::A8_UNORM_KHR => FormatClass::Alpha8,
|
||||
|
||||
// 24-bit
|
||||
F::R8G8B8_UNORM
|
||||
| F::R8G8B8_SNORM
|
||||
| F::R8G8B8_USCALED
|
||||
| F::R8G8B8_SSCALED
|
||||
| F::R8G8B8_UINT
|
||||
| F::R8G8B8_SINT
|
||||
| F::R8G8B8_SRGB
|
||||
| F::B8G8R8_UNORM
|
||||
| F::B8G8R8_SNORM
|
||||
| F::B8G8R8_USCALED
|
||||
| F::B8G8R8_SSCALED
|
||||
| F::B8G8R8_UINT
|
||||
| F::B8G8R8_SINT
|
||||
| F::B8G8R8_SRGB => FormatClass::Bits24,
|
||||
|
||||
// 32-bit
|
||||
F::R10X6G10X6_UNORM_2PACK16
|
||||
| F::R12X4G12X4_UNORM_2PACK16
|
||||
// | F::R16G16_SFIXED5_NV
|
||||
// | F::R10X6G10X6_UINT_2PACK16_ARM
|
||||
// | F::R12X4G12X4_UINT_2PACK16_ARM
|
||||
// | F::R14X2G14X2_UINT_2PACK16_ARM
|
||||
// | F::R14X2G14X2_UNORM_2PACK16_ARM
|
||||
| F::R8G8B8A8_UNORM
|
||||
| F::R8G8B8A8_SNORM
|
||||
| F::R8G8B8A8_USCALED
|
||||
| F::R8G8B8A8_SSCALED
|
||||
| F::R8G8B8A8_UINT
|
||||
| F::R8G8B8A8_SINT
|
||||
| F::R8G8B8A8_SRGB
|
||||
| F::B8G8R8A8_UNORM
|
||||
| F::B8G8R8A8_SNORM
|
||||
| F::B8G8R8A8_USCALED
|
||||
| F::B8G8R8A8_SSCALED
|
||||
| F::B8G8R8A8_UINT
|
||||
| F::B8G8R8A8_SINT
|
||||
| F::B8G8R8A8_SRGB
|
||||
| F::A8B8G8R8_UNORM_PACK32
|
||||
| F::A8B8G8R8_SNORM_PACK32
|
||||
| F::A8B8G8R8_USCALED_PACK32
|
||||
| F::A8B8G8R8_SSCALED_PACK32
|
||||
| F::A8B8G8R8_UINT_PACK32
|
||||
| F::A8B8G8R8_SINT_PACK32
|
||||
| F::A8B8G8R8_SRGB_PACK32
|
||||
| F::A2R10G10B10_UNORM_PACK32
|
||||
| F::A2R10G10B10_SNORM_PACK32
|
||||
| F::A2R10G10B10_USCALED_PACK32
|
||||
| F::A2R10G10B10_SSCALED_PACK32
|
||||
| F::A2R10G10B10_UINT_PACK32
|
||||
| F::A2R10G10B10_SINT_PACK32
|
||||
| F::A2B10G10R10_UNORM_PACK32
|
||||
| F::A2B10G10R10_SNORM_PACK32
|
||||
| F::A2B10G10R10_USCALED_PACK32
|
||||
| F::A2B10G10R10_SSCALED_PACK32
|
||||
| F::A2B10G10R10_UINT_PACK32
|
||||
| F::A2B10G10R10_SINT_PACK32
|
||||
| F::R16G16_UNORM
|
||||
| F::R16G16_SNORM
|
||||
| F::R16G16_USCALED
|
||||
| F::R16G16_SSCALED
|
||||
| F::R16G16_UINT
|
||||
| F::R16G16_SINT
|
||||
| F::R16G16_SFLOAT
|
||||
| F::R32_UINT
|
||||
| F::R32_SINT
|
||||
| F::R32_SFLOAT
|
||||
| F::B10G11R11_UFLOAT_PACK32
|
||||
| F::E5B9G9R9_UFLOAT_PACK32 => FormatClass::Bits32,
|
||||
|
||||
// 48-bit
|
||||
F::R16G16B16_UNORM
|
||||
| F::R16G16B16_SNORM
|
||||
| F::R16G16B16_USCALED
|
||||
| F::R16G16B16_SSCALED
|
||||
| F::R16G16B16_UINT
|
||||
| F::R16G16B16_SINT
|
||||
| F::R16G16B16_SFLOAT => FormatClass::Bits48,
|
||||
|
||||
// 64-bit
|
||||
F::R16G16B16A16_UNORM
|
||||
| F::R16G16B16A16_SNORM
|
||||
| F::R16G16B16A16_USCALED
|
||||
| F::R16G16B16A16_SSCALED
|
||||
| F::R16G16B16A16_UINT
|
||||
| F::R16G16B16A16_SINT
|
||||
| F::R16G16B16A16_SFLOAT
|
||||
| F::R32G32_UINT
|
||||
| F::R32G32_SINT
|
||||
| F::R32G32_SFLOAT
|
||||
| F::R64_UINT
|
||||
| F::R64_SINT
|
||||
| F::R64_SFLOAT => FormatClass::Bits64,
|
||||
|
||||
// 96-bit
|
||||
F::R32G32B32_UINT | F::R32G32B32_SINT | F::R32G32B32_SFLOAT => FormatClass::Bits96,
|
||||
|
||||
// 128-bit
|
||||
F::R32G32B32A32_UINT
|
||||
| F::R32G32B32A32_SINT
|
||||
| F::R32G32B32A32_SFLOAT
|
||||
| F::R64G64_UINT
|
||||
| F::R64G64_SINT
|
||||
| F::R64G64_SFLOAT => FormatClass::Bits128,
|
||||
|
||||
// 192-bit
|
||||
F::R64G64B64_UINT | F::R64G64B64_SINT | F::R64G64B64_SFLOAT => FormatClass::Bits192,
|
||||
|
||||
// 256-bit
|
||||
F::R64G64B64A64_UINT | F::R64G64B64A64_SINT | F::R64G64B64A64_SFLOAT => {
|
||||
FormatClass::Bits256
|
||||
}
|
||||
|
||||
// Depth / Stencil
|
||||
F::D16_UNORM => FormatClass::D16,
|
||||
F::X8_D24_UNORM_PACK32 => FormatClass::D24,
|
||||
F::D32_SFLOAT => FormatClass::D32,
|
||||
F::S8_UINT => FormatClass::S8,
|
||||
F::D16_UNORM_S8_UINT => FormatClass::D16S8,
|
||||
F::D24_UNORM_S8_UINT => FormatClass::D24S8,
|
||||
F::D32_SFLOAT_S8_UINT => FormatClass::D32S8,
|
||||
|
||||
// BCn
|
||||
F::BC1_RGB_UNORM_BLOCK | F::BC1_RGB_SRGB_BLOCK => FormatClass::Bc1Rgb,
|
||||
F::BC1_RGBA_UNORM_BLOCK | F::BC1_RGBA_SRGB_BLOCK => FormatClass::Bc1Rgba,
|
||||
F::BC2_UNORM_BLOCK | F::BC2_SRGB_BLOCK => FormatClass::Bc2,
|
||||
F::BC3_UNORM_BLOCK | F::BC3_SRGB_BLOCK => FormatClass::Bc3,
|
||||
F::BC4_UNORM_BLOCK | F::BC4_SNORM_BLOCK => FormatClass::Bc4,
|
||||
F::BC5_UNORM_BLOCK | F::BC5_SNORM_BLOCK => FormatClass::Bc5,
|
||||
F::BC6H_UFLOAT_BLOCK | F::BC6H_SFLOAT_BLOCK => FormatClass::Bc6h,
|
||||
F::BC7_UNORM_BLOCK | F::BC7_SRGB_BLOCK => FormatClass::Bc7,
|
||||
|
||||
// ETC2 / EAC
|
||||
F::ETC2_R8G8B8_UNORM_BLOCK | F::ETC2_R8G8B8_SRGB_BLOCK => FormatClass::Etc2Rgb,
|
||||
F::ETC2_R8G8B8A1_UNORM_BLOCK | F::ETC2_R8G8B8A1_SRGB_BLOCK => FormatClass::Etc2Rgba,
|
||||
F::ETC2_R8G8B8A8_UNORM_BLOCK | F::ETC2_R8G8B8A8_SRGB_BLOCK => FormatClass::Etc2EacRgba,
|
||||
F::EAC_R11_UNORM_BLOCK | F::EAC_R11_SNORM_BLOCK => FormatClass::EacR,
|
||||
F::EAC_R11G11_UNORM_BLOCK | F::EAC_R11G11_SNORM_BLOCK => FormatClass::EacRg,
|
||||
|
||||
// ASTC 2D
|
||||
F::ASTC_4X4_SFLOAT_BLOCK | F::ASTC_4X4_UNORM_BLOCK | F::ASTC_4X4_SRGB_BLOCK => {
|
||||
FormatClass::Astc4x4
|
||||
}
|
||||
F::ASTC_5X4_SFLOAT_BLOCK | F::ASTC_5X4_UNORM_BLOCK | F::ASTC_5X4_SRGB_BLOCK => {
|
||||
FormatClass::Astc5x4
|
||||
}
|
||||
F::ASTC_5X5_SFLOAT_BLOCK | F::ASTC_5X5_UNORM_BLOCK | F::ASTC_5X5_SRGB_BLOCK => {
|
||||
FormatClass::Astc5x5
|
||||
}
|
||||
F::ASTC_6X5_SFLOAT_BLOCK | F::ASTC_6X5_UNORM_BLOCK | F::ASTC_6X5_SRGB_BLOCK => {
|
||||
FormatClass::Astc6x5
|
||||
}
|
||||
F::ASTC_6X6_SFLOAT_BLOCK | F::ASTC_6X6_UNORM_BLOCK | F::ASTC_6X6_SRGB_BLOCK => {
|
||||
FormatClass::Astc6x6
|
||||
}
|
||||
F::ASTC_8X5_SFLOAT_BLOCK | F::ASTC_8X5_UNORM_BLOCK | F::ASTC_8X5_SRGB_BLOCK => {
|
||||
FormatClass::Astc8x5
|
||||
}
|
||||
F::ASTC_8X6_SFLOAT_BLOCK | F::ASTC_8X6_UNORM_BLOCK | F::ASTC_8X6_SRGB_BLOCK => {
|
||||
FormatClass::Astc8x6
|
||||
}
|
||||
F::ASTC_8X8_SFLOAT_BLOCK | F::ASTC_8X8_UNORM_BLOCK | F::ASTC_8X8_SRGB_BLOCK => {
|
||||
FormatClass::Astc8x8
|
||||
}
|
||||
F::ASTC_10X5_SFLOAT_BLOCK | F::ASTC_10X5_UNORM_BLOCK | F::ASTC_10X5_SRGB_BLOCK => {
|
||||
FormatClass::Astc10x5
|
||||
}
|
||||
F::ASTC_10X6_SFLOAT_BLOCK | F::ASTC_10X6_UNORM_BLOCK | F::ASTC_10X6_SRGB_BLOCK => {
|
||||
FormatClass::Astc10x6
|
||||
}
|
||||
F::ASTC_10X8_SFLOAT_BLOCK | F::ASTC_10X8_UNORM_BLOCK | F::ASTC_10X8_SRGB_BLOCK => {
|
||||
FormatClass::Astc10x8
|
||||
}
|
||||
F::ASTC_10X10_SFLOAT_BLOCK | F::ASTC_10X10_UNORM_BLOCK | F::ASTC_10X10_SRGB_BLOCK => {
|
||||
FormatClass::Astc10x10
|
||||
}
|
||||
F::ASTC_12X10_SFLOAT_BLOCK | F::ASTC_12X10_UNORM_BLOCK | F::ASTC_12X10_SRGB_BLOCK => {
|
||||
FormatClass::Astc12x10
|
||||
}
|
||||
F::ASTC_12X12_SFLOAT_BLOCK | F::ASTC_12X12_UNORM_BLOCK | F::ASTC_12X12_SRGB_BLOCK => {
|
||||
FormatClass::Astc12x12
|
||||
}
|
||||
|
||||
// Packed/YCbCr-ish (as listed)
|
||||
F::G8B8G8R8_422_UNORM => FormatClass::YuvG8B8G8R8_422,
|
||||
F::B8G8R8G8_422_UNORM => FormatClass::YuvB8G8R8G8_422,
|
||||
|
||||
F::G8_B8_R8_3PLANE_420_UNORM => FormatClass::YuvG8B8R8Triplane420,
|
||||
F::G8_B8R8_2PLANE_420_UNORM => FormatClass::YuvG8B8R8Biplane420,
|
||||
F::G8_B8_R8_3PLANE_422_UNORM => FormatClass::YuvG8B8R8Triplane422,
|
||||
F::G8_B8R8_2PLANE_422_UNORM => FormatClass::YuvG8B8R8Biplane422,
|
||||
F::G8_B8_R8_3PLANE_444_UNORM => FormatClass::YuvG8B8R8Triplane444,
|
||||
|
||||
F::G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG10X6B10X6R10X6Triplane420
|
||||
}
|
||||
F::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG10X6B10X6R10X6Biplane420
|
||||
}
|
||||
F::G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG10X6B10X6R10X6Triplane422
|
||||
}
|
||||
F::G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG10X6B10X6R10X6Biplane422
|
||||
}
|
||||
F::G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG10X6B10X6R10X6Triplane444
|
||||
}
|
||||
|
||||
F::G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG12X4B12X4R12X4Triplane420
|
||||
}
|
||||
F::G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG12X4B12X4R12X4Biplane420
|
||||
}
|
||||
F::G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG12X4B12X4R12X4Triplane422
|
||||
}
|
||||
F::G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG12X4B12X4R12X4Biplane422
|
||||
}
|
||||
F::G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG12X4B12X4R12X4Triplane444
|
||||
}
|
||||
|
||||
F::G16_B16_R16_3PLANE_420_UNORM => FormatClass::YuvG16B16R16Triplane420,
|
||||
F::G16_B16R16_2PLANE_420_UNORM => FormatClass::YuvG16B16R16Biplane420,
|
||||
F::G16_B16_R16_3PLANE_422_UNORM => FormatClass::YuvG16B16R16Triplane422,
|
||||
F::G16_B16R16_2PLANE_422_UNORM => FormatClass::YuvG16B16R16Biplane422,
|
||||
F::G16_B16_R16_3PLANE_444_UNORM => FormatClass::YuvG16B16R16Triplane444,
|
||||
|
||||
// 2-plane 444 (additional section)
|
||||
F::G8_B8R8_2PLANE_444_UNORM => FormatClass::YuvG8B8R8Biplane444,
|
||||
F::G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG10X6B10X6R10X6Biplane444
|
||||
}
|
||||
F::G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 => {
|
||||
FormatClass::YuvG12X4B12X4R12X4Biplane444
|
||||
}
|
||||
F::G16_B16R16_2PLANE_444_UNORM => FormatClass::YuvG16B16R16Biplane444,
|
||||
|
||||
// 64-bit special grouped headings from the markdown
|
||||
F::R10X6G10X6B10X6A10X6_UNORM_4PACK16 /* | F::R10X6G10X6B10X6A10X6_UINT_4PACK16_ARM */
|
||||
=> {
|
||||
FormatClass::Bits64R10G10B10A10
|
||||
}
|
||||
F::G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 => FormatClass::Bits64G10B10G10R10_422,
|
||||
F::B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 => FormatClass::Bits64B10G10R10G10_422,
|
||||
F::R12X4G12X4B12X4A12X4_UNORM_4PACK16 /*| F::R12X4G12X4B12X4A12X4_UINT_4PACK16_ARM */
|
||||
=> {
|
||||
FormatClass::Bits64R12G12B12A12
|
||||
}
|
||||
F::G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 => FormatClass::Bits64G12B12G12R12_422,
|
||||
F::B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 => FormatClass::Bits64B12G12R12G12_422,
|
||||
F::G16B16G16R16_422_UNORM => FormatClass::Bits64G16B16G16R16_422,
|
||||
F::B16G16R16G16_422_UNORM => FormatClass::Bits64B16G16R16G16_422,
|
||||
|
||||
// F::R14X2G14X2B14X2A14X2_UINT_4PACK16_ARM
|
||||
// | F::R14X2G14X2B14X2A14X2_UNORM_4PACK16_ARM => FormatClass::Bits64_R14G14B14A14,
|
||||
|
||||
// PVRTC
|
||||
F::PVRTC1_2BPP_UNORM_BLOCK_IMG | F::PVRTC1_2BPP_SRGB_BLOCK_IMG => {
|
||||
FormatClass::Pvrtc1_2bpp
|
||||
}
|
||||
F::PVRTC1_4BPP_UNORM_BLOCK_IMG | F::PVRTC1_4BPP_SRGB_BLOCK_IMG => {
|
||||
FormatClass::Pvrtc1_4bpp
|
||||
}
|
||||
F::PVRTC2_2BPP_UNORM_BLOCK_IMG | F::PVRTC2_2BPP_SRGB_BLOCK_IMG => {
|
||||
FormatClass::Pvrtc2_2bpp
|
||||
}
|
||||
F::PVRTC2_4BPP_UNORM_BLOCK_IMG | F::PVRTC2_4BPP_SRGB_BLOCK_IMG => {
|
||||
FormatClass::Pvrtc2_4bpp
|
||||
}
|
||||
|
||||
// ASTC 3D (EXT)
|
||||
// F::ASTC_3X3X3_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_3X3X3_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_3X3X3_SFLOAT_BLOCK_EXT => FormatClass::Astc3x3x3,
|
||||
// F::ASTC_4X3X3_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_4X3X3_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_4X3X3_SFLOAT_BLOCK_EXT => FormatClass::Astc4x3x3,
|
||||
// F::ASTC_4X4X3_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_4X4X3_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_4X4X3_SFLOAT_BLOCK_EXT => FormatClass::Astc4x4x3,
|
||||
// F::ASTC_4X4X4_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_4X4X4_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_4X4X4_SFLOAT_BLOCK_EXT => FormatClass::Astc4x4x4,
|
||||
// F::ASTC_5X4X4_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_5X4X4_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_5X4X4_SFLOAT_BLOCK_EXT => FormatClass::Astc5x4x4,
|
||||
// F::ASTC_5X5X4_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_5X5X4_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_5X5X4_SFLOAT_BLOCK_EXT => FormatClass::Astc5x5x4,
|
||||
// F::ASTC_5X5X5_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_5X5X5_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_5X5X5_SFLOAT_BLOCK_EXT => FormatClass::Astc5x5x5,
|
||||
// F::ASTC_6X5X5_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_6X5X5_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_6X5X5_SFLOAT_BLOCK_EXT => FormatClass::Astc6x5x5,
|
||||
// F::ASTC_6X6X5_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_6X6X5_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_6X6X5_SFLOAT_BLOCK_EXT => FormatClass::Astc6x6x5,
|
||||
// F::ASTC_6X6X6_UNORM_BLOCK_EXT
|
||||
// | F::ASTC_6X6X6_SRGB_BLOCK_EXT
|
||||
// | F::ASTC_6X6X6_SFLOAT_BLOCK_EXT => FormatClass::Astc6x6x6,
|
||||
|
||||
// // 14-bit 2-plane
|
||||
// F::G14X2_B14X2R14X2_2PLANE_420_UNORM_3PACK16_ARM => {
|
||||
// FormatClass::YuvG14X2_B14X2R14X2_2Plane_420
|
||||
// }
|
||||
// F::G14X2_B14X2R14X2_2PLANE_422_UNORM_3PACK16_ARM => {
|
||||
// FormatClass::YuvG14X2_B14X2R14X2_2Plane_422
|
||||
// }
|
||||
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use std::{
|
||||
cell::OnceCell,
|
||||
cmp::Ordering,
|
||||
ffi::{CStr, CString},
|
||||
ops::Deref,
|
||||
|
|
|
|||
|
|
@ -118,8 +118,6 @@ pub enum Error {
|
|||
},
|
||||
#[error("Unspecified Error")]
|
||||
Unspecified,
|
||||
#[error("BEEP BOOP create an error variant for {0} BEEP BOOP")]
|
||||
Todo(&'static str),
|
||||
}
|
||||
|
||||
pub type Result<T> = core::result::Result<T, Error>;
|
||||
|
|
@ -1023,13 +1021,10 @@ impl Renderer2 {
|
|||
surface: &swapchain::Surface,
|
||||
cb: F,
|
||||
) -> Result<T> {
|
||||
let Some(frame) = surface.acquire_image() else {
|
||||
return Err(Error::SuboptimalSwapchain);
|
||||
};
|
||||
let (frame, _suboptimal) = frame.await?;
|
||||
let frame = surface.acquire_image().await?;
|
||||
|
||||
let mut rg = render_graph::RenderGraph::new();
|
||||
let _framebuffer = rg.import_framebuffer(frame.image().clone());
|
||||
let _framebuffer = rg.import_framebuffer(frame.image.clone());
|
||||
|
||||
let out = cb(self, &mut rg);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,15 +47,6 @@ pub struct QueueInner {
|
|||
pub(crate) lock: Mutex<()>,
|
||||
}
|
||||
|
||||
impl QueueInner {
|
||||
pub fn raw(&self) -> vk::Queue {
|
||||
self.raw
|
||||
}
|
||||
pub fn family_index(&self) -> u32 {
|
||||
self.family.index
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct QueueFamily {
|
||||
pub index: u32,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||
buffers::{Buffer, BufferDesc},
|
||||
commands::{self, traits::CommandBufferExt},
|
||||
def_monotonic_id,
|
||||
device::{self},
|
||||
device::{self, DeviceOwned},
|
||||
images::{self, Image, ImageDesc},
|
||||
util::{self, Rgba, WithLifetime},
|
||||
};
|
||||
|
|
@ -62,11 +62,13 @@ impl GraphResource {
|
|||
discr.hash(&mut state);
|
||||
|
||||
match self {
|
||||
GraphResource::Framebuffer(swapchain_frame) => (swapchain_frame.raw()).hash(&mut state),
|
||||
GraphResource::ImportedImage(image) => image.raw().hash(&mut state),
|
||||
GraphResource::ImportedBuffer(buffer) => buffer.raw().hash(&mut state),
|
||||
GraphResource::Image(image) => image.raw().hash(&mut state),
|
||||
GraphResource::Buffer(buffer) => buffer.raw().hash(&mut state),
|
||||
GraphResource::Framebuffer(swapchain_frame) => {
|
||||
(swapchain_frame.handle()).hash(&mut state)
|
||||
}
|
||||
GraphResource::ImportedImage(image) => image.handle().hash(&mut state),
|
||||
GraphResource::ImportedBuffer(buffer) => buffer.handle().hash(&mut state),
|
||||
GraphResource::Image(image) => image.handle().hash(&mut state),
|
||||
GraphResource::Buffer(buffer) => buffer.handle().hash(&mut state),
|
||||
GraphResource::ImageDesc(image_desc) => image_desc.hash(&mut state),
|
||||
GraphResource::BufferDesc(buffer_desc) => buffer_desc.hash(&mut state),
|
||||
GraphResource::Default => {}
|
||||
|
|
@ -484,7 +486,7 @@ impl RenderGraph {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
crate::Result::Ok(())
|
||||
ash::prelude::VkResult::Ok(())
|
||||
})?;
|
||||
|
||||
let pool =
|
||||
|
|
@ -559,19 +561,19 @@ impl RenderGraph {
|
|||
) {
|
||||
let barrier: Barrier = match res {
|
||||
GraphResource::Framebuffer(arc) => {
|
||||
image_barrier(arc.raw(), arc.format(), from, to, None).into()
|
||||
image_barrier(arc.handle(), arc.format(), from, to, None).into()
|
||||
}
|
||||
GraphResource::ImportedImage(arc) => {
|
||||
image_barrier(arc.raw(), arc.format(), from, to, None).into()
|
||||
image_barrier(arc.handle(), arc.format(), from, to, None).into()
|
||||
}
|
||||
GraphResource::ImportedBuffer(arc) => {
|
||||
buffer_barrier(arc.raw(), 0, arc.len(), from, to, None).into()
|
||||
buffer_barrier(arc.handle(), 0, arc.len(), from, to, None).into()
|
||||
}
|
||||
GraphResource::Image(image) => {
|
||||
image_barrier(image.raw(), image.format(), from, to, None).into()
|
||||
image_barrier(image.handle(), image.format(), from, to, None).into()
|
||||
}
|
||||
GraphResource::Buffer(buffer) => {
|
||||
buffer_barrier(buffer.raw(), 0, buffer.len(), from, to, None).into()
|
||||
buffer_barrier(buffer.handle(), 0, buffer.len(), from, to, None).into()
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
|
|
@ -1295,7 +1297,7 @@ pub fn clear_pass(rg: &mut RenderGraph, color: Rgba, target: GraphResourceId) {
|
|||
let cmd = &ctx.cmd;
|
||||
|
||||
cmd.clear_color_image(
|
||||
target.raw(),
|
||||
target.handle(),
|
||||
target.format(),
|
||||
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||
color,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ use std::sync::Arc;
|
|||
|
||||
use ash::vk;
|
||||
use glam::{f32::Mat4, vec3};
|
||||
use gpu_allocator::MemoryLocation;
|
||||
|
||||
pub use crate::egui_pass::{egui_pass, egui_pre_pass};
|
||||
|
||||
|
|
@ -10,7 +9,7 @@ use crate::{
|
|||
Result,
|
||||
buffers::{Buffer, BufferDesc},
|
||||
commands::{self, traits::CommandBufferExt},
|
||||
device::Device,
|
||||
device::{Device, DeviceOwned},
|
||||
images::ImageViewDesc,
|
||||
pipeline,
|
||||
render_graph::{
|
||||
|
|
@ -51,15 +50,16 @@ impl Wireframe {
|
|||
name: Some("wireframe-staging".into()),
|
||||
size: staging_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_SRC,
|
||||
mem_location: MemoryLocation::CpuToGpu,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferHost,
|
||||
alloc_flags: vk_mem::AllocationCreateFlags::MAPPED
|
||||
| vk_mem::AllocationCreateFlags::HOST_ACCESS_SEQUENTIAL_WRITE
|
||||
| vk_mem::AllocationCreateFlags::STRATEGY_FIRST_FIT,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
||||
{
|
||||
let map = staging
|
||||
.map_mut()
|
||||
.expect("staging buffer should be host visible");
|
||||
let mut map = staging.map()?;
|
||||
|
||||
map[..positions_size].copy_from_slice(bytemuck::cast_slice(&positions));
|
||||
map[indices_offset..][..indices_size].copy_from_slice(bytemuck::cast_slice(&indices));
|
||||
|
|
@ -72,7 +72,7 @@ impl Wireframe {
|
|||
name: Some("wireframe-positions".into()),
|
||||
size: positions_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::VERTEX_BUFFER,
|
||||
mem_location: MemoryLocation::GpuOnly,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
|
@ -82,7 +82,7 @@ impl Wireframe {
|
|||
name: Some("wireframe-indices".into()),
|
||||
size: indices_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::INDEX_BUFFER,
|
||||
mem_location: MemoryLocation::GpuOnly,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
|
@ -92,7 +92,7 @@ impl Wireframe {
|
|||
name: Some("wireframe-colors".into()),
|
||||
size: colors_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::VERTEX_BUFFER,
|
||||
mem_location: MemoryLocation::GpuOnly,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
|
@ -102,8 +102,8 @@ impl Wireframe {
|
|||
let cmd = pool.alloc()?;
|
||||
|
||||
cmd.copy_buffers(
|
||||
staging.raw(),
|
||||
positions.raw(),
|
||||
staging.handle(),
|
||||
positions.handle(),
|
||||
&[vk::BufferCopy {
|
||||
src_offset: 0,
|
||||
dst_offset: 0,
|
||||
|
|
@ -111,8 +111,8 @@ impl Wireframe {
|
|||
}],
|
||||
);
|
||||
cmd.copy_buffers(
|
||||
staging.raw(),
|
||||
indices.raw(),
|
||||
staging.handle(),
|
||||
indices.handle(),
|
||||
&[vk::BufferCopy {
|
||||
src_offset: indices_offset as u64,
|
||||
dst_offset: 0,
|
||||
|
|
@ -120,8 +120,8 @@ impl Wireframe {
|
|||
}],
|
||||
);
|
||||
cmd.copy_buffers(
|
||||
staging.raw(),
|
||||
colors.raw(),
|
||||
staging.handle(),
|
||||
colors.handle(),
|
||||
&[vk::BufferCopy {
|
||||
src_offset: colors_offset as u64,
|
||||
dst_offset: 0,
|
||||
|
|
@ -131,7 +131,7 @@ impl Wireframe {
|
|||
|
||||
let barriers = [
|
||||
buffer_barrier(
|
||||
positions.raw(),
|
||||
positions.handle(),
|
||||
0,
|
||||
positions.len(),
|
||||
Access::transfer_write(),
|
||||
|
|
@ -139,7 +139,7 @@ impl Wireframe {
|
|||
None,
|
||||
),
|
||||
buffer_barrier(
|
||||
indices.raw(),
|
||||
indices.handle(),
|
||||
0,
|
||||
indices.len(),
|
||||
Access::transfer_write(),
|
||||
|
|
@ -147,7 +147,7 @@ impl Wireframe {
|
|||
None,
|
||||
),
|
||||
buffer_barrier(
|
||||
colors.raw(),
|
||||
colors.handle(),
|
||||
0,
|
||||
colors.len(),
|
||||
Access::transfer_write(),
|
||||
|
|
@ -334,7 +334,12 @@ impl Wireframe {
|
|||
|
||||
let color_attachment = &vk::RenderingAttachmentInfo::default()
|
||||
.image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
|
||||
.image_view(target.create_view(ImageViewDesc::color_2d())?.raw())
|
||||
.image_view(target.get_view(ImageViewDesc {
|
||||
kind: vk::ImageViewType::TYPE_2D,
|
||||
format: target.format(),
|
||||
aspect: vk::ImageAspectFlags::COLOR,
|
||||
..Default::default()
|
||||
})?)
|
||||
.load_op(vk::AttachmentLoadOp::LOAD)
|
||||
.store_op(vk::AttachmentStoreOp::STORE);
|
||||
|
||||
|
|
@ -358,8 +363,8 @@ impl Wireframe {
|
|||
.height(target.height() as f32)]);
|
||||
|
||||
cmd.bind_pipeline(&pipeline);
|
||||
cmd.bind_indices(indices.raw(), 0, vk::IndexType::UINT32);
|
||||
cmd.bind_vertex_buffers(&[positions.raw(), colors.raw()], &[0, 0]);
|
||||
cmd.bind_indices(indices.buffer(), 0, vk::IndexType::UINT32);
|
||||
cmd.bind_vertex_buffers(&[positions.handle(), colors.handle()], &[0, 0]);
|
||||
cmd.push_constants(
|
||||
&layout,
|
||||
vk::ShaderStageFlags::VERTEX,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
ops::Deref,
|
||||
marker::PhantomData,
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::{AtomicU32, AtomicU64, Ordering},
|
||||
|
|
@ -12,14 +12,16 @@ use ash::{
|
|||
prelude::VkResult,
|
||||
vk::{self, Handle},
|
||||
};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use parking_lot::{Mutex, RawMutex, RwLock};
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
||||
|
||||
use crate::{
|
||||
Instance, PhysicalDeviceInfo, Result, SurfaceCapabilities,
|
||||
device::{Device, DeviceObject},
|
||||
images::{self, ImageViewDesc},
|
||||
sync::Fence,
|
||||
Instance, PhysicalDeviceInfo, Result, SurfaceCapabilities, define_device_owned_handle,
|
||||
device::{Device, DeviceObject, DeviceOwned},
|
||||
images,
|
||||
instance::InstanceInner,
|
||||
sync::{self, Fence},
|
||||
util::RawMutexGuard,
|
||||
};
|
||||
|
||||
use derive_more::Debug;
|
||||
|
|
@ -272,18 +274,6 @@ impl Surface {
|
|||
composite_alpha_mode,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn acquire_image(
|
||||
&self,
|
||||
) -> Option<impl std::future::Future<Output = crate::Result<(SwapchainImage, bool)>>> {
|
||||
// ensure lock does not block for the entire duration of the async image acquisition.
|
||||
let swapchain = self.swapchain.read().as_ref().cloned();
|
||||
if let Some(swapchain) = swapchain {
|
||||
Some(swapchain.acquire_image())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -312,7 +302,7 @@ pub struct Swapchain {
|
|||
|
||||
// Some of the swapchain operations require external synchronisation; this mutex allows `Swapchain` to be `Sync`.
|
||||
#[debug(skip)]
|
||||
pub(crate) guard: parking_lot::Mutex<()>,
|
||||
guard: parking_lot::RawMutex,
|
||||
|
||||
// for khr_present_id/khr_present_wait
|
||||
#[allow(unused)]
|
||||
|
|
@ -375,7 +365,7 @@ impl Swapchain {
|
|||
.expect("swapchain extension not loaded");
|
||||
|
||||
let (swapchain, images) = {
|
||||
let _lock = old_swapchain.as_ref().map(|old| old.guard.lock());
|
||||
let _lock = old_swapchain.as_ref().map(|old| old.lock());
|
||||
let old_swapchain = old_swapchain
|
||||
.map(|swp| *swp.swapchain)
|
||||
.unwrap_or(vk::SwapchainKHR::null());
|
||||
|
|
@ -477,7 +467,7 @@ impl Swapchain {
|
|||
),
|
||||
images,
|
||||
config,
|
||||
guard: Mutex::new(()),
|
||||
guard: <RawMutex as parking_lot::lock_api::RawMutex>::INIT,
|
||||
min_image_count: surface_caps.capabilities.min_image_count,
|
||||
acquire_semaphores,
|
||||
release_semaphores,
|
||||
|
|
@ -495,15 +485,11 @@ impl Swapchain {
|
|||
self.images.len() as u32
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> vk::SwapchainKHR {
|
||||
*self.swapchain
|
||||
}
|
||||
|
||||
/// returns a future yielding the frame, and true if the swapchain is
|
||||
/// suboptimal and should be recreated.
|
||||
fn acquire_image(
|
||||
self: Arc<Self>,
|
||||
) -> impl std::future::Future<Output = crate::Result<(SwapchainImage, bool)>> {
|
||||
) -> impl std::future::Future<Output = crate::Result<(SwapchainFrame, bool)>> {
|
||||
let frame = self
|
||||
.current_frame
|
||||
.try_update(Ordering::Release, Ordering::Relaxed, |i| {
|
||||
|
|
@ -521,34 +507,28 @@ impl Swapchain {
|
|||
// spawn on threadpool because it might block.
|
||||
let (idx, suboptimal) = smol::unblock({
|
||||
let this = self.clone();
|
||||
let fence = fence.raw();
|
||||
move || unsafe {
|
||||
this.with_locked(|swapchain| {
|
||||
this.functor
|
||||
.acquire_next_image(swapchain.raw(), u64::MAX, acquire, fence)
|
||||
.acquire_next_image(swapchain, u64::MAX, acquire, fence.raw())
|
||||
})
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
|
||||
let idx = idx as usize;
|
||||
let image = self.images[idx].clone();
|
||||
let image = Arc::new(images::Image::from_swapchain_image(image, &self));
|
||||
let view = image.create_view(ImageViewDesc {
|
||||
name: Some(format!("swapchain-{:x}-image-view-{idx}", self.raw().as_raw()).into()),
|
||||
kind: vk::ImageViewType::TYPE_2D,
|
||||
format: self.config.format,
|
||||
aspect: vk::ImageAspectFlags::COLOR,
|
||||
..Default::default()
|
||||
})?;
|
||||
|
||||
// wait for image to become available.
|
||||
fence.into_future().await;
|
||||
|
||||
let idx = idx as usize;
|
||||
let image = self.images[idx].clone();
|
||||
let view = self.image_views[idx];
|
||||
|
||||
Ok((
|
||||
SwapchainImage {
|
||||
SwapchainFrame {
|
||||
index: idx as u32,
|
||||
swapchain: self,
|
||||
swapchain: self.clone(),
|
||||
format: self.config.format,
|
||||
image,
|
||||
view,
|
||||
acquire,
|
||||
release,
|
||||
|
|
@ -558,20 +538,12 @@ impl Swapchain {
|
|||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// The caller must ensure that the provided index corresponds to an image
|
||||
/// that is currently acquired and not yet presented.
|
||||
unsafe fn present(&self, index: u32, wait: Option<vk::Semaphore>) -> Result<()> {
|
||||
let _lock = self.guard.lock();
|
||||
fn present(&self, frame: SwapchainFrame, wait: Option<vk::Semaphore>) -> Result<()> {
|
||||
let swpchain = self.lock();
|
||||
let queue = self.device().present_queue().lock();
|
||||
|
||||
let wait_semaphores = wait.as_slice();
|
||||
let present_info = vk::PresentInfoKHR::default()
|
||||
.image_indices(core::slice::from_ref(&index))
|
||||
.swapchains(core::slice::from_ref(&*self.swapchain))
|
||||
.wait_semaphores(wait_semaphores);
|
||||
|
||||
let queue = self.swapchain.device().queues.graphics();
|
||||
queue.with_locked(|queue| -> crate::Result<()> {
|
||||
// TODO: make this optional for devices with no support for present_wait/present_id
|
||||
// let present_id = self
|
||||
// .present_id
|
||||
|
|
@ -579,15 +551,18 @@ impl Swapchain {
|
|||
// let mut present_id =
|
||||
// vk::PresentIdKHR::default().present_ids(core::slice::from_ref(&present_id));
|
||||
|
||||
let present_info = vk::PresentInfoKHR::default()
|
||||
.image_indices(core::slice::from_ref(&frame.index))
|
||||
.swapchains(core::slice::from_ref(&swpchain))
|
||||
.wait_semaphores(wait_semaphores);
|
||||
//.push_next(&mut present_id)
|
||||
|
||||
// call winits pre_present_notify here
|
||||
|
||||
unsafe {
|
||||
self.functor.queue_present(queue.raw(), &present_info)?;
|
||||
self.functor.queue_present(*queue, &present_info)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
|
|
@ -640,41 +615,6 @@ impl Swapchain {
|
|||
}
|
||||
static SWAPCHAIN_COUNT: AtomicU64 = AtomicU64::new(0);
|
||||
|
||||
#[derive(Debug)]
|
||||
#[must_use = "This struct represents an acquired image from the Swapchain and
|
||||
must be presented in order to free resources on the device."]
|
||||
pub struct SwapchainImage {
|
||||
view: images::ImageView,
|
||||
// The swapchain must be kept alive while the image is in use, because the
|
||||
// image is owned by the swapchain and will be freed when the swapchain is
|
||||
// dropped. Additionally, we need access to the swapchain in order to
|
||||
// present the image.
|
||||
swapchain: Arc<Swapchain>,
|
||||
index: u32,
|
||||
pub acquire: vk::Semaphore,
|
||||
pub release: vk::Semaphore,
|
||||
}
|
||||
|
||||
impl Deref for SwapchainImage {
|
||||
type Target = images::ImageView;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.view
|
||||
}
|
||||
}
|
||||
|
||||
impl SwapchainImage {
|
||||
pub fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
|
||||
pub fn present(self, wait: Option<vk::Semaphore>) -> crate::Result<()> {
|
||||
// SAFETY: we know the index is valid because we've aquired the image,
|
||||
// and we know it isn't presented yet because we still own the image.
|
||||
unsafe { self.swapchain.present(self.index, wait) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[must_use = "This struct represents an acquired image from the swapchain and
|
||||
must be presented in order to free resources on the device."]
|
||||
|
|
@ -697,8 +637,7 @@ impl PartialEq for SwapchainFrame {
|
|||
|
||||
impl SwapchainFrame {
|
||||
pub fn present(self, wait: Option<vk::Semaphore>) -> crate::Result<()> {
|
||||
// SAFETY: we know the index is valid because we've aquired the image, and we know it isn't presented yet because we still own the image.
|
||||
unsafe { self.swapchain.present(self.index, wait) }
|
||||
self.swapchain.clone().present(self, wait)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -739,9 +678,19 @@ pub struct SwapchainConfiguration {
|
|||
}
|
||||
|
||||
impl Swapchain {
|
||||
pub fn with_locked<T, F: FnOnce(&Self) -> T>(&self, f: F) -> T {
|
||||
let _lock = self.guard.lock();
|
||||
f(self)
|
||||
pub fn lock(&self) -> RawMutexGuard<'_, vk::SwapchainKHR> {
|
||||
use parking_lot::lock_api::RawMutex;
|
||||
self.guard.lock();
|
||||
RawMutexGuard {
|
||||
mutex: &self.guard,
|
||||
value: &*self.swapchain,
|
||||
_pd: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_locked<T, F: FnOnce(vk::SwapchainKHR) -> T>(&self, f: F) -> T {
|
||||
let lock = self.lock();
|
||||
f(*lock)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,16 @@ use std::borrow::Cow;
|
|||
use std::{
|
||||
future::Future,
|
||||
marker::PhantomData,
|
||||
mem::ManuallyDrop,
|
||||
sync::{Arc, atomic::AtomicU32},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::device::{DeviceObject, Pool, PoolObject, Pooled};
|
||||
use crate::device::{DeviceObject, DeviceOwned, Pool, PoolObject, Pooled};
|
||||
use crate::{Result, device::DeviceInner};
|
||||
|
||||
use super::Device;
|
||||
use ash::{prelude::VkResult, vk};
|
||||
use ash::{prelude::*, vk};
|
||||
use crossbeam::channel::{Receiver, Sender};
|
||||
|
||||
type Message = (SyncPrimitive, std::task::Waker);
|
||||
|
|
@ -211,7 +212,7 @@ impl Fence {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn wait_on(&self, timeout: Option<u64>) -> VkResult<()> {
|
||||
pub fn wait_on(&self, timeout: Option<u64>) -> Result<()> {
|
||||
unsafe {
|
||||
self.device().raw.wait_for_fences(
|
||||
core::slice::from_ref(&self.raw()),
|
||||
|
|
|
|||
Loading…
Reference in a new issue