mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Add public structs for indirect command buffers
and fix missing IndirectBufferOverrun error for IndirectDispatch
This commit is contained in:
@@ -23,7 +23,7 @@ use thiserror::Error;
|
||||
use wgt::{BufferAddress, BufferUsage, ShaderStage};
|
||||
|
||||
use crate::track::UseExtendError;
|
||||
use std::{fmt, iter, str};
|
||||
use std::{fmt, iter, mem, str};
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@@ -140,6 +140,12 @@ pub enum ComputePassErrorInner {
|
||||
InvalidQuerySet(id::QuerySetId),
|
||||
#[error("indirect buffer {0:?} is invalid or destroyed")]
|
||||
InvalidIndirectBuffer(id::BufferId),
|
||||
#[error("indirect buffer uses bytes {offset}..{end_offset} which overruns indirect buffer of size {buffer_size}")]
|
||||
IndirectBufferOverrun {
|
||||
offset: u64,
|
||||
end_offset: u64,
|
||||
buffer_size: u64,
|
||||
},
|
||||
#[error(transparent)]
|
||||
ResourceUsageConflict(#[from] UsageConflict),
|
||||
#[error(transparent)]
|
||||
@@ -490,6 +496,17 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.map_pass_err(scope)?;
|
||||
check_buffer_usage(indirect_buffer.usage, BufferUsage::INDIRECT)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let end_offset = offset + mem::size_of::<wgt::DispatchIndirectArgs>() as u64;
|
||||
if end_offset > indirect_buffer.size {
|
||||
return Err(ComputePassErrorInner::IndirectBufferOverrun {
|
||||
offset,
|
||||
end_offset,
|
||||
buffer_size: indirect_buffer.size,
|
||||
})
|
||||
.map_pass_err(scope);
|
||||
}
|
||||
|
||||
let &(ref buf_raw, _) = indirect_buffer
|
||||
.raw
|
||||
.as_ref()
|
||||
|
||||
@@ -45,6 +45,7 @@ use std::{
|
||||
collections::hash_map::Entry,
|
||||
fmt, iter,
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
num::NonZeroU32,
|
||||
ops::Range,
|
||||
str,
|
||||
@@ -417,11 +418,10 @@ pub enum RenderPassErrorInner {
|
||||
InvalidValuesOffset,
|
||||
#[error("required device features not enabled: {0:?}")]
|
||||
MissingDeviceFeatures(wgt::Features),
|
||||
#[error("indirect draw with offset {offset}{} uses bytes {begin_offset}..{end_offset} which overruns indirect buffer of size {buffer_size}", count.map_or_else(String::new, |v| format!(" and count {}", v)))]
|
||||
#[error("indirect draw uses bytes {offset}..{end_offset} {} which overruns indirect buffer of size {buffer_size}", count.map_or_else(String::new, |v| format!("(using count {})", v)))]
|
||||
IndirectBufferOverrun {
|
||||
offset: u64,
|
||||
count: Option<NonZeroU32>,
|
||||
begin_offset: u64,
|
||||
offset: u64,
|
||||
end_offset: u64,
|
||||
buffer_size: u64,
|
||||
},
|
||||
@@ -1549,9 +1549,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
state.is_ready().map_pass_err(scope)?;
|
||||
|
||||
let stride = match indexed {
|
||||
false => 16,
|
||||
true => 20,
|
||||
};
|
||||
false => mem::size_of::<wgt::DrawIndirectArgs>(),
|
||||
true => mem::size_of::<wgt::DrawIndexedIndirectArgs>(),
|
||||
} as u64;
|
||||
|
||||
if count.is_some() {
|
||||
check_device_features(
|
||||
@@ -1577,13 +1577,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let actual_count = count.map_or(1, |c| c.get());
|
||||
|
||||
let begin_offset = offset;
|
||||
let end_offset = offset + stride * actual_count as u64;
|
||||
if end_offset > indirect_buffer.size {
|
||||
return Err(RenderPassErrorInner::IndirectBufferOverrun {
|
||||
offset,
|
||||
count,
|
||||
begin_offset,
|
||||
offset,
|
||||
end_offset,
|
||||
buffer_size: indirect_buffer.size,
|
||||
})
|
||||
@@ -1625,9 +1623,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
state.is_ready().map_pass_err(scope)?;
|
||||
|
||||
let stride = match indexed {
|
||||
false => 16,
|
||||
true => 20,
|
||||
};
|
||||
false => mem::size_of::<wgt::DrawIndirectArgs>(),
|
||||
true => mem::size_of::<wgt::DrawIndexedIndirectArgs>(),
|
||||
} as u64;
|
||||
|
||||
check_device_features(
|
||||
device.features,
|
||||
@@ -1663,13 +1661,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.ok_or(RenderCommandError::DestroyedBuffer(count_buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let begin_offset = offset;
|
||||
let end_offset = offset + stride * max_count as u64;
|
||||
if end_offset > indirect_buffer.size {
|
||||
return Err(RenderPassErrorInner::IndirectBufferOverrun {
|
||||
offset,
|
||||
count: None,
|
||||
begin_offset,
|
||||
offset,
|
||||
end_offset,
|
||||
buffer_size: indirect_buffer.size,
|
||||
})
|
||||
|
||||
@@ -2811,3 +2811,45 @@ bitflags::bitflags! {
|
||||
const COMPUTE_SHADER_INVOCATIONS = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
/// Argument buffer layout for draw_indirect commands.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DrawIndirectArgs {
|
||||
/// The number of vertices to draw.
|
||||
pub vertex_count: u32,
|
||||
/// The number of instances to draw.
|
||||
pub instance_count: u32,
|
||||
/// Offset into the vertex buffers, in vertices, to begin drawing from.
|
||||
pub first_vertex: u32,
|
||||
/// First instance to draw.
|
||||
pub first_instance: u32,
|
||||
}
|
||||
|
||||
/// Argument buffer layout for draw_indexed_indirect commands.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DrawIndexedIndirectArgs {
|
||||
/// The number of indices to draw.
|
||||
pub index_count: u32,
|
||||
/// The number of instances to draw.
|
||||
pub instance_count: u32,
|
||||
/// Offset into the index buffer, in indices, begin drawing from.
|
||||
pub first_index: u32,
|
||||
/// Added to each index value before indexing into the vertex buffers.
|
||||
pub base_vertex: i32,
|
||||
/// First instance to draw.
|
||||
pub first_instance: u32,
|
||||
}
|
||||
|
||||
/// Argument buffer layout for dispatch_indirect commands.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DispatchIndirectArgs {
|
||||
/// X dimension of the grid of workgroups to dispatch.
|
||||
pub group_size_x: u32,
|
||||
/// Y dimension of the grid of workgroups to dispatch.
|
||||
pub group_size_y: u32,
|
||||
/// Z dimension of the grid of workgroups to dispatch.
|
||||
pub group_size_z: u32,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user