diff --git a/Cargo.lock b/Cargo.lock index 8694b827cc..61b743e116 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,6 +42,11 @@ dependencies = [ "shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "atom" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "autocfg" version = "0.1.2" @@ -134,6 +139,11 @@ dependencies = [ "objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "colorful" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "copyless" version = "0.1.2" @@ -490,6 +500,14 @@ dependencies = [ "gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hibitset" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atom 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "iovec" version = "0.1.2" @@ -959,6 +977,16 @@ name = "redox_syscall" version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "relevant" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "remove_dir_all" version = "0.5.1" @@ -967,6 +995,35 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rendy-descriptor" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "derivative 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "gfx-hal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "relevant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rendy-memory" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "colorful 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derivative 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "gfx-hal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hibitset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "relevant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-demangle" version = "0.1.14" @@ -1242,6 +1299,8 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rendy-descriptor 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rendy-memory 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "winit 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1387,6 +1446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum ash 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "003d1fb2eb12eb06d4a03dbe02eea67a9fac910fa97932ab9e3a75b96a1ea5e5" +"checksum atom 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3c86699c3f02778ec07158376991c8f783dd1f2f95c579ffaf0738dc984b2fe2" "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" "checksum backtrace 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "f92d5d536fa03dc3d93711d97bac1fae2eb59aba467ca4c6600c0119da614f51" "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" @@ -1399,6 +1459,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cgl 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "55e7ec0b74fe5897894cbc207092c577e87c52f8a59e8ca8d97ef37551f60a49" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b" +"checksum colorful 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bca1619ff57dd7a56b58a8e25ef4199f123e78e503fe1653410350a1b98ae65" "checksum copyless 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59de7722d3b5c7b35dd519d617fe5116c9b879a0f145dc5431d78ab1f61d7c23" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" @@ -1435,6 +1496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum glutin_gles2_sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "89996c30857ae1b4de4b5189abf1ea822a20a9fe9e1c93e5e7b862ff0bdd5cdf" "checksum glutin_glx_sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1290a5ca5e46fcfa7f66f949cc9d9194b2cb6f2ed61892c8c2b82343631dba57" "checksum glutin_wgl_sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f801bbc91efc22dd1c4818a47814fc72bf74d024510451b119381579bfa39021" +"checksum hibitset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6527bc88f32e0d3926c7572874b2bf17a19b36978aacd0aacf75f7d27a5992d0" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum ipc-channel 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79d98ee7dd1d2e796d254807fd86ea7189d07571aeaa74007603e29a79d15217" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -1487,7 +1549,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum range-alloc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5927936723a9e8b715d37d7e4b390455087c4bdf25b9f702309460577b14f9" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" +"checksum relevant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bbc232e13d37f4547f5b9b42a5efc380cabe5dbc1807f8b893580640b2ab0308" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" +"checksum rendy-descriptor 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d994004622af2fe3848fde527258dd6bee8cf089a51e2e83fe5f2b7aeb09f6c0" +"checksum rendy-memory 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbdab806e4d349037b60ff6a25dad1260da58eb4b43ecac31350443278d5c002" "checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rusttype 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "25951e85bb2647960969f72c559392245a5bd07446a589390bf427dda31cdc4a" diff --git a/ffi/wgpu-remote.h b/ffi/wgpu-remote.h index e41ecdc9e0..65336655dc 100644 --- a/ffi/wgpu-remote.h +++ b/ffi/wgpu-remote.h @@ -1,6 +1,6 @@ -/* Generated with cbindgen:0.8.6 */ +/* Generated with cbindgen:0.8.7 */ #include #include diff --git a/ffi/wgpu.h b/ffi/wgpu.h index 971d78be63..4c6b385611 100644 --- a/ffi/wgpu.h +++ b/ffi/wgpu.h @@ -1,6 +1,6 @@ #define WGPU_LOCAL -/* Generated with cbindgen:0.8.6 */ +/* Generated with cbindgen:0.8.7 */ #include #include diff --git a/wgpu-native/Cargo.toml b/wgpu-native/Cargo.toml index 78c8c215e1..e6f670837d 100644 --- a/wgpu-native/Cargo.toml +++ b/wgpu-native/Cargo.toml @@ -28,7 +28,6 @@ bitflags = "1.0" copyless = "0.1" lazy_static = "1.1.0" log = "0.4" -parking_lot = { version = "0.8" } hal = { package = "gfx-hal", version = "0.2" } gfx-backend-empty = { version = "0.2" } gfx-backend-vulkan = { version = "0.2", optional = true } @@ -36,7 +35,9 @@ gfx-backend-dx11 = { version = "0.2", optional = true } gfx-backend-dx12 = { version = "0.2", optional = true } gfx-backend-metal = { version = "0.2", optional = true } gfx-backend-gl = { version = "0.2", optional = true } -#rendy-memory = { git = "https://github.com/rustgd/rendy", rev = "ce7dd7f", features = ["gfx-hal"] } +parking_lot = { version = "0.8" } +rendy-memory = "0.2" +rendy-descriptor = "0.2" serde = { version = "1.0", features = ["serde_derive"], optional = true } vec_map = "0.8" winit = { version = "0.19", optional = true } diff --git a/wgpu-native/src/binding_model.rs b/wgpu-native/src/binding_model.rs index 77086ce121..32dbdc3e77 100644 --- a/wgpu-native/src/binding_model.rs +++ b/wgpu-native/src/binding_model.rs @@ -10,6 +10,7 @@ use crate::{ use arrayvec::ArrayVec; use bitflags::bitflags; +use rendy_descriptor::{DescriptorRanges, DescriptorSet}; pub const MAX_BIND_GROUPS: usize = 4; @@ -52,6 +53,7 @@ pub struct BindGroupLayoutDescriptor { pub struct BindGroupLayout { pub(crate) raw: B::DescriptorSetLayout, pub(crate) bindings: Vec, + pub(crate) desc_ranges: DescriptorRanges, pub(crate) dynamic_count: usize, } @@ -94,7 +96,7 @@ pub struct BindGroupDescriptor { } pub struct BindGroup { - pub(crate) raw: B::DescriptorSet, + pub(crate) raw: DescriptorSet, pub(crate) layout_id: BindGroupLayoutId, pub(crate) life_guard: LifeGuard, pub(crate) used: TrackerSet, diff --git a/wgpu-native/src/command/compute.rs b/wgpu-native/src/command/compute.rs index bed7301857..75e09c1593 100644 --- a/wgpu-native/src/command/compute.rs +++ b/wgpu-native/src/command/compute.rs @@ -91,7 +91,7 @@ pub extern "C" fn wgpu_compute_pass_set_bind_group( { let pipeline_layout_guard = HUB.pipeline_layouts.read(); let bind_groups = - iter::once(&bind_group.raw).chain(follow_up.map(|bg_id| &bind_group_guard[bg_id].raw)); + iter::once(bind_group.raw.raw()).chain(follow_up.map(|bg_id| bind_group_guard[bg_id].raw.raw())); unsafe { pass.raw.bind_compute_descriptor_sets( &pipeline_layout_guard[pipeline_layout_id].raw, @@ -162,7 +162,7 @@ pub extern "C" fn wgpu_compute_pass_set_pipeline( .enumerate() { if let LayoutChange::Match(bg_id) = entry.expect_layout(bgl_id) { - let desc_set = &bind_group_guard[bg_id].raw; + let desc_set = bind_group_guard[bg_id].raw.raw(); unsafe { pass.raw.bind_compute_descriptor_sets( &pipeline_layout.raw, diff --git a/wgpu-native/src/command/render.rs b/wgpu-native/src/command/render.rs index 3c36bbf98b..587fbbb5fc 100644 --- a/wgpu-native/src/command/render.rs +++ b/wgpu-native/src/command/render.rs @@ -227,7 +227,7 @@ pub extern "C" fn wgpu_render_pass_set_bind_group( { let pipeline_layout_guard = HUB.pipeline_layouts.read(); let bind_groups = - iter::once(&bind_group.raw).chain(follow_up.map(|bg_id| &bind_group_guard[bg_id].raw)); + iter::once(bind_group.raw.raw()).chain(follow_up.map(|bg_id| bind_group_guard[bg_id].raw.raw())); unsafe { pass.raw.bind_graphics_descriptor_sets( &&pipeline_layout_guard[pipeline_layout_id].raw, @@ -414,7 +414,7 @@ pub extern "C" fn wgpu_render_pass_set_pipeline( .enumerate() { if let LayoutChange::Match(bg_id) = entry.expect_layout(bgl_id) { - let desc_set = &bind_group_guard[bg_id].raw; + let desc_set = bind_group_guard[bg_id].raw.raw(); unsafe { pass.raw.bind_graphics_descriptor_sets( &pipeline_layout.raw, diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 22c5d39218..2bcfd3db5b 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -44,17 +44,17 @@ use hal::{ backend::FastHashMap, command::RawCommandBuffer, queue::RawCommandQueue, - DescriptorPool as _, Device as _, Surface as _, }; use log::{info, trace}; -//use rendy_memory::{allocator, Config, Heaps}; use parking_lot::Mutex; +use rendy_descriptor::{DescriptorAllocator, DescriptorRanges}; +use rendy_memory::{Block, Heaps, MemoryBlock}; #[cfg(feature = "local")] use std::sync::atomic::AtomicBool; -use std::{collections::hash_map::Entry, ffi, iter, ptr, slice, sync::atomic::Ordering}; +use std::{collections::hash_map::Entry, ffi, iter, ptr, ops::Range, slice, sync::atomic::Ordering}; const CLEANUP_WAIT_MS: u64 = 5000; pub const MAX_COLOR_TARGETS: usize = 4; @@ -111,8 +111,8 @@ enum ResourceId { } enum NativeResource { - Buffer(B::Buffer, B::Memory), - Image(B::Image, B::Memory), + Buffer(B::Buffer, MemoryBlock), + Image(B::Image, MemoryBlock), ImageView(B::ImageView), Framebuffer(B::Framebuffer), } @@ -168,7 +168,12 @@ impl PendingResources { } /// Returns the last submission index that is done. - fn cleanup(&mut self, device: &B::Device, force_wait: bool) -> SubmissionIndex { + fn cleanup( + &mut self, + device: &B::Device, + heaps_mutex: &Mutex>, + force_wait: bool, + ) -> SubmissionIndex { if force_wait { let status = unsafe { device.wait_for_fences( @@ -190,7 +195,7 @@ impl PendingResources { let last_done = if done_count != 0 { self.active[done_count - 1].index } else { - 0 + return 0 }; for a in self.active.drain(.. done_count) { @@ -202,15 +207,16 @@ impl PendingResources { } } + let mut heaps = heaps_mutex.lock(); for resource in self.free.drain(..) { match resource { NativeResource::Buffer(raw, memory) => unsafe { device.destroy_buffer(raw); - device.free_memory(memory); + heaps.free(device, memory); }, NativeResource::Image(raw, memory) => unsafe { device.destroy_image(raw); - device.free_memory(memory); + heaps.free(device, memory); }, NativeResource::ImageView(raw) => unsafe { device.destroy_image_view(raw); @@ -342,7 +348,6 @@ impl PendingResources { fn handle_mapping( &mut self, raw: &::Device, - limits: &hal::Limits, ) -> Vec { self.ready_to_map .drain(..) @@ -352,10 +357,10 @@ impl PendingResources { let operation = buffer.pending_map_operation.take().unwrap(); let result = match operation { BufferMapOperation::Read(ref range, ..) => { - map_buffer(raw, limits, buffer, range, HostMap::Read) + map_buffer(raw, buffer, range.clone(), HostMap::Read) } BufferMapOperation::Write(ref range, ..) => { - map_buffer(raw, limits, buffer, range, HostMap::Write) + map_buffer(raw, buffer, range.clone(), HostMap::Write) } }; (operation, result) @@ -369,58 +374,47 @@ type BufferMapPendingCallback = (BufferMapOperation, BufferMapResult); fn map_buffer( raw: &::Device, - limits: &hal::Limits, buffer: &mut resource::Buffer, - original_range: &std::ops::Range, + buffer_range: Range, kind: HostMap, ) -> BufferMapResult { - // gfx-rs requires mapping and flushing/invalidation ranges to be done at `non_coherent_atom_size` - // granularity for memory types that aren't coherent. We achieve that by flooring the start offset - // and ceiling the end offset to those atom sizes, using bitwise operations on an `atom_mask`. - let is_coherent = buffer - .memory_properties + let is_coherent = buffer.memory + .properties() .contains(hal::memory::Properties::COHERENT); - let atom_mask = if is_coherent { - 0 - } else { - limits.non_coherent_atom_size as u64 - 1 + let (ptr, mapped_range) = { + let mapped = buffer.memory.map(raw, buffer_range)?; + (mapped.ptr(), mapped.range()) }; - let atom_offset = original_range.start & atom_mask; - let range = (original_range.start & !atom_mask) .. ((original_range.end - 1) | atom_mask) + 1; - let pointer = unsafe { raw.map_memory(&buffer.memory, range.clone()) }?; if !is_coherent { match kind { HostMap::Read => unsafe { - raw.invalidate_mapped_memory_ranges(iter::once((&buffer.memory, range))) + raw.invalidate_mapped_memory_ranges( + iter::once((buffer.memory.memory(), mapped_range)), + ) .unwrap(); }, HostMap::Write => { - buffer.mapped_write_ranges.push(range); + buffer.mapped_write_ranges.push(mapped_range); } } } - Ok(unsafe { - // Since we map with a potentially smaller offset than the user requested, - // we adjust the returned pointer to compensate. - pointer.offset(atom_offset as isize) - }) + Ok(ptr.as_ptr()) } pub struct Device { pub(crate) raw: B::Device, adapter_id: AdapterId, + limits: hal::Limits, pub(crate) queue_group: hal::QueueGroup, - //mem_allocator: Heaps, pub(crate) com_allocator: command::CommandAllocator, + mem_allocator: Mutex>, + desc_allocator: Mutex>, life_guard: LifeGuard, pub(crate) trackers: Mutex, - mem_props: hal::MemoryProperties, - limits: hal::Limits, pub(crate) render_passes: Mutex>, pub(crate) framebuffers: Mutex>, - desc_pool: Mutex, pending: Mutex>, } @@ -432,81 +426,48 @@ impl Device { mem_props: hal::MemoryProperties, limits: hal::Limits, ) -> Self { - // TODO: These values are just taken from rendy's test - // Need to set reasonable values per memory type instead - /*let arena = Some(allocator::ArenaConfig { - arena_size: 32 * 1024, - }); - let dynamic = Some(allocator::DynamicConfig { - blocks_per_chunk: 64, - block_size_granularity: 256, - max_block_size: 32 * 1024, - }); - let config = Config { arena, dynamic }; - let mem_allocator = unsafe { - Heaps::new( - mem_props - .memory_types - .iter() - .map(|mt| (mt.properties.into(), mt.heap_index as u32, config)), - mem_props.memory_heaps.clone(), - ) - };*/ - - //TODO: generic allocator for descriptors - let desc_pool = Mutex::new( - unsafe { - raw.create_descriptor_pool( - 10000, - &[ - hal::pso::DescriptorRangeDesc { - ty: hal::pso::DescriptorType::Sampler, - count: 100, - }, - hal::pso::DescriptorRangeDesc { - ty: hal::pso::DescriptorType::SampledImage, - count: 1000, - }, - hal::pso::DescriptorRangeDesc { - ty: hal::pso::DescriptorType::UniformBuffer, - count: 10000, - }, - hal::pso::DescriptorRangeDesc { - ty: hal::pso::DescriptorType::UniformBufferDynamic, - count: 100, - }, - hal::pso::DescriptorRangeDesc { - ty: hal::pso::DescriptorType::StorageBuffer, - count: 1000, - }, - hal::pso::DescriptorRangeDesc { - ty: hal::pso::DescriptorType::StorageBufferDynamic, - count: 100, - }, - ], - hal::pso::DescriptorPoolCreateFlags::empty(), - ) - } - .unwrap(), - ); - // don't start submission index at zero let life_guard = LifeGuard::new(); life_guard.submission_index.fetch_add(1, Ordering::Relaxed); + let heaps = { + let types = mem_props.memory_types + .iter() + .map(|mt| { + use rendy_memory::{HeapsConfig, LinearConfig, DynamicConfig}; + let config = HeapsConfig { + linear: if mt.properties.contains(hal::memory::Properties::CPU_VISIBLE) { + Some(LinearConfig { + linear_size: 0x10_00_00, + }) + } else { + None + }, + dynamic: Some(DynamicConfig { + block_size_granularity: 0x1_00, + max_chunk_size: 0x1_00_00_00, + min_device_allocation: 0x1_00_00, + }), + }; + (mt.properties.into(), mt.heap_index as u32, config) + }); + unsafe { + Heaps::new(types, mem_props.memory_heaps.iter().cloned()) + } + }; + Device { raw, adapter_id, - //mem_allocator, + limits, com_allocator: command::CommandAllocator::new(queue_group.family()), + mem_allocator: Mutex::new(heaps), + desc_allocator: Mutex::new(DescriptorAllocator::new()), queue_group, life_guard, trackers: Mutex::new(TrackerSet::new()), - mem_props, - limits, render_passes: Mutex::new(FastHashMap::default()), framebuffers: Mutex::new(FastHashMap::default()), - desc_pool, pending: Mutex::new(PendingResources { mapped: Vec::new(), referenced: Vec::new(), @@ -525,8 +486,8 @@ impl Device { pending.triage_referenced(&mut *trackers); pending.triage_framebuffers(&mut *self.framebuffers.lock()); - let last_done = pending.cleanup(&self.raw, force_wait); - let callbacks = pending.handle_mapping(&self.raw, &self.limits); + let last_done = pending.cleanup(&self.raw, &self.mem_allocator, force_wait); + let callbacks = pending.handle_mapping(&self.raw); if last_done != 0 { self.com_allocator.maintain(last_done); @@ -564,37 +525,39 @@ pub fn device_create_buffer( ) -> resource::Buffer { let device_guard = HUB.devices.read(); let device = &device_guard[device_id]; - let (usage, memory_properties) = conv::map_buffer_usage(desc.usage); + let (usage, _memory_properties) = conv::map_buffer_usage(desc.usage); + + let rendy_usage = { + use resource::BufferUsage as Bu; + use rendy_memory::MemoryUsageValue as Muv; + + if (Bu::MAP_WRITE | Bu::TRANSFER_SRC).contains(desc.usage) { + Muv::Upload + } else if (Bu::MAP_READ | Bu::TRANSFER_DST).contains(desc.usage) { + Muv::Download + } else if !desc.usage.contains(Bu::MAP_READ | Bu::MAP_WRITE) { + Muv::Data + } else { + Muv::Dynamic + } + }; let mut buffer = unsafe { device.raw.create_buffer(desc.size, usage).unwrap() }; let requirements = unsafe { device.raw.get_buffer_requirements(&buffer) }; - let device_type = device - .mem_props - .memory_types - .iter() - .enumerate() - .position(|(id, memory_type)| { - requirements.type_mask & (1 << id) != 0 - && memory_type.properties.contains(memory_properties) - }) - .unwrap() - .into(); - // TODO: allocate with rendy + let memory = device.mem_allocator + .lock() + .allocate( + &device.raw, + requirements.type_mask as u32, + rendy_usage, + requirements.size, + requirements.alignment, + ) + .unwrap(); - // if the memory is mapped but not coherent, round up to the atom size - let mut mem_size = requirements.size; - if memory_properties.contains(hal::memory::Properties::CPU_VISIBLE) - && !memory_properties.contains(hal::memory::Properties::COHERENT) - { - let mask = device.limits.non_coherent_atom_size as u64 - 1; - mem_size = ((mem_size - 1) | mask) + 1; - } - - let memory = unsafe { device.raw.allocate_memory(device_type, mem_size).unwrap() }; unsafe { - device - .raw - .bind_buffer_memory(&memory, 0, &mut buffer) + device.raw + .bind_buffer_memory(memory.memory(), memory.range().start, &mut buffer) .unwrap() }; @@ -604,7 +567,6 @@ pub fn device_create_buffer( value: device_id, ref_count: device.life_guard.ref_count.clone(), }, - memory_properties, memory, size: desc.size, mapped_write_ranges: Vec::new(), @@ -654,13 +616,11 @@ pub extern "C" fn wgpu_device_create_buffer_mapped( { let device_guard = HUB.devices.read(); let device = &device_guard[device_id]; - let range = 0 .. desc.size; match map_buffer( &device.raw, - &device.limits, &mut buffer, - &range, + 0 .. desc.size, HostMap::Write, ) { Ok(ptr) => unsafe { @@ -715,31 +675,21 @@ pub fn device_create_texture( } .unwrap(); let requirements = unsafe { device.raw.get_image_requirements(&image) }; - let device_type = device - .mem_props - .memory_types - .iter() - .enumerate() - .position(|(id, memory_type)| { - // TODO - requirements.type_mask & (1 << id) != 0 - && memory_type - .properties - .contains(hal::memory::Properties::DEVICE_LOCAL) - }) - .unwrap() - .into(); - // TODO: allocate with rendy - let memory = unsafe { - device - .raw - .allocate_memory(device_type, requirements.size) - .unwrap() - }; + + let memory = device.mem_allocator + .lock() + .allocate( + &device.raw, + requirements.type_mask as u32, + rendy_memory::Data, + requirements.size, + requirements.alignment, + ) + .unwrap(); + unsafe { - device - .raw - .bind_image_memory(&memory, 0, &mut image) + device.raw + .bind_image_memory(memory.memory(), memory.range().start, &mut image) .unwrap() }; @@ -953,27 +903,28 @@ pub fn device_create_bind_group_layout( ) -> binding_model::BindGroupLayout { let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length) }; + let raw_bindings = bindings + .iter() + .map(|binding| hal::pso::DescriptorSetLayoutBinding { + binding: binding.binding, + ty: conv::map_binding_type(binding.ty), + count: 1, //TODO: consolidate + stage_flags: conv::map_shader_stage_flags(binding.visibility), + immutable_samplers: false, // TODO + }) + .collect::>(); //TODO: avoid heap allocation + let raw = unsafe { HUB.devices.read()[device_id] .raw - .create_descriptor_set_layout( - bindings.iter().map(|binding| { - hal::pso::DescriptorSetLayoutBinding { - binding: binding.binding, - ty: conv::map_binding_type(binding.ty), - count: 1, //TODO: consolidate - stage_flags: conv::map_shader_stage_flags(binding.visibility), - immutable_samplers: false, // TODO - } - }), - &[], - ) + .create_descriptor_set_layout(&raw_bindings, &[]) .unwrap() }; binding_model::BindGroupLayout { raw, bindings: bindings.to_vec(), + desc_ranges: DescriptorRanges::from_bindings(&raw_bindings), dynamic_count: bindings .iter() .filter(|b| match b.ty { @@ -1042,8 +993,20 @@ pub fn device_create_bind_group( let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length as usize) }; assert_eq!(bindings.len(), bind_group_layout.bindings.len()); - let mut desc_pool = device.desc_pool.lock(); - let desc_set = unsafe { desc_pool.allocate_set(&bind_group_layout.raw).unwrap() }; + let desc_set = unsafe { + let mut desc_sets = ArrayVec::<[_; 1]>::new(); + device.desc_allocator + .lock() + .allocate( + &device.raw, + &bind_group_layout.raw, + bind_group_layout.desc_ranges, + 1, + &mut desc_sets, + ) + .unwrap(); + desc_sets.pop().unwrap() + }; let buffer_guard = HUB.buffers.read(); let sampler_guard = HUB.samplers.read(); @@ -1116,7 +1079,7 @@ pub fn device_create_bind_group( } }; writes.alloc().init(hal::pso::DescriptorSetWrite { - set: &desc_set, + set: desc_set.raw(), binding: b.binding, array_offset: 0, //TODO descriptors: iter::once(descriptor), @@ -1964,12 +1927,12 @@ pub extern "C" fn wgpu_buffer_unmap(buffer_id: BufferId) { buffer .mapped_write_ranges .iter() - .map(|r| (&buffer.memory, r.clone())), + .map(|r| (buffer.memory.memory(), r.clone())), ) .unwrap() - }; // TODO + }; buffer.mapped_write_ranges.clear(); } - unsafe { device_raw.unmap_memory(&buffer.memory) }; + buffer.memory.unmap(device_raw); } diff --git a/wgpu-native/src/resource.rs b/wgpu-native/src/resource.rs index 234765b320..5e76248d0d 100644 --- a/wgpu-native/src/resource.rs +++ b/wgpu-native/src/resource.rs @@ -14,6 +14,7 @@ use crate::{ use bitflags::bitflags; use hal; use parking_lot::Mutex; +use rendy_memory::MemoryBlock; use std::borrow::Borrow; @@ -60,8 +61,7 @@ unsafe impl Sync for BufferMapOperation {} pub struct Buffer { pub(crate) raw: B::Buffer, pub(crate) device_id: Stored, - pub(crate) memory_properties: hal::memory::Properties, - pub(crate) memory: B::Memory, + pub(crate) memory: MemoryBlock, pub(crate) size: BufferAddress, pub(crate) mapped_write_ranges: Vec>, pub(crate) pending_map_operation: Option, @@ -179,7 +179,7 @@ pub struct TextureDescriptor { pub(crate) enum TexturePlacement { #[cfg_attr(feature = "remote", allow(unused))] SwapChain(SwapChainLink>), - Memory(B::Memory), + Memory(MemoryBlock), Void, }