Bug 1632323 - Separate WebGPU internal usage bits from the public API r=groves

Differential Revision: https://phabricator.services.mozilla.com/D72065
This commit is contained in:
Dzmitry Malyshau 2020-04-23 15:52:01 +00:00
parent cd8e73dd4c
commit 01bd7e3c8a
16 changed files with 339 additions and 298 deletions

View File

@ -200,11 +200,6 @@ ipc::IPCResult WebGPUParent::RecvDeviceCreateBuffer(
ffi::WGPUBufferDescriptor desc = {};
desc.usage = aDesc.mUsage;
desc.size = aDesc.mSize;
// tweak: imply STORAGE_READ. This is yet to be figured out by the spec,
// see https://github.com/gpuweb/gpuweb/issues/541
if (desc.usage & WGPUBufferUsage_STORAGE) {
desc.usage |= WGPUBufferUsage_STORAGE_READ;
}
ffi::wgpu_server_device_create_buffer(mContext, aSelfId, &desc, aNewId);
return IPC_OK();
}

64
gfx/wgpu/.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,64 @@
name: CI
on:
push:
branches-ignore: [ staging.tmp ]
pull_request:
branches-ignore: [ staging.tmp ]
jobs:
build:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
name: [
iOS Stable,
MacOS Stable,
MacOS Nightly,
Ubuntu Stable,
Ubuntu Nightly,
Windows Stable,
Windows Nightly,
]
include:
- os: macos-10.15
name: iOS Stable
channel: stable
build_command: rustup target add aarch64-apple-ios; cargo clippy --target aarch64-apple-ios
- os: macos-10.15
name: MacOS Stable
channel: stable
build_command: cargo clippy
- os: macos-10.15
name: MacOS Nightly
channel: nightly
build_command: cargo check
- os: ubuntu-18.04
name: Ubuntu Stable
channel: stable
build_command: cargo clippy
- os: ubuntu-18.04
name: Ubuntu Nightly
channel: nightly
build_command: cargo check
- os: windows-2019
name: Windows Stable
channel: stable
build_command: rustup default stable-msvc; cargo clippy
- os: windows-2019
name: Windows Nightly
channel: nightly
build_command: rustup default nightly-msvc; cargo clippy
steps:
- uses: actions/checkout@v2
- if: matrix.channel == 'nightly'
name: Install latest nightly
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- uses: actions/checkout@v2
- name: cargo check
run: ${{ matrix.build_command }}

View File

@ -1,69 +0,0 @@
language: rust
sudo: false
dist: xenial
matrix:
include:
# Linux 64bit
- os: linux
rust: stable
compiler: gcc
env:
- BUILD_COMMAND=clippy
#TODO: unlock when libglfw3 on Ubuntu comes with Vulkan support
# or when we add a GL backend.
#- os: linux
# rust: nightly
# compiler: gcc
# env:
# - BUILD_COMMAND=check
# Windows 64bit
- os: windows
rust: stable
env:
- BUILD_COMMAND=clippy
- os: windows
rust: nightly
env:
- BUILD_COMMAND=check
# macOS 64bit
- os: osx
osx_image: xcode9.4
rust: stable
compiler: clang
env:
- MACOSX_DEPLOYMENT_TARGET=10.9
- BUILD_COMMAND=clippy
- os: osx
osx_image: xcode9.4
rust: nightly
compiler: clang
env:
- MACOSX_DEPLOYMENT_TARGET=10.9
- BUILD_COMMAND=check
# iPhoneOS 64bit
- os: osx
osx_image: xcode11
rust: stable
env:
- TARGET=aarch64-apple-ios
- BUILD_COMMAND=clippy
branches:
except:
- staging.tmp
before_install:
- if [[ $TRAVIS_RUST_VERSION != "nightly" ]] && [[ $TRAVIS_OS_NAME == "windows" ]]; then rustup default stable-msvc; fi
- if [[ $TRAVIS_RUST_VERSION == "nightly" ]] && [[ $TRAVIS_OS_NAME == "windows" ]]; then rustup default nightly-msvc; fi
before_script:
- if [[ $BUILD_COMMAND == "clippy" ]]; then rustup component add clippy; fi
script:
- cargo test
- (cd wgpu-core && cargo $BUILD_COMMAND --all-features)
- if [[ $TRAVIS_OS_NAME == "linux" ]]; then cargo $BUILD_COMMAND --release; fi

View File

@ -1,6 +1,11 @@
status = [
"continuous-integration/travis-ci/push",
#"continuous-integration/appveyor/branch"
"iOS Stable",
"MacOS Stable",
"MacOS Nightly",
"Ubuntu Stable",
"Ubuntu Nightly",
"Windows Stable",
"Windows Nightly",
]
timeout_sec = 18000 # 5 hours

View File

@ -10,6 +10,7 @@ use crate::{
device::all_buffer_stages,
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Token},
id,
resource::BufferUse,
};
use hal::command::CommandBuffer as _;
@ -228,7 +229,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&*buffer_guard,
buffer_id,
(),
BufferUsage::INDIRECT,
BufferUse::INDIRECT,
);
assert!(src_buffer.usage.contains(BufferUsage::INDIRECT));

View File

@ -15,7 +15,7 @@ use crate::{
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Token},
id,
pipeline::PipelineFlags,
resource::TextureViewInner,
resource::{BufferUse, TextureUse, TextureViewInner},
track::TrackerSet,
Stored,
};
@ -385,7 +385,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
type OutputAttachment<'a> = (
&'a Stored<id::TextureId>,
&'a hal::image::SubresourceRange,
Option<TextureUsage>,
Option<TextureUse>,
);
let mut output_attachments =
ArrayVec::<[OutputAttachment; MAX_TOTAL_ATTACHMENTS]>::new();
@ -414,12 +414,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
// Using render pass for transition.
let consistent_usage = base_trackers
let consistent_use = base_trackers
.textures
.query(source_id.value, view.range.clone());
output_attachments.push((source_id, &view.range, consistent_usage));
output_attachments.push((source_id, &view.range, consistent_use));
let old_layout = match consistent_usage {
let old_layout = match consistent_use {
Some(usage) => {
conv::map_texture_state(
usage,
@ -464,12 +464,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let layouts = match view.inner {
TextureViewInner::Native { ref source_id, .. } => {
let consistent_usage = base_trackers
let consistent_use = base_trackers
.textures
.query(source_id.value, view.range.clone());
output_attachments.push((source_id, &view.range, consistent_usage));
output_attachments.push((source_id, &view.range, consistent_use));
let old_layout = match consistent_usage {
let old_layout = match consistent_use {
Some(usage) => {
conv::map_texture_state(usage, hal::format::Aspects::COLOR).1
}
@ -486,9 +486,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
let end = hal::image::Layout::Present;
let start = match base_trackers.views.query(at.attachment, ()) {
Some(_) => end,
None => hal::image::Layout::Undefined,
let start = match at.load_op {
LoadOp::Clear => hal::image::Layout::Undefined,
LoadOp::Load => end,
};
start..end
}
@ -516,12 +516,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let layouts = match view.inner {
TextureViewInner::Native { ref source_id, .. } => {
let consistent_usage = base_trackers
let consistent_use = base_trackers
.textures
.query(source_id.value, view.range.clone());
output_attachments.push((source_id, &view.range, consistent_usage));
output_attachments.push((source_id, &view.range, consistent_use));
let old_layout = match consistent_usage {
let old_layout = match consistent_use {
Some(usage) => {
conv::map_texture_state(usage, hal::format::Aspects::COLOR).1
}
@ -536,13 +536,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
assert!(used_swap_chain.is_none());
used_swap_chain = Some(source_id.clone());
}
let end = hal::image::Layout::Present;
let start = match base_trackers.views.query(resolve_target, ()) {
Some(_) => end,
None => hal::image::Layout::Undefined,
};
start..end
hal::image::Layout::Undefined..hal::image::Layout::Present
}
};
@ -565,11 +559,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
};
for (source_id, view_range, consistent_usage) in output_attachments {
for (source_id, view_range, consistent_use) in output_attachments {
let texture = &texture_guard[source_id.value];
assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT));
let usage = consistent_usage.unwrap_or(TextureUsage::OUTPUT_ATTACHMENT);
let usage = consistent_use.unwrap_or(TextureUse::OUTPUT_ATTACHMENT);
// this is important to record the `first` state.
let _ = trackers.textures.change_replace(
source_id.value,
@ -577,14 +571,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
view_range.clone(),
usage,
);
if consistent_usage.is_some() {
if consistent_use.is_some() {
// If we expect the texture to be transited to a new state by the
// render pass configuration, make the tracker aware of that.
let _ = trackers.textures.change_replace(
source_id.value,
&source_id.ref_count,
view_range.clone(),
TextureUsage::OUTPUT_ATTACHMENT,
TextureUse::OUTPUT_ATTACHMENT,
);
};
}
@ -950,7 +944,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
if let Some((buffer_id, ref range)) = state.index.bound_buffer_view {
let buffer = trackers
.buffers
.use_extend(&*buffer_guard, buffer_id, (), BufferUsage::INDEX)
.use_extend(&*buffer_guard, buffer_id, (), BufferUse::INDEX)
.unwrap();
let view = hal::buffer::IndexBufferView {
@ -988,7 +982,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
} => {
let buffer = trackers
.buffers
.use_extend(&*buffer_guard, buffer_id, (), BufferUsage::INDEX)
.use_extend(&*buffer_guard, buffer_id, (), BufferUse::INDEX)
.unwrap();
assert!(buffer.usage.contains(BufferUsage::INDEX), "An invalid setIndexBuffer call has been made. The buffer usage is {:?} which does not contain required usage INDEX", buffer.usage);
@ -1021,7 +1015,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
} => {
let buffer = trackers
.buffers
.use_extend(&*buffer_guard, buffer_id, (), BufferUsage::VERTEX)
.use_extend(&*buffer_guard, buffer_id, (), BufferUse::VERTEX)
.unwrap();
assert!(buffer.usage.contains(BufferUsage::VERTEX), "An invalid setVertexBuffer call has been made. The buffer usage is {:?} which does not contain required usage VERTEX", buffer.usage);
let empty_slots = (1 + slot as usize).saturating_sub(state.vertex.inputs.len());
@ -1145,7 +1139,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let buffer = trackers
.buffers
.use_extend(&*buffer_guard, buffer_id, (), BufferUsage::INDIRECT)
.use_extend(&*buffer_guard, buffer_id, (), BufferUse::INDIRECT)
.unwrap();
assert!(buffer.usage.contains(BufferUsage::INDIRECT), "An invalid drawIndirect call has been made. The buffer usage is {:?} which does not contain required usage INDIRECT", buffer.usage);
@ -1158,7 +1152,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let buffer = trackers
.buffers
.use_extend(&*buffer_guard, buffer_id, (), BufferUsage::INDIRECT)
.use_extend(&*buffer_guard, buffer_id, (), BufferUse::INDIRECT)
.unwrap();
assert!(buffer.usage.contains(BufferUsage::INDIRECT), "An invalid drawIndexedIndirect call has been made. The buffer usage is {:?} which does not contain required usage INDIRECT", buffer.usage);

View File

@ -7,6 +7,7 @@ use crate::{
device::{all_buffer_stages, all_image_stages},
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Token},
id::{BufferId, CommandEncoderId, TextureId},
resource::{BufferUse, TextureUse},
};
use hal::command::CommandBuffer as _;
@ -92,16 +93,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (src_buffer, src_pending) =
cmb.trackers
.buffers
.use_replace(&*buffer_guard, source, (), BufferUsage::COPY_SRC);
.use_replace(&*buffer_guard, source, (), BufferUse::COPY_SRC);
assert!(src_buffer.usage.contains(BufferUsage::COPY_SRC));
barriers.extend(src_pending.map(|pending| pending.into_hal(src_buffer)));
let (dst_buffer, dst_pending) = cmb.trackers.buffers.use_replace(
&*buffer_guard,
destination,
(),
BufferUsage::COPY_DST,
);
let (dst_buffer, dst_pending) =
cmb.trackers
.buffers
.use_replace(&*buffer_guard, destination, (), BufferUse::COPY_DST);
assert!(dst_buffer.usage.contains(BufferUsage::COPY_DST));
barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_buffer)));
@ -140,7 +139,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&*buffer_guard,
source.buffer,
(),
BufferUsage::COPY_SRC,
BufferUse::COPY_SRC,
);
assert!(src_buffer.usage.contains(BufferUsage::COPY_SRC));
let src_barriers = src_pending.map(|pending| pending.into_hal(src_buffer));
@ -149,7 +148,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&*texture_guard,
destination.texture,
destination.to_selector(aspects),
TextureUsage::COPY_DST,
TextureUse::COPY_DST,
);
assert!(dst_texture.usage.contains(TextureUsage::COPY_DST));
let dst_barriers = dst_pending.map(|pending| pending.into_hal(dst_texture));
@ -204,7 +203,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&*texture_guard,
source.texture,
source.to_selector(aspects),
TextureUsage::COPY_SRC,
TextureUse::COPY_SRC,
);
assert!(src_texture.usage.contains(TextureUsage::COPY_SRC));
let src_barriers = src_pending.map(|pending| pending.into_hal(src_texture));
@ -213,7 +212,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&*buffer_guard,
destination.buffer,
(),
BufferUsage::COPY_DST,
BufferUse::COPY_DST,
);
assert!(dst_buffer.usage.contains(BufferUsage::COPY_DST));
let dst_barrier = dst_barriers.map(|pending| pending.into_hal(dst_buffer));
@ -273,7 +272,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&*texture_guard,
source.texture,
source.to_selector(aspects),
TextureUsage::COPY_SRC,
TextureUse::COPY_SRC,
);
assert!(src_texture.usage.contains(TextureUsage::COPY_SRC));
barriers.extend(src_pending.map(|pending| pending.into_hal(src_texture)));
@ -282,7 +281,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&*texture_guard,
destination.texture,
destination.to_selector(aspects),
TextureUsage::COPY_DST,
TextureUse::COPY_DST,
);
assert!(dst_texture.usage.contains(TextureUsage::COPY_DST));
barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_texture)));

View File

@ -2,13 +2,7 @@
* 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 crate::{binding_model, Features};
use wgt::{
BlendDescriptor, BlendFactor, Color, ColorStateDescriptor, ColorWrite, CompareFunction,
CullMode, DepthStencilStateDescriptor, Extent3d, FrontFace, IndexFormat, Origin3d,
PrimitiveTopology, RasterizationStateDescriptor, StencilOperation, StencilStateFaceDescriptor,
TextureFormat, VertexFormat,
};
use crate::{binding_model, resource, Features};
pub fn map_buffer_usage(usage: wgt::BufferUsage) -> (hal::buffer::Usage, hal::memory::Properties) {
use hal::buffer::Usage as U;
@ -39,7 +33,7 @@ pub fn map_buffer_usage(usage: wgt::BufferUsage) -> (hal::buffer::Usage, hal::me
if usage.contains(W::UNIFORM) {
hal_usage |= U::UNIFORM;
}
if usage.intersects(W::STORAGE | W::STORAGE_READ) {
if usage.contains(W::STORAGE) {
hal_usage |= U::STORAGE;
}
if usage.contains(W::INDIRECT) {
@ -135,7 +129,7 @@ pub fn map_shader_stage_flags(shader_stage_flags: wgt::ShaderStage) -> hal::pso:
value
}
pub fn map_origin(origin: Origin3d) -> hal::image::Offset {
pub fn map_origin(origin: wgt::Origin3d) -> hal::image::Offset {
hal::image::Offset {
x: origin.x as i32,
y: origin.y as i32,
@ -143,7 +137,7 @@ pub fn map_origin(origin: Origin3d) -> hal::image::Offset {
}
}
pub fn map_extent(extent: Extent3d) -> hal::image::Extent {
pub fn map_extent(extent: wgt::Extent3d) -> hal::image::Extent {
hal::image::Extent {
width: extent.width,
height: extent.height,
@ -151,7 +145,7 @@ pub fn map_extent(extent: Extent3d) -> hal::image::Extent {
}
}
pub fn map_primitive_topology(primitive_topology: PrimitiveTopology) -> hal::pso::Primitive {
pub fn map_primitive_topology(primitive_topology: wgt::PrimitiveTopology) -> hal::pso::Primitive {
use hal::pso::Primitive as H;
use wgt::PrimitiveTopology as Pt;
match primitive_topology {
@ -163,10 +157,10 @@ pub fn map_primitive_topology(primitive_topology: PrimitiveTopology) -> hal::pso
}
}
pub fn map_color_state_descriptor(desc: &ColorStateDescriptor) -> hal::pso::ColorBlendDesc {
pub fn map_color_state_descriptor(desc: &wgt::ColorStateDescriptor) -> hal::pso::ColorBlendDesc {
let color_mask = desc.write_mask;
let blend_state = if desc.color_blend != BlendDescriptor::REPLACE
|| desc.alpha_blend != BlendDescriptor::REPLACE
let blend_state = if desc.color_blend != wgt::BlendDescriptor::REPLACE
|| desc.alpha_blend != wgt::BlendDescriptor::REPLACE
{
Some(hal::pso::BlendState {
color: map_blend_descriptor(&desc.color_blend),
@ -181,7 +175,7 @@ pub fn map_color_state_descriptor(desc: &ColorStateDescriptor) -> hal::pso::Colo
}
}
fn map_color_write_flags(flags: ColorWrite) -> hal::pso::ColorMask {
fn map_color_write_flags(flags: wgt::ColorWrite) -> hal::pso::ColorMask {
use hal::pso::ColorMask as H;
use wgt::ColorWrite as Cw;
@ -201,7 +195,7 @@ fn map_color_write_flags(flags: ColorWrite) -> hal::pso::ColorMask {
value
}
fn map_blend_descriptor(blend_desc: &BlendDescriptor) -> hal::pso::BlendOp {
fn map_blend_descriptor(blend_desc: &wgt::BlendDescriptor) -> hal::pso::BlendOp {
use hal::pso::BlendOp as H;
use wgt::BlendOperation as Bo;
match blend_desc.operation {
@ -222,7 +216,7 @@ fn map_blend_descriptor(blend_desc: &BlendDescriptor) -> hal::pso::BlendOp {
}
}
fn map_blend_factor(blend_factor: BlendFactor) -> hal::pso::Factor {
fn map_blend_factor(blend_factor: wgt::BlendFactor) -> hal::pso::Factor {
use hal::pso::Factor as H;
use wgt::BlendFactor as Bf;
match blend_factor {
@ -243,10 +237,10 @@ fn map_blend_factor(blend_factor: BlendFactor) -> hal::pso::Factor {
}
pub fn map_depth_stencil_state_descriptor(
desc: &DepthStencilStateDescriptor,
desc: &wgt::DepthStencilStateDescriptor,
) -> hal::pso::DepthStencilDesc {
hal::pso::DepthStencilDesc {
depth: if desc.depth_write_enabled || desc.depth_compare != CompareFunction::Always {
depth: if desc.depth_write_enabled || desc.depth_compare != wgt::CompareFunction::Always {
Some(hal::pso::DepthTest {
fun: map_compare_function(desc.depth_compare)
.expect("DepthStencilStateDescriptor has undefined compare function"),
@ -258,8 +252,8 @@ pub fn map_depth_stencil_state_descriptor(
depth_bounds: false, // TODO
stencil: if desc.stencil_read_mask != !0
|| desc.stencil_write_mask != !0
|| desc.stencil_front != StencilStateFaceDescriptor::IGNORE
|| desc.stencil_back != StencilStateFaceDescriptor::IGNORE
|| desc.stencil_front != wgt::StencilStateFaceDescriptor::IGNORE
|| desc.stencil_back != wgt::StencilStateFaceDescriptor::IGNORE
{
Some(hal::pso::StencilTest {
faces: hal::pso::Sided {
@ -280,7 +274,9 @@ pub fn map_depth_stencil_state_descriptor(
}
}
fn map_stencil_face(stencil_state_face_desc: &StencilStateFaceDescriptor) -> hal::pso::StencilFace {
fn map_stencil_face(
stencil_state_face_desc: &wgt::StencilStateFaceDescriptor,
) -> hal::pso::StencilFace {
hal::pso::StencilFace {
fun: map_compare_function(stencil_state_face_desc.compare)
.expect("StencilStateFaceDescriptor has undefined compare function"),
@ -290,7 +286,9 @@ fn map_stencil_face(stencil_state_face_desc: &StencilStateFaceDescriptor) -> hal
}
}
pub fn map_compare_function(compare_function: CompareFunction) -> Option<hal::pso::Comparison> {
pub fn map_compare_function(
compare_function: wgt::CompareFunction,
) -> Option<hal::pso::Comparison> {
use hal::pso::Comparison as H;
use wgt::CompareFunction as Cf;
match compare_function {
@ -306,7 +304,7 @@ pub fn map_compare_function(compare_function: CompareFunction) -> Option<hal::ps
}
}
fn map_stencil_operation(stencil_operation: StencilOperation) -> hal::pso::StencilOp {
fn map_stencil_operation(stencil_operation: wgt::StencilOperation) -> hal::pso::StencilOp {
use hal::pso::StencilOp as H;
use wgt::StencilOperation as So;
match stencil_operation {
@ -322,7 +320,7 @@ fn map_stencil_operation(stencil_operation: StencilOperation) -> hal::pso::Stenc
}
pub(crate) fn map_texture_format(
texture_format: TextureFormat,
texture_format: wgt::TextureFormat,
features: Features,
) -> hal::format::Format {
use hal::format::Format as H;
@ -394,7 +392,7 @@ pub(crate) fn map_texture_format(
}
}
pub fn map_vertex_format(vertex_format: VertexFormat) -> hal::format::Format {
pub fn map_vertex_format(vertex_format: wgt::VertexFormat) -> hal::format::Format {
use hal::format::Format as H;
use wgt::VertexFormat as Vf;
match vertex_format {
@ -436,13 +434,17 @@ fn checked_u32_as_u16(value: u32) -> u16 {
value as u16
}
fn is_power_of_two(val: u32) -> bool {
val != 0 && (val & (val - 1)) == 0
}
pub fn map_texture_dimension_size(
dimension: wgt::TextureDimension,
Extent3d {
wgt::Extent3d {
width,
height,
depth,
}: Extent3d,
}: wgt::Extent3d,
sample_size: u32,
) -> hal::image::Kind {
use hal::image::Kind as H;
@ -455,7 +457,7 @@ pub fn map_texture_dimension_size(
}
D2 => {
assert!(
sample_size <= 32 && sample_size & (sample_size - 1) == 0,
sample_size <= 32 && is_power_of_two(sample_size),
"Invalid sample_count of {}",
sample_size
);
@ -481,11 +483,17 @@ pub fn map_texture_view_dimension(dimension: wgt::TextureViewDimension) -> hal::
}
}
pub fn map_buffer_state(usage: wgt::BufferUsage) -> hal::buffer::State {
pub(crate) fn map_buffer_state(usage: resource::BufferUse) -> hal::buffer::State {
use crate::resource::BufferUse as W;
use hal::buffer::Access as A;
use wgt::BufferUsage as W;
let mut access = A::empty();
if usage.contains(W::MAP_READ) {
access |= A::HOST_READ;
}
if usage.contains(W::MAP_WRITE) {
access |= A::HOST_WRITE;
}
if usage.contains(W::COPY_SRC) {
access |= A::TRANSFER_READ;
}
@ -501,22 +509,22 @@ pub fn map_buffer_state(usage: wgt::BufferUsage) -> hal::buffer::State {
if usage.contains(W::UNIFORM) {
access |= A::UNIFORM_READ | A::SHADER_READ;
}
if usage.contains(W::STORAGE_READ) {
if usage.contains(W::STORAGE_LOAD) {
access |= A::SHADER_READ;
}
if usage.contains(W::STORAGE) {
if usage.contains(W::STORAGE_STORE) {
access |= A::SHADER_WRITE;
}
access
}
pub fn map_texture_state(
usage: wgt::TextureUsage,
pub(crate) fn map_texture_state(
usage: resource::TextureUse,
aspects: hal::format::Aspects,
) -> hal::image::State {
use crate::resource::TextureUse as W;
use hal::image::{Access as A, Layout as L};
use wgt::TextureUsage as W;
let is_color = aspects.contains(hal::format::Aspects::COLOR);
let layout = match usage {
@ -539,9 +547,6 @@ pub fn map_texture_state(
if usage.contains(W::SAMPLED) {
access |= A::SHADER_READ;
}
if usage.contains(W::STORAGE) {
access |= A::SHADER_WRITE;
}
if usage.contains(W::OUTPUT_ATTACHMENT) {
//TODO: read-only attachments
access |= if is_color {
@ -550,6 +555,12 @@ pub fn map_texture_state(
A::DEPTH_STENCIL_ATTACHMENT_WRITE
};
}
if usage.contains(W::STORAGE_LOAD) {
access |= A::SHADER_READ;
}
if usage.contains(W::STORAGE_STORE) {
access |= A::SHADER_WRITE;
}
(access, layout)
}
@ -567,7 +578,7 @@ pub fn map_load_store_ops(load: wgt::LoadOp, store: wgt::StoreOp) -> hal::pass::
}
}
pub fn map_color_f32(color: &Color) -> hal::pso::ColorValue {
pub fn map_color_f32(color: &wgt::Color) -> hal::pso::ColorValue {
[
color.r as f32,
color.g as f32,
@ -575,7 +586,7 @@ pub fn map_color_f32(color: &Color) -> hal::pso::ColorValue {
color.a as f32,
]
}
pub fn map_color_i32(color: &Color) -> [i32; 4] {
pub fn map_color_i32(color: &wgt::Color) -> [i32; 4] {
[
color.r as i32,
color.g as i32,
@ -583,7 +594,7 @@ pub fn map_color_i32(color: &Color) -> [i32; 4] {
color.a as i32,
]
}
pub fn map_color_u32(color: &Color) -> [u32; 4] {
pub fn map_color_u32(color: &wgt::Color) -> [u32; 4] {
[
color.r as u32,
color.g as u32,
@ -610,20 +621,20 @@ pub fn map_wrap(address: wgt::AddressMode) -> hal::image::WrapMode {
}
pub fn map_rasterization_state_descriptor(
desc: &RasterizationStateDescriptor,
desc: &wgt::RasterizationStateDescriptor,
) -> hal::pso::Rasterizer {
use hal::pso;
pso::Rasterizer {
depth_clamping: false,
polygon_mode: pso::PolygonMode::Fill,
cull_face: match desc.cull_mode {
CullMode::None => pso::Face::empty(),
CullMode::Front => pso::Face::FRONT,
CullMode::Back => pso::Face::BACK,
wgt::CullMode::None => pso::Face::empty(),
wgt::CullMode::Front => pso::Face::FRONT,
wgt::CullMode::Back => pso::Face::BACK,
},
front_face: match desc.front_face {
FrontFace::Ccw => pso::FrontFace::CounterClockwise,
FrontFace::Cw => pso::FrontFace::Clockwise,
wgt::FrontFace::Ccw => pso::FrontFace::CounterClockwise,
wgt::FrontFace::Cw => pso::FrontFace::Clockwise,
},
depth_bias: if desc.depth_bias != 0
|| desc.depth_bias_slope_scale != 0.0
@ -642,9 +653,9 @@ pub fn map_rasterization_state_descriptor(
}
}
pub fn map_index_format(index_format: IndexFormat) -> hal::IndexType {
pub fn map_index_format(index_format: wgt::IndexFormat) -> hal::IndexType {
match index_format {
IndexFormat::Uint16 => hal::IndexType::U16,
IndexFormat::Uint32 => hal::IndexType::U32,
wgt::IndexFormat::Uint16 => hal::IndexType::U16,
wgt::IndexFormat::Uint32 => hal::IndexType::U32,
}
}

View File

@ -58,7 +58,7 @@ pub fn all_image_stages() -> hal::pso::PipelineStage {
}
#[derive(Clone, Copy, Debug, PartialEq)]
enum HostMap {
pub enum HostMap {
Read,
Write,
}
@ -500,7 +500,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.init(
id,
ref_count,
BufferState::with_usage(wgt::BufferUsage::empty()),
BufferState::with_usage(resource::BufferUse::EMPTY),
)
.unwrap();
id
@ -547,7 +547,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.init(
id,
ref_count,
BufferState::with_usage(wgt::BufferUsage::MAP_WRITE),
BufferState::with_usage(resource::BufferUse::MAP_WRITE),
)
.unwrap();
@ -1084,22 +1084,28 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.expect("Failed to find binding declaration for binding");
let descriptor = match b.resource {
binding_model::BindingResource::Buffer(ref bb) => {
let (alignment, usage) = match decl.ty {
binding_model::BindingType::UniformBuffer => {
(BIND_BUFFER_ALIGNMENT, wgt::BufferUsage::UNIFORM)
}
binding_model::BindingType::StorageBuffer => {
(BIND_BUFFER_ALIGNMENT, wgt::BufferUsage::STORAGE)
}
binding_model::BindingType::ReadonlyStorageBuffer => {
(BIND_BUFFER_ALIGNMENT, wgt::BufferUsage::STORAGE_READ)
}
let (alignment, pub_usage, internal_use) = match decl.ty {
binding_model::BindingType::UniformBuffer => (
BIND_BUFFER_ALIGNMENT,
wgt::BufferUsage::UNIFORM,
resource::BufferUse::UNIFORM,
),
binding_model::BindingType::StorageBuffer => (
BIND_BUFFER_ALIGNMENT,
wgt::BufferUsage::STORAGE,
resource::BufferUse::STORAGE_STORE,
),
binding_model::BindingType::ReadonlyStorageBuffer => (
BIND_BUFFER_ALIGNMENT,
wgt::BufferUsage::STORAGE,
resource::BufferUse::STORAGE_LOAD,
),
binding_model::BindingType::Sampler
| binding_model::BindingType::ComparisonSampler
| binding_model::BindingType::SampledTexture
| binding_model::BindingType::ReadonlyStorageTexture
| binding_model::BindingType::WriteonlyStorageTexture => {
panic!("Mismatched buffer binding for {:?}", decl)
panic!("Mismatched buffer binding type for {:?}. Expected a type of UniformBuffer, StorageBuffer or ReadonlyStorageBuffer", decl)
}
};
assert_eq!(
@ -1110,12 +1116,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
);
let buffer = used
.buffers
.use_extend(&*buffer_guard, bb.buffer, (), usage)
.use_extend(&*buffer_guard, bb.buffer, (), internal_use)
.unwrap();
assert!(
buffer.usage.contains(usage),
buffer.usage.contains(pub_usage),
"Expected buffer usage {:?}",
usage
pub_usage
);
let sub_range = hal::buffer::SubRange {
@ -1139,7 +1145,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
match decl.ty {
binding_model::BindingType::Sampler
| binding_model::BindingType::ComparisonSampler => {}
_ => panic!("Wrong binding type for a sampler: {:?}", decl.ty),
_ => panic!("Mismatched sampler binding type in {:?}. Expected a type of Sampler or ComparisonSampler", decl.ty),
}
let sampler = used
.samplers
@ -1148,16 +1154,23 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
hal::pso::Descriptor::Sampler(&sampler.raw)
}
binding_model::BindingResource::TextureView(id) => {
let (usage, image_layout) = match decl.ty {
let (pub_usage, internal_use, image_layout) = match decl.ty {
binding_model::BindingType::SampledTexture => (
wgt::TextureUsage::SAMPLED,
resource::TextureUse::SAMPLED,
hal::image::Layout::ShaderReadOnlyOptimal,
),
binding_model::BindingType::ReadonlyStorageTexture
| binding_model::BindingType::WriteonlyStorageTexture => {
(wgt::TextureUsage::STORAGE, hal::image::Layout::General)
}
_ => panic!("Mismatched texture binding for {:?}", decl),
binding_model::BindingType::ReadonlyStorageTexture => (
wgt::TextureUsage::STORAGE,
resource::TextureUse::STORAGE_LOAD,
hal::image::Layout::General,
),
binding_model::BindingType::WriteonlyStorageTexture => (
wgt::TextureUsage::STORAGE,
resource::TextureUse::STORAGE_STORE,
hal::image::Layout::General,
),
_ => panic!("Mismatched texture binding type in {:?}. Expected a type of SampledTexture, ReadonlyStorageTexture or WriteonlyStorageTexture", decl),
};
let view = used
.views
@ -1176,10 +1189,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
source_id.value,
&source_id.ref_count,
view.range.clone(),
usage,
internal_use,
)
.unwrap();
assert!(texture.usage.contains(usage));
assert!(
texture.usage.contains(pub_usage),
"Expected buffer usage {:?}",
pub_usage
);
hal::pso::Descriptor::Image(raw, image_layout)
}
@ -1461,6 +1478,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
if !buffer_guard[id].life_guard.use_at(submit_index) {
if let resource::BufferMapState::Active = buffer_guard[id].map_state {
log::warn!("Dropped buffer has a pending mapping.");
unmap_buffer(&device.raw, &mut buffer_guard[id]);
}
device.temp_suspected.buffers.push(id);
@ -2098,26 +2116,26 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn buffer_map_async<B: GfxBackend>(
&self,
buffer_id: id::BufferId,
usage: wgt::BufferUsage,
range: std::ops::Range<BufferAddress>,
operation: resource::BufferMapOperation,
) {
let hub = B::hub(self);
let mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token);
let (pub_usage, internal_use) = match operation {
resource::BufferMapOperation::Read { .. } => {
(wgt::BufferUsage::MAP_READ, resource::BufferUse::MAP_READ)
}
resource::BufferMapOperation::Write { .. } => {
(wgt::BufferUsage::MAP_WRITE, resource::BufferUse::MAP_WRITE)
}
};
let (device_id, ref_count) = {
let (mut buffer_guard, _) = hub.buffers.write(&mut token);
let buffer = &mut buffer_guard[buffer_id];
if usage.contains(wgt::BufferUsage::MAP_READ) {
assert!(buffer.usage.contains(wgt::BufferUsage::MAP_READ));
}
if usage.contains(wgt::BufferUsage::MAP_WRITE) {
assert!(buffer.usage.contains(wgt::BufferUsage::MAP_WRITE));
}
assert!(buffer.usage.contains(pub_usage));
buffer.map_state = match buffer.map_state {
resource::BufferMapState::Active => panic!("Buffer already mapped"),
resource::BufferMapState::Waiting(_) => {
@ -2146,7 +2164,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.trackers
.lock()
.buffers
.change_replace(buffer_id, &ref_count, (), usage);
.change_replace(buffer_id, &ref_count, (), internal_use);
device.lock_life(&mut token).map(buffer_id, ref_count);
}

View File

@ -26,7 +26,7 @@ pub mod backend {
pub mod binding_model;
pub mod command;
pub mod conv;
mod conv;
pub mod device;
pub mod hub;
pub mod id;
@ -35,7 +35,7 @@ pub mod pipeline;
pub mod power;
pub mod resource;
pub mod swap_chain;
pub mod track;
mod track;
pub use hal::pso::read_spirv;

View File

@ -13,6 +13,55 @@ use wgt::{BufferAddress, BufferUsage, TextureFormat, TextureUsage};
use std::{borrow::Borrow, fmt};
bitflags::bitflags! {
/// The internal enum mirrored from `BufferUsage`. The values don't have to match!
pub (crate) struct BufferUse: u32 {
const EMPTY = 0;
const MAP_READ = 1;
const MAP_WRITE = 2;
const COPY_SRC = 4;
const COPY_DST = 8;
const INDEX = 16;
const VERTEX = 32;
const UNIFORM = 64;
const STORAGE_LOAD = 128;
const STORAGE_STORE = 256;
const INDIRECT = 512;
/// The combination of all read-only usages.
const READ_ALL = Self::MAP_READ.bits | Self::COPY_SRC.bits |
Self::INDEX.bits | Self::VERTEX.bits | Self::UNIFORM.bits |
Self::STORAGE_LOAD.bits | Self::INDIRECT.bits;
/// The combination of all write-only and read-write usages.
const WRITE_ALL = Self::MAP_WRITE.bits | Self::COPY_DST.bits | Self::STORAGE_STORE.bits;
/// The combination of all usages that the are guaranteed to be be ordered by the hardware.
/// If a usage is not ordered, then even if it doesn't change between draw calls, there
/// still need to be pipeline barriers inserted for synchronization.
const ORDERED = Self::READ_ALL.bits | Self::MAP_WRITE.bits | Self::COPY_DST.bits;
}
}
bitflags::bitflags! {
/// The internal enum mirrored from `TextureUsage`. The values don't have to match!
pub(crate) struct TextureUse: u32 {
const EMPTY = 0;
const COPY_SRC = 1;
const COPY_DST = 2;
const SAMPLED = 4;
const OUTPUT_ATTACHMENT = 8;
const STORAGE_LOAD = 16;
const STORAGE_STORE = 32;
/// The combination of all read-only usages.
const READ_ALL = Self::COPY_SRC.bits | Self::SAMPLED.bits | Self::STORAGE_LOAD.bits;
/// The combination of all write-only and read-write usages.
const WRITE_ALL = Self::COPY_DST.bits | Self::OUTPUT_ATTACHMENT.bits | Self::STORAGE_STORE.bits;
/// The combination of all usages that the are guaranteed to be be ordered by the hardware.
/// If a usage is not ordered, then even if it doesn't change between draw calls, there
/// still need to be pipeline barriers inserted for synchronization.
const ORDERED = Self::READ_ALL.bits | Self::COPY_DST.bits | Self::OUTPUT_ATTACHMENT.bits;
const UNINITIALIZED = 0xFFFF;
}
}
#[repr(C)]
#[derive(Debug)]
pub enum BufferMapAsyncStatus {

View File

@ -3,18 +3,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use super::{PendingTransition, ResourceState, Unit};
use crate::id::BufferId;
use wgt::BufferUsage;
use crate::{id::BufferId, resource::BufferUse};
//TODO: store `hal::buffer::State` here to avoid extra conversions
pub type BufferState = Unit<BufferUsage>;
pub(crate) type BufferState = Unit<BufferUse>;
impl PendingTransition<BufferState> {
fn collapse(self) -> Result<BufferUsage, Self> {
fn collapse(self) -> Result<BufferUse, Self> {
if self.usage.start.is_empty()
|| self.usage.start == self.usage.end
|| !BufferUsage::WRITE_ALL.intersects(self.usage.start | self.usage.end)
|| !BufferUse::WRITE_ALL.intersects(self.usage.start | self.usage.end)
{
Ok(self.usage.start | self.usage.end)
} else {
@ -27,13 +25,13 @@ impl Default for BufferState {
fn default() -> Self {
BufferState {
first: None,
last: BufferUsage::empty(),
last: BufferUse::empty(),
}
}
}
impl BufferState {
pub fn with_usage(usage: BufferUsage) -> Self {
pub fn with_usage(usage: BufferUse) -> Self {
Unit::new(usage)
}
}
@ -41,7 +39,7 @@ impl BufferState {
impl ResourceState for BufferState {
type Id = BufferId;
type Selector = ();
type Usage = BufferUsage;
type Usage = BufferUse;
fn query(&self, _selector: Self::Selector) -> Option<Self::Usage> {
Some(self.last)
@ -55,7 +53,7 @@ impl ResourceState for BufferState {
output: Option<&mut Vec<PendingTransition<Self>>>,
) -> Result<(), PendingTransition<Self>> {
let old = self.last;
if old != usage || !BufferUsage::ORDERED.contains(usage) {
if old != usage || !BufferUse::ORDERED.contains(usage) {
let pending = PendingTransition {
id,
selector: (),
@ -89,7 +87,7 @@ impl ResourceState for BufferState {
) -> Result<(), PendingTransition<Self>> {
let old = self.last;
let new = other.port();
if old == new && BufferUsage::ORDERED.contains(new) {
if old == new && BufferUse::ORDERED.contains(new) {
if output.is_some() && self.first.is_none() {
self.first = Some(old);
}
@ -131,64 +129,64 @@ mod test {
fn change_extend() {
let mut bs = Unit {
first: None,
last: BufferUsage::INDEX,
last: BufferUse::INDEX,
};
let id = Id::default();
assert_eq!(
bs.change(id, (), BufferUsage::STORAGE, None),
bs.change(id, (), BufferUse::STORAGE_STORE, None),
Err(PendingTransition {
id,
selector: (),
usage: BufferUsage::INDEX..BufferUsage::STORAGE,
usage: BufferUse::INDEX..BufferUse::STORAGE_STORE,
}),
);
bs.change(id, (), BufferUsage::VERTEX, None).unwrap();
bs.change(id, (), BufferUsage::INDEX, None).unwrap();
assert_eq!(bs, Unit::new(BufferUsage::VERTEX | BufferUsage::INDEX));
bs.change(id, (), BufferUse::VERTEX, None).unwrap();
bs.change(id, (), BufferUse::INDEX, None).unwrap();
assert_eq!(bs, Unit::new(BufferUse::VERTEX | BufferUse::INDEX));
}
#[test]
fn change_replace() {
let mut bs = Unit {
first: None,
last: BufferUsage::STORAGE,
last: BufferUse::STORAGE_STORE,
};
let id = Id::default();
let mut list = Vec::new();
bs.change(id, (), BufferUsage::VERTEX, Some(&mut list))
bs.change(id, (), BufferUse::VERTEX, Some(&mut list))
.unwrap();
assert_eq!(
&list,
&[PendingTransition {
id,
selector: (),
usage: BufferUsage::STORAGE..BufferUsage::VERTEX,
usage: BufferUse::STORAGE_STORE..BufferUse::VERTEX,
}],
);
assert_eq!(
bs,
Unit {
first: Some(BufferUsage::STORAGE),
last: BufferUsage::VERTEX,
first: Some(BufferUse::STORAGE_STORE),
last: BufferUse::VERTEX,
}
);
list.clear();
bs.change(id, (), BufferUsage::STORAGE, Some(&mut list))
bs.change(id, (), BufferUse::STORAGE_STORE, Some(&mut list))
.unwrap();
assert_eq!(
&list,
&[PendingTransition {
id,
selector: (),
usage: BufferUsage::VERTEX..BufferUsage::STORAGE,
usage: BufferUse::VERTEX..BufferUse::STORAGE_STORE,
}],
);
assert_eq!(
bs,
Unit {
first: Some(BufferUsage::STORAGE),
last: BufferUsage::STORAGE,
first: Some(BufferUse::STORAGE_STORE),
last: BufferUse::STORAGE_STORE,
}
);
}

View File

@ -17,8 +17,8 @@ use std::{
borrow::Borrow, collections::hash_map::Entry, fmt, marker::PhantomData, ops, vec::Drain,
};
pub use buffer::BufferState;
pub use texture::TextureState;
pub(crate) use buffer::BufferState;
pub(crate) use texture::TextureState;
/// A single unit of state tracking. It keeps an initial
/// usage as well as the last/current one, similar to `Range`.
@ -436,7 +436,7 @@ pub const DUMMY_SELECTOR: () = ();
/// A set of trackers for all relevant resources.
#[derive(Debug)]
pub struct TrackerSet {
pub(crate) struct TrackerSet {
pub buffers: ResourceTracker<BufferState>,
pub textures: ResourceTracker<TextureState>,
pub views: ResourceTracker<PhantomData<id::TextureViewId>>,

View File

@ -3,28 +3,27 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use super::{range::RangedStates, PendingTransition, ResourceState, Unit};
use crate::{device::MAX_MIP_LEVELS, id::TextureId};
use crate::{device::MAX_MIP_LEVELS, id::TextureId, resource::TextureUse};
use arrayvec::ArrayVec;
use wgt::TextureUsage;
use std::{iter, ops::Range};
//TODO: store `hal::image::State` here to avoid extra conversions
type PlaneStates = RangedStates<hal::image::Layer, Unit<TextureUsage>>;
type PlaneStates = RangedStates<hal::image::Layer, Unit<TextureUse>>;
#[derive(Clone, Debug, Default, PartialEq)]
pub struct TextureState {
pub(crate) struct TextureState {
mips: ArrayVec<[PlaneStates; MAX_MIP_LEVELS]>,
/// True if we have the information about all the subresources here
full: bool,
}
impl PendingTransition<TextureState> {
fn collapse(self) -> Result<TextureUsage, Self> {
fn collapse(self) -> Result<TextureUse, Self> {
if self.usage.start.is_empty()
|| self.usage.start == self.usage.end
|| !TextureUsage::WRITE_ALL.intersects(self.usage.start | self.usage.end)
|| !TextureUse::WRITE_ALL.intersects(self.usage.start | self.usage.end)
{
Ok(self.usage.start | self.usage.end)
} else {
@ -39,7 +38,7 @@ impl TextureState {
debug_assert_eq!(range.levels.start, 0);
TextureState {
mips: iter::repeat_with(|| {
PlaneStates::from_range(0..range.layers.end, Unit::new(TextureUsage::UNINITIALIZED))
PlaneStates::from_range(0..range.layers.end, Unit::new(TextureUse::UNINITIALIZED))
})
.take(range.levels.end as usize)
.collect(),
@ -51,7 +50,7 @@ impl TextureState {
impl ResourceState for TextureState {
type Id = TextureId;
type Selector = hal::image::SubresourceRange;
type Usage = TextureUsage;
type Usage = TextureUse;
fn query(&self, selector: Self::Selector) -> Option<Self::Usage> {
let mut result = None;
@ -99,7 +98,7 @@ impl ResourceState for TextureState {
let level = selector.levels.start + mip_id as hal::image::Level;
let layers = mip.isolate(&selector.layers, Unit::new(usage));
for &mut (ref range, ref mut unit) in layers {
if unit.last == usage && TextureUsage::ORDERED.contains(usage) {
if unit.last == usage && TextureUse::ORDERED.contains(usage) {
continue;
}
// TODO: Can't satisfy clippy here unless we modify
@ -176,7 +175,7 @@ impl ResourceState for TextureState {
end: Some(end),
} => {
let to_usage = end.port();
if start.last == to_usage && TextureUsage::ORDERED.contains(to_usage) {
if start.last == to_usage && TextureUse::ORDERED.contains(to_usage) {
Unit {
first: match output {
None => start.first,
@ -245,9 +244,9 @@ mod test {
let mut ts = TextureState::default();
ts.mips.push(PlaneStates::empty());
ts.mips.push(PlaneStates::from_slice(&[
(1..3, Unit::new(TextureUsage::SAMPLED)),
(3..5, Unit::new(TextureUsage::SAMPLED)),
(5..6, Unit::new(TextureUsage::STORAGE)),
(1..3, Unit::new(TextureUse::SAMPLED)),
(3..5, Unit::new(TextureUse::SAMPLED)),
(5..6, Unit::new(TextureUse::STORAGE_LOAD)),
]));
assert_eq!(
@ -257,7 +256,7 @@ mod test {
layers: 2..5,
}),
// level 1 matches
Some(TextureUsage::SAMPLED),
Some(TextureUse::SAMPLED),
);
assert_eq!(
ts.query(SubresourceRange {
@ -266,7 +265,7 @@ mod test {
layers: 2..5,
}),
// level 0 is empty, level 1 matches
Some(TextureUsage::SAMPLED),
Some(TextureUse::SAMPLED),
);
assert_eq!(
ts.query(SubresourceRange {
@ -275,7 +274,7 @@ mod test {
layers: 1..5,
}),
// level 1 matches with gaps
Some(TextureUsage::SAMPLED),
Some(TextureUse::SAMPLED),
);
assert_eq!(
ts.query(SubresourceRange {
@ -294,7 +293,7 @@ mod test {
let mut ts1 = TextureState::default();
ts1.mips.push(PlaneStates::from_slice(&[(
1..3,
Unit::new(TextureUsage::SAMPLED),
Unit::new(TextureUse::SAMPLED),
)]));
let mut ts2 = TextureState::default();
assert_eq!(
@ -305,7 +304,7 @@ mod test {
ts2.mips.push(PlaneStates::from_slice(&[(
1..2,
Unit::new(TextureUsage::COPY_SRC),
Unit::new(TextureUse::COPY_SRC),
)]));
assert_eq!(
ts1.merge(Id::default(), &ts2, None),
@ -316,12 +315,12 @@ mod test {
ts1.mips[0].query(&(1..2), |&v| v),
Some(Ok(Unit {
first: None,
last: TextureUsage::SAMPLED | TextureUsage::COPY_SRC,
last: TextureUse::SAMPLED | TextureUse::COPY_SRC,
})),
"wrong extension result"
);
ts2.mips[0] = PlaneStates::from_slice(&[(1..2, Unit::new(TextureUsage::COPY_DST))]);
ts2.mips[0] = PlaneStates::from_slice(&[(1..2, Unit::new(TextureUse::COPY_DST))]);
assert_eq!(
ts1.clone().merge(Id::default(), &ts2, None),
Err(PendingTransition {
@ -331,19 +330,19 @@ mod test {
levels: 0..1,
layers: 1..2,
},
usage: TextureUsage::SAMPLED | TextureUsage::COPY_SRC..TextureUsage::COPY_DST,
usage: TextureUse::SAMPLED | TextureUse::COPY_SRC..TextureUse::COPY_DST,
}),
"wrong error on extending with incompatible state"
);
let mut list = Vec::new();
ts2.mips[0] = PlaneStates::from_slice(&[
(1..2, Unit::new(TextureUsage::COPY_DST)),
(1..2, Unit::new(TextureUse::COPY_DST)),
(
2..3,
Unit {
first: Some(TextureUsage::COPY_SRC),
last: TextureUsage::OUTPUT_ATTACHMENT,
first: Some(TextureUse::COPY_SRC),
last: TextureUse::OUTPUT_ATTACHMENT,
},
),
]);
@ -358,7 +357,7 @@ mod test {
levels: 0..1,
layers: 1..2,
},
usage: TextureUsage::SAMPLED | TextureUsage::COPY_SRC..TextureUsage::COPY_DST,
usage: TextureUse::SAMPLED | TextureUse::COPY_SRC..TextureUse::COPY_DST,
},
PendingTransition {
id,
@ -369,7 +368,7 @@ mod test {
},
// the transition links the end of the base rage (..SAMPLED)
// with the start of the next range (COPY_SRC..)
usage: TextureUsage::SAMPLED..TextureUsage::COPY_SRC,
usage: TextureUse::SAMPLED..TextureUse::COPY_SRC,
},
],
"replacing produced wrong transitions"
@ -377,16 +376,16 @@ mod test {
assert_eq!(
ts1.mips[0].query(&(1..2), |&v| v),
Some(Ok(Unit {
first: Some(TextureUsage::SAMPLED | TextureUsage::COPY_SRC),
last: TextureUsage::COPY_DST,
first: Some(TextureUse::SAMPLED | TextureUse::COPY_SRC),
last: TextureUse::COPY_DST,
})),
"wrong final layer 1 state"
);
assert_eq!(
ts1.mips[0].query(&(2..3), |&v| v),
Some(Ok(Unit {
first: Some(TextureUsage::SAMPLED),
last: TextureUsage::OUTPUT_ATTACHMENT,
first: Some(TextureUse::SAMPLED),
last: TextureUse::OUTPUT_ATTACHMENT,
})),
"wrong final layer 2 state"
);
@ -395,8 +394,8 @@ mod test {
ts2.mips[0] = PlaneStates::from_slice(&[(
2..3,
Unit {
first: Some(TextureUsage::OUTPUT_ATTACHMENT),
last: TextureUsage::COPY_SRC,
first: Some(TextureUse::OUTPUT_ATTACHMENT),
last: TextureUse::COPY_SRC,
},
)]);
ts1.merge(Id::default(), &ts2, Some(&mut list)).unwrap();
@ -406,8 +405,8 @@ mod test {
ts2.mips[0] = PlaneStates::from_slice(&[(
2..3,
Unit {
first: Some(TextureUsage::COPY_DST),
last: TextureUsage::COPY_DST,
first: Some(TextureUse::COPY_DST),
last: TextureUse::COPY_DST,
},
)]);
ts1.merge(Id::default(), &ts2, Some(&mut list)).unwrap();
@ -420,7 +419,7 @@ mod test {
levels: 0..1,
layers: 2..3,
},
usage: TextureUsage::COPY_SRC..TextureUsage::COPY_DST,
usage: TextureUse::COPY_SRC..TextureUse::COPY_DST,
},],
"invalid replacing transition"
);
@ -428,8 +427,8 @@ mod test {
ts1.mips[0].query(&(2..3), |&v| v),
Some(Ok(Unit {
// the initial state here is never expected to change
first: Some(TextureUsage::SAMPLED),
last: TextureUsage::COPY_DST,
first: Some(TextureUse::SAMPLED),
last: TextureUse::COPY_DST,
})),
"wrong final layer 2 state"
);

View File

@ -523,18 +523,6 @@ bitflags::bitflags! {
const UNIFORM = 64;
const STORAGE = 128;
const INDIRECT = 256;
const STORAGE_READ = 512;
const NONE = 0;
/// The combination of all read-only usages.
const READ_ALL = Self::MAP_READ.bits | Self::COPY_SRC.bits |
Self::INDEX.bits | Self::VERTEX.bits | Self::UNIFORM.bits |
Self::STORAGE_READ.bits | Self::INDIRECT.bits;
/// The combination of all write-only and read-write usages.
const WRITE_ALL = Self::MAP_WRITE.bits | Self::COPY_DST.bits | Self::STORAGE.bits;
/// The combination of all usages that the are guaranteed to be be ordered by the hardware.
/// If a usage is not ordered, then even if it doesn't change between draw calls, there
/// still need to be pipeline barriers inserted for synchronization.
const ORDERED = Self::READ_ALL.bits;
}
}
@ -592,16 +580,6 @@ bitflags::bitflags! {
const SAMPLED = 4;
const STORAGE = 8;
const OUTPUT_ATTACHMENT = 16;
const NONE = 0;
/// The combination of all read-only usages.
const READ_ALL = Self::COPY_SRC.bits | Self::SAMPLED.bits;
/// The combination of all write-only and read-write usages.
const WRITE_ALL = Self::COPY_DST.bits | Self::STORAGE.bits | Self::OUTPUT_ATTACHMENT.bits;
/// The combination of all usages that the are guaranteed to be be ordered by the hardware.
/// If a usage is not ordered, then even if it doesn't change between draw calls, there
/// still need to be pipeline barriers inserted for synchronization.
const ORDERED = Self::READ_ALL.bits | Self::OUTPUT_ATTACHMENT.bits;
const UNINITIALIZED = 0xFFFF;
}
}

View File

@ -123,7 +123,6 @@ pub extern "C" fn wgpu_server_buffer_map_read(
gfx_select!(buffer_id => global.buffer_map_async(
buffer_id,
wgt::BufferUsage::MAP_READ,
start .. start + size,
operation
));