mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-02-21 19:32:49 +00:00
hal/vk: hook up gpu-descriptor
This commit is contained in:
parent
006c1baaf2
commit
4eae5a38d0
10
Cargo.toml
10
Cargo.toml
@ -1,4 +1,5 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"dummy",
|
||||
"player",
|
||||
@ -18,15 +19,6 @@ default-members = ["wgpu", "player", "wgpu-hal"]
|
||||
[patch."https://github.com/zakarumych/gpu-alloc"]
|
||||
#gpu-alloc = { path = "../gpu-alloc/gpu-alloc" }
|
||||
|
||||
[patch."https://github.com/gfx-rs/gfx"]
|
||||
#gfx-hal = { path = "../gfx/src/hal" }
|
||||
#gfx-backend-empty = { path = "../gfx/src/backend/empty" }
|
||||
#gfx-backend-vulkan = { path = "../gfx/src/backend/vulkan" }
|
||||
#gfx-backend-gl = { path = "../gfx/src/backend/gl" }
|
||||
#gfx-backend-dx12 = { path = "../gfx/src/backend/dx12" }
|
||||
#gfx-backend-dx11 = { path = "../gfx/src/backend/dx11" }
|
||||
#gfx-backend-metal = { path = "../gfx/src/backend/metal" }
|
||||
|
||||
[patch.crates-io]
|
||||
#web-sys = { path = "../wasm-bindgen/crates/web-sys" }
|
||||
#js-sys = { path = "../wasm-bindgen/crates/js-sys" }
|
||||
|
@ -53,7 +53,7 @@ version = "0.1"
|
||||
hal = { path = "../wgpu-hal", package = "wgpu-hal", features = ["metal"] }
|
||||
#Note: could also enable "vulkan" for Vulkan Portability
|
||||
|
||||
[target.'cfg(all(not(target_arch = "wasm32"), all(unix, not(target_os = "ios"), not(target_os = "macos"))))'.dependencies]
|
||||
[target.'cfg(all(not(target_arch = "wasm32"), unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies]
|
||||
hal = { path = "../wgpu-hal", package = "wgpu-hal", features = ["vulkan"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -11,7 +11,7 @@ fn main() {
|
||||
unix_wo_apple: {all(unix, not(apple))},
|
||||
|
||||
// Backends
|
||||
vulkan: { all(false, not(wasm), any(windows, unix_wo_apple)) },
|
||||
vulkan: { all(not(wasm), any(windows, unix_wo_apple)) },
|
||||
metal: { all(not(wasm), apple) },
|
||||
dx12: { all(false, not(wasm), windows) },
|
||||
dx11: { all(false, not(wasm), windows) },
|
||||
|
@ -234,8 +234,8 @@ macro_rules! gfx_select {
|
||||
// Note: For some reason the cfg aliases defined in build.rs don't succesfully apply in this
|
||||
// macro so we must specify their equivalents manually
|
||||
match $id.backend() {
|
||||
//#[cfg(all(not(target_arch = "wasm32"), not(target_os = "ios"), not(target_os = "macos")))]
|
||||
//wgt::Backend::Vulkan => $global.$method::<$crate::backend::Vulkan>( $($param),* ),
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(target_os = "ios"), not(target_os = "macos")))]
|
||||
wgt::Backend::Vulkan => $global.$method::<$crate::backend::Vulkan>( $($param),* ),
|
||||
#[cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))]
|
||||
wgt::Backend::Metal => $global.$method::<$crate::api::Metal>( $($param),* ),
|
||||
/*
|
||||
|
@ -52,8 +52,13 @@ struct Example<A: hal::Api> {
|
||||
|
||||
impl<A: hal::Api> Example<A> {
|
||||
fn init(window: &winit::window::Window) -> Result<Self, hal::InstanceError> {
|
||||
let instance = unsafe { A::Instance::init()? };
|
||||
let instance_desc = hal::InstanceDescriptor {
|
||||
name: "example",
|
||||
flags: hal::InstanceFlag::all(),
|
||||
};
|
||||
let instance = unsafe { A::Instance::init(&instance_desc)? };
|
||||
let mut surface = unsafe { instance.create_surface(window).unwrap() };
|
||||
|
||||
let hal::OpenDevice { device, mut queue } = unsafe {
|
||||
let adapters = instance.enumerate_adapters();
|
||||
let exposed = adapters.get(0).ok_or(hal::InstanceError)?;
|
||||
@ -330,6 +335,7 @@ impl<A: hal::Api> Example<A> {
|
||||
label: None,
|
||||
format: texture_desc.format,
|
||||
dimension: wgt::TextureViewDimension::D2,
|
||||
usage: hal::TextureUse::SAMPLED,
|
||||
range: wgt::ImageSubresourceRange::default(),
|
||||
};
|
||||
let view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() };
|
||||
@ -500,6 +506,7 @@ impl<A: hal::Api> Example<A> {
|
||||
label: None,
|
||||
format: self.surface_format,
|
||||
dimension: wgt::TextureViewDimension::D2,
|
||||
usage: hal::TextureUse::COLOR_TARGET,
|
||||
range: wgt::ImageSubresourceRange::default(),
|
||||
};
|
||||
let surface_tex_view = unsafe {
|
||||
|
@ -741,6 +741,7 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
};
|
||||
gpu_alloc::GpuAllocator::new(config, properties)
|
||||
};
|
||||
let desc_allocator = gpu_descriptor::DescriptorAllocator::new(0);
|
||||
|
||||
let device = super::Device {
|
||||
shared: Arc::new(super::DeviceShared {
|
||||
@ -756,6 +757,7 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
timestamp_period: self.phd_capabilities.properties.limits.timestamp_period,
|
||||
}),
|
||||
mem_allocator: Mutex::new(mem_allocator),
|
||||
desc_allocator: Mutex::new(desc_allocator),
|
||||
valid_ash_memory_types,
|
||||
naga_options,
|
||||
};
|
||||
|
@ -75,7 +75,7 @@ impl crate::CommandBuffer<super::Api> for super::Encoder {
|
||||
&mut self,
|
||||
layout: &super::PipelineLayout,
|
||||
index: u32,
|
||||
group: &Resource,
|
||||
group: &super::BindGroup,
|
||||
dynamic_offsets: &[wgt::DynamicOffset],
|
||||
) {
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::conv;
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use ash::{extensions::khr, version::DeviceV1_0, vk};
|
||||
use inplace_it::inplace_or_alloc_from_iter;
|
||||
use parking_lot::Mutex;
|
||||
@ -134,6 +135,138 @@ impl gpu_alloc::MemoryDevice<vk::DeviceMemory> for super::DeviceShared {
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
gpu_descriptor::DescriptorDevice<vk::DescriptorSetLayout, vk::DescriptorPool, vk::DescriptorSet>
|
||||
for super::DeviceShared
|
||||
{
|
||||
unsafe fn create_descriptor_pool(
|
||||
&self,
|
||||
descriptor_count: &gpu_descriptor::DescriptorTotalCount,
|
||||
max_sets: u32,
|
||||
flags: gpu_descriptor::DescriptorPoolCreateFlags,
|
||||
) -> Result<vk::DescriptorPool, gpu_descriptor::CreatePoolError> {
|
||||
//Note: ignoring other types, since they can't appear here
|
||||
let unfiltered_counts = [
|
||||
(vk::DescriptorType::SAMPLER, descriptor_count.sampler),
|
||||
(
|
||||
vk::DescriptorType::SAMPLED_IMAGE,
|
||||
descriptor_count.sampled_image,
|
||||
),
|
||||
(
|
||||
vk::DescriptorType::STORAGE_IMAGE,
|
||||
descriptor_count.storage_image,
|
||||
),
|
||||
(
|
||||
vk::DescriptorType::UNIFORM_BUFFER,
|
||||
descriptor_count.uniform_buffer,
|
||||
),
|
||||
(
|
||||
vk::DescriptorType::UNIFORM_BUFFER_DYNAMIC,
|
||||
descriptor_count.uniform_buffer_dynamic,
|
||||
),
|
||||
(
|
||||
vk::DescriptorType::STORAGE_BUFFER,
|
||||
descriptor_count.storage_buffer,
|
||||
),
|
||||
(
|
||||
vk::DescriptorType::STORAGE_BUFFER_DYNAMIC,
|
||||
descriptor_count.storage_buffer_dynamic,
|
||||
),
|
||||
];
|
||||
|
||||
let filtered_counts = unfiltered_counts
|
||||
.iter()
|
||||
.cloned()
|
||||
.filter(|&(_, count)| count != 0)
|
||||
.map(|(ty, count)| vk::DescriptorPoolSize {
|
||||
ty,
|
||||
descriptor_count: count,
|
||||
})
|
||||
.collect::<ArrayVec<[_; 8]>>();
|
||||
|
||||
let mut vk_flags = vk::DescriptorPoolCreateFlags::empty();
|
||||
if flags.contains(gpu_descriptor::DescriptorPoolCreateFlags::FREE_DESCRIPTOR_SET) {
|
||||
vk_flags |= vk::DescriptorPoolCreateFlags::FREE_DESCRIPTOR_SET;
|
||||
}
|
||||
let vk_info = vk::DescriptorPoolCreateInfo::builder()
|
||||
.max_sets(max_sets)
|
||||
.flags(vk_flags)
|
||||
.pool_sizes(&filtered_counts)
|
||||
.build();
|
||||
|
||||
match self.raw.create_descriptor_pool(&vk_info, None) {
|
||||
Ok(pool) => Ok(pool),
|
||||
Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => {
|
||||
Err(gpu_descriptor::CreatePoolError::OutOfHostMemory)
|
||||
}
|
||||
Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => {
|
||||
Err(gpu_descriptor::CreatePoolError::OutOfDeviceMemory)
|
||||
}
|
||||
Err(vk::Result::ERROR_FRAGMENTATION) => {
|
||||
Err(gpu_descriptor::CreatePoolError::Fragmentation)
|
||||
}
|
||||
Err(other) => {
|
||||
log::error!("create_descriptor_pool: {:?}", other);
|
||||
Err(gpu_descriptor::CreatePoolError::OutOfHostMemory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn destroy_descriptor_pool(&self, pool: vk::DescriptorPool) {
|
||||
self.raw.destroy_descriptor_pool(pool, None)
|
||||
}
|
||||
|
||||
unsafe fn alloc_descriptor_sets<'a>(
|
||||
&self,
|
||||
pool: &mut vk::DescriptorPool,
|
||||
layouts: impl ExactSizeIterator<Item = &'a vk::DescriptorSetLayout>,
|
||||
sets: &mut impl Extend<vk::DescriptorSet>,
|
||||
) -> Result<(), gpu_descriptor::DeviceAllocationError> {
|
||||
let result = inplace_or_alloc_from_iter(layouts.cloned(), |layouts_slice| {
|
||||
let vk_info = vk::DescriptorSetAllocateInfo::builder()
|
||||
.descriptor_pool(*pool)
|
||||
.set_layouts(layouts_slice)
|
||||
.build();
|
||||
self.raw.allocate_descriptor_sets(&vk_info)
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(vk_sets) => {
|
||||
sets.extend(vk_sets);
|
||||
Ok(())
|
||||
}
|
||||
Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY)
|
||||
| Err(vk::Result::ERROR_OUT_OF_POOL_MEMORY) => {
|
||||
Err(gpu_descriptor::DeviceAllocationError::OutOfHostMemory)
|
||||
}
|
||||
Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => {
|
||||
Err(gpu_descriptor::DeviceAllocationError::OutOfDeviceMemory)
|
||||
}
|
||||
Err(vk::Result::ERROR_FRAGMENTED_POOL) => {
|
||||
Err(gpu_descriptor::DeviceAllocationError::FragmentedPool)
|
||||
}
|
||||
Err(other) => {
|
||||
log::error!("allocate_descriptor_sets: {:?}", other);
|
||||
Err(gpu_descriptor::DeviceAllocationError::OutOfHostMemory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn dealloc_descriptor_sets<'a>(
|
||||
&self,
|
||||
pool: &mut vk::DescriptorPool,
|
||||
sets: impl Iterator<Item = vk::DescriptorSet>,
|
||||
) {
|
||||
let result = inplace_or_alloc_from_iter(sets, |sets_slice| {
|
||||
self.raw.free_descriptor_sets(*pool, sets_slice)
|
||||
});
|
||||
match result {
|
||||
Ok(()) => {}
|
||||
Err(err) => log::error!("free_descriptor_sets: {:?}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Device {
|
||||
pub(super) unsafe fn create_swapchain(
|
||||
&self,
|
||||
@ -483,6 +616,42 @@ impl crate::Device<super::Api> for super::Device {
|
||||
&self,
|
||||
desc: &crate::BindGroupLayoutDescriptor,
|
||||
) -> Result<super::BindGroupLayout, crate::DeviceError> {
|
||||
let mut desc_count = gpu_descriptor::DescriptorTotalCount::default();
|
||||
for entry in desc.entries {
|
||||
let count = entry.count.map_or(1, |c| c.get());
|
||||
match entry.ty {
|
||||
wgt::BindingType::Buffer {
|
||||
ty,
|
||||
has_dynamic_offset,
|
||||
..
|
||||
} => match ty {
|
||||
wgt::BufferBindingType::Uniform => {
|
||||
if has_dynamic_offset {
|
||||
desc_count.uniform_buffer_dynamic += count;
|
||||
} else {
|
||||
desc_count.uniform_buffer += count;
|
||||
}
|
||||
}
|
||||
wgt::BufferBindingType::Storage { .. } => {
|
||||
if has_dynamic_offset {
|
||||
desc_count.storage_buffer_dynamic += count;
|
||||
} else {
|
||||
desc_count.storage_buffer += count;
|
||||
}
|
||||
}
|
||||
},
|
||||
wgt::BindingType::Sampler { .. } => {
|
||||
desc_count.sampler += count;
|
||||
}
|
||||
wgt::BindingType::Texture { .. } => {
|
||||
desc_count.sampled_image += count;
|
||||
}
|
||||
wgt::BindingType::StorageTexture { .. } => {
|
||||
desc_count.storage_image += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Note: not bothering with inplace_or_alloc_from_iter her as it's low frequency
|
||||
let vk_bindings = desc
|
||||
.entries
|
||||
@ -510,7 +679,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
.set_object_name(vk::ObjectType::DESCRIPTOR_SET_LAYOUT, raw, label);
|
||||
}
|
||||
|
||||
Ok(super::BindGroupLayout { raw })
|
||||
Ok(super::BindGroupLayout { raw, desc_count })
|
||||
}
|
||||
unsafe fn destroy_bind_group_layout(&self, bg_layout: super::BindGroupLayout) {
|
||||
self.shared
|
||||
@ -561,10 +730,23 @@ impl crate::Device<super::Api> for super::Device {
|
||||
unsafe fn create_bind_group(
|
||||
&self,
|
||||
desc: &crate::BindGroupDescriptor<super::Api>,
|
||||
) -> DeviceResult<Resource> {
|
||||
Ok(Resource)
|
||||
) -> Result<super::BindGroup, crate::DeviceError> {
|
||||
let mut vk_sets = self.desc_allocator.lock().allocate(
|
||||
&*self.shared,
|
||||
&desc.layout.raw,
|
||||
gpu_descriptor::DescriptorSetLayoutCreateFlags::empty(),
|
||||
&desc.layout.desc_count,
|
||||
1,
|
||||
)?;
|
||||
Ok(super::BindGroup {
|
||||
raw: vk_sets.pop().unwrap(),
|
||||
})
|
||||
}
|
||||
unsafe fn destroy_bind_group(&self, group: super::BindGroup) {
|
||||
self.desc_allocator
|
||||
.lock()
|
||||
.free(&*self.shared, Some(group.raw));
|
||||
}
|
||||
unsafe fn destroy_bind_group(&self, group: Resource) {}
|
||||
|
||||
unsafe fn create_shader_module(
|
||||
&self,
|
||||
@ -627,7 +809,6 @@ impl From<gpu_alloc::AllocationError> for crate::DeviceError {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<gpu_alloc::MapError> for crate::DeviceError {
|
||||
fn from(error: gpu_alloc::MapError) -> Self {
|
||||
use gpu_alloc::MapError as Me;
|
||||
@ -640,3 +821,9 @@ impl From<gpu_alloc::MapError> for crate::DeviceError {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<gpu_descriptor::AllocationError> for crate::DeviceError {
|
||||
fn from(error: gpu_descriptor::AllocationError) -> Self {
|
||||
log::error!("descriptor allocation: {:?}", error);
|
||||
Self::OutOfMemory
|
||||
}
|
||||
}
|
||||
|
@ -503,6 +503,7 @@ impl crate::Instance<super::Api> for super::Instance {
|
||||
unix,
|
||||
not(target_os = "android"),
|
||||
not(target_os = "macos"),
|
||||
not(target_os = "ios"),
|
||||
not(target_os = "solaris")
|
||||
))]
|
||||
RawWindowHandle::Wayland(handle)
|
||||
@ -514,6 +515,7 @@ impl crate::Instance<super::Api> for super::Instance {
|
||||
unix,
|
||||
not(target_os = "android"),
|
||||
not(target_os = "macos"),
|
||||
not(target_os = "ios"),
|
||||
not(target_os = "solaris")
|
||||
))]
|
||||
RawWindowHandle::Xlib(handle)
|
||||
|
@ -42,7 +42,7 @@ impl crate::Api for Api {
|
||||
type Fence = Resource;
|
||||
|
||||
type BindGroupLayout = BindGroupLayout;
|
||||
type BindGroup = Resource;
|
||||
type BindGroup = BindGroup;
|
||||
type PipelineLayout = PipelineLayout;
|
||||
type ShaderModule = Resource;
|
||||
type RenderPipeline = Resource;
|
||||
@ -147,6 +147,8 @@ struct DeviceShared {
|
||||
pub struct Device {
|
||||
shared: Arc<DeviceShared>,
|
||||
mem_allocator: Mutex<gpu_alloc::GpuAllocator<vk::DeviceMemory>>,
|
||||
desc_allocator:
|
||||
Mutex<gpu_descriptor::DescriptorAllocator<vk::DescriptorPool, vk::DescriptorSet>>,
|
||||
valid_ash_memory_types: u32,
|
||||
naga_options: naga::back::spv::Options,
|
||||
}
|
||||
@ -183,6 +185,7 @@ pub struct Sampler {
|
||||
#[derive(Debug)]
|
||||
pub struct BindGroupLayout {
|
||||
raw: vk::DescriptorSetLayout,
|
||||
desc_count: gpu_descriptor::DescriptorTotalCount,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -190,6 +193,11 @@ pub struct PipelineLayout {
|
||||
raw: vk::PipelineLayout,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BindGroup {
|
||||
raw: gpu_descriptor::DescriptorSet<vk::DescriptorSet>,
|
||||
}
|
||||
|
||||
impl crate::Queue<Api> for Queue {
|
||||
unsafe fn submit<I>(
|
||||
&mut self,
|
||||
|
Loading…
Reference in New Issue
Block a user