Skip to content

Commit 7d8ffb6

Browse files
committed
fix(naga): Support dual-source blending for SPIR-V shaders
Fixes #8864
1 parent 1d520a0 commit 7d8ffb6

4 files changed

Lines changed: 76 additions & 0 deletions

File tree

naga/src/front/spv/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ struct Decoration {
215215
name: Option<String>,
216216
built_in: Option<spirv::Word>,
217217
location: Option<spirv::Word>,
218+
index: Option<spirv::Word>,
218219
desc_set: Option<spirv::Word>,
219220
desc_index: Option<spirv::Word>,
220221
specialization_constant_id: Option<spirv::Word>,
@@ -256,6 +257,18 @@ impl Decoration {
256257
invariant,
257258
..
258259
} => Ok(crate::Binding::BuiltIn(map_builtin(built_in, invariant)?)),
260+
Decoration {
261+
built_in: None,
262+
location: Some(location),
263+
index: Some(index),
264+
..
265+
} => Ok(crate::Binding::Location {
266+
location,
267+
interpolation: None,
268+
sampling: None,
269+
blend_src: Some(index),
270+
per_primitive: false,
271+
}),
259272
Decoration {
260273
built_in: None,
261274
location: Some(location),
@@ -746,6 +759,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
746759
inst.expect(base_words + 2)?;
747760
dec.location = Some(self.next()?);
748761
}
762+
spirv::Decoration::Index => {
763+
inst.expect(base_words + 2)?;
764+
dec.index = Some(self.next()?);
765+
}
749766
spirv::Decoration::DescriptorSet => {
750767
inst.expect(base_words + 2)?;
751768
dec.desc_set = Some(self.next()?);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; SPIR-V
2+
; Version: 1.0
3+
; Generator: Khronos SPIR-V Tools Assembler; 0
4+
; Bound: 22
5+
; Schema: 0
6+
OpCapability Shader
7+
%1 = OpExtInstImport "GLSL.std.450"
8+
OpMemoryModel Logical GLSL450
9+
OpEntryPoint Fragment %main "main" %output0 %output1
10+
OpExecutionMode %main OriginUpperLeft
11+
OpSource GLSL 450
12+
OpName %main "main"
13+
OpName %output0 "output0"
14+
OpName %output1 "output1"
15+
OpDecorate %output0 Location 0
16+
OpDecorate %output0 Index 0
17+
OpDecorate %output1 Location 0
18+
OpDecorate %output1 Index 1
19+
%void = OpTypeVoid
20+
%3 = OpTypeFunction %void
21+
%float = OpTypeFloat 32
22+
%v4float = OpTypeVector %float 4
23+
%_ptr_Output_v4float = OpTypePointer Output %v4float
24+
%output0 = OpVariable %_ptr_Output_v4float Output
25+
%float_1 = OpConstant %float 1
26+
%float_0 = OpConstant %float 0
27+
%13 = OpConstantComposite %v4float %float_1 %float_0 %float_1 %float_0
28+
%output1 = OpVariable %_ptr_Output_v4float Output
29+
%15 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
30+
%main = OpFunction %void None %3
31+
%5 = OpLabel
32+
OpStore %output0 %13
33+
OpStore %output1 %15
34+
OpReturn
35+
OpFunctionEnd
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
capabilities = "DUAL_SOURCE_BLENDING"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
enable dual_source_blending;
2+
3+
struct FragmentOutput {
4+
@location(0) @blend_src(0) member: vec4<f32>,
5+
@location(0) @blend_src(1) member_1: vec4<f32>,
6+
}
7+
8+
var<private> output0_: vec4<f32>;
9+
var<private> output1_: vec4<f32>;
10+
11+
fn main_1() {
12+
output0_ = vec4<f32>(1f, 0f, 1f, 0f);
13+
output1_ = vec4<f32>(0f, 1f, 0f, 1f);
14+
return;
15+
}
16+
17+
@fragment
18+
fn main() -> FragmentOutput {
19+
main_1();
20+
let _e2 = output0_;
21+
let _e3 = output1_;
22+
return FragmentOutput(_e2, _e3);
23+
}

0 commit comments

Comments
 (0)