use crate::{
binding_model::PushConstantUploadError,
id,
resource::BufferUse,
track::UseExtendError,
validation::{MissingBufferUsageError, MissingTextureUsageError},
};
use wgt::{BufferAddress, BufferSize, Color};
use std::num::NonZeroU32;
use thiserror::Error;
pub type BufferError = UseExtendError<BufferUse>;
#[derive(Clone, Debug, Error, PartialEq)]
pub enum DrawError {
#[error("blend color needs to be set")]
MissingBlendColor,
#[error("stencil reference needs to be set")]
MissingStencilReference,
#[error("render pipeline must be set")]
MissingPipeline,
#[error("current render pipeline has a layout which is incompatible with a currently set bind group, first differing at entry index {index}")]
IncompatibleBindGroup {
index: u32,
},
#[error("vertex {last_vertex} extends beyond limit {vertex_limit}")]
VertexBeyondLimit { last_vertex: u32, vertex_limit: u32 },
#[error("instance {last_instance} extends beyond limit {instance_limit}")]
InstanceBeyondLimit {
last_instance: u32,
instance_limit: u32,
},
#[error("index {last_index} extends beyond limit {index_limit}")]
IndexBeyondLimit { last_index: u32, index_limit: u32 },
}
#[derive(Clone, Debug, Error)]
pub enum RenderCommandError {
#[error("bind group {0:?} is invalid")]
InvalidBindGroup(id::BindGroupId),
#[error("bind group index {index} is greater than the device's requested `max_bind_group` limit {max}")]
BindGroupIndexOutOfRange { index: u8, max: u32 },
#[error("dynamic buffer offset {0} does not respect `BIND_BUFFER_ALIGNMENT`")]
UnalignedBufferOffset(u64),
#[error("number of buffer offsets ({actual}) does not match the number of dynamic bindings ({expected})")]
InvalidDynamicOffsetCount { actual: usize, expected: usize },
#[error("render pipeline {0:?} is invalid")]
InvalidPipeline(id::RenderPipelineId),
#[error("render pipeline output formats and sample counts do not match render pass attachment formats")]
IncompatiblePipeline,
#[error("pipeline is not compatible with the depth-stencil read-only render pass")]
IncompatibleReadOnlyDepthStencil,
#[error("buffer {0:?} is in error {1:?}")]
Buffer(id::BufferId, BufferError),
#[error(transparent)]
MissingBufferUsage(#[from] MissingBufferUsageError),
#[error(transparent)]
MissingTextureUsage(#[from] MissingTextureUsageError),
#[error(transparent)]
PushConstants(#[from] PushConstantUploadError),
}
#[derive(Clone, Copy, Debug, Default)]
#[cfg_attr(
any(feature = "serial-pass", feature = "trace"),
derive(serde::Serialize)
)]
#[cfg_attr(
any(feature = "serial-pass", feature = "replay"),
derive(serde::Deserialize)
)]
pub struct Rect<T> {
pub x: T,
pub y: T,
pub w: T,
pub h: T,
}
#[doc(hidden)]
#[derive(Clone, Copy, Debug)]
#[cfg_attr(
any(feature = "serial-pass", feature = "trace"),
derive(serde::Serialize)
)]
#[cfg_attr(
any(feature = "serial-pass", feature = "replay"),
derive(serde::Deserialize)
)]
pub enum RenderCommand {
SetBindGroup {
index: u8,
num_dynamic_offsets: u8,
bind_group_id: id::BindGroupId,
},
SetPipeline(id::RenderPipelineId),
SetIndexBuffer {
buffer_id: id::BufferId,
offset: BufferAddress,
size: Option<BufferSize>,
},
SetVertexBuffer {
slot: u32,
buffer_id: id::BufferId,
offset: BufferAddress,
size: Option<BufferSize>,
},
SetBlendColor(Color),
SetStencilReference(u32),
SetViewport {
rect: Rect<f32>,
depth_min: f32,
depth_max: f32,
},
SetScissor(Rect<u32>),
SetPushConstant {
stages: wgt::ShaderStage,
offset: u32,
size_bytes: u32,
values_offset: Option<u32>,
},
Draw {
vertex_count: u32,
instance_count: u32,
first_vertex: u32,
first_instance: u32,
},
DrawIndexed {
index_count: u32,
instance_count: u32,
first_index: u32,
base_vertex: i32,
first_instance: u32,
},
MultiDrawIndirect {
buffer_id: id::BufferId,
offset: BufferAddress,
count: Option<NonZeroU32>,
indexed: bool,
},
MultiDrawIndirectCount {
buffer_id: id::BufferId,
offset: BufferAddress,
count_buffer_id: id::BufferId,
count_buffer_offset: BufferAddress,
max_count: u32,
indexed: bool,
},
PushDebugGroup {
color: u32,
len: usize,
},
PopDebugGroup,
InsertDebugMarker {
color: u32,
len: usize,
},
ExecuteBundle(id::RenderBundleId),
}