mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Merge #112
112: Correctness fixes from 0.2, plus a lot of goodies r=kvark a=kvark These are changes from #110 back-ported to master. Co-authored-by: Dzmitry Malyshau <dmalyshau@mozilla.com>
This commit is contained in:
@@ -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:
|
||||
|
||||
21
Cargo.lock
generated
21
Cargo.lock
generated
@@ -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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wgpu-native"
|
||||
version = "0.2.0"
|
||||
version = "0.2.4"
|
||||
authors = [
|
||||
"Dzmitry Malyshau <kvark@mozilla.com>",
|
||||
"Joshua Groves <josh@joshgroves.com>",
|
||||
@@ -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" }
|
||||
|
||||
@@ -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<B: hal::Backend> {
|
||||
pub(crate) raw: B::DescriptorSetLayout,
|
||||
pub(crate) bindings: Vec<BindGroupLayoutBinding>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@@ -46,7 +54,7 @@ pub struct PipelineLayoutDescriptor {
|
||||
|
||||
pub struct PipelineLayout<B: hal::Backend> {
|
||||
pub(crate) raw: B::PipelineLayout,
|
||||
pub(crate) bind_group_layout_ids: Vec<BindGroupLayoutId>,
|
||||
pub(crate) bind_group_layout_ids: ArrayVec<[BindGroupLayoutId; MAX_BIND_GROUPS]>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
||||
@@ -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<B: hal::Backend> {
|
||||
raw: B::CommandPool,
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use crate::{BindGroupHandle, BindGroupId, BindGroupLayoutId, PipelineLayoutId, Stored};
|
||||
|
||||
use copyless::VecHelper as _;
|
||||
|
||||
|
||||
pub struct BindGroupPair {
|
||||
layout_id: BindGroupLayoutId,
|
||||
group_id: Stored<BindGroupId>,
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<B: hal::Backend> {
|
||||
raw: B::CommandBuffer,
|
||||
cmb_id: Stored<CommandBufferId>,
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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<B: hal::Backend> {
|
||||
raw: B::CommandBuffer,
|
||||
cmb_id: Stored<CommandBufferId>,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<T> {
|
||||
pub colors: ArrayVec<[T; 4]>,
|
||||
pub colors: ArrayVec<[T; MAX_COLOR_TARGETS]>,
|
||||
pub depth_stencil: Option<T>,
|
||||
}
|
||||
impl<T: PartialEq> Eq for AttachmentData<T> {}
|
||||
@@ -198,7 +210,9 @@ impl DestroyedResources<back::Backend> {
|
||||
|
||||
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<back::Backend> {
|
||||
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: &<back::Backend as hal::Backend>::Device) {
|
||||
fn handle_mapping(
|
||||
&mut self,
|
||||
raw: &<back::Backend as hal::Backend>::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<back::Backend> {
|
||||
|
||||
fn map_buffer(
|
||||
raw: &<back::Backend as hal::Backend>::Device,
|
||||
limits: &hal::Limits,
|
||||
buffer: &mut resource::Buffer<back::Backend>,
|
||||
range: std::ops::Range<u64>,
|
||||
read: bool,
|
||||
write: bool,
|
||||
original_range: &std::ops::Range<u64>,
|
||||
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<B: hal::Backend> {
|
||||
@@ -345,6 +366,7 @@ pub struct Device<B: hal::Backend> {
|
||||
life_guard: LifeGuard,
|
||||
pub(crate) trackers: Mutex<TrackerSet>,
|
||||
mem_props: hal::MemoryProperties,
|
||||
limits: hal::Limits,
|
||||
pub(crate) render_passes: Mutex<FastHashMap<RenderPassKey, B::RenderPass>>,
|
||||
pub(crate) framebuffers: Mutex<FastHashMap<FramebufferKey, B::Framebuffer>>,
|
||||
desc_pool: Mutex<B::DescriptorPool>,
|
||||
@@ -357,6 +379,7 @@ impl<B: hal::Backend> Device<B> {
|
||||
adapter_id: AdapterId,
|
||||
queue_group: hal::QueueGroup<B, hal::General>,
|
||||
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<B: hal::Backend> Device<B> {
|
||||
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<B: hal::Backend> Device<B> {
|
||||
},
|
||||
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<B: hal::Backend> Device<B> {
|
||||
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(),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<E> {
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wgpu"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
authors = [
|
||||
"Dzmitry Malyshau <kvark@mozilla.com>",
|
||||
"Joshua Groves <josh@joshgroves.com>",
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user