From 34b68121c610f554fc5d73dc008e27db8fb5faf0 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 22 Jul 2021 17:45:41 -0400 Subject: [PATCH] Check bundle RODS against pass RODS --- wgpu-core/src/command/bundle.rs | 12 +++++++----- wgpu-core/src/command/draw.rs | 8 ++++---- wgpu-core/src/command/render.rs | 20 +++++++++++++++----- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 7f2fd259b6..1be82838d6 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -243,13 +243,13 @@ impl RenderBundleEncoder { self.context .check_compatible(&pipeline.pass_context) - .map_err(RenderCommandError::IncompatiblePipeline) + .map_err(RenderCommandError::IncompatiblePipelineTargets) .map_pass_err(scope)?; if pipeline.flags.contains(PipelineFlags::WRITES_DEPTH_STENCIL) && self.is_ds_read_only { - return Err(RenderCommandError::IncompatibleReadOnlyDepthStencil) + return Err(RenderCommandError::IncompatiblePipelineRods) .map_pass_err(scope); } @@ -517,6 +517,7 @@ impl RenderBundleEncoder { string_data: Vec::new(), push_constant_data: Vec::new(), }, + is_ds_read_only: self.is_ds_read_only, device_id: Stored { value: id::Valid(self.parent_id), ref_count: device.life_guard.add_ref(), @@ -570,10 +571,11 @@ pub struct RenderBundle { // Normalized command stream. It can be executed verbatim, // without re-binding anything on the pipeline change. base: BasePass, + pub(super) is_ds_read_only: bool, pub(crate) device_id: Stored, pub(crate) used: TrackerSet, - pub(crate) buffer_memory_init_actions: Vec>, - pub(crate) context: RenderPassContext, + pub(super) buffer_memory_init_actions: Vec>, + pub(super) context: RenderPassContext, pub(crate) life_guard: LifeGuard, } @@ -590,7 +592,7 @@ impl RenderBundle { /// Note that the function isn't expected to fail, generally. /// All the validation has already been done by this point. /// The only failure condition is if some of the used buffers are destroyed. - pub(crate) unsafe fn execute( + pub(super) unsafe fn execute( &self, raw: &mut A::CommandEncoder, pipeline_layout_guard: &Storage< diff --git a/wgpu-core/src/command/draw.rs b/wgpu-core/src/command/draw.rs index 2d936d14e0..e9b266392e 100644 --- a/wgpu-core/src/command/draw.rs +++ b/wgpu-core/src/command/draw.rs @@ -72,10 +72,10 @@ pub enum RenderCommandError { InvalidPipeline(id::RenderPipelineId), #[error("QuerySet {0:?} is invalid")] InvalidQuerySet(id::QuerySetId), - #[error("Render pipeline is incompatible with render pass")] - IncompatiblePipeline(#[from] crate::device::RenderPassCompatibilityError), - #[error("pipeline is not compatible with the depth-stencil read-only render pass")] - IncompatibleReadOnlyDepthStencil, + #[error("Render pipeline targets are incompatible with render pass")] + IncompatiblePipelineTargets(#[from] crate::device::RenderPassCompatibilityError), + #[error("pipeline writes to depth/stencil, while the pass has read-only depth/stencil")] + IncompatiblePipelineRods, #[error("buffer {0:?} is in error {1:?}")] Buffer(id::BufferId, BufferError), #[error("buffer {0:?} is destroyed")] diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 133c7b5748..ec2ab4c526 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -444,8 +444,10 @@ pub enum RenderPassErrorInner { InvalidPopDebugGroup, #[error(transparent)] ResourceUsageConflict(#[from] UsageConflict), - #[error("render bundle is incompatible, {0}")] - IncompatibleRenderBundle(#[from] RenderPassCompatibilityError), + #[error("render bundle has incompatible targets, {0}")] + IncompatibleBundleTargets(#[from] RenderPassCompatibilityError), + #[error("render bundle has an incompatible read-only depth/stencil flag: bundle is {bundle}, while the pass is {pass}")] + IncompatibleBundleRods { pass: bool, bundle: bool }, #[error(transparent)] RenderCommand(#[from] RenderCommandError), #[error(transparent)] @@ -994,7 +996,7 @@ impl Global { info.context .check_compatible(&pipeline.pass_context) - .map_err(RenderCommandError::IncompatiblePipeline) + .map_err(RenderCommandError::IncompatiblePipelineTargets) .map_pass_err(scope)?; state.pipeline_flags = pipeline.flags; @@ -1002,7 +1004,7 @@ impl Global { if pipeline.flags.contains(PipelineFlags::WRITES_DEPTH_STENCIL) && info.is_ds_read_only { - return Err(RenderCommandError::IncompatibleReadOnlyDepthStencil) + return Err(RenderCommandError::IncompatiblePipelineRods) .map_pass_err(scope); } @@ -1678,9 +1680,17 @@ impl Global { info.context .check_compatible(&bundle.context) - .map_err(RenderPassErrorInner::IncompatibleRenderBundle) + .map_err(RenderPassErrorInner::IncompatibleBundleTargets) .map_pass_err(scope)?; + if info.is_ds_read_only != bundle.is_ds_read_only { + return Err(RenderPassErrorInner::IncompatibleBundleRods { + pass: info.is_ds_read_only, + bundle: bundle.is_ds_read_only, + }) + .map_pass_err(scope); + } + cmd_buf.buffer_memory_init_actions.extend( bundle .buffer_memory_init_actions