mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
move the BGL compatibility check in the binder
This commit is contained in:
@@ -5,10 +5,11 @@ use crate::{
|
||||
device::SHADER_STAGE_COUNT,
|
||||
hal_api::HalApi,
|
||||
pipeline::LateSizedBufferGroup,
|
||||
resource::Labeled,
|
||||
resource::{Labeled, ResourceErrorIdent},
|
||||
};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use thiserror::Error;
|
||||
|
||||
type BindGroupMask = u8;
|
||||
|
||||
@@ -214,6 +215,14 @@ mod compat {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error("Bind group at index {index} is incompatible with the current set {pipeline}")]
|
||||
pub struct IncompatibleBindGroupError {
|
||||
index: u32,
|
||||
pipeline: ResourceErrorIdent,
|
||||
diff: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct LateBufferBinding {
|
||||
shader_expect_size: wgt::BufferAddress,
|
||||
@@ -358,12 +367,20 @@ impl<A: HalApi> Binder<A> {
|
||||
.map(move |index| payloads[index].group.as_ref().unwrap())
|
||||
}
|
||||
|
||||
pub(super) fn invalid_mask(&self) -> BindGroupMask {
|
||||
self.manager.invalid_mask()
|
||||
}
|
||||
|
||||
pub(super) fn bgl_diff(&self) -> Vec<String> {
|
||||
self.manager.bgl_diff()
|
||||
pub(super) fn check_compatibility<T: Labeled>(
|
||||
&self,
|
||||
pipeline: &T,
|
||||
) -> Result<(), IncompatibleBindGroupError> {
|
||||
let bind_mask = self.manager.invalid_mask();
|
||||
if bind_mask == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(IncompatibleBindGroupError {
|
||||
index: bind_mask.trailing_zeros(),
|
||||
pipeline: pipeline.error_ident(),
|
||||
diff: self.manager.bgl_diff(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Scan active buffer bindings corresponding to layouts without `min_binding_size` specified.
|
||||
|
||||
@@ -20,7 +20,7 @@ use crate::{
|
||||
pipeline::ComputePipeline,
|
||||
resource::{
|
||||
self, Buffer, DestroyedResourceError, Labeled, MissingBufferUsageError, ParentDevice,
|
||||
ResourceErrorIdent, Trackable,
|
||||
Trackable,
|
||||
},
|
||||
snatch::SnatchGuard,
|
||||
track::{ResourceUsageCompatibilityError, Tracker, TrackerIndex, UsageScope},
|
||||
@@ -35,7 +35,10 @@ use wgt::{BufferAddress, DynamicOffset};
|
||||
use std::sync::Arc;
|
||||
use std::{fmt, mem, str};
|
||||
|
||||
use super::{memory_init::CommandBufferTextureMemoryActions, DynComputePass};
|
||||
use super::{
|
||||
bind::IncompatibleBindGroupError, memory_init::CommandBufferTextureMemoryActions,
|
||||
DynComputePass,
|
||||
};
|
||||
|
||||
pub struct ComputePass<A: HalApi> {
|
||||
/// All pass data & records is stored here.
|
||||
@@ -117,12 +120,8 @@ struct ArcComputePassDescriptor<'a, A: HalApi> {
|
||||
pub enum DispatchError {
|
||||
#[error("Compute pipeline must be set")]
|
||||
MissingPipeline,
|
||||
#[error("Bind group at index {index} is incompatible with the current set {pipeline}")]
|
||||
IncompatibleBindGroup {
|
||||
index: u32,
|
||||
pipeline: ResourceErrorIdent,
|
||||
diff: Vec<String>,
|
||||
},
|
||||
#[error(transparent)]
|
||||
IncompatibleBindGroup(#[from] IncompatibleBindGroupError),
|
||||
#[error(
|
||||
"Each current dispatch group size dimension ({current:?}) must be less or equal to {limit}"
|
||||
)]
|
||||
@@ -186,16 +185,7 @@ pub enum ComputePassErrorInner {
|
||||
PassEnded,
|
||||
}
|
||||
|
||||
impl PrettyError for ComputePassErrorInner {
|
||||
fn fmt_pretty(&self, fmt: &mut ErrorFormatter) {
|
||||
fmt.error(self);
|
||||
if let Self::Dispatch(DispatchError::IncompatibleBindGroup { ref diff, .. }) = *self {
|
||||
for d in diff {
|
||||
fmt.note(&d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl PrettyError for ComputePassErrorInner {}
|
||||
|
||||
/// Error encountered when performing a compute pass.
|
||||
#[derive(Clone, Debug, Error)]
|
||||
@@ -259,14 +249,7 @@ impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi>
|
||||
{
|
||||
fn is_ready(&self) -> Result<(), DispatchError> {
|
||||
if let Some(pipeline) = self.pipeline.as_ref() {
|
||||
let bind_mask = self.binder.invalid_mask();
|
||||
if bind_mask != 0 {
|
||||
return Err(DispatchError::IncompatibleBindGroup {
|
||||
index: bind_mask.trailing_zeros(),
|
||||
pipeline: pipeline.error_ident(),
|
||||
diff: self.binder.bgl_diff(),
|
||||
});
|
||||
}
|
||||
self.binder.check_compatibility(pipeline.as_ref())?;
|
||||
self.binder.check_late_buffer_bindings()?;
|
||||
Ok(())
|
||||
} else {
|
||||
|
||||
@@ -11,6 +11,8 @@ use wgt::VertexStepMode;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use super::bind::IncompatibleBindGroupError;
|
||||
|
||||
/// Error validating a draw call.
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
@@ -26,12 +28,8 @@ pub enum DrawError {
|
||||
},
|
||||
#[error("Index buffer must be set")]
|
||||
MissingIndexBuffer,
|
||||
#[error("Bind group at index {index} is incompatible with the current set {pipeline}")]
|
||||
IncompatibleBindGroup {
|
||||
index: u32,
|
||||
pipeline: ResourceErrorIdent,
|
||||
diff: Vec<String>,
|
||||
},
|
||||
#[error(transparent)]
|
||||
IncompatibleBindGroup(#[from] IncompatibleBindGroupError),
|
||||
#[error("Vertex {last_vertex} extends beyond limit {vertex_limit} imposed by the buffer in slot {slot}. Did you bind the correct `Vertex` step-rate vertex buffer?")]
|
||||
VertexBeyondLimit {
|
||||
last_vertex: u64,
|
||||
|
||||
@@ -481,14 +481,7 @@ impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi>
|
||||
{
|
||||
fn is_ready(&self, indexed: bool) -> Result<(), DrawError> {
|
||||
if let Some(pipeline) = self.pipeline.as_ref() {
|
||||
let bind_mask = self.binder.invalid_mask();
|
||||
if bind_mask != 0 {
|
||||
return Err(DrawError::IncompatibleBindGroup {
|
||||
index: bind_mask.trailing_zeros(),
|
||||
pipeline: pipeline.error_ident(),
|
||||
diff: self.binder.bgl_diff(),
|
||||
});
|
||||
}
|
||||
self.binder.check_compatibility(pipeline.as_ref())?;
|
||||
self.binder.check_late_buffer_bindings()?;
|
||||
|
||||
if self.blend_constant == OptionalState::Required {
|
||||
@@ -717,16 +710,7 @@ pub enum RenderPassErrorInner {
|
||||
PassEnded,
|
||||
}
|
||||
|
||||
impl PrettyError for RenderPassErrorInner {
|
||||
fn fmt_pretty(&self, fmt: &mut ErrorFormatter) {
|
||||
fmt.error(self);
|
||||
if let Self::Draw(DrawError::IncompatibleBindGroup { diff, .. }) = self {
|
||||
for d in diff {
|
||||
fmt.note(&d);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
impl PrettyError for RenderPassErrorInner {}
|
||||
|
||||
impl From<MissingBufferUsageError> for RenderPassErrorInner {
|
||||
fn from(error: MissingBufferUsageError) -> Self {
|
||||
|
||||
Reference in New Issue
Block a user