From 61e2e242cd27a98b11f4e237cdd81d058378a180 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 11 Jun 2021 19:14:41 -0400 Subject: [PATCH] hal/vk: textures and samplers --- wgpu-core/src/device/mod.rs | 5 +- wgpu-core/src/resource.rs | 1 + wgpu-core/src/swap_chain.rs | 1 + wgpu-hal/README.md | 23 ++++ wgpu-hal/src/lib.rs | 29 +++-- wgpu-hal/src/vulkan/adapter.rs | 2 +- wgpu-hal/src/vulkan/conv.rs | 75 +++++++++++ wgpu-hal/src/vulkan/device.rs | 216 ++++++++++++++++++++++---------- wgpu-hal/src/vulkan/instance.rs | 6 + wgpu-hal/src/vulkan/mod.rs | 40 +++--- 10 files changed, 295 insertions(+), 103 deletions(-) create mode 100644 wgpu-hal/README.md diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 7d8632afd..0caf8d006 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -513,6 +513,7 @@ impl Device { return Err(resource::CreateTextureError::InvalidMipLevelCount(mips)); } + let hal_usage = conv::map_texture_usage(desc.usage, desc.format.into()); let hal_desc = hal::TextureDescriptor { label: desc.label.borrow_option(), size: desc.size, @@ -520,7 +521,7 @@ impl Device { sample_count: desc.sample_count, dimension: desc.dimension, format: desc.format, - usage: conv::map_texture_usage(desc.usage, desc.format.into()), + usage: hal_usage, memory_flags: hal::MemoryFlag::empty(), }; let raw = unsafe { @@ -536,6 +537,7 @@ impl Device { ref_count: self.life_guard.add_ref(), }, desc: desc.map_label(|_| ()), + hal_usage, format_features, full_range: TextureSelector { levels: 0..desc.mip_level_count, @@ -677,6 +679,7 @@ impl Device { label: desc.label.borrow_option(), format, dimension: view_dim, + usage: texture.hal_usage, // pass-through range: desc.range.clone(), }; diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 57eed6989..4b5b0a418 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -165,6 +165,7 @@ pub struct Texture { pub(crate) raw: Option, pub(crate) device_id: Stored, pub(crate) desc: wgt::TextureDescriptor<()>, + pub(crate) hal_usage: hal::TextureUse, pub(crate) format_features: wgt::TextureFormatFeatures, pub(crate) full_range: TextureSelector, pub(crate) life_guard: LifeGuard, diff --git a/wgpu-core/src/swap_chain.rs b/wgpu-core/src/swap_chain.rs index 2ec7eefca..59ab53168 100644 --- a/wgpu-core/src/swap_chain.rs +++ b/wgpu-core/src/swap_chain.rs @@ -174,6 +174,7 @@ impl Global { label: Some("_Frame"), format: sc.desc.format, dimension: wgt::TextureViewDimension::D2, + usage: hal::TextureUse::COLOR_TARGET, range: wgt::ImageSubresourceRange::default(), }; diff --git a/wgpu-hal/README.md b/wgpu-hal/README.md new file mode 100644 index 000000000..6c2e11e3a --- /dev/null +++ b/wgpu-hal/README.md @@ -0,0 +1,23 @@ +*wgpu-hal* is an explicit low-level GPU abstraction powering *wgpu-core*. +It's a spiritual successor to [gfx-hal](https://github.com/gfx-rs/gfx), +but with reduced scope, and oriented towards WebGPU implementation goals. + +It has no overhead for validation or tracking, and the API translation overhead is kept to the bare minimum by the design of WebGPU. +This API can be used for resource-demaninging applications and engines. + +# Usage notes + +All of the API is `unsafe`. Documenting the exact safety requirements for the +state and function arguments is desired, but will likely be incomplete while the library is in early development. + +The returned errors are only for cases that the user can't anticipate, +such as running out-of-memory, or losing the device. +For the counter-example, there is no error for mapping a buffer that's not mappable. +As the buffer creator, the user should already know if they can map it. + +The API accept iterators in order to avoid forcing the user to store data in particular containers. The implementation doesn't guarantee that any of the iterators are drained, unless stated otherwise by the function documentation. +For this reason, we recommend that iterators don't do any mutating work. + +# Debugging + +Most of the information in https://github.com/gfx-rs/wgpu/wiki/Debugging-wgpu-Applications still applies to this API, with an exception of API tracing infrastructure. diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index f081e9467..085fb749d 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -12,7 +12,10 @@ * - Resource transitions are explicit. * - All layouts are explicit. Binding model has compatibility. * - * General design direction: follow 2/3 major target APIs. + * General design direction is to follow the majority by the following weights: + * - wgpu-core: 1.5 + * - primary backends (Vulkan/Metal/DX12): 1.0 each + * - secondary backends (DX11/GLES): 0.5 each */ #![allow( @@ -197,16 +200,12 @@ pub trait Device: Send + Sync { range: MemoryRange, ) -> Result; unsafe fn unmap_buffer(&self, buffer: &A::Buffer) -> Result<(), DeviceError>; - unsafe fn flush_mapped_ranges>( - &self, - buffer: &A::Buffer, - ranges: I, - ); - unsafe fn invalidate_mapped_ranges>( - &self, - buffer: &A::Buffer, - ranges: I, - ); + unsafe fn flush_mapped_ranges(&self, buffer: &A::Buffer, ranges: I) + where + I: Iterator; + unsafe fn invalidate_mapped_ranges(&self, buffer: &A::Buffer, ranges: I) + where + I: Iterator; /// Creates a new texture. /// @@ -696,11 +695,19 @@ pub struct TextureDescriptor<'a> { pub memory_flags: MemoryFlag, } +/// TextureView descriptor. +/// +/// Valid usage: +///. - `format` has to be the same as `TextureDescriptor::format` +///. - `dimension` has to be compatible with `TextureDescriptor::dimension` +///. - `usage` has to be a subset of `TextureDescriptor::usage` +///. - `range` has to be a subset of parent texture #[derive(Clone, Debug)] pub struct TextureViewDescriptor<'a> { pub label: Label<'a>, pub format: wgt::TextureFormat, pub dimension: wgt::TextureViewDimension, + pub usage: TextureUse, pub range: wgt::ImageSubresourceRange, } diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 9c8802030..08d9a991d 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -585,7 +585,6 @@ impl super::Instance { | vk::MemoryPropertyFlags::LAZILY_ALLOCATED, phd_capabilities, phd_features, - available_features, downlevel_flags, private_caps, }; @@ -750,6 +749,7 @@ impl crate::Adapter for super::Adapter { }, features, vendor_id: self.phd_capabilities.properties.vendor_id, + downlevel_flags: self.downlevel_flags, private_caps: self.private_caps.clone(), timestamp_period: self.phd_capabilities.properties.limits.timestamp_period, }), diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index cb32e0dc6..9a0d1efe8 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -1,4 +1,5 @@ use ash::vk; +use std::num::NonZeroU32; impl super::PrivateCapabilities { pub fn map_texture_format(&self, format: wgt::TextureFormat) -> vk::Format { @@ -303,3 +304,77 @@ pub fn map_buffer_usage(usage: crate::BufferUse) -> vk::BufferUsageFlags { } flags } + +pub fn map_view_dimension(dim: wgt::TextureViewDimension) -> vk::ImageViewType { + match dim { + wgt::TextureViewDimension::D1 => vk::ImageViewType::TYPE_1D, + wgt::TextureViewDimension::D2 => vk::ImageViewType::TYPE_2D, + wgt::TextureViewDimension::D2Array => vk::ImageViewType::TYPE_2D_ARRAY, + wgt::TextureViewDimension::Cube => vk::ImageViewType::CUBE, + wgt::TextureViewDimension::CubeArray => vk::ImageViewType::CUBE_ARRAY, + wgt::TextureViewDimension::D3 => vk::ImageViewType::TYPE_3D, + } +} + +pub fn map_subresource_range( + range: &wgt::ImageSubresourceRange, + texture_aspect: crate::FormatAspect, +) -> vk::ImageSubresourceRange { + vk::ImageSubresourceRange { + aspect_mask: map_aspects(crate::FormatAspect::from(range.aspect) & texture_aspect), + base_mip_level: range.base_mip_level, + level_count: range + .mip_level_count + .map_or(vk::REMAINING_MIP_LEVELS, NonZeroU32::get), + base_array_layer: range.base_array_layer, + layer_count: range + .array_layer_count + .map_or(vk::REMAINING_ARRAY_LAYERS, NonZeroU32::get), + } +} + +pub fn map_filter_mode(mode: wgt::FilterMode) -> vk::Filter { + match mode { + wgt::FilterMode::Nearest => vk::Filter::NEAREST, + wgt::FilterMode::Linear => vk::Filter::LINEAR, + } +} + +pub fn map_mip_filter_mode(mode: wgt::FilterMode) -> vk::SamplerMipmapMode { + match mode { + wgt::FilterMode::Nearest => vk::SamplerMipmapMode::NEAREST, + wgt::FilterMode::Linear => vk::SamplerMipmapMode::LINEAR, + } +} + +pub fn map_address_mode(mode: wgt::AddressMode) -> vk::SamplerAddressMode { + match mode { + wgt::AddressMode::ClampToEdge => vk::SamplerAddressMode::CLAMP_TO_EDGE, + wgt::AddressMode::Repeat => vk::SamplerAddressMode::REPEAT, + wgt::AddressMode::MirrorRepeat => vk::SamplerAddressMode::MIRRORED_REPEAT, + wgt::AddressMode::ClampToBorder => vk::SamplerAddressMode::CLAMP_TO_BORDER, + //wgt::AddressMode::MirrorClamp => vk::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, + } +} + +pub fn map_border_color(border_color: wgt::SamplerBorderColor) -> vk::BorderColor { + match border_color { + wgt::SamplerBorderColor::TransparentBlack => vk::BorderColor::FLOAT_TRANSPARENT_BLACK, + wgt::SamplerBorderColor::OpaqueBlack => vk::BorderColor::FLOAT_OPAQUE_BLACK, + wgt::SamplerBorderColor::OpaqueWhite => vk::BorderColor::FLOAT_OPAQUE_WHITE, + } +} + +pub fn map_comparison(fun: wgt::CompareFunction) -> vk::CompareOp { + use wgt::CompareFunction as Cf; + match fun { + Cf::Never => vk::CompareOp::NEVER, + Cf::Less => vk::CompareOp::LESS, + Cf::LessEqual => vk::CompareOp::LESS_OR_EQUAL, + Cf::Equal => vk::CompareOp::EQUAL, + Cf::GreaterEqual => vk::CompareOp::GREATER_OR_EQUAL, + Cf::Greater => vk::CompareOp::GREATER, + Cf::NotEqual => vk::CompareOp::NOT_EQUAL, + Cf::Always => vk::CompareOp::ALWAYS, + } +} diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 9095960c6..373148e44 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1,6 +1,7 @@ use super::conv; use ash::{extensions::khr, version::DeviceV1_0, vk}; +use parking_lot::Mutex; use std::{ptr::NonNull, sync::Arc}; @@ -71,57 +72,18 @@ impl gpu_alloc::MemoryDevice for super::DeviceShared { unsafe fn invalidate_memory_ranges( &self, - ranges: &[gpu_alloc::MappedMemoryRange<'_, vk::DeviceMemory>], + _ranges: &[gpu_alloc::MappedMemoryRange<'_, vk::DeviceMemory>], ) -> Result<(), gpu_alloc::OutOfMemory> { - let vk_ranges = ranges.iter().map(|range| { - vk::MappedMemoryRange::builder() - .memory(*range.memory) - .offset(range.offset) - .size(range.size) - .build() - }); - let result = inplace_it::inplace_or_alloc_from_iter(vk_ranges, |array| { - self.raw.invalidate_mapped_memory_ranges(array) - }); - result.map_err(|err| match err { - vk::Result::ERROR_OUT_OF_DEVICE_MEMORY => gpu_alloc::OutOfMemory::OutOfDeviceMemory, - vk::Result::ERROR_OUT_OF_HOST_MEMORY => gpu_alloc::OutOfMemory::OutOfHostMemory, - err => panic!("Unexpected Vulkan error: `{}`", err), - }) + // should never be called + unimplemented!() } unsafe fn flush_memory_ranges( &self, - ranges: &[gpu_alloc::MappedMemoryRange<'_, vk::DeviceMemory>], + _ranges: &[gpu_alloc::MappedMemoryRange<'_, vk::DeviceMemory>], ) -> Result<(), gpu_alloc::OutOfMemory> { - let vk_ranges = ranges.iter().map(|range| { - vk::MappedMemoryRange::builder() - .memory(*range.memory) - .offset(range.offset) - .size(range.size) - .build() - }); - let result = inplace_it::inplace_or_alloc_from_iter(vk_ranges, |array| { - self.raw.flush_mapped_memory_ranges(array) - }); - result.map_err(|err| match err { - vk::Result::ERROR_OUT_OF_DEVICE_MEMORY => gpu_alloc::OutOfMemory::OutOfDeviceMemory, - vk::Result::ERROR_OUT_OF_HOST_MEMORY => gpu_alloc::OutOfMemory::OutOfHostMemory, - err => panic!("Unexpected Vulkan error: `{}`", err), - }) - } -} - -impl From for crate::DeviceError { - fn from(error: gpu_alloc::AllocationError) -> Self { - use gpu_alloc::AllocationError as Ae; - match error { - Ae::OutOfDeviceMemory | Ae::OutOfHostMemory => Self::OutOfMemory, - _ => { - log::error!("memory allocation: {:?}", error); - Self::Lost - } - } + // should never be called + unimplemented!() } } @@ -189,16 +151,9 @@ impl super::Device { .create_fence(&vk_info, None) .map_err(crate::DeviceError::from)?; - let extent = vk::Extent3D { - width: config.extent.width, - height: config.extent.height, - depth: 1, - }; - Ok(super::Swapchain { raw, functor, - extent, device: Arc::clone(&self.shared), fence, images, @@ -257,27 +212,71 @@ impl crate::Device for super::Device { .raw .bind_buffer_memory(raw, *block.memory(), block.offset())?; - Ok(super::Buffer { raw, block }) + Ok(super::Buffer { + raw, + block: Mutex::new(block), + }) } unsafe fn destroy_buffer(&self, buffer: super::Buffer) { self.shared.raw.destroy_buffer(buffer.raw, None); self.mem_allocator .lock() - .dealloc(&*self.shared, buffer.block); + .dealloc(&*self.shared, buffer.block.into_inner()); } unsafe fn map_buffer( &self, buffer: &super::Buffer, range: crate::MemoryRange, - ) -> DeviceResult { - Err(crate::DeviceError::Lost) + ) -> Result { + let size = range.end - range.start; + let mut block = buffer.block.lock(); + let ptr = block.map(&*self.shared, range.start, size as usize)?; + let is_coherent = block + .props() + .contains(gpu_alloc::MemoryPropertyFlags::HOST_COHERENT); + Ok(crate::BufferMapping { ptr, is_coherent }) } - unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> DeviceResult<()> { + unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> { + buffer.block.lock().unmap(&*self.shared); Ok(()) } - unsafe fn flush_mapped_ranges(&self, buffer: &super::Buffer, ranges: I) {} - unsafe fn invalidate_mapped_ranges(&self, buffer: &super::Buffer, ranges: I) {} + + unsafe fn flush_mapped_ranges(&self, buffer: &super::Buffer, ranges: I) + where + I: Iterator, + { + let block = buffer.block.lock(); + let vk_ranges = ranges.map(|range| { + vk::MappedMemoryRange::builder() + .memory(*block.memory()) + .offset(block.offset() + range.start) + .size(range.end - range.start) + .build() + }); + inplace_it::inplace_or_alloc_from_iter(vk_ranges, |array| { + self.shared.raw.flush_mapped_memory_ranges(array).unwrap() + }); + } + unsafe fn invalidate_mapped_ranges(&self, buffer: &super::Buffer, ranges: I) + where + I: Iterator, + { + let block = buffer.block.lock(); + let vk_ranges = ranges.map(|range| { + vk::MappedMemoryRange::builder() + .memory(*block.memory()) + .offset(block.offset() + range.start) + .size(range.end - range.start) + .build() + }); + inplace_it::inplace_or_alloc_from_iter(vk_ranges, |array| { + self.shared + .raw + .invalidate_mapped_memory_ranges(array) + .unwrap() + }); + } unsafe fn create_texture( &self, @@ -322,6 +321,7 @@ impl crate::Device for super::Device { Ok(super::Texture { raw, block: Some(block), + aspects: crate::FormatAspect::from(desc.format), }) } unsafe fn destroy_texture(&self, texture: super::Texture) { @@ -335,14 +335,74 @@ impl crate::Device for super::Device { &self, texture: &super::Texture, desc: &crate::TextureViewDescriptor, - ) -> DeviceResult { - Ok(Resource) + ) -> Result { + let mut vk_info = vk::ImageViewCreateInfo::builder() + .flags(vk::ImageViewCreateFlags::empty()) + .image(texture.raw) + .view_type(conv::map_view_dimension(desc.dimension)) + .format(self.shared.private_caps.map_texture_format(desc.format)) + //.components(conv::map_swizzle(swizzle)) + .subresource_range(conv::map_subresource_range(&desc.range, texture.aspects)); + + let mut image_view_info; + if self.shared.private_caps.image_view_usage { + image_view_info = vk::ImageViewUsageCreateInfo::builder() + .usage(conv::map_texture_usage(desc.usage)) + .build(); + vk_info = vk_info.push_next(&mut image_view_info); + } + + let raw = self.shared.raw.create_image_view(&vk_info, None)?; + + Ok(super::TextureView { raw }) } - unsafe fn destroy_texture_view(&self, view: Resource) {} - unsafe fn create_sampler(&self, desc: &crate::SamplerDescriptor) -> DeviceResult { - Ok(Resource) + unsafe fn destroy_texture_view(&self, view: super::TextureView) { + self.shared.raw.destroy_image_view(view.raw, None); + } + + unsafe fn create_sampler( + &self, + desc: &crate::SamplerDescriptor, + ) -> Result { + let mut vk_info = vk::SamplerCreateInfo::builder() + .flags(vk::SamplerCreateFlags::empty()) + .mag_filter(conv::map_filter_mode(desc.mag_filter)) + .min_filter(conv::map_filter_mode(desc.min_filter)) + .mipmap_mode(conv::map_mip_filter_mode(desc.mipmap_filter)) + .address_mode_u(conv::map_address_mode(desc.address_modes[0])) + .address_mode_v(conv::map_address_mode(desc.address_modes[1])) + .address_mode_w(conv::map_address_mode(desc.address_modes[2])); + + if let Some(fun) = desc.compare { + vk_info = vk_info + .compare_enable(true) + .compare_op(conv::map_comparison(fun)); + } + if let Some(ref range) = desc.lod_clamp { + vk_info = vk_info.min_lod(range.start).max_lod(range.end); + } + if let Some(aniso) = desc.anisotropy_clamp { + if self + .shared + .downlevel_flags + .contains(wgt::DownlevelFlags::ANISOTROPIC_FILTERING) + { + vk_info = vk_info + .anisotropy_enable(true) + .max_anisotropy(aniso.get() as f32); + } + } + if let Some(color) = desc.border_color { + vk_info = vk_info.border_color(conv::map_border_color(color)); + } + + let raw = self.shared.raw.create_sampler(&vk_info, None)?; + + Ok(super::Sampler { raw }) + } + unsafe fn destroy_sampler(&self, sampler: super::Sampler) { + self.shared.raw.destroy_sampler(sampler.raw, None); } - unsafe fn destroy_sampler(&self, sampler: Resource) {} unsafe fn create_command_buffer( &self, @@ -422,3 +482,29 @@ impl crate::Device for super::Device { } unsafe fn stop_capture(&self) {} } + +impl From for crate::DeviceError { + fn from(error: gpu_alloc::AllocationError) -> Self { + use gpu_alloc::AllocationError as Ae; + match error { + Ae::OutOfDeviceMemory | Ae::OutOfHostMemory => Self::OutOfMemory, + _ => { + log::error!("memory allocation: {:?}", error); + Self::Lost + } + } + } +} + +impl From for crate::DeviceError { + fn from(error: gpu_alloc::MapError) -> Self { + use gpu_alloc::MapError as Me; + match error { + Me::OutOfDeviceMemory | Me::OutOfHostMemory => Self::OutOfMemory, + _ => { + log::error!("memory mapping: {:?}", error); + Self::Lost + } + } + } +} diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 913926bac..9899c0a26 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -20,6 +20,7 @@ impl super::Swapchain { } impl super::Instance { + #[allow(dead_code)] fn create_surface_from_xlib( &self, dpy: *mut vk::Display, @@ -43,6 +44,7 @@ impl super::Instance { self.create_surface_from_vk_surface_khr(surface) } + #[allow(dead_code)] fn create_surface_from_xcb( &self, connection: *mut vk::xcb_connection_t, @@ -66,6 +68,7 @@ impl super::Instance { self.create_surface_from_vk_surface_khr(surface) } + #[allow(dead_code)] fn create_surface_from_wayland( &self, display: *mut c_void, @@ -88,6 +91,7 @@ impl super::Instance { self.create_surface_from_vk_surface_khr(surface) } + #[allow(dead_code)] fn create_surface_android(&self, window: *const c_void) -> super::Surface { let surface = { let a_loader = khr::AndroidSurface::new(&self.entry, &self.shared.raw); @@ -101,6 +105,7 @@ impl super::Instance { self.create_surface_from_vk_surface_khr(surface) } + #[allow(dead_code)] fn create_surface_from_hwnd( &self, hinstance: *mut c_void, @@ -512,6 +517,7 @@ impl crate::Surface for super::Surface { texture: super::Texture { raw: sc.images[index as usize], block: None, + aspects: crate::FormatAspect::COLOR, }, }; Ok(Some(crate::AcquiredSurfaceTexture { diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 17b9c426d..c5476bd9e 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -33,8 +33,8 @@ impl crate::Api for Api { type Buffer = Buffer; type Texture = Texture; type SurfaceTexture = SurfaceTexture; - type TextureView = Resource; - type Sampler = Resource; + type TextureView = TextureView; + type Sampler = Sampler; type QuerySet = Resource; type Fence = Resource; @@ -46,21 +46,11 @@ impl crate::Api for Api { type ComputePipeline = Resource; } -struct RenderDocEntry { - api: renderdoc_sys::RENDERDOC_API_1_4_1, - lib: libloading::Library, -} - -unsafe impl Send for RenderDocEntry {} -unsafe impl Sync for RenderDocEntry {} - struct InstanceShared { raw: ash::Instance, flags: crate::InstanceFlag, get_physical_device_properties: Option, - //TODO //debug_messenger: Option, - //render_doc_entry: Result, } pub struct Instance { @@ -72,7 +62,6 @@ pub struct Instance { struct Swapchain { raw: vk::SwapchainKHR, functor: khr::Swapchain, - extent: vk::Extent3D, device: Arc, fence: vk::Fence, //semaphore: vk::Semaphore, @@ -105,7 +94,6 @@ pub struct Adapter { known_memory_flags: vk::MemoryPropertyFlags, phd_capabilities: adapter::PhysicalDeviceCapabilities, phd_features: adapter::PhysicalDeviceFeatures, - available_features: wgt::Features, downlevel_flags: wgt::DownlevelFlags, private_caps: PrivateCapabilities, } @@ -118,16 +106,6 @@ enum ExtensionFn { Promoted, } -impl ExtensionFn { - /// Expect `self` to be `Self::Extension` and return the inner value. - fn unwrap_extension(&self) -> &T { - match *self { - Self::Extension(ref t) => t, - Self::Promoted => panic!(), - } - } -} - struct DeviceExtensionFunctions { draw_indirect_count: Option>, } @@ -153,6 +131,7 @@ struct DeviceShared { features: wgt::Features, vendor_id: u32, timestamp_period: f32, + downlevel_flags: wgt::DownlevelFlags, private_caps: PrivateCapabilities, } @@ -172,13 +151,24 @@ pub struct Queue { #[derive(Debug)] pub struct Buffer { raw: vk::Buffer, - block: gpu_alloc::MemoryBlock, + block: Mutex>, } #[derive(Debug)] pub struct Texture { raw: vk::Image, block: Option>, + aspects: crate::FormatAspect, +} + +#[derive(Debug)] +pub struct TextureView { + raw: vk::ImageView, +} + +#[derive(Debug)] +pub struct Sampler { + raw: vk::Sampler, } impl crate::Queue for Queue {