mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
Separate public usage from internal use (#601)
This commit is contained in:
parent
21b441d087
commit
5e458b5d45
@ -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));
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -559,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,
|
||||
@ -571,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,
|
||||
);
|
||||
};
|
||||
}
|
||||
@ -944,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 {
|
||||
@ -982,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);
|
||||
|
||||
@ -1015,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());
|
||||
@ -1139,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);
|
||||
|
||||
@ -1152,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);
|
||||
|
||||
|
@ -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)));
|
||||
|
@ -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 {
|
||||
@ -438,11 +436,11 @@ fn checked_u32_as_u16(value: u32) -> u16 {
|
||||
|
||||
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;
|
||||
@ -481,9 +479,9 @@ 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) {
|
||||
@ -507,22 +505,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 {
|
||||
@ -545,9 +543,6 @@ pub fn map_texture_state(
|
||||
if usage.contains(W::SAMPLED) {
|
||||
access |= A::SHADER_READ;
|
||||
}
|
||||
if usage.contains(W::STORAGE) {
|
||||
access |= A::SHADER_READ | A::SHADER_WRITE;
|
||||
}
|
||||
if usage.contains(W::OUTPUT_ATTACHMENT) {
|
||||
//TODO: read-only attachments
|
||||
access |= if is_color {
|
||||
@ -556,6 +551,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)
|
||||
}
|
||||
@ -573,7 +574,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,
|
||||
@ -581,7 +582,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,
|
||||
@ -589,7 +590,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,
|
||||
@ -616,20 +617,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
|
||||
@ -648,9 +649,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,
|
||||
}
|
||||
}
|
||||
|
@ -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,16 +1084,22 @@ 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
|
||||
@ -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 {
|
||||
@ -1148,15 +1154,22 @@ 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)
|
||||
}
|
||||
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,
|
||||
),
|
||||
found => panic!("Mismatched texture binding type in {:?}. Expected a type of SampledTexture, ReadonlyStorageTexture or WriteonlyStorageTexture but found {:?}", decl, found),
|
||||
};
|
||||
let view = used
|
||||
@ -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)
|
||||
}
|
||||
@ -2099,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(_) => {
|
||||
@ -2147,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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -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>>,
|
||||
|
@ -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"
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user