Skip to content

Commit 8c5c498

Browse files
authored
Merge branch 'trunk' into feature/enable
2 parents 428cc6f + 18b758e commit 8c5c498

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ By @stefnotch in [#5410](https://github.com/gfx-rs/wgpu/pull/5410)
9292

9393
### Bug Fixes
9494

95+
### General
96+
97+
- Ensure render pipelines have at least 1 target. By @ErichDonGubler in [#5715](https://github.com/gfx-rs/wgpu/pull/5715)
98+
9599
#### Vulkan
96100

97101
- Fix enablement of subgroup ops extension on Vulkan devices that don't support Vulkan 1.3. By @cwfitzgerald in [#5624](https://github.com/gfx-rs/wgpu/pull/5624).

tests/tests/pipeline.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,46 @@ static PIPELINE_DEFAULT_LAYOUT_BAD_MODULE: GpuTestConfiguration = GpuTestConfigu
3535
pipeline.get_bind_group_layout(0);
3636
});
3737
});
38+
39+
const TRIVIAL_VERTEX_SHADER_DESC: wgpu::ShaderModuleDescriptor = wgpu::ShaderModuleDescriptor {
40+
label: Some("trivial vertex shader"),
41+
source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
42+
"@vertex fn main() -> @builtin(position) vec4<f32> { return vec4<f32>(0); }",
43+
)),
44+
};
45+
46+
#[gpu_test]
47+
static NO_TARGETLESS_RENDER: GpuTestConfiguration = GpuTestConfiguration::new()
48+
.parameters(TestParameters::default())
49+
.run_sync(|ctx| {
50+
fail(&ctx.device, || {
51+
// Testing multisampling is important, because some backends don't behave well if one
52+
// tries to compile code in an unsupported multisample count. Failing to validate here
53+
// has historically resulted in requesting the back end to compile code.
54+
for power_of_two in [1, 2, 4, 8, 16, 32, 64] {
55+
ctx.device
56+
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
57+
label: None,
58+
layout: None,
59+
vertex: wgpu::VertexState {
60+
module: &ctx.device.create_shader_module(TRIVIAL_VERTEX_SHADER_DESC),
61+
entry_point: "main",
62+
compilation_options: Default::default(),
63+
buffers: &[],
64+
},
65+
primitive: Default::default(),
66+
depth_stencil: None,
67+
multisample: wgpu::MultisampleState {
68+
count: power_of_two,
69+
..Default::default()
70+
},
71+
fragment: None,
72+
multiview: None,
73+
cache: None,
74+
});
75+
}
76+
})
77+
// TODO: concrete error message:
78+
// At least one color attachment or depth-stencil attachment was expected, but no
79+
// render target for the pipeline was specified.
80+
});

wgpu-core/src/device/resource.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3048,8 +3048,11 @@ impl<A: HalApi> Device<A> {
30483048
);
30493049
}
30503050

3051+
let mut target_specified = false;
3052+
30513053
for (i, cs) in color_targets.iter().enumerate() {
30523054
if let Some(cs) = cs.as_ref() {
3055+
target_specified = true;
30533056
let error = loop {
30543057
if cs.write_mask.contains_invalid_bits() {
30553058
break Some(pipeline::ColorStateError::InvalidWriteMask(cs.write_mask));
@@ -3077,6 +3080,7 @@ impl<A: HalApi> Device<A> {
30773080
if !hal::FormatAspects::from(cs.format).contains(hal::FormatAspects::COLOR) {
30783081
break Some(pipeline::ColorStateError::FormatNotColor(cs.format));
30793082
}
3083+
30803084
if desc.multisample.count > 1
30813085
&& !format_features
30823086
.flags
@@ -3095,6 +3099,7 @@ impl<A: HalApi> Device<A> {
30953099
.supported_sample_counts(),
30963100
));
30973101
}
3102+
30983103
if let Some(blend_mode) = cs.blend {
30993104
for factor in [
31003105
blend_mode.color.src_factor,
@@ -3134,6 +3139,7 @@ impl<A: HalApi> Device<A> {
31343139
}
31353140

31363141
if let Some(ds) = depth_stencil_state {
3142+
target_specified = true;
31373143
let error = loop {
31383144
let format_features = self.describe_format_features(adapter, ds.format)?;
31393145
if !format_features
@@ -3184,6 +3190,10 @@ impl<A: HalApi> Device<A> {
31843190
}
31853191
}
31863192

3193+
if !target_specified {
3194+
return Err(pipeline::CreateRenderPipelineError::NoTargetSpecified);
3195+
}
3196+
31873197
// Get the pipeline layout from the desc if it is provided.
31883198
let pipeline_layout = match desc.layout {
31893199
Some(pipeline_layout_id) => {

wgpu-core/src/pipeline.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,11 @@ pub enum CreateRenderPipelineError {
495495
PipelineExpectsShaderToUseDualSourceBlending,
496496
#[error("Shader entry point expects the pipeline to make use of dual-source blending.")]
497497
ShaderExpectsPipelineToUseDualSourceBlending,
498+
#[error("{}", concat!(
499+
"At least one color attachment or depth-stencil attachment was expected, ",
500+
"but no render target for the pipeline was specified."
501+
))]
502+
NoTargetSpecified,
498503
}
499504

500505
bitflags::bitflags! {

0 commit comments

Comments
 (0)