Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure render pipelines have at least 1 target #5715

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ By @stefnotch in [#5410](https://github.com/gfx-rs/wgpu/pull/5410)

### Bug Fixes

### General

- Ensure render pipelines have at least 1 target. By @ErichDonGubler in [#5715](https://github.com/gfx-rs/wgpu/pull/5715)

#### Vulkan

- 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).
Expand Down
43 changes: 43 additions & 0 deletions tests/tests/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,46 @@ static PIPELINE_DEFAULT_LAYOUT_BAD_MODULE: GpuTestConfiguration = GpuTestConfigu
pipeline.get_bind_group_layout(0);
});
});

const TRIVIAL_VERTEX_SHADER_DESC: wgpu::ShaderModuleDescriptor = wgpu::ShaderModuleDescriptor {
label: Some("trivial vertex shader"),
source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
"@vertex fn main() -> @builtin(position) vec4<f32> { return vec4<f32>(0); }",
)),
};

#[gpu_test]
static NO_TARGETLESS_RENDER: GpuTestConfiguration = GpuTestConfiguration::new()
.parameters(TestParameters::default())
.run_sync(|ctx| {
fail(&ctx.device, || {
// Testing multisampling is important, because some backends don't behave well if one
// tries to compile code in an unsupported multisample count. Failing to validate here
// has historically resulted in requesting the back end to compile code.
for power_of_two in [1, 2, 4, 8, 16, 32, 64] {
ctx.device
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None,
layout: None,
vertex: wgpu::VertexState {
module: &ctx.device.create_shader_module(TRIVIAL_VERTEX_SHADER_DESC),
entry_point: "main",
compilation_options: Default::default(),
buffers: &[],
},
primitive: Default::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState {
count: power_of_two,
..Default::default()
},
fragment: None,
multiview: None,
cache: None,
});
}
})
// TODO: concrete error message:
// At least one color attachment or depth-stencil attachment was expected, but no
// render target for the pipeline was specified.
});
10 changes: 10 additions & 0 deletions wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3044,8 +3044,11 @@ impl<A: HalApi> Device<A> {
);
}

let mut target_specified = false;

for (i, cs) in color_targets.iter().enumerate() {
if let Some(cs) = cs.as_ref() {
target_specified = true;
let error = loop {
if cs.write_mask.contains_invalid_bits() {
break Some(pipeline::ColorStateError::InvalidWriteMask(cs.write_mask));
Expand Down Expand Up @@ -3073,6 +3076,7 @@ impl<A: HalApi> Device<A> {
if !hal::FormatAspects::from(cs.format).contains(hal::FormatAspects::COLOR) {
break Some(pipeline::ColorStateError::FormatNotColor(cs.format));
}

if desc.multisample.count > 1
&& !format_features
.flags
Expand All @@ -3091,6 +3095,7 @@ impl<A: HalApi> Device<A> {
.supported_sample_counts(),
));
}

if let Some(blend_mode) = cs.blend {
for factor in [
blend_mode.color.src_factor,
Expand Down Expand Up @@ -3130,6 +3135,7 @@ impl<A: HalApi> Device<A> {
}

if let Some(ds) = depth_stencil_state {
target_specified = true;
let error = loop {
let format_features = self.describe_format_features(adapter, ds.format)?;
if !format_features
Expand Down Expand Up @@ -3180,6 +3186,10 @@ impl<A: HalApi> Device<A> {
}
}

if !target_specified {
return Err(pipeline::CreateRenderPipelineError::NoTargetSpecified);
}

// Get the pipeline layout from the desc if it is provided.
let pipeline_layout = match desc.layout {
Some(pipeline_layout_id) => {
Expand Down
5 changes: 5 additions & 0 deletions wgpu-core/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,11 @@ pub enum CreateRenderPipelineError {
PipelineExpectsShaderToUseDualSourceBlending,
#[error("Shader entry point expects the pipeline to make use of dual-source blending.")]
ShaderExpectsPipelineToUseDualSourceBlending,
#[error("{}", concat!(
"At least one color attachment or depth-stencil attachment was expected, ",
"but no render target for the pipeline was specified."
))]
NoTargetSpecified,
}

bitflags::bitflags! {
Expand Down
Loading