Skip to content

Commit c82e37b

Browse files
Validate pipelines with passthrough shaders but no explicit layout passed (gfx-rs#8881)
1 parent db8270e commit c82e37b

3 files changed

Lines changed: 28 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Bottom level categories:
8080
- BREAKING: Migrated from the `maxInterStageShaderComponents` limit to `maxInterStageShaderVariables`, which changes validation in a way that should not affect most programs. This follows the latest changes of the WebGPU spec. By @ErichDonGubler in [#8652](https://github.com/gfx-rs/wgpu/pull/8652), [#8792](https://github.com/gfx-rs/wgpu/pull/8792).
8181
- Fixed validation of the texture format in GPUDepthStencilState when neither depth nor stencil is actually enabled. By @andyleiserson in [#8766](https://github.com/gfx-rs/wgpu/pull/8766).
8282
- Tracing support has been restored. By @andyleiserson in [#8429](https://github.com/gfx-rs/wgpu/pull/8429).
83+
- Pipelines using passthrough shaders now correctly require explicit pipeline layout. By @inner-daemons in #8881.
8384

8485
#### naga
8586

wgpu-core/src/device/global.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,7 @@ impl Global {
13921392
Ok(cache) => cache,
13931393
Err(e) => break 'error e.into(),
13941394
};
1395+
let mut passthrough_stages = wgt::ShaderStages::empty();
13951396

13961397
let vertex = match desc.vertex {
13971398
RenderPipelineVertexProcessor::Vertex(ref vertex) => {
@@ -1407,6 +1408,9 @@ impl Global {
14071408
Ok(module) => module,
14081409
Err(e) => break 'error e,
14091410
};
1411+
if module.interface.is_none() {
1412+
passthrough_stages |= wgt::ShaderStages::VERTEX;
1413+
}
14101414
let stage = ResolvedProgrammableStageDescriptor {
14111415
module,
14121416
entry_point: vertex.stage.entry_point.clone(),
@@ -1434,6 +1438,9 @@ impl Global {
14341438
Ok(module) => module,
14351439
Err(e) => break 'error e,
14361440
};
1441+
if module.interface.is_none() {
1442+
passthrough_stages |= wgt::ShaderStages::TASK;
1443+
}
14371444
let state = ResolvedProgrammableStageDescriptor {
14381445
module,
14391446
entry_point: task.stage.entry_point.clone(),
@@ -1458,6 +1465,9 @@ impl Global {
14581465
Ok(module) => module,
14591466
Err(e) => break 'error e,
14601467
};
1468+
if mesh_module.interface.is_none() {
1469+
passthrough_stages |= wgt::ShaderStages::VERTEX;
1470+
}
14611471
let mesh_stage = ResolvedProgrammableStageDescriptor {
14621472
module: mesh_module,
14631473
entry_point: mesh.stage.entry_point.clone(),
@@ -1486,6 +1496,9 @@ impl Global {
14861496
Ok(module) => module,
14871497
Err(e) => break 'error e,
14881498
};
1499+
if module.interface.is_none() {
1500+
passthrough_stages |= wgt::ShaderStages::FRAGMENT;
1501+
}
14891502
let stage = ResolvedProgrammableStageDescriptor {
14901503
module,
14911504
entry_point: state.stage.entry_point.clone(),
@@ -1500,6 +1513,12 @@ impl Global {
15001513
None
15011514
};
15021515

1516+
if !passthrough_stages.is_empty() && layout.is_none() {
1517+
break 'error pipeline::CreateRenderPipelineError::Implicit(
1518+
pipeline::ImplicitLayoutError::Passthrough(passthrough_stages),
1519+
);
1520+
}
1521+
15031522
let desc = ResolvedGeneralRenderPipelineDescriptor {
15041523
label: desc.label.clone(),
15051524
layout,
@@ -1642,6 +1661,11 @@ impl Global {
16421661
Ok(module) => module,
16431662
Err(e) => break 'error e.into(),
16441663
};
1664+
if module.interface.is_none() && layout.is_none() {
1665+
break 'error pipeline::CreateComputePipelineError::Implicit(
1666+
pipeline::ImplicitLayoutError::Passthrough(wgt::ShaderStages::COMPUTE),
1667+
);
1668+
}
16451669
let stage = ResolvedProgrammableStageDescriptor {
16461670
module,
16471671
entry_point: desc.stage.entry_point.clone(),

wgpu-core/src/pipeline.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ pub enum ImplicitLayoutError {
202202
BindGroup(#[from] CreateBindGroupLayoutError),
203203
#[error(transparent)]
204204
Pipeline(#[from] CreatePipelineLayoutError),
205+
#[error("Unable to create implicit pipeline layout from passthrough shader stage: {0:?}")]
206+
Passthrough(wgt::ShaderStages),
205207
}
206208

207209
impl WebGpuError for ImplicitLayoutError {
@@ -210,6 +212,7 @@ impl WebGpuError for ImplicitLayoutError {
210212
Self::ReflectionError(_) => return ErrorType::Validation,
211213
Self::BindGroup(e) => e,
212214
Self::Pipeline(e) => e,
215+
Self::Passthrough(_) => return ErrorType::Validation,
213216
};
214217
e.webgpu_error_type()
215218
}

0 commit comments

Comments
 (0)