Skip to content

Commit

Permalink
Merge branch 'trunk' into ray-tracing-new
Browse files Browse the repository at this point in the history
  • Loading branch information
Vecvec authored Oct 4, 2024
2 parents 1e860ca + ee0d170 commit 5c086b0
Show file tree
Hide file tree
Showing 54 changed files with 1,548 additions and 572 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ By @bradwerth [#6216](https://github.com/gfx-rs/wgpu/pull/6216).
#### GLES / OpenGL

- Fix GL debug message callbacks not being properly cleaned up (causing UB). By @Imberflur in [#6114](https://github.com/gfx-rs/wgpu/pull/6114)
- Fix calling `slice::from_raw_parts` with unaligned pointers in push constant handling. By @Imberflur in [#6341](https://github.com/gfx-rs/wgpu/pull/6341)

#### WebGPU

Expand Down
14 changes: 3 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ arrayvec = "0.7"
bincode = "1"
bit-vec = "0.8"
bitflags = "2.6"
bytemuck = { version = "1.18", features = ["derive"] }
bytemuck = { version = "1.18" }
cfg_aliases = "0.1"
cfg-if = "1"
criterion = "0.5"
Expand Down Expand Up @@ -104,7 +104,7 @@ nanorand = { version = "0.7", default-features = false, features = ["wyrand"] }
noise = { version = "0.8", git = "https://github.com/Razaekel/noise-rs.git", rev = "c6942d4fb70af26db4441edcf41f90fa115333f2" }
nv-flip = "0.1"
obj = "0.10"
once_cell = "1.20.1"
once_cell = "1.19.0"
parking_lot = "0.12.1"
pico-args = { version = "0.5.0", features = [
"eq-separator",
Expand Down
2 changes: 1 addition & 1 deletion examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ webgl = ["wgpu/webgl"]
webgpu = ["wgpu/webgpu"]

[dependencies]
bytemuck.workspace = true
bytemuck = { workspace = true, features = ["derive"] }
cfg-if.workspace = true
encase = { workspace = true, features = ["glam"] }
flume.workspace = true
Expand Down
5 changes: 4 additions & 1 deletion naga/src/back/pipeline_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use thiserror::Error;
pub enum PipelineConstantError {
#[error("Missing value for pipeline-overridable constant with identifier string: '{0}'")]
MissingValue(String),
#[error("Source f64 value needs to be finite (NaNs and Inifinites are not allowed) for number destinations")]
#[error(
"Source f64 value needs to be finite ({}) for number destinations",
"NaNs and Inifinites are not allowed"
)]
SrcNeedsToBeFinite,
#[error("Source f64 value doesn't fit in destination")]
DstRangeTooSmall,
Expand Down
154 changes: 136 additions & 18 deletions naga/src/back/spv/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ Implementations for `BlockContext` methods.

use super::{
helpers, index::BoundsCheckResult, make_local, selection::Selection, Block, BlockContext,
Dimension, Error, Instruction, LocalType, LookupType, LoopContext, ResultMember, Writer,
WriterFlags,
Dimension, Error, Instruction, LocalType, LookupType, ResultMember, Writer, WriterFlags,
};
use crate::{arena::Handle, proc::TypeResolution, Statement};
use spirv::Word;
Expand Down Expand Up @@ -39,7 +38,7 @@ enum ExpressionPointer {
}

/// The termination statement to be added to the end of the block
pub enum BlockExit {
enum BlockExit {
/// Generates an OpReturn (void return)
Return,
/// Generates an OpBranch to the specified block
Expand All @@ -60,6 +59,36 @@ pub enum BlockExit {
},
}

/// What code generation did with a provided [`BlockExit`] value.
///
/// A function that accepts a [`BlockExit`] argument should return a value of
/// this type, to indicate whether the code it generated ended up using the
/// provided exit, or ignored it and did a non-local exit of some other kind
/// (say, [`Break`] or [`Continue`]). Some callers must use this information to
/// decide whether to generate the target block at all.
///
/// [`Break`]: Statement::Break
/// [`Continue`]: Statement::Continue
#[must_use]
enum BlockExitDisposition {
/// The generated code used the provided `BlockExit` value. If it included a
/// block label, the caller should be sure to actually emit the block it
/// refers to.
Used,

/// The generated code did not use the provided `BlockExit` value. If it
/// included a block label, the caller should not bother to actually emit
/// the block it refers to, unless it knows the block is needed for
/// something else.
Discarded,
}

#[derive(Clone, Copy, Default)]
struct LoopContext {
continuing_id: Option<Word>,
break_id: Option<Word>,
}

#[derive(Debug)]
pub(crate) struct DebugInfoInner<'a> {
pub source_code: &'a str,
Expand Down Expand Up @@ -343,14 +372,40 @@ impl<'w> BlockContext<'w> {

load_id
}
crate::TypeInner::Array {
base: ty_element, ..
} => {
let index_id = self.cached[index];
let base_id = self.cached[base];
let base_ty = match self.fun_info[base].ty {
TypeResolution::Handle(handle) => handle,
TypeResolution::Value(_) => {
return Err(Error::Validation(
"Array types should always be in the arena",
))
}
};
let (id, variable) = self.writer.promote_access_expression_to_variable(
&self.ir_module.types,
result_type_id,
base_id,
base_ty,
index_id,
ty_element,
block,
)?;
self.function.internal_variables.push(variable);
id
}
// wgpu#4337: Support `crate::TypeInner::Matrix`
ref other => {
log::error!(
"Unable to access base {:?} of type {:?}",
self.ir_function.expressions[base],
other
);
return Err(Error::Validation(
"only vectors may be dynamically indexed by value",
"only vectors and arrays may be dynamically indexed by value",
));
}
}
Expand Down Expand Up @@ -2034,14 +2089,30 @@ impl<'w> BlockContext<'w> {
}
}

pub(super) fn write_block(
/// Generate one or more SPIR-V blocks for `naga_block`.
///
/// Use `label_id` as the label for the SPIR-V entry point block.
///
/// If control reaches the end of the SPIR-V block, terminate it according
/// to `exit`. This function's return value indicates whether it acted on
/// this parameter or not; see [`BlockExitDisposition`].
///
/// If the block contains [`Break`] or [`Continue`] statements,
/// `loop_context` supplies the labels of the SPIR-V blocks to jump to. If
/// either of these labels are `None`, then it should have been a Naga
/// validation error for the corresponding statement to occur in this
/// context.
///
/// [`Break`]: Statement::Break
/// [`Continue`]: Statement::Continue
fn write_block(
&mut self,
label_id: Word,
naga_block: &crate::Block,
exit: BlockExit,
loop_context: LoopContext,
debug_info: Option<&DebugInfoInner>,
) -> Result<(), Error> {
) -> Result<BlockExitDisposition, Error> {
let mut block = Block::new(label_id);
for (statement, span) in naga_block.span_iter() {
if let (Some(debug_info), false) = (
Expand Down Expand Up @@ -2077,15 +2148,22 @@ impl<'w> BlockContext<'w> {
self.function.consume(block, Instruction::branch(scope_id));

let merge_id = self.gen_id();
self.write_block(
let merge_used = self.write_block(
scope_id,
block_statements,
BlockExit::Branch { target: merge_id },
loop_context,
debug_info,
)?;

block = Block::new(merge_id);
match merge_used {
BlockExitDisposition::Used => {
block = Block::new(merge_id);
}
BlockExitDisposition::Discarded => {
return Ok(BlockExitDisposition::Discarded);
}
}
}
Statement::If {
condition,
Expand Down Expand Up @@ -2121,7 +2199,11 @@ impl<'w> BlockContext<'w> {
);

if let Some(block_id) = accept_id {
self.write_block(
// We can ignore the `BlockExitDisposition` returned here because,
// even if `merge_id` is not actually reachable, it is always
// referred to by the `OpSelectionMerge` instruction we emitted
// earlier.
let _ = self.write_block(
block_id,
accept,
BlockExit::Branch { target: merge_id },
Expand All @@ -2130,7 +2212,11 @@ impl<'w> BlockContext<'w> {
)?;
}
if let Some(block_id) = reject_id {
self.write_block(
// We can ignore the `BlockExitDisposition` returned here because,
// even if `merge_id` is not actually reachable, it is always
// referred to by the `OpSelectionMerge` instruction we emitted
// earlier.
let _ = self.write_block(
block_id,
reject,
BlockExit::Branch { target: merge_id },
Expand Down Expand Up @@ -2208,7 +2294,15 @@ impl<'w> BlockContext<'w> {
} else {
merge_id
};
self.write_block(
// We can ignore the `BlockExitDisposition` returned here because
// `case_finish_id` is always referred to by either:
//
// - the `OpSwitch`, if it's the next case's label for a
// fall-through, or
//
// - the `OpSelectionMerge`, if it's the switch's overall merge
// block because there's no fall-through.
let _ = self.write_block(
*label_id,
&case.body,
BlockExit::Branch {
Expand Down Expand Up @@ -2254,7 +2348,10 @@ impl<'w> BlockContext<'w> {
));
self.function.consume(block, Instruction::branch(body_id));

self.write_block(
// We can ignore the `BlockExitDisposition` returned here because,
// even if `continuing_id` is not actually reachable, it is always
// referred to by the `OpLoopMerge` instruction we emitted earlier.
let _ = self.write_block(
body_id,
body,
BlockExit::Branch {
Expand All @@ -2277,7 +2374,10 @@ impl<'w> BlockContext<'w> {
},
};

self.write_block(
// We can ignore the `BlockExitDisposition` returned here because,
// even if `merge_id` is not actually reachable, it is always referred
// to by the `OpLoopMerge` instruction we emitted earlier.
let _ = self.write_block(
continuing_id,
continuing,
exit,
Expand All @@ -2293,14 +2393,14 @@ impl<'w> BlockContext<'w> {
Statement::Break => {
self.function
.consume(block, Instruction::branch(loop_context.break_id.unwrap()));
return Ok(());
return Ok(BlockExitDisposition::Discarded);
}
Statement::Continue => {
self.function.consume(
block,
Instruction::branch(loop_context.continuing_id.unwrap()),
);
return Ok(());
return Ok(BlockExitDisposition::Discarded);
}
Statement::Return { value: Some(value) } => {
let value_id = self.cached[value];
Expand All @@ -2319,15 +2419,15 @@ impl<'w> BlockContext<'w> {
None => Instruction::return_value(value_id),
};
self.function.consume(block, instruction);
return Ok(());
return Ok(BlockExitDisposition::Discarded);
}
Statement::Return { value: None } => {
self.function.consume(block, Instruction::return_void());
return Ok(());
return Ok(BlockExitDisposition::Discarded);
}
Statement::Kill => {
self.function.consume(block, Instruction::kill());
return Ok(());
return Ok(BlockExitDisposition::Discarded);
}
Statement::Barrier(flags) => {
self.writer.write_barrier(flags, &mut block);
Expand Down Expand Up @@ -2693,6 +2793,24 @@ impl<'w> BlockContext<'w> {
};

self.function.consume(block, termination);
Ok(BlockExitDisposition::Used)
}

pub(super) fn write_function_body(
&mut self,
entry_id: Word,
debug_info: Option<&DebugInfoInner>,
) -> Result<(), Error> {
// We can ignore the `BlockExitDisposition` returned here because
// `BlockExit::Return` doesn't refer to a block.
let _ = self.write_block(
entry_id,
&self.ir_function.body,
super::block::BlockExit::Return,
LoopContext::default(),
debug_info,
)?;

Ok(())
}
}
17 changes: 2 additions & 15 deletions naga/src/back/spv/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,9 @@ impl crate::AddressSpace {

/// Return true if the global requires a type decorated with `Block`.
///
/// In the Vulkan spec 1.3.296, the section [Descriptor Set Interface][dsi] says:
/// See [`back::spv::GlobalVariable`] for details.
///
/// > Variables identified with the `Uniform` storage class are used to
/// > access transparent buffer backed resources. Such variables must
/// > be:
/// >
/// > - typed as `OpTypeStruct`, or an array of this type,
/// >
/// > - identified with a `Block` or `BufferBlock` decoration, and
/// >
/// > - laid out explicitly using the `Offset`, `ArrayStride`, and
/// > `MatrixStride` decorations as specified in §15.6.4, "Offset
/// > and Stride Assignment."
///
/// [dsi]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#interfaces-resources-descset
// See `back::spv::GlobalVariable::access_id` for details.
/// [`back::spv::GlobalVariable`]: super::GlobalVariable
pub fn global_needs_wrapper(ir_module: &crate::Module, var: &crate::GlobalVariable) -> bool {
match var.space {
crate::AddressSpace::Uniform
Expand Down
Loading

0 comments on commit 5c086b0

Please sign in to comment.