move the BGL compatibility check in the binder

This commit is contained in:
teoxoy
2024-06-27 19:12:12 +02:00
committed by Teodor Tanasoaia
parent ca0027d12b
commit 9ec0f45efd
4 changed files with 39 additions and 57 deletions

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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 {