mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Merge #1056
1056: Replace gfx-descriptor by gpu-descriptor r=cwfitzgerald a=kvark **Connections** Unblocks #1027 cc @zakarumych **Description** Removes the last link we had between us and gfx-rs. **Testing** Tested on wgpu-rs Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
41
Cargo.lock
generated
41
Cargo.lock
generated
@@ -15,6 +15,12 @@ version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6789e291be47ace86a60303502173d84af8327e3627ecf334356ee0f87a164c"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
@@ -690,18 +696,6 @@ dependencies = [
|
||||
"x11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gfx-descriptor"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd8c7afcd000f279d541a490e27117e61037537279b9342279abf4938fe60c6b"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"fxhash",
|
||||
"gfx-hal",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gfx-hal"
|
||||
version = "0.6.0"
|
||||
@@ -778,11 +772,32 @@ dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gpu-descriptor"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zakarumych/gpu-descriptor?rev=831460c4b5120d9a74744d542f39a95b9816b5ab#831460c4b5120d9a74744d542f39a95b9816b5ab"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"gpu-descriptor-types",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gpu-descriptor-types"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zakarumych/gpu-descriptor?rev=831460c4b5120d9a74744d542f39a95b9816b5ab#831460c4b5120d9a74744d542f39a95b9816b5ab"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
@@ -2198,9 +2213,9 @@ dependencies = [
|
||||
"gfx-backend-gl",
|
||||
"gfx-backend-metal",
|
||||
"gfx-backend-vulkan",
|
||||
"gfx-descriptor",
|
||||
"gfx-hal",
|
||||
"gpu-alloc",
|
||||
"gpu-descriptor",
|
||||
"loom",
|
||||
"naga",
|
||||
"parking_lot 0.11.0",
|
||||
|
||||
@@ -7,7 +7,7 @@ This is an active GitHub mirror of the WebGPU implementation in Rust, which now
|
||||
[](https://matrix.to/#/#wgpu:matrix.org) [](https://matrix.to/#/#wgpu-users:matrix.org)
|
||||
[](https://github.com/gfx-rs/wgpu/actions)
|
||||
|
||||
This is the core logic of an experimental [WebGPU](https://www.w3.org/community/gpu/) implementation. It's written in Rust and is based on [gfx-hal](https://github.com/gfx-rs/gfx) with help of [gfx-extras](https://github.com/gfx-rs/gfx-extras). See the upstream [WebGPU specification](https://gpuweb.github.io/gpuweb/) (work in progress).
|
||||
This is the core logic of an experimental [WebGPU](https://www.w3.org/community/gpu/) implementation. It's written in Rust and is based on [gfx-hal](https://github.com/gfx-rs/gfx) with help of [gpu-alloc](https://github.com/zakarumych/gpu-alloc) and [gpu-descriptor](https://github.com/zakarumych/gpu-descriptor). See the upstream [WebGPU specification](https://gpuweb.github.io/gpuweb/) (work in progress).
|
||||
|
||||
The implementation consists of the following parts:
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ serde = { version = "1.0", features = ["serde_derive"], optional = true }
|
||||
smallvec = "1"
|
||||
tracing = { version = "0.1", default-features = false, features = ["std"] }
|
||||
thiserror = "1"
|
||||
gfx-descriptor = "0.2"
|
||||
gpu-alloc = { git = "https://github.com/zakarumych/gpu-alloc", rev = "d07be73f9439a37c89f5b72f2500cbf0eb4ff613" }
|
||||
gpu-descriptor = { git = "https://github.com/zakarumych/gpu-descriptor", rev = "831460c4b5120d9a74744d542f39a95b9816b5ab"}
|
||||
|
||||
[dependencies.naga]
|
||||
version = "0.2"
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::{
|
||||
device::{DeviceError, SHADER_STAGE_COUNT},
|
||||
device::{
|
||||
descriptor::{DescriptorSet, DescriptorTotalCount},
|
||||
DeviceError, SHADER_STAGE_COUNT,
|
||||
},
|
||||
hub::Resource,
|
||||
id::{BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureViewId, Valid},
|
||||
track::{TrackerSet, DUMMY_SELECTOR},
|
||||
@@ -12,7 +15,6 @@ use crate::{
|
||||
};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use gfx_descriptor::{DescriptorCounts, DescriptorSet};
|
||||
|
||||
#[cfg(feature = "replay")]
|
||||
use serde::Deserialize;
|
||||
@@ -322,7 +324,7 @@ pub struct BindGroupLayout<B: hal::Backend> {
|
||||
pub(crate) device_id: Stored<DeviceId>,
|
||||
pub(crate) multi_ref_count: MultiRefCount,
|
||||
pub(crate) entries: BindEntryMap,
|
||||
pub(crate) desc_counts: DescriptorCounts,
|
||||
pub(crate) desc_count: DescriptorTotalCount,
|
||||
pub(crate) dynamic_count: usize,
|
||||
pub(crate) count_validator: BindingTypeMaxCountValidator,
|
||||
#[cfg(debug_assertions)]
|
||||
|
||||
168
wgpu-core/src/device/descriptor.rs
Normal file
168
wgpu-core/src/device/descriptor.rs
Normal file
@@ -0,0 +1,168 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use super::DeviceError;
|
||||
use arrayvec::ArrayVec;
|
||||
|
||||
pub use gpu_descriptor::DescriptorTotalCount;
|
||||
|
||||
pub type DescriptorSet<B> = gpu_descriptor::DescriptorSet<<B as hal::Backend>::DescriptorSet>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DescriptorAllocator<B: hal::Backend>(
|
||||
gpu_descriptor::DescriptorAllocator<B::DescriptorPool, B::DescriptorSet>,
|
||||
);
|
||||
struct DescriptorDevice<'a, B: hal::Backend>(&'a B::Device);
|
||||
|
||||
impl<B: hal::Backend> DescriptorAllocator<B> {
|
||||
pub fn new() -> Self {
|
||||
DescriptorAllocator(unsafe { gpu_descriptor::DescriptorAllocator::new(0) })
|
||||
}
|
||||
|
||||
pub fn allocate(
|
||||
&mut self,
|
||||
device: &B::Device,
|
||||
layout: &B::DescriptorSetLayout,
|
||||
layout_descriptor_count: &DescriptorTotalCount,
|
||||
count: u32,
|
||||
) -> Result<Vec<DescriptorSet<B>>, DeviceError> {
|
||||
self.0
|
||||
.allocate(
|
||||
&DescriptorDevice::<B>(device),
|
||||
layout,
|
||||
gpu_descriptor::DescriptorSetLayoutCreateFlags::empty(),
|
||||
layout_descriptor_count,
|
||||
count,
|
||||
)
|
||||
.map_err(|err| {
|
||||
tracing::warn!("Descriptor set allocation failed: {}", err);
|
||||
DeviceError::OutOfMemory
|
||||
})
|
||||
}
|
||||
|
||||
pub fn free(&mut self, device: &B::Device, sets: impl IntoIterator<Item = DescriptorSet<B>>) {
|
||||
unsafe { self.0.free(&DescriptorDevice::<B>(device), sets) }
|
||||
}
|
||||
|
||||
pub fn cleanup(&mut self, device: &B::Device) {
|
||||
self.0.cleanup(&DescriptorDevice::<B>(device))
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: hal::Backend>
|
||||
gpu_descriptor::DescriptorDevice<B::DescriptorSetLayout, B::DescriptorPool, B::DescriptorSet>
|
||||
for DescriptorDevice<'_, B>
|
||||
{
|
||||
unsafe fn create_descriptor_pool(
|
||||
&self,
|
||||
descriptor_count: &DescriptorTotalCount,
|
||||
max_sets: u32,
|
||||
flags: gpu_descriptor::DescriptorPoolCreateFlags,
|
||||
) -> Result<B::DescriptorPool, gpu_descriptor::CreatePoolError> {
|
||||
let mut ranges = ArrayVec::<[_; 7]>::new();
|
||||
ranges.push(hal::pso::DescriptorRangeDesc {
|
||||
ty: hal::pso::DescriptorType::Sampler,
|
||||
count: descriptor_count.sampler as _,
|
||||
});
|
||||
ranges.push(hal::pso::DescriptorRangeDesc {
|
||||
ty: hal::pso::DescriptorType::Image {
|
||||
ty: hal::pso::ImageDescriptorType::Sampled {
|
||||
with_sampler: false,
|
||||
},
|
||||
},
|
||||
count: descriptor_count.sampled_image as _,
|
||||
});
|
||||
ranges.push(hal::pso::DescriptorRangeDesc {
|
||||
ty: hal::pso::DescriptorType::Image {
|
||||
ty: hal::pso::ImageDescriptorType::Storage { read_only: false },
|
||||
},
|
||||
count: descriptor_count.storage_image as _,
|
||||
});
|
||||
ranges.push(hal::pso::DescriptorRangeDesc {
|
||||
ty: hal::pso::DescriptorType::Buffer {
|
||||
ty: hal::pso::BufferDescriptorType::Uniform,
|
||||
format: hal::pso::BufferDescriptorFormat::Structured {
|
||||
dynamic_offset: false,
|
||||
},
|
||||
},
|
||||
count: descriptor_count.uniform_buffer as _,
|
||||
});
|
||||
ranges.push(hal::pso::DescriptorRangeDesc {
|
||||
ty: hal::pso::DescriptorType::Buffer {
|
||||
ty: hal::pso::BufferDescriptorType::Storage { read_only: false },
|
||||
format: hal::pso::BufferDescriptorFormat::Structured {
|
||||
dynamic_offset: false,
|
||||
},
|
||||
},
|
||||
count: descriptor_count.storage_buffer as _,
|
||||
});
|
||||
ranges.push(hal::pso::DescriptorRangeDesc {
|
||||
ty: hal::pso::DescriptorType::Buffer {
|
||||
ty: hal::pso::BufferDescriptorType::Uniform,
|
||||
format: hal::pso::BufferDescriptorFormat::Structured {
|
||||
dynamic_offset: true,
|
||||
},
|
||||
},
|
||||
count: descriptor_count.uniform_buffer_dynamic as _,
|
||||
});
|
||||
ranges.push(hal::pso::DescriptorRangeDesc {
|
||||
ty: hal::pso::DescriptorType::Buffer {
|
||||
ty: hal::pso::BufferDescriptorType::Storage { read_only: false },
|
||||
format: hal::pso::BufferDescriptorFormat::Structured {
|
||||
dynamic_offset: true,
|
||||
},
|
||||
},
|
||||
count: descriptor_count.storage_buffer_dynamic as _,
|
||||
});
|
||||
ranges.retain(|rd| rd.count != 0);
|
||||
|
||||
match hal::device::Device::create_descriptor_pool(
|
||||
self.0,
|
||||
max_sets as usize,
|
||||
ranges,
|
||||
hal::pso::DescriptorPoolCreateFlags::from_bits_truncate(flags.bits() as u32),
|
||||
) {
|
||||
Ok(pool) => Ok(pool),
|
||||
Err(hal::device::OutOfMemory::Host) => {
|
||||
Err(gpu_descriptor::CreatePoolError::OutOfHostMemory)
|
||||
}
|
||||
Err(hal::device::OutOfMemory::Device) => {
|
||||
Err(gpu_descriptor::CreatePoolError::OutOfDeviceMemory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn destroy_descriptor_pool(&self, pool: B::DescriptorPool) {
|
||||
hal::device::Device::destroy_descriptor_pool(self.0, pool);
|
||||
}
|
||||
|
||||
unsafe fn alloc_descriptor_sets<'a>(
|
||||
&self,
|
||||
pool: &mut B::DescriptorPool,
|
||||
layouts: impl Iterator<Item = &'a B::DescriptorSetLayout>,
|
||||
sets: &mut impl Extend<B::DescriptorSet>,
|
||||
) -> Result<(), gpu_descriptor::DeviceAllocationError> {
|
||||
use gpu_descriptor::DeviceAllocationError as Dae;
|
||||
match hal::pso::DescriptorPool::allocate(pool, layouts, sets) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(hal::pso::AllocationError::OutOfMemory(oom)) => Err(match oom {
|
||||
hal::device::OutOfMemory::Host => Dae::OutOfHostMemory,
|
||||
hal::device::OutOfMemory::Device => Dae::OutOfDeviceMemory,
|
||||
}),
|
||||
Err(hal::pso::AllocationError::OutOfPoolMemory) => Err(Dae::OutOfPoolMemory),
|
||||
Err(hal::pso::AllocationError::FragmentedPool) => Err(Dae::FragmentedPool),
|
||||
Err(hal::pso::AllocationError::IncompatibleLayout) => {
|
||||
panic!("Incompatible descriptor set layout")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn dealloc_descriptor_sets<'a>(
|
||||
&self,
|
||||
pool: &mut B::DescriptorPool,
|
||||
sets: impl Iterator<Item = B::DescriptorSet>,
|
||||
) {
|
||||
hal::pso::DescriptorPool::free(pool, sets)
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,12 @@
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::device::trace;
|
||||
use crate::{
|
||||
device::{alloc, queue::TempResource, DeviceError},
|
||||
device::{
|
||||
alloc,
|
||||
descriptor::{DescriptorAllocator, DescriptorSet},
|
||||
queue::TempResource,
|
||||
DeviceError,
|
||||
},
|
||||
hub::{GfxBackend, GlobalIdentityHandlerFactory, Hub, Token},
|
||||
id, resource,
|
||||
track::TrackerSet,
|
||||
@@ -13,7 +18,6 @@ use crate::{
|
||||
};
|
||||
|
||||
use copyless::VecHelper as _;
|
||||
use gfx_descriptor::{DescriptorAllocator, DescriptorSet};
|
||||
use hal::device::Device as _;
|
||||
use parking_lot::Mutex;
|
||||
use thiserror::Error;
|
||||
@@ -159,7 +163,7 @@ impl<B: hal::Backend> NonReferencedResources<B> {
|
||||
if !self.desc_sets.is_empty() {
|
||||
descriptor_allocator_mutex
|
||||
.lock()
|
||||
.free(self.desc_sets.drain(..));
|
||||
.free(device, self.desc_sets.drain(..));
|
||||
}
|
||||
|
||||
for raw in self.compute_pipes.drain(..) {
|
||||
|
||||
@@ -17,7 +17,6 @@ use crate::{
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use copyless::VecHelper as _;
|
||||
use gfx_descriptor::DescriptorAllocator;
|
||||
use hal::{
|
||||
command::CommandBuffer as _,
|
||||
device::Device as _,
|
||||
@@ -41,6 +40,7 @@ use std::{
|
||||
};
|
||||
|
||||
pub mod alloc;
|
||||
pub mod descriptor;
|
||||
mod life;
|
||||
mod queue;
|
||||
#[cfg(any(feature = "trace", feature = "replay"))]
|
||||
@@ -218,7 +218,7 @@ pub struct Device<B: hal::Backend> {
|
||||
pub(crate) queue_group: hal::queue::QueueGroup<B>,
|
||||
pub(crate) cmd_allocator: command::CommandAllocator<B>,
|
||||
mem_allocator: Mutex<alloc::MemoryAllocator<B>>,
|
||||
desc_allocator: Mutex<DescriptorAllocator<B>>,
|
||||
desc_allocator: Mutex<descriptor::DescriptorAllocator<B>>,
|
||||
//Note: The submission index here corresponds to the last submission that is done.
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
pub(crate) active_submission_index: SubmissionIndex,
|
||||
@@ -260,7 +260,7 @@ impl<B: GfxBackend> Device<B> {
|
||||
.or(Err(CreateDeviceError::OutOfMemory))?;
|
||||
|
||||
let mem_allocator = alloc::MemoryAllocator::new(mem_props, hal_limits);
|
||||
let descriptors = unsafe { DescriptorAllocator::new() };
|
||||
let descriptors = descriptor::DescriptorAllocator::new();
|
||||
#[cfg(not(feature = "trace"))]
|
||||
match trace_path {
|
||||
Some(_) => tracing::error!("Feature 'trace' is not enabled"),
|
||||
@@ -985,23 +985,51 @@ impl<B: GfxBackend> Device<B> {
|
||||
label: Option<&str>,
|
||||
entry_map: binding_model::BindEntryMap,
|
||||
) -> Result<binding_model::BindGroupLayout<B>, binding_model::CreateBindGroupLayoutError> {
|
||||
// Validate the count parameter
|
||||
let mut desc_count = descriptor::DescriptorTotalCount::default();
|
||||
for binding in entry_map.values() {
|
||||
if binding.count.is_some() {
|
||||
match binding.ty {
|
||||
wgt::BindingType::Texture { .. } => {
|
||||
if !self
|
||||
.features
|
||||
.contains(wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY)
|
||||
{
|
||||
return Err(binding_model::CreateBindGroupLayoutError::MissingFeature(
|
||||
wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY,
|
||||
));
|
||||
}
|
||||
use wgt::BindingType as Bt;
|
||||
let (counter, array_feature) = match binding.ty {
|
||||
Bt::Buffer {
|
||||
ty: wgt::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: _,
|
||||
} => (&mut desc_count.uniform_buffer, None),
|
||||
Bt::Buffer {
|
||||
ty: wgt::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: true,
|
||||
min_binding_size: _,
|
||||
} => (&mut desc_count.uniform_buffer_dynamic, None),
|
||||
Bt::Buffer {
|
||||
ty: wgt::BufferBindingType::Storage { .. },
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: _,
|
||||
} => (&mut desc_count.storage_buffer, None),
|
||||
Bt::Buffer {
|
||||
ty: wgt::BufferBindingType::Storage { .. },
|
||||
has_dynamic_offset: true,
|
||||
min_binding_size: _,
|
||||
} => (&mut desc_count.storage_buffer_dynamic, None),
|
||||
Bt::Sampler { .. } => (&mut desc_count.sampler, None),
|
||||
Bt::Texture { .. } => (
|
||||
&mut desc_count.sampled_image,
|
||||
Some(wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY),
|
||||
),
|
||||
Bt::StorageTexture { .. } => (&mut desc_count.storage_image, None),
|
||||
};
|
||||
*counter += match binding.count {
|
||||
// Validate the count parameter
|
||||
Some(count) => {
|
||||
let feature = array_feature
|
||||
.ok_or(binding_model::CreateBindGroupLayoutError::ArrayUnsupported)?;
|
||||
if !self.features.contains(feature) {
|
||||
return Err(binding_model::CreateBindGroupLayoutError::MissingFeature(
|
||||
feature,
|
||||
));
|
||||
}
|
||||
_ => return Err(binding_model::CreateBindGroupLayoutError::ArrayUnsupported),
|
||||
count.get()
|
||||
}
|
||||
}
|
||||
None => 1,
|
||||
};
|
||||
}
|
||||
|
||||
let raw_bindings = entry_map
|
||||
@@ -1015,8 +1043,6 @@ impl<B: GfxBackend> Device<B> {
|
||||
stage_flags: conv::map_shader_stage_flags(entry.visibility),
|
||||
immutable_samplers: false, // TODO
|
||||
});
|
||||
let desc_counts = raw_bindings.clone().collect();
|
||||
|
||||
let raw = unsafe {
|
||||
let mut raw_layout = self
|
||||
.raw
|
||||
@@ -1046,7 +1072,7 @@ impl<B: GfxBackend> Device<B> {
|
||||
ref_count: self.life_guard.add_ref(),
|
||||
},
|
||||
multi_ref_count: MultiRefCount::new(),
|
||||
desc_counts,
|
||||
desc_count,
|
||||
dynamic_count: entry_map
|
||||
.values()
|
||||
.filter(|b| b.ty.has_dynamic_offset())
|
||||
@@ -1343,17 +1369,10 @@ impl<B: GfxBackend> Device<B> {
|
||||
}
|
||||
}
|
||||
|
||||
let mut desc_sets = ArrayVec::<[_; 1]>::new();
|
||||
self.desc_allocator
|
||||
.lock()
|
||||
.allocate(
|
||||
&self.raw,
|
||||
&layout.raw,
|
||||
&layout.desc_counts,
|
||||
1,
|
||||
&mut desc_sets,
|
||||
)
|
||||
.expect("failed to allocate descriptor set");
|
||||
let mut desc_sets =
|
||||
self.desc_allocator
|
||||
.lock()
|
||||
.allocate(&self.raw, &layout.raw, &layout.desc_count, 1)?;
|
||||
let mut desc_set = desc_sets.pop().unwrap();
|
||||
|
||||
// Set the descriptor set's label for easier debugging.
|
||||
@@ -2156,9 +2175,9 @@ impl<B: GfxBackend> Device<B> {
|
||||
|
||||
impl<B: hal::Backend> Device<B> {
|
||||
pub(crate) fn destroy_bind_group(&self, bind_group: binding_model::BindGroup<B>) {
|
||||
unsafe {
|
||||
self.desc_allocator.lock().free(iter::once(bind_group.raw));
|
||||
}
|
||||
self.desc_allocator
|
||||
.lock()
|
||||
.free(&self.raw, iter::once(bind_group.raw));
|
||||
}
|
||||
|
||||
pub(crate) fn destroy_buffer(&self, buffer: resource::Buffer<B>) {
|
||||
@@ -2195,7 +2214,7 @@ impl<B: hal::Backend> Device<B> {
|
||||
.dispose(&self.raw, &self.cmd_allocator, &mut mem_alloc);
|
||||
self.cmd_allocator.destroy(&self.raw);
|
||||
unsafe {
|
||||
desc_alloc.clear(&self.raw);
|
||||
desc_alloc.cleanup(&self.raw);
|
||||
mem_alloc.clear(&self.raw);
|
||||
for (_, rp) in self.render_passes.lock().drain() {
|
||||
self.raw.destroy_render_pass(rp);
|
||||
|
||||
Reference in New Issue
Block a user