Skip to content

Commit 312ac16

Browse files
WIP: fix(core): add max_inter_stage_shader_variables validation
1 parent 28583d9 commit 312ac16

File tree

11 files changed

+53
-4
lines changed

11 files changed

+53
-4
lines changed

deno_webgpu/01_webgpu.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,7 @@ ObjectDefineProperty(GPUSupportedLimitsPrototype, privateCustomInspect, {
273273
"maxBufferSize",
274274
"maxVertexAttributes",
275275
"maxVertexBufferArrayStride",
276-
// TODO(@crowlKats): support max_inter_stage_shader_variables
277-
// "maxInterStageShaderVariables",
276+
"maxInterStageShaderVariables",
278277
"maxColorAttachments",
279278
"maxColorAttachmentBytesPerSample",
280279
"maxComputeWorkgroupStorageSize",

deno_webgpu/adapter.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,10 @@ impl GPUSupportedLimits {
344344
self.0.max_vertex_buffer_array_stride
345345
}
346346

347-
// TODO(@crowlKats): support max_inter_stage_shader_variables
347+
#[getter]
348+
fn maxInterStageShaderVariables(&self) -> u32 {
349+
self.0.max_inter_stage_shader_variables
350+
}
348351

349352
#[getter]
350353
fn maxColorAttachments(&self) -> u32 {

wgpu-core/src/validation.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1331,10 +1331,40 @@ impl Interface {
13311331

13321332
match shader_stage {
13331333
naga::ShaderStage::Vertex => {
1334+
let max_vertex_shader_output_variables =
1335+
self.limits.max_inter_stage_shader_variables;
1336+
let max_vertex_shader_output_location = max_vertex_shader_output_variables - 1;
1337+
1338+
// TODO: decrease `max_vertex_shader_output_variables` by 1 if `point-list`
1339+
// topology is used
1340+
1341+
let clip_distances_penalty = entry_point
1342+
.outputs
1343+
.iter()
1344+
.filter_map(|output| {
1345+
if let Varying::BuiltIn(builtin) = output {
1346+
match builtin {
1347+
naga::BuiltIn::ClipDistance => {
1348+
todo!("get size of `clip_distances` binding")
1349+
}
1350+
_ => 0,
1351+
}
1352+
}
1353+
})
1354+
.sum()
1355+
.div_ceil(4);
1356+
max_vertex_shader_output_variables -= clip_distances_penalty;
1357+
max_vertex_shader_output_location -= clip_distances_penalty;
1358+
13341359
for output in entry_point.outputs.iter() {
13351360
//TODO: count builtins towards the limit?
13361361
inter_stage_components += match *output {
1337-
Varying::Local { ref iv, .. } => iv.ty.dim.num_components(),
1362+
Varying::Local { ref iv, location } => {
1363+
if location > max_vertex_shader_output_location {
1364+
todo!();
1365+
}
1366+
iv.ty.dim.num_components()
1367+
}
13381368
Varying::BuiltIn(_) => 0,
13391369
};
13401370

wgpu-hal/src/dx12/adapter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@ impl super::Adapter {
717717
//
718718
// Source: https://learn.microsoft.com/en-us/windows/win32/direct3d12/root-signature-limits#memory-limits-and-costs
719719
max_immediate_size: 128,
720+
max_inter_stage_shader_variables: 16,
720721
min_uniform_buffer_offset_alignment:
721722
Direct3D12::D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT,
722723
min_storage_buffer_offset_alignment: 4,

wgpu-hal/src/gles/adapter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ impl super::Adapter {
754754
min_subgroup_size: 0,
755755
max_subgroup_size: 0,
756756
max_immediate_size: super::MAX_IMMEDIATES as u32 * 4,
757+
max_inter_stage_shader_variables: 16,
757758
min_uniform_buffer_offset_alignment,
758759
min_storage_buffer_offset_alignment,
759760
max_inter_stage_shader_components: {

wgpu-hal/src/metal/adapter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,7 @@ impl super::PrivateCapabilities {
11031103
min_subgroup_size: 4,
11041104
max_subgroup_size: 64,
11051105
max_immediate_size: 0x1000,
1106+
max_inter_stage_shader_variables: 16,
11061107
min_uniform_buffer_offset_alignment: self.buffer_alignment as u32,
11071108
min_storage_buffer_offset_alignment: self.buffer_alignment as u32,
11081109
max_inter_stage_shader_components: self.max_varying_components,

wgpu-hal/src/noop/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ pub const CAPABILITIES: crate::Capabilities = {
178178
max_buffer_size: ALLOC_MAX_U32 as u64,
179179
max_vertex_attributes: ALLOC_MAX_U32,
180180
max_vertex_buffer_array_stride: ALLOC_MAX_U32,
181+
max_inter_stage_shader_variables: ALLOC_MAX_U32,
181182
min_uniform_buffer_offset_alignment: 1,
182183
min_storage_buffer_offset_alignment: 1,
183184
max_inter_stage_shader_components: ALLOC_MAX_U32,

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,7 @@ impl PhysicalDeviceProperties {
13401340
.map(|subgroup_size| subgroup_size.max_subgroup_size)
13411341
.unwrap_or(0),
13421342
max_immediate_size: limits.max_push_constants_size,
1343+
max_inter_stage_shader_variables: 16,
13431344
min_uniform_buffer_offset_alignment: limits.min_uniform_buffer_offset_alignment as u32,
13441345
min_storage_buffer_offset_alignment: limits.min_storage_buffer_offset_alignment as u32,
13451346
max_inter_stage_shader_components: limits

wgpu-info/src/human.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize
146146
max_buffer_size,
147147
max_vertex_attributes,
148148
max_vertex_buffer_array_stride,
149+
max_inter_stage_shader_variables,
149150
min_uniform_buffer_offset_alignment,
150151
min_storage_buffer_offset_alignment,
151152
max_inter_stage_shader_components,
@@ -198,6 +199,7 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize
198199
writeln!(output, "\t\t Min Subgroup Size: {min_subgroup_size}")?;
199200
writeln!(output, "\t\t Max Subgroup Size: {max_subgroup_size}")?;
200201
writeln!(output, "\t\t Max Immediate data Size: {max_immediate_size}")?;
202+
writeln!(output, "\t\t Max Inter-stage Shader Variables: {max_inter_stage_shader_variables}")?;
201203
writeln!(output, "\t\t Min Uniform Buffer Offset Alignment: {min_uniform_buffer_offset_alignment}")?;
202204
writeln!(output, "\t\t Min Storage Buffer Offset Alignment: {min_storage_buffer_offset_alignment}")?;
203205
writeln!(output, "\t\t Max Inter-Stage Shader Component: {max_inter_stage_shader_components}")?;

wgpu-types/src/limits.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ pub struct Limits {
175175
/// Maximum value for `VertexBufferLayout::array_stride` when creating a `RenderPipeline`.
176176
/// Defaults to 2048. Higher is "better".
177177
pub max_vertex_buffer_array_stride: u32,
178+
/// Maximum value for the number of input or output variables for inter-stage communication
179+
/// (like vertex outputs or fragment inputs) `@location(…)`s (in WGSL parlance)
180+
/// when creating a `RenderPipeline`.
181+
/// Defaults to 16. Higher is "better".
182+
pub max_inter_stage_shader_variables: u32,
178183
/// Required `BufferBindingType::Uniform` alignment for `BufferBinding::offset`
179184
/// when creating a `BindGroup`, or for `set_bind_group` `dynamicOffsets`.
180185
/// Defaults to 256. Lower is "better".
@@ -305,6 +310,7 @@ impl Limits {
305310
/// max_buffer_size: 256 << 20, // (256 MiB)
306311
/// max_vertex_attributes: 16,
307312
/// max_vertex_buffer_array_stride: 2048,
313+
/// max_inter_stage_shader_variables: 16,
308314
/// min_uniform_buffer_offset_alignment: 256,
309315
/// min_storage_buffer_offset_alignment: 256,
310316
/// max_inter_stage_shader_components: 60,
@@ -358,6 +364,7 @@ impl Limits {
358364
max_buffer_size: 256 << 20, // (256 MiB)
359365
max_vertex_attributes: 16,
360366
max_vertex_buffer_array_stride: 2048,
367+
max_inter_stage_shader_variables: 16,
361368
min_uniform_buffer_offset_alignment: 256,
362369
min_storage_buffer_offset_alignment: 256,
363370
max_inter_stage_shader_components: 60,
@@ -417,6 +424,7 @@ impl Limits {
417424
/// min_subgroup_size: 0,
418425
/// max_subgroup_size: 0,
419426
/// max_immediate_size: 0,
427+
/// max_inter_stage_shader_variables: 16, // TODO: accurate?
420428
/// min_uniform_buffer_offset_alignment: 256,
421429
/// min_storage_buffer_offset_alignment: 256,
422430
/// max_inter_stage_shader_components: 60,
@@ -494,6 +502,7 @@ impl Limits {
494502
/// min_subgroup_size: 0,
495503
/// max_subgroup_size: 0,
496504
/// max_immediate_size: 0,
505+
/// max_inter_stage_shader_variables: 16, // TODO: accurate?
497506
/// min_uniform_buffer_offset_alignment: 256,
498507
/// min_storage_buffer_offset_alignment: 256,
499508
/// max_inter_stage_shader_components: 31,

0 commit comments

Comments
 (0)