mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +00:00
Merge #1234
1234: Release 0.7.1 r=kvark a=kvark **Connections** Includes #1183, #1198, #1214, #1201, plus the code to expose the queue module. **Description** Picking a few things from master to publish as a patch **Testing** Tested on wgpu-rs examples Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com> Co-authored-by: Daniel Tang <danielzgtg.opensource@gmail.com> Co-authored-by: Jakob Hellermann <jakob.hellermann@protonmail.com>
This commit is contained in:
commit
ad2e1b6ff8
@ -1,5 +1,10 @@
|
||||
# Change Log
|
||||
|
||||
## v0.7.1 (2021-02-25)
|
||||
- expose `wgc::device::queue` sub-module in public
|
||||
- fix the indexed buffer check
|
||||
- fix command allocator race condition
|
||||
|
||||
## v0.7 (2021-01-31)
|
||||
- Major API changes:
|
||||
- `RenderPipelineDescriptor`
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1799,7 +1799,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wgpu-core"
|
||||
version = "0.7.0"
|
||||
version = "0.7.1"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wgpu-core"
|
||||
version = "0.7.0"
|
||||
version = "0.7.1"
|
||||
authors = ["wgpu developers"]
|
||||
edition = "2018"
|
||||
description = "WebGPU core logic on gfx-hal"
|
||||
|
@ -440,7 +440,7 @@ pub struct PipelineLayoutDescriptor<'a> {
|
||||
/// must define the range in push constant memory that corresponds to its single `layout(push_constant)`
|
||||
/// uniform block.
|
||||
///
|
||||
/// If this array is non-empty, the [`Features::PUSH_CONSTANTS`] must be enabled.
|
||||
/// If this array is non-empty, the [`Features::PUSH_CONSTANTS`](wgt::Features::PUSH_CONSTANTS) must be enabled.
|
||||
pub push_constant_ranges: Cow<'a, [wgt::PushConstantRange]>,
|
||||
}
|
||||
|
||||
|
@ -98,26 +98,32 @@ impl<B: GfxBackend> CommandAllocator<B> {
|
||||
let mut inner = self.inner.lock();
|
||||
|
||||
use std::collections::hash_map::Entry;
|
||||
if let Entry::Vacant(e) = inner.pools.entry(thread_id) {
|
||||
tracing::info!("Starting on thread {:?}", thread_id);
|
||||
let raw = unsafe {
|
||||
device
|
||||
.create_command_pool(
|
||||
self.queue_family,
|
||||
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
|
||||
)
|
||||
.or(Err(DeviceError::OutOfMemory))?
|
||||
};
|
||||
e.insert(CommandPool {
|
||||
raw,
|
||||
total: 0,
|
||||
available: Vec::new(),
|
||||
pending: Vec::new(),
|
||||
});
|
||||
}
|
||||
let pool = match inner.pools.entry(thread_id) {
|
||||
Entry::Vacant(e) => {
|
||||
tracing::info!("Starting on thread {:?}", thread_id);
|
||||
let raw = unsafe {
|
||||
device
|
||||
.create_command_pool(
|
||||
self.queue_family,
|
||||
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
|
||||
)
|
||||
.or(Err(DeviceError::OutOfMemory))?
|
||||
};
|
||||
e.insert(CommandPool {
|
||||
raw,
|
||||
total: 0,
|
||||
available: Vec::new(),
|
||||
pending: Vec::new(),
|
||||
})
|
||||
}
|
||||
Entry::Occupied(e) => e.into_mut(),
|
||||
};
|
||||
|
||||
//Note: we have to allocate the first buffer right here, or otherwise
|
||||
// the pool may be cleaned up by maintenance called from another thread.
|
||||
|
||||
Ok(CommandBuffer {
|
||||
raw: Vec::new(),
|
||||
raw: vec![pool.allocate()],
|
||||
is_recording: true,
|
||||
recorded_thread_id: thread_id,
|
||||
device_id,
|
||||
|
@ -336,7 +336,7 @@ struct State {
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn is_ready(&self) -> Result<(), DrawError> {
|
||||
fn is_ready(&self, indexed: bool) -> Result<(), DrawError> {
|
||||
// Determine how many vertex buffers have already been bound
|
||||
let bound_buffers = self.vertex.inputs.iter().take_while(|v| v.bound).count() as u32;
|
||||
// Compare with the needed quantity
|
||||
@ -359,17 +359,19 @@ impl State {
|
||||
if self.blend_color == OptionalState::Required {
|
||||
return Err(DrawError::MissingBlendColor);
|
||||
}
|
||||
// Pipeline expects an index buffer
|
||||
if let Some(pipeline_index_format) = self.index.pipeline_format {
|
||||
// We have a buffer bound
|
||||
let buffer_index_format = self.index.format.ok_or(DrawError::MissingIndexBuffer)?;
|
||||
if indexed {
|
||||
// Pipeline expects an index buffer
|
||||
if let Some(pipeline_index_format) = self.index.pipeline_format {
|
||||
// We have a buffer bound
|
||||
let buffer_index_format = self.index.format.ok_or(DrawError::MissingIndexBuffer)?;
|
||||
|
||||
// The buffers are different formats
|
||||
if pipeline_index_format != buffer_index_format {
|
||||
return Err(DrawError::UnmatchedIndexFormats {
|
||||
pipeline: pipeline_index_format,
|
||||
buffer: buffer_index_format,
|
||||
});
|
||||
// The buffers are different formats
|
||||
if pipeline_index_format != buffer_index_format {
|
||||
return Err(DrawError::UnmatchedIndexFormats {
|
||||
pipeline: pipeline_index_format,
|
||||
buffer: buffer_index_format,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -1458,12 +1460,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
first_vertex,
|
||||
first_instance,
|
||||
} => {
|
||||
let indexed = false;
|
||||
let scope = PassErrorScope::Draw {
|
||||
indexed: false,
|
||||
indexed,
|
||||
indirect: false,
|
||||
pipeline: state.pipeline.last_state,
|
||||
};
|
||||
state.is_ready().map_pass_err(scope)?;
|
||||
state.is_ready(indexed).map_pass_err(scope)?;
|
||||
|
||||
let last_vertex = first_vertex + vertex_count;
|
||||
let vertex_limit = state.vertex.vertex_limit;
|
||||
if last_vertex > vertex_limit {
|
||||
@ -1499,12 +1503,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
base_vertex,
|
||||
first_instance,
|
||||
} => {
|
||||
let indexed = true;
|
||||
let scope = PassErrorScope::Draw {
|
||||
indexed: true,
|
||||
indexed,
|
||||
indirect: false,
|
||||
pipeline: state.pipeline.last_state,
|
||||
};
|
||||
state.is_ready().map_pass_err(scope)?;
|
||||
state.is_ready(indexed).map_pass_err(scope)?;
|
||||
|
||||
//TODO: validate that base_vertex + max_index() is within the provided range
|
||||
let last_index = first_index + index_count;
|
||||
@ -1546,7 +1551,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
indirect: true,
|
||||
pipeline: state.pipeline.last_state,
|
||||
};
|
||||
state.is_ready().map_pass_err(scope)?;
|
||||
state.is_ready(indexed).map_pass_err(scope)?;
|
||||
|
||||
let stride = match indexed {
|
||||
false => mem::size_of::<wgt::DrawIndirectArgs>(),
|
||||
@ -1620,7 +1625,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
indirect: true,
|
||||
pipeline: state.pipeline.last_state,
|
||||
};
|
||||
state.is_ready().map_pass_err(scope)?;
|
||||
state.is_ready(indexed).map_pass_err(scope)?;
|
||||
|
||||
let stride = match indexed {
|
||||
false => mem::size_of::<wgt::DrawIndirectArgs>(),
|
||||
|
@ -220,7 +220,7 @@ pub(crate) fn validate_linear_texture_data(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Function copied with minor modifications from webgpu standard https://gpuweb.github.io/gpuweb/#valid-texture-copy-range
|
||||
/// Function copied with minor modifications from webgpu standard <https://gpuweb.github.io/gpuweb/#valid-texture-copy-range>
|
||||
pub(crate) fn validate_texture_copy_range(
|
||||
texture_copy_view: &TextureCopyView,
|
||||
texture_format: wgt::TextureFormat,
|
||||
|
@ -249,7 +249,7 @@ impl<B: hal::Backend> LifetimeTracker<B> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn track_submission(
|
||||
pub(super) fn track_submission(
|
||||
&mut self,
|
||||
index: SubmissionIndex,
|
||||
fence: B::Fence,
|
||||
@ -356,7 +356,7 @@ impl<B: hal::Backend> LifetimeTracker<B> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn schedule_resource_destruction(
|
||||
pub(super) fn schedule_resource_destruction(
|
||||
&mut self,
|
||||
temp_resource: TempResource<B>,
|
||||
memory: alloc::MemoryBlock<B>,
|
||||
|
@ -42,7 +42,7 @@ use std::{
|
||||
pub mod alloc;
|
||||
pub mod descriptor;
|
||||
mod life;
|
||||
mod queue;
|
||||
pub mod queue;
|
||||
#[cfg(any(feature = "trace", feature = "replay"))]
|
||||
pub mod trace;
|
||||
|
||||
@ -3549,14 +3549,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
Err(e) => break e,
|
||||
};
|
||||
|
||||
let mut raw = device.cmd_allocator.extend(&command_buffer);
|
||||
let mut raw = command_buffer.raw.first_mut().unwrap();
|
||||
unsafe {
|
||||
if let Some(ref label) = desc.label {
|
||||
device.raw.set_command_buffer_name(&mut raw, label);
|
||||
}
|
||||
raw.begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT);
|
||||
}
|
||||
command_buffer.raw.push(raw);
|
||||
|
||||
let id = hub
|
||||
.command_buffers
|
||||
|
@ -29,13 +29,13 @@ struct StagingData<B: hal::Backend> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TempResource<B: hal::Backend> {
|
||||
pub(super) enum TempResource<B: hal::Backend> {
|
||||
Buffer(B::Buffer),
|
||||
Image(B::Image),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PendingWrites<B: hal::Backend> {
|
||||
pub(super) struct PendingWrites<B: hal::Backend> {
|
||||
pub command_buffer: Option<B::CommandBuffer>,
|
||||
pub temp_resources: Vec<(TempResource<B>, alloc::MemoryBlock<B>)>,
|
||||
pub dst_buffers: FastHashSet<id::BufferId>,
|
||||
|
@ -273,7 +273,7 @@ pub struct TextureViewDescriptor<'a> {
|
||||
/// The dimension of the texture view. For 1D textures, this must be `1D`. For 2D textures it must be one of
|
||||
/// `D2`, `D2Array`, `Cube`, and `CubeArray`. For 3D textures it must be `3D`
|
||||
pub dimension: Option<wgt::TextureViewDimension>,
|
||||
/// Aspect of the texture. Color textures must be [`TextureAspect::All`].
|
||||
/// Aspect of the texture. Color textures must be [`TextureAspect::All`](wgt::TextureAspect::All).
|
||||
pub aspect: wgt::TextureAspect,
|
||||
/// Base mip level.
|
||||
pub base_mip_level: u32,
|
||||
@ -393,7 +393,7 @@ pub struct SamplerDescriptor<'a> {
|
||||
pub compare: Option<wgt::CompareFunction>,
|
||||
/// Valid values: 1, 2, 4, 8, and 16.
|
||||
pub anisotropy_clamp: Option<NonZeroU8>,
|
||||
/// Border color to use when address_mode is [`AddressMode::ClampToBorder`]
|
||||
/// Border color to use when address_mode is [`AddressMode::ClampToBorder`](wgt::AddressMode::ClampToBorder)
|
||||
pub border_color: Option<wgt::SamplerBorderColor>,
|
||||
}
|
||||
|
||||
|
@ -436,7 +436,7 @@ bitflags::bitflags! {
|
||||
/// implementation needs to support more than is needed. You should ideally only request exactly what
|
||||
/// you need.
|
||||
///
|
||||
/// See also: https://gpuweb.github.io/gpuweb/#dictdef-gpulimits
|
||||
/// See also: <https://gpuweb.github.io/gpuweb/#dictdef-gpulimits>
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
@ -847,9 +847,9 @@ impl Default for CullMode {
|
||||
pub enum PolygonMode {
|
||||
/// Polygons are filled
|
||||
Fill = 0,
|
||||
/// Polygons are draw as line segments
|
||||
/// Polygons are drawn as line segments
|
||||
Line = 1,
|
||||
/// Polygons are draw as points
|
||||
/// Polygons are drawn as points
|
||||
Point = 2,
|
||||
}
|
||||
|
||||
@ -867,13 +867,14 @@ impl Default for PolygonMode {
|
||||
pub struct PrimitiveState {
|
||||
/// The primitive topology used to interpret vertices.
|
||||
pub topology: PrimitiveTopology,
|
||||
/// The format of index buffers for strip topologies. Should be left `None` for non-strip.
|
||||
/// When drawing strip topologies with indices, this is the required format for the index buffer.
|
||||
/// This has no effect on non-indexed or non-strip draws.
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
pub strip_index_format: Option<IndexFormat>,
|
||||
/// The face to consider the front for the purpose of culling and stencil operations.
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
pub front_face: FrontFace,
|
||||
/// The fact culling mode.
|
||||
/// The face culling mode.
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
pub cull_mode: CullMode,
|
||||
/// Controls the way each polygon is rasterized. Can be either `Fill` (default), `Line` or `Point`
|
||||
@ -1368,7 +1369,7 @@ impl TextureFormat {
|
||||
let storage = basic | TextureUsage::STORAGE;
|
||||
let all_flags = TextureUsage::all();
|
||||
|
||||
// See https://gpuweb.github.io/gpuweb/#texture-format-caps for reference
|
||||
// See <https://gpuweb.github.io/gpuweb/#texture-format-caps> for reference
|
||||
let (required_features, sample_type, srgb, block_dimensions, block_size, allowed_usages) =
|
||||
match self {
|
||||
// Normal 8 bit textures
|
||||
@ -2462,7 +2463,7 @@ pub struct TextureDataLayout {
|
||||
|
||||
/// Specific type of a buffer binding.
|
||||
///
|
||||
/// WebGPU spec: https://gpuweb.github.io/gpuweb/#enumdef-gpubufferbindingtype
|
||||
/// WebGPU spec: <https://gpuweb.github.io/gpuweb/#enumdef-gpubufferbindingtype>
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@ -2508,7 +2509,7 @@ impl Default for BufferBindingType {
|
||||
|
||||
/// Specific type of a sample in a texture binding.
|
||||
///
|
||||
/// WebGPU spec: https://gpuweb.github.io/gpuweb/#enumdef-gputexturesampletype
|
||||
/// WebGPU spec: <https://gpuweb.github.io/gpuweb/#enumdef-gputexturesampletype>
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@ -2559,7 +2560,7 @@ impl Default for TextureSampleType {
|
||||
|
||||
/// Specific type of a sample in a texture binding.
|
||||
///
|
||||
/// WebGPU spec: https://gpuweb.github.io/gpuweb/#enumdef-gpustoragetextureaccess
|
||||
/// WebGPU spec: <https://gpuweb.github.io/gpuweb/#enumdef-gpustoragetextureaccess>
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@ -2579,7 +2580,7 @@ pub enum StorageTextureAccess {
|
||||
/// ```
|
||||
WriteOnly,
|
||||
/// The texture can be both read and written in the shader.
|
||||
/// [`Features::STORAGE_TEXTURE_ACCESS_READ_WRITE`] must be enabled to use this access mode.
|
||||
/// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] must be enabled to use this access mode.
|
||||
///
|
||||
/// Example GLSL syntax:
|
||||
/// ```cpp,ignore
|
||||
@ -2591,10 +2592,10 @@ pub enum StorageTextureAccess {
|
||||
/// Specific type of a binding.
|
||||
///
|
||||
/// WebGPU spec: the enum of
|
||||
/// - https://gpuweb.github.io/gpuweb/#dictdef-gpubufferbindinglayout
|
||||
/// - https://gpuweb.github.io/gpuweb/#dictdef-gpusamplerbindinglayout
|
||||
/// - https://gpuweb.github.io/gpuweb/#dictdef-gputexturebindinglayout
|
||||
/// - https://gpuweb.github.io/gpuweb/#dictdef-gpustoragetexturebindinglayout
|
||||
/// - <https://gpuweb.github.io/gpuweb/#dictdef-gpubufferbindinglayout>
|
||||
/// - <https://gpuweb.github.io/gpuweb/#dictdef-gpusamplerbindinglayout>
|
||||
/// - <https://gpuweb.github.io/gpuweb/#dictdef-gputexturebindinglayout>
|
||||
/// - <https://gpuweb.github.io/gpuweb/#dictdef-gpustoragetexturebindinglayout>
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@ -2628,7 +2629,7 @@ pub enum BindingType {
|
||||
/// A filtering sampler can only be used with a filterable texture.
|
||||
filtering: bool,
|
||||
/// Use as a comparison sampler instead of a normal sampler.
|
||||
/// For more info take a look at the analogous functionality in OpenGL: https://www.khronos.org/opengl/wiki/Sampler_Object#Comparison_mode.
|
||||
/// For more info take a look at the analogous functionality in OpenGL: <https://www.khronos.org/opengl/wiki/Sampler_Object#Comparison_mode>.
|
||||
comparison: bool,
|
||||
},
|
||||
/// A texture binding.
|
||||
@ -2655,7 +2656,7 @@ pub enum BindingType {
|
||||
/// layout(set=0, binding=0, r32f) uniform image2D myStorageImage;
|
||||
/// ```
|
||||
/// Note that the texture format must be specified in the shader as well.
|
||||
/// A list of valid formats can be found in the specification here: https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.html#layout-qualifiers
|
||||
/// A list of valid formats can be found in the specification here: <https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.html#layout-qualifiers>
|
||||
StorageTexture {
|
||||
/// Allowed access to this texture.
|
||||
access: StorageTextureAccess,
|
||||
|
Loading…
Reference in New Issue
Block a user