[ir][spirv-writer] Add index to IO output names
Avoids a bug in Qualcomm drivers that cannot handle duplicate names.
Change-Id: I8075098df45922d31e4c14d619eaf22786cecace
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/153460
Kokoro: Kokoro <noreply+kokoro@google.com>
Auto-Submit: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/core/ir/disassembler.cc b/src/tint/lang/core/ir/disassembler.cc
index 6625466..08648f3 100644
--- a/src/tint/lang/core/ir/disassembler.cc
+++ b/src/tint/lang/core/ir/disassembler.cc
@@ -487,6 +487,9 @@
if (v->Attributes().location.has_value()) {
out_ << " @location(" << v->Attributes().location.value() << ")";
}
+ if (v->Attributes().index.has_value()) {
+ out_ << " @index(" << v->Attributes().index.value() << ")";
+ }
if (v->Attributes().interpolation.has_value()) {
auto& interp = v->Attributes().interpolation.value();
out_ << " @interpolate(" << interp.type;
diff --git a/src/tint/lang/spirv/writer/function_test.cc b/src/tint/lang/spirv/writer/function_test.cc
index dcbb23c..cb84965 100644
--- a/src/tint/lang/spirv/writer/function_test.cc
+++ b/src/tint/lang/spirv/writer/function_test.cc
@@ -346,25 +346,26 @@
});
ASSERT_TRUE(Generate()) << Error() << output_;
- EXPECT_INST(R"(OpEntryPoint Fragment %main "main" %main_loc0_Output %main_loc0_Output_0)");
+ EXPECT_INST(
+ R"(OpEntryPoint Fragment %main "main" %main_loc0_idx0_Output %main_loc0_idx1_Output)");
EXPECT_INST(R"(
- OpDecorate %main_loc0_Output Location 0
- OpDecorate %main_loc0_Output Index 0
- OpDecorate %main_loc0_Output_0 Location 0
- OpDecorate %main_loc0_Output_0 Index 1
+ OpDecorate %main_loc0_idx0_Output Location 0
+ OpDecorate %main_loc0_idx0_Output Index 0
+ OpDecorate %main_loc0_idx1_Output Location 0
+ OpDecorate %main_loc0_idx1_Output Index 1
)");
EXPECT_INST(R"(
-%main_loc0_Output = OpVariable %_ptr_Output_float Output
-%main_loc0_Output_0 = OpVariable %_ptr_Output_float Output
+%main_loc0_idx0_Output = OpVariable %_ptr_Output_float Output
+%main_loc0_idx1_Output = OpVariable %_ptr_Output_float Output
)");
EXPECT_INST(R"(
%main = OpFunction %void None %14
%15 = OpLabel
%16 = OpFunctionCall %Outputs %main_inner
%17 = OpCompositeExtract %float %16 0
- OpStore %main_loc0_Output %17
+ OpStore %main_loc0_idx0_Output %17
%18 = OpCompositeExtract %float %16 1
- OpStore %main_loc0_Output_0 %18
+ OpStore %main_loc0_idx1_Output %18
OpReturn
OpFunctionEnd
)");
diff --git a/src/tint/lang/spirv/writer/raise/shader_io.cc b/src/tint/lang/spirv/writer/raise/shader_io.cc
index f807c31..2aa195e 100644
--- a/src/tint/lang/spirv/writer/raise/shader_io.cc
+++ b/src/tint/lang/spirv/writer/raise/shader_io.cc
@@ -83,6 +83,9 @@
}
} else {
name << "_loc" << io.attributes.location.value();
+ if (io.attributes.index.has_value()) {
+ name << "_idx" << io.attributes.index.value();
+ }
}
name << name_suffix;
diff --git a/src/tint/lang/spirv/writer/raise/shader_io_test.cc b/src/tint/lang/spirv/writer/raise/shader_io_test.cc
index 343f778..c37f9fb 100644
--- a/src/tint/lang/spirv/writer/raise/shader_io_test.cc
+++ b/src/tint/lang/spirv/writer/raise/shader_io_test.cc
@@ -547,6 +547,78 @@
EXPECT_EQ(expect, str());
}
+TEST_F(SpirvWriter_ShaderIOTest, ReturnValue_DualSourceBlending) {
+ auto* str_ty = ty.Struct(mod.symbols.New("Output"), {
+ {
+ mod.symbols.New("color1"),
+ ty.f32(),
+ {0u, 0u, {}, {}, false},
+ },
+ {
+ mod.symbols.New("color2"),
+ ty.f32(),
+ {0u, 1u, {}, {}, false},
+ },
+ });
+
+ auto* ep = b.Function("foo", str_ty);
+ ep->SetStage(core::ir::Function::PipelineStage::kFragment);
+
+ b.Append(ep->Block(), [&] { //
+ b.Return(ep, b.Construct(str_ty, 0.25_f, 0.75_f));
+ });
+
+ auto* src = R"(
+Output = struct @align(4) {
+ color1:f32 @offset(0), @location(0)
+ color2:f32 @offset(4), @location(0)
+}
+
+%foo = @fragment func():Output -> %b1 {
+ %b1 = block {
+ %2:Output = construct 0.25f, 0.75f
+ ret %2
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+Output = struct @align(4) {
+ color1:f32 @offset(0)
+ color2:f32 @offset(4)
+}
+
+%b1 = block { # root
+ %foo_loc0_idx0_Output:ptr<__out, f32, write> = var @location(0) @index(0)
+ %foo_loc0_idx1_Output:ptr<__out, f32, write> = var @location(0) @index(1)
+}
+
+%foo_inner = func():Output -> %b2 {
+ %b2 = block {
+ %4:Output = construct 0.25f, 0.75f
+ ret %4
+ }
+}
+%foo = @fragment func():void -> %b3 {
+ %b3 = block {
+ %6:Output = call %foo_inner
+ %7:f32 = access %6, 0u
+ store %foo_loc0_idx0_Output, %7
+ %8:f32 = access %6, 1u
+ store %foo_loc0_idx1_Output, %8
+ ret
+ }
+}
+)";
+
+ ShaderIOConfig config;
+ config.clamp_frag_depth = false;
+ Run(ShaderIO, config);
+
+ EXPECT_EQ(expect, str());
+}
+
TEST_F(SpirvWriter_ShaderIOTest, Struct_SharedByVertexAndFragment) {
auto* vec4f = ty.vec4<f32>();
auto* str_ty = ty.Struct(mod.symbols.New("Interface"),