diff --git a/CHANGELOG.md b/CHANGELOG.md index 48941d106e..2ccd5d582e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## v0.2.3 (20-03-2019) + - fixed vertex format mapping + - fixed building with "empty" backend on Windows + - bumped the default descriptor pool size + - fixed host mapping aligments + - validating the uniform buffer offset + ## v0.2 (06-03-2019) - Platforms: iOS/Metal, D3D11 - Crates: diff --git a/Cargo.lock b/Cargo.lock index 534e64dc99..3b4e8fc3a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,6 +220,11 @@ dependencies = [ "objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "copyless" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "core-foundation" version = "0.6.3" @@ -320,8 +325,8 @@ name = "examples" version = "0.1.0" dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "wgpu 0.2.0", - "wgpu-native 0.2.0", + "wgpu 0.2.1", + "wgpu-native 0.2.4", ] [[package]] @@ -498,7 +503,7 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "wgpu 0.2.0", + "wgpu 0.2.1", ] [[package]] @@ -1384,10 +1389,10 @@ dependencies = [ [[package]] name = "wgpu" -version = "0.2.0" +version = "0.2.1" dependencies = [ "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wgpu-native 0.2.0", + "wgpu-native 0.2.4", ] [[package]] @@ -1399,10 +1404,11 @@ dependencies = [ [[package]] name = "wgpu-native" -version = "0.2.0" +version = "0.2.4" dependencies = [ "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "copyless 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx-backend-dx11 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "gfx-backend-dx12 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx-backend-empty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1425,7 +1431,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "wgpu-native 0.2.0", + "wgpu-native 0.2.4", ] [[package]] @@ -1578,6 +1584,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a" "checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b" +"checksum copyless 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59de7722d3b5c7b35dd519d617fe5116c9b879a0f145dc5431d78ab1f61d7c23" "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" diff --git a/wgpu-native/Cargo.toml b/wgpu-native/Cargo.toml index 44fb34c7ac..17f8ed4e28 100644 --- a/wgpu-native/Cargo.toml +++ b/wgpu-native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wgpu-native" -version = "0.2.0" +version = "0.2.4" authors = [ "Dzmitry Malyshau ", "Joshua Groves ", @@ -25,6 +25,7 @@ window-winit = ["winit", "gfx-backend-empty/winit"] [dependencies] arrayvec = "0.4" bitflags = "1.0" +copyless = "0.1" lazy_static = "1.1.0" log = "0.4" parking_lot = { version = "0.7" } diff --git a/wgpu-native/src/binding_model.rs b/wgpu-native/src/binding_model.rs index 634f2bf281..977cc3f9f9 100644 --- a/wgpu-native/src/binding_model.rs +++ b/wgpu-native/src/binding_model.rs @@ -1,8 +1,14 @@ -use crate::track::TrackerSet; -use crate::{BindGroupLayoutId, BufferId, LifeGuard, SamplerId, TextureViewId}; +use crate::{ + track::TrackerSet, + BindGroupLayoutId, BufferId, LifeGuard, SamplerId, TextureViewId, +}; +use arrayvec::ArrayVec; use bitflags::bitflags; + +pub const MAX_BIND_GROUPS: usize = 4; + bitflags! { #[repr(transparent)] pub struct ShaderStageFlags: u32 { @@ -22,6 +28,7 @@ pub enum BindingType { } #[repr(C)] +#[derive(Clone, Debug, Hash)] pub struct BindGroupLayoutBinding { pub binding: u32, pub visibility: ShaderStageFlags, @@ -36,6 +43,7 @@ pub struct BindGroupLayoutDescriptor { pub struct BindGroupLayout { pub(crate) raw: B::DescriptorSetLayout, + pub(crate) bindings: Vec, } #[repr(C)] @@ -46,7 +54,7 @@ pub struct PipelineLayoutDescriptor { pub struct PipelineLayout { pub(crate) raw: B::PipelineLayout, - pub(crate) bind_group_layout_ids: Vec, + pub(crate) bind_group_layout_ids: ArrayVec<[BindGroupLayoutId; MAX_BIND_GROUPS]>, } #[repr(C)] diff --git a/wgpu-native/src/command/allocator.rs b/wgpu-native/src/command/allocator.rs index 3f50c2c8cd..ef0663002b 100644 --- a/wgpu-native/src/command/allocator.rs +++ b/wgpu-native/src/command/allocator.rs @@ -1,15 +1,21 @@ use super::CommandBuffer; -use crate::track::TrackerSet; -use crate::{DeviceId, LifeGuard, Stored, SubmissionIndex}; +use crate::{ + track::TrackerSet, + DeviceId, LifeGuard, Stored, SubmissionIndex, +}; -use hal::command::RawCommandBuffer; -use hal::pool::RawCommandPool; -use hal::Device; +use hal::{ + command::RawCommandBuffer, + pool::RawCommandPool, + Device, +}; use parking_lot::Mutex; -use std::collections::HashMap; -use std::sync::atomic::Ordering; -use std::thread; +use std::{ + collections::HashMap, + sync::atomic::Ordering, + thread, +}; struct CommandPool { raw: B::CommandPool, diff --git a/wgpu-native/src/command/bind.rs b/wgpu-native/src/command/bind.rs index a66d9bd516..29c2c9e253 100644 --- a/wgpu-native/src/command/bind.rs +++ b/wgpu-native/src/command/bind.rs @@ -1,5 +1,8 @@ use crate::{BindGroupHandle, BindGroupId, BindGroupLayoutId, PipelineLayoutId, Stored}; +use copyless::VecHelper as _; + + pub struct BindGroupPair { layout_id: BindGroupLayoutId, group_id: Stored, @@ -64,7 +67,7 @@ pub struct Binder { impl Binder { pub fn ensure_length(&mut self, length: usize) { while self.entries.len() < length { - self.entries.push(BindGroupEntry::default()); + self.entries.alloc().init(BindGroupEntry::default()); } } diff --git a/wgpu-native/src/command/compute.rs b/wgpu-native/src/command/compute.rs index 0fb579a116..4c49879f0a 100644 --- a/wgpu-native/src/command/compute.rs +++ b/wgpu-native/src/command/compute.rs @@ -1,15 +1,18 @@ -use crate::command::bind::Binder; -use crate::hub::HUB; -use crate::track::{Stitch, TrackerSet}; use crate::{ + command::bind::Binder, + hub::HUB, + track::{Stitch, TrackerSet}, BindGroupId, CommandBuffer, CommandBufferId, ComputePassId, ComputePipelineId, Stored, }; -use hal; -use hal::command::RawCommandBuffer; +use hal::{ + self, + command::RawCommandBuffer, +}; use std::iter; + pub struct ComputePass { raw: B::CommandBuffer, cmb_id: Stored, diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index ec4bb5ce67..155b9e62d6 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -9,15 +9,15 @@ pub use self::compute::*; pub use self::render::*; pub use self::transfer::*; -use crate::conv; -use crate::device::{ - all_buffer_stages, all_image_stages, FramebufferKey, RenderPassContext, RenderPassKey, -}; -use crate::hub::{Storage, HUB}; -use crate::resource::TexturePlacement; -use crate::swap_chain::{SwapChainLink, SwapImageEpoch}; -use crate::track::{DummyUsage, Stitch, TrackerSet}; use crate::{ + conv, + device::{ + all_buffer_stages, all_image_stages, FramebufferKey, RenderPassContext, RenderPassKey, + }, + hub::{Storage, HUB}, + resource::TexturePlacement, + swap_chain::{SwapChainLink, SwapImageEpoch}, + track::{DummyUsage, Stitch, TrackerSet}, BufferHandle, Color, CommandBufferHandle, CommandBufferId, CommandEncoderId, DeviceId, LifeGuard, Stored, TextureHandle, TextureUsageFlags, TextureViewId, }; @@ -25,13 +25,18 @@ use crate::{ use crate::{ComputePassId, RenderPassId}; use back::Backend; -use hal::command::RawCommandBuffer; -use hal::Device as _Device; +use hal::{ + Device as _, + command::RawCommandBuffer, +}; use log::trace; -use std::collections::hash_map::Entry; -use std::thread::ThreadId; -use std::{iter, slice}; +use std::{ + iter, slice, + collections::hash_map::Entry, + thread::ThreadId, +}; + #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] diff --git a/wgpu-native/src/command/render.rs b/wgpu-native/src/command/render.rs index 3b7fa0bbe6..a2e89ed989 100644 --- a/wgpu-native/src/command/render.rs +++ b/wgpu-native/src/command/render.rs @@ -1,9 +1,9 @@ -use crate::command::bind::Binder; -use crate::device::RenderPassContext; -use crate::hub::HUB; -use crate::resource::BufferUsageFlags; -use crate::track::{Stitch, TrackerSet}; use crate::{ + command::bind::Binder, + device::RenderPassContext, + hub::HUB, + resource::BufferUsageFlags, + track::{Stitch, TrackerSet}, BindGroupId, BufferId, CommandBuffer, CommandBufferId, RenderPassId, RenderPipelineId, Stored, }; @@ -11,6 +11,7 @@ use hal::command::RawCommandBuffer; use std::{iter, slice}; + pub struct RenderPass { raw: B::CommandBuffer, cmb_id: Stored, diff --git a/wgpu-native/src/command/transfer.rs b/wgpu-native/src/command/transfer.rs index 3c285892d4..124b69215d 100644 --- a/wgpu-native/src/command/transfer.rs +++ b/wgpu-native/src/command/transfer.rs @@ -1,16 +1,18 @@ -use crate::conv; -use crate::device::{all_buffer_stages, all_image_stages}; -use crate::hub::HUB; -use crate::resource::TexturePlacement; -use crate::swap_chain::SwapChainLink; use crate::{ + conv, + device::{all_buffer_stages, all_image_stages}, + hub::HUB, + resource::TexturePlacement, + swap_chain::SwapChainLink, BufferId, BufferUsageFlags, CommandBufferId, Extent3d, Origin3d, TextureId, TextureUsageFlags, }; +use copyless::VecHelper as _; use hal::command::RawCommandBuffer; use std::iter; + const BITS_PER_BYTE: u32 = 8; #[repr(C)] @@ -130,7 +132,7 @@ pub extern "C" fn wgpu_command_buffer_copy_buffer_to_texture( }); if let TexturePlacement::SwapChain(ref link) = dst_texture.placement { - cmb.swap_chain_links.push(SwapChainLink { + cmb.swap_chain_links.alloc().init(SwapChainLink { swap_chain_id: link.swap_chain_id.clone(), epoch: *link.epoch.lock(), image_index: link.image_index, @@ -306,7 +308,7 @@ pub extern "C" fn wgpu_command_buffer_copy_texture_to_texture( }); if let TexturePlacement::SwapChain(ref link) = dst_texture.placement { - cmb.swap_chain_links.push(SwapChainLink { + cmb.swap_chain_links.alloc().init(SwapChainLink { swap_chain_id: link.swap_chain_id.clone(), epoch: *link.epoch.lock(), image_index: link.image_index, diff --git a/wgpu-native/src/conv.rs b/wgpu-native/src/conv.rs index 25b80ab6b7..d9ead57576 100644 --- a/wgpu-native/src/conv.rs +++ b/wgpu-native/src/conv.rs @@ -1,4 +1,8 @@ -use crate::{binding_model, command, pipeline, resource, Color, Extent3d, Origin3d}; +use crate::{ + binding_model, command, pipeline, resource, + Color, Extent3d, Origin3d, +}; + pub fn map_buffer_usage( usage: resource::BufferUsageFlags, diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 9d466ecc8c..e07f1d3a33 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -1,32 +1,38 @@ -use crate::hub::HUB; -use crate::track::{DummyUsage, Stitch, TrackPermit, TrackerSet}; -use crate::{binding_model, command, conv, pipeline, resource, swap_chain}; use crate::{ + binding_model, command, conv, pipeline, resource, swap_chain, + hub::HUB, + track::{DummyUsage, Stitch, TrackPermit, TrackerSet}, AdapterId, BindGroupId, BufferId, CommandBufferId, DeviceId, QueueId, SurfaceId, TextureId, TextureViewId, + BufferMapAsyncStatus, BufferMapOperation, LifeGuard, RefCount, Stored, SubmissionIndex, }; #[cfg(feature = "local")] use crate::{ BindGroupLayoutId, CommandEncoderId, ComputePipelineId, PipelineLayoutId, RenderPipelineId, SamplerId, ShaderModuleId, SwapChainId, }; -use crate::{ - BufferMapAsyncStatus, BufferMapOperation, LifeGuard, RefCount, Stored, SubmissionIndex, -}; use arrayvec::ArrayVec; +use copyless::VecHelper as _; use back; -use hal::backend::FastHashMap; -use hal::command::RawCommandBuffer; -use hal::queue::RawCommandQueue; -use hal::{self, DescriptorPool as _DescriptorPool, Device as _Device, Surface as _Surface}; +use hal::{ + self, DescriptorPool as _, Device as _, Surface as _, + backend::FastHashMap, + command::RawCommandBuffer, + queue::RawCommandQueue, +}; use log::{info, trace}; //use rendy_memory::{allocator, Config, Heaps}; use parking_lot::Mutex; -use std::collections::hash_map::Entry; -use std::sync::atomic::Ordering; -use std::{ffi, iter, slice}; +use std::{ + ffi, iter, ptr, slice, + collections::hash_map::Entry, + sync::atomic::Ordering, +}; + + +pub const MAX_COLOR_TARGETS: usize = 4; pub fn all_buffer_stages() -> hal::pso::PipelineStage { use hal::pso::PipelineStage as Ps; @@ -49,9 +55,15 @@ pub fn all_image_stages() -> hal::pso::PipelineStage { | Ps::TRANSFER } +#[derive(Clone, Copy, Debug, PartialEq)] +enum HostMap { + Read, + Write, +} + #[derive(Clone, Debug, Hash, PartialEq)] pub(crate) struct AttachmentData { - pub colors: ArrayVec<[T; 4]>, + pub colors: ArrayVec<[T; MAX_COLOR_TARGETS]>, pub depth_stencil: Option, } impl Eq for AttachmentData {} @@ -198,7 +210,9 @@ impl DestroyedResources { let submit_index = life_guard.submission_index.load(Ordering::Acquire); match self.active.iter_mut().find(|a| a.index == submit_index) { - Some(a) => a.resources.push((Some(resource_id), resource)), + Some(a) => { + a.resources.alloc().init((Some(resource_id), resource)); + } None => self.free.push(resource), } } @@ -261,47 +275,47 @@ impl DestroyedResources { for (ref key, submit_index) in remove_list { let resource = NativeResource::Framebuffer(framebuffers.remove(key).unwrap()); match self.active.iter_mut().find(|a| a.index == submit_index) { - Some(a) => a.resources.push((None, resource)), + Some(a) => { + a.resources.alloc().init((None, resource)); + } None => self.free.push(resource), } } } - fn handle_mapping(&mut self, raw: &::Device) { + fn handle_mapping( + &mut self, + raw: &::Device, + limits: &hal::Limits, + ) { for buffer_id in self.ready_to_map.drain(..) { - let mut operation = None; - let (result, ptr) = { + let (operation, status, ptr) = { let mut buffer_guard = HUB.buffers.write(); let mut buffer = &mut buffer_guard[buffer_id]; - std::mem::swap(&mut operation, &mut buffer.pending_map_operation); - match operation.clone().unwrap() { - BufferMapOperation::Read(range, ..) => { - match map_buffer(raw, &mut buffer, range.clone(), true, false) { - Ok(ptr) => (BufferMapAsyncStatus::Success, Some(ptr)), - Err(e) => { - log::error!("failed to map buffer for reading: {}", e); - (BufferMapAsyncStatus::Error, None) - } - } + let operation = buffer.pending_map_operation.take().unwrap(); + let result = match operation { + BufferMapOperation::Read(ref range, ..) => { + map_buffer(raw, limits, &mut buffer, range, HostMap::Read) } - BufferMapOperation::Write(range, ..) => { - match map_buffer(raw, &mut buffer, range.clone(), false, true) { - Ok(ptr) => (BufferMapAsyncStatus::Success, Some(ptr)), - Err(e) => { - log::error!("failed to map buffer for writing: {}", e); - (BufferMapAsyncStatus::Error, None) - } - } + BufferMapOperation::Write(ref range, ..) => { + map_buffer(raw, limits, &mut buffer, range, HostMap::Write) + } + }; + match result { + Ok(ptr) => (operation, BufferMapAsyncStatus::Success, ptr), + Err(e) => { + log::error!("failed to map buffer: {}", e); + (operation, BufferMapAsyncStatus::Error, ptr::null_mut()) } } }; - match operation.unwrap() { + match operation { BufferMapOperation::Read(_, callback, userdata) => { - callback(result, ptr.unwrap_or(std::ptr::null_mut()), userdata) + callback(status, ptr, userdata) } BufferMapOperation::Write(_, callback, userdata) => { - callback(result, ptr.unwrap_or(std::ptr::null_mut()), userdata) + callback(status, ptr, userdata) } }; } @@ -310,30 +324,37 @@ impl DestroyedResources { fn map_buffer( raw: &::Device, + limits: &hal::Limits, buffer: &mut resource::Buffer, - range: std::ops::Range, - read: bool, - write: bool, + original_range: &std::ops::Range, + kind: HostMap, ) -> Result<*mut u8, hal::mapping::Error> { + // 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.contains(hal::memory::Properties::COHERENT); + let atom_mask = if is_coherent { 0 } else { limits.non_coherent_atom_size as u64 - 1 }; + 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 read - && !buffer - .memory_properties - .contains(hal::memory::Properties::COHERENT) - { - unsafe { - raw.invalidate_mapped_memory_ranges(iter::once((&buffer.memory, range.clone()))) - .unwrap() - }; // TODO + + if !is_coherent { + match kind { + HostMap::Read => unsafe { + raw.invalidate_mapped_memory_ranges(iter::once((&buffer.memory, range))) + .unwrap(); + }, + HostMap::Write => { + buffer.mapped_write_ranges.push(range); + } + } } - if write - && !buffer - .memory_properties - .contains(hal::memory::Properties::COHERENT) - { - buffer.mapped_write_ranges.push(range.clone()); - } - Ok(pointer) + + 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) + }) } pub struct Device { @@ -345,6 +366,7 @@ pub struct Device { 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, @@ -357,6 +379,7 @@ impl Device { adapter_id: AdapterId, queue_group: hal::QueueGroup, 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 @@ -383,7 +406,7 @@ impl Device { let desc_pool = Mutex::new( unsafe { raw.create_descriptor_pool( - 100, + 10000, &[ hal::pso::DescriptorRangeDesc { ty: hal::pso::DescriptorType::Sampler, @@ -391,15 +414,15 @@ impl Device { }, hal::pso::DescriptorRangeDesc { ty: hal::pso::DescriptorType::SampledImage, - count: 100, + count: 1000, }, hal::pso::DescriptorRangeDesc { ty: hal::pso::DescriptorType::UniformBuffer, - count: 100, + count: 10000, }, hal::pso::DescriptorRangeDesc { ty: hal::pso::DescriptorType::StorageBuffer, - count: 100, + count: 1000, }, ], ) @@ -420,6 +443,7 @@ impl Device { life_guard, trackers: Mutex::new(TrackerSet::new()), mem_props, + limits, render_passes: Mutex::new(FastHashMap::default()), framebuffers: Mutex::new(FastHashMap::default()), desc_pool, @@ -532,15 +556,16 @@ 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 as u64; - match map_buffer(&device.raw, &mut buffer, 0..(desc.size as u64), false, true) { + match map_buffer(&device.raw, &device.limits, &mut buffer, &range, HostMap::Write) { Ok(ptr) => unsafe { *mapped_ptr_out = ptr; }, Err(e) => { log::error!("failed to create buffer in a mapped state: {}", e); unsafe { - *mapped_ptr_out = std::ptr::null_mut(); + *mapped_ptr_out = ptr::null_mut(); } } } @@ -847,7 +872,10 @@ pub fn device_create_bind_group_layout( .unwrap() }; - binding_model::BindGroupLayout { raw } + binding_model::BindGroupLayout { + raw, + bindings: bindings.to_vec(), + } } #[cfg(feature = "local")] @@ -904,6 +932,7 @@ pub fn device_create_bind_group( let bind_group_layout_guard = HUB.bind_group_layouts.read(); let bind_group_layout = &bind_group_layout_guard[desc.layout]; 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() }; @@ -915,7 +944,7 @@ pub fn device_create_bind_group( //TODO: group writes into contiguous sections let mut writes = Vec::new(); let mut used = TrackerSet::new(); - for b in bindings { + for (b, decl) in bindings.iter().zip(&bind_group_layout.bindings) { let descriptor = match b.resource { binding_model::BindingResource::Buffer(ref bb) => { let buffer = used @@ -926,6 +955,12 @@ pub fn device_create_bind_group( resource::BufferUsageFlags::UNIFORM, ) .unwrap(); + let alignment = match decl.ty { + binding_model::BindingType::UniformBuffer => device.limits.min_uniform_buffer_offset_alignment, + _ => panic!("Mismatched buffer binding for {:?}", decl), + }; + assert_eq!(bb.offset as hal::buffer::Offset % alignment, 0, + "Misaligned buffer offset {}", bb.offset); let range = Some(bb.offset as u64)..Some((bb.offset + bb.size) as u64); hal::pso::Descriptor::Buffer(&buffer.raw, range) } @@ -947,13 +982,12 @@ pub fn device_create_bind_group( hal::pso::Descriptor::Image(&view.raw, hal::image::Layout::ShaderReadOnlyOptimal) } }; - let write = hal::pso::DescriptorSetWrite { + writes.alloc().init(hal::pso::DescriptorSetWrite { set: &desc_set, binding: b.binding, array_offset: 0, //TODO descriptors: iter::once(descriptor), - }; - writes.push(write); + }); } unsafe { @@ -1177,9 +1211,9 @@ pub extern "C" fn wgpu_queue_submit( let last_done = { let mut destroyed = device.destroyed.lock(); let last_done = destroyed.cleanup(&device.raw); - destroyed.handle_mapping(&device.raw); + destroyed.handle_mapping(&device.raw, &device.limits); - destroyed.active.push(ActiveSubmission { + destroyed.active.alloc().init(ActiveSubmission { index: old_submit_index + 1, fence, resources: Vec::new(), @@ -1313,7 +1347,7 @@ pub fn device_create_render_pipeline( if vb_state.attributes_count == 0 { continue; } - vertex_buffers.push(hal::pso::VertexBufferDesc { + vertex_buffers.alloc().init(hal::pso::VertexBufferDesc { binding: i as u32, stride: vb_state.stride, rate: match vb_state.step_mode { @@ -1324,7 +1358,7 @@ pub fn device_create_render_pipeline( let desc_atts = unsafe { slice::from_raw_parts(vb_state.attributes, vb_state.attributes_count) }; for attribute in desc_atts { - attributes.push(hal::pso::AttributeDesc { + attributes.alloc().init(hal::pso::AttributeDesc { location: attribute.attribute_index, binding: i as u32, element: hal::pso::Element { @@ -1657,7 +1691,7 @@ pub fn swap_chain_populate_textures( .views .query(view_id.value, &view_id.ref_count, DummyUsage); - swap_chain.frames.push(swap_chain::Frame { + swap_chain.frames.alloc().init(swap_chain::Frame { texture_id, view_id, fence: device.raw.create_fence(true).unwrap(), diff --git a/wgpu-native/src/hub.rs b/wgpu-native/src/hub.rs index 4e50ab23b1..43f35e75c9 100644 --- a/wgpu-native/src/hub.rs +++ b/wgpu-native/src/hub.rs @@ -13,8 +13,11 @@ use parking_lot::RwLock; use serde::{Deserialize, Serialize}; use vec_map::VecMap; -use std::ops; -use std::sync::Arc; +use std::{ + ops, + sync::Arc, +}; + pub(crate) type Index = u32; pub(crate) type Epoch = u32; diff --git a/wgpu-native/src/instance.rs b/wgpu-native/src/instance.rs index 8a1bd553b3..3f1699c2e4 100644 --- a/wgpu-native/src/instance.rs +++ b/wgpu-native/src/instance.rs @@ -1,12 +1,15 @@ -use crate::hub::HUB; -use crate::{AdapterHandle, AdapterId, DeviceHandle, InstanceId, SurfaceHandle}; +use crate::{ + hub::HUB, + AdapterHandle, AdapterId, DeviceHandle, InstanceId, SurfaceHandle, +}; #[cfg(feature = "local")] use crate::{DeviceId, SurfaceId}; #[cfg(feature = "remote")] use serde::{Deserialize, Serialize}; -use hal::{self, Instance as _Instance, PhysicalDevice as _PhysicalDevice}; +use hal::{self, Instance as _, PhysicalDevice as _}; + #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] @@ -173,7 +176,8 @@ pub fn adapter_create_device(adapter_id: AdapterId, _desc: &DeviceDescriptor) -> let adapter = &adapter_guard[adapter_id]; let (raw, queue_group) = adapter.open_with::<_, hal::General>(1, |_qf| true).unwrap(); let mem_props = adapter.physical_device.memory_properties(); - DeviceHandle::new(raw, adapter_id, queue_group, mem_props) + let limits = adapter.physical_device.limits(); + DeviceHandle::new(raw, adapter_id, queue_group, mem_props, limits) } #[cfg(feature = "local")] diff --git a/wgpu-native/src/pipeline.rs b/wgpu-native/src/pipeline.rs index 94048113f4..a90f164da3 100644 --- a/wgpu-native/src/pipeline.rs +++ b/wgpu-native/src/pipeline.rs @@ -1,9 +1,12 @@ -use crate::device::RenderPassContext; -use crate::resource; -use crate::{ByteArray, PipelineLayoutId, ShaderModuleId}; +use crate::{ + device::RenderPassContext, + resource, + ByteArray, PipelineLayoutId, ShaderModuleId, +}; use bitflags::bitflags; + pub type ShaderAttributeIndex = u32; #[repr(C)] diff --git a/wgpu-native/src/resource.rs b/wgpu-native/src/resource.rs index 93eb593c5e..9acd10386c 100644 --- a/wgpu-native/src/resource.rs +++ b/wgpu-native/src/resource.rs @@ -1,5 +1,5 @@ -use crate::swap_chain::{SwapChainLink, SwapImageEpoch}; use crate::{ + swap_chain::{SwapChainLink, SwapImageEpoch}, BufferMapReadCallback, BufferMapWriteCallback, DeviceId, Extent3d, LifeGuard, RefCount, Stored, TextureId, }; @@ -10,6 +10,7 @@ use parking_lot::Mutex; use std::borrow::Borrow; + bitflags! { #[repr(transparent)] pub struct BufferUsageFlags: u32 { diff --git a/wgpu-native/src/swap_chain.rs b/wgpu-native/src/swap_chain.rs index 918f7f099b..371bbdbc8e 100644 --- a/wgpu-native/src/swap_chain.rs +++ b/wgpu-native/src/swap_chain.rs @@ -1,16 +1,18 @@ -use crate::device::all_image_stages; -use crate::hub::HUB; -use crate::track::TrackPermit; -use crate::{conv, resource}; -use crate::{DeviceId, Extent3d, Stored, SwapChainId, TextureId, TextureViewId}; +use crate::{ + conv, resource, + device::all_image_stages, + hub::HUB, + track::TrackPermit, + DeviceId, Extent3d, Stored, SwapChainId, TextureId, TextureViewId, +}; -use hal; -use hal::{Device as _Device, Swapchain as _Swapchain}; +use hal::{self, Device as _, Swapchain as _}; use log::{trace, warn}; use parking_lot::Mutex; use std::{iter, mem}; + pub type SwapImageEpoch = u16; pub(crate) struct SwapChainLink { diff --git a/wgpu-native/src/track.rs b/wgpu-native/src/track.rs index c221d0fb9e..fb30458165 100644 --- a/wgpu-native/src/track.rs +++ b/wgpu-native/src/track.rs @@ -1,15 +1,20 @@ -use crate::hub::{Epoch, Id, Index, NewId, Storage}; -use crate::resource::{BufferUsageFlags, TextureUsageFlags}; -use crate::{BufferId, RefCount, TextureId, TextureViewId}; +use crate::{ + hub::{Epoch, Id, Index, NewId, Storage}, + resource::{BufferUsageFlags, TextureUsageFlags}, + BufferId, RefCount, TextureId, TextureViewId, +}; use bitflags::bitflags; use hal::backend::FastHashMap; -use std::borrow::Borrow; -use std::collections::hash_map::Entry; -use std::marker::PhantomData; -use std::mem; -use std::ops::{BitOr, Range}; +use std::{ + borrow::Borrow, + collections::hash_map::Entry, + marker::PhantomData, + mem, + ops::{BitOr, Range}, +}; + #[derive(Clone, Debug, PartialEq)] #[allow(unused)] diff --git a/wgpu-rs/Cargo.toml b/wgpu-rs/Cargo.toml index c79655bf39..e3eae484bc 100644 --- a/wgpu-rs/Cargo.toml +++ b/wgpu-rs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wgpu" -version = "0.2.0" +version = "0.2.1" authors = [ "Dzmitry Malyshau ", "Joshua Groves ", diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs index 32eb32b7df..171ad370eb 100644 --- a/wgpu-rs/src/lib.rs +++ b/wgpu-rs/src/lib.rs @@ -323,7 +323,7 @@ impl Device { } => wgn::BindingResource::Buffer(wgn::BufferBinding { buffer: buffer.id, offset: range.start, - size: range.end, + size: range.end - range.start, }), BindingResource::Sampler(ref sampler) => { wgn::BindingResource::Sampler(sampler.id)