Rename builtin(frag_coord) to builtin(position) Use the variable storage class to determine the correct builtin to use in the SPIR-V generator. Added a deprecation warning for frag_coord. Bug: tint:714 Change-Id: I5ad4956f9345e2f39f4af16e84668dec345ac82e Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47742 Auto-Submit: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/ast/builtin.h b/src/ast/builtin.h index 0e8151d..3806e44 100644 --- a/src/ast/builtin.h +++ b/src/ast/builtin.h
@@ -27,7 +27,7 @@ kVertexIndex, kInstanceIndex, kFrontFacing, - kFragCoord, + kFragCoord, // TODO(crbug.com/tint/714): Remove this kFragDepth, kLocalInvocationId, kLocalInvocationIndex,
diff --git a/src/reader/spirv/enum_converter.cc b/src/reader/spirv/enum_converter.cc index bfdb4fb..15491eb 100644 --- a/src/reader/spirv/enum_converter.cc +++ b/src/reader/spirv/enum_converter.cc
@@ -77,7 +77,7 @@ case SpvBuiltInFrontFacing: return ast::Builtin::kFrontFacing; case SpvBuiltInFragCoord: - return ast::Builtin::kFragCoord; + return ast::Builtin::kPosition; case SpvBuiltInFragDepth: return ast::Builtin::kFragDepth; case SpvBuiltInLocalInvocationId:
diff --git a/src/reader/spirv/enum_converter_test.cc b/src/reader/spirv/enum_converter_test.cc index 670e63d..7011216 100644 --- a/src/reader/spirv/enum_converter_test.cc +++ b/src/reader/spirv/enum_converter_test.cc
@@ -214,7 +214,7 @@ BuiltinCase{SpvBuiltInFrontFacing, ast::StorageClass::kInput, true, ast::Builtin::kFrontFacing}, BuiltinCase{SpvBuiltInFragCoord, ast::StorageClass::kInput, true, - ast::Builtin::kFragCoord}, + ast::Builtin::kPosition}, BuiltinCase{SpvBuiltInLocalInvocationId, ast::StorageClass::kInput, true, ast::Builtin::kLocalInvocationId}, BuiltinCase{SpvBuiltInLocalInvocationIndex, ast::StorageClass::kInput,
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc index c873095..923053c 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc
@@ -1379,6 +1379,10 @@ if (builtin == ast::Builtin::kNone) return add_error(ident.source, "invalid value for builtin decoration"); + if (builtin == ast::Builtin::kFragCoord) { + deprecated(ident.source, "use 'position' instead of 'frag_coord'"); + } + return {builtin, ident.source}; }
diff --git a/src/reader/wgsl/parser_impl_param_list_test.cc b/src/reader/wgsl/parser_impl_param_list_test.cc index c581145..4949c38 100644 --- a/src/reader/wgsl/parser_impl_param_list_test.cc +++ b/src/reader/wgsl/parser_impl_param_list_test.cc
@@ -97,7 +97,7 @@ TEST_F(ParserImplTest, ParamList_Decorations) { auto p = parser( - "[[builtin(frag_coord)]] coord : vec4<f32>, " + "[[builtin(position)]] coord : vec4<f32>, " "[[location(1)]] loc1 : f32"); auto* f32 = p->builder().create<type::F32>(); @@ -115,12 +115,12 @@ ASSERT_EQ(decos0.size(), 1u); EXPECT_TRUE(decos0[0]->Is<ast::BuiltinDecoration>()); EXPECT_EQ(decos0[0]->As<ast::BuiltinDecoration>()->value(), - ast::Builtin::kFragCoord); + ast::Builtin::kPosition); ASSERT_EQ(e.value[0]->source().range.begin.line, 1u); - ASSERT_EQ(e.value[0]->source().range.begin.column, 25u); + ASSERT_EQ(e.value[0]->source().range.begin.column, 23u); ASSERT_EQ(e.value[0]->source().range.end.line, 1u); - ASSERT_EQ(e.value[0]->source().range.end.column, 30u); + ASSERT_EQ(e.value[0]->source().range.end.column, 28u); EXPECT_EQ(e.value[1]->symbol(), p->builder().Symbols().Get("loc1")); EXPECT_EQ(e.value[1]->declared_type(), f32); @@ -131,9 +131,9 @@ EXPECT_EQ(decos1[0]->As<ast::LocationDecoration>()->value(), 1u); ASSERT_EQ(e.value[1]->source().range.begin.line, 1u); - ASSERT_EQ(e.value[1]->source().range.begin.column, 60u); + ASSERT_EQ(e.value[1]->source().range.begin.column, 58u); ASSERT_EQ(e.value[1]->source().range.end.line, 1u); - ASSERT_EQ(e.value[1]->source().range.end.column, 64u); + ASSERT_EQ(e.value[1]->source().range.end.column, 62u); } } // namespace
diff --git a/src/reader/wgsl/parser_impl_variable_decoration_test.cc b/src/reader/wgsl/parser_impl_variable_decoration_test.cc index 4f4f6af..ea44069 100644 --- a/src/reader/wgsl/parser_impl_variable_decoration_test.cc +++ b/src/reader/wgsl/parser_impl_variable_decoration_test.cc
@@ -305,6 +305,28 @@ "1:7: expected signed integer literal for group decoration"); } +TEST_F(ParserImplTest, Decoration_FragCoord_Deprecated) { + auto p = parser("builtin(frag_coord)"); + auto deco = p->decoration(); + EXPECT_TRUE(deco.matched); + EXPECT_FALSE(deco.errored); + ASSERT_NE(deco.value, nullptr); + auto* var_deco = deco.value->As<ast::Decoration>(); + ASSERT_NE(var_deco, nullptr); + ASSERT_FALSE(p->has_error()); + ASSERT_TRUE(var_deco->Is<ast::BuiltinDecoration>()); + + auto* builtin = var_deco->As<ast::BuiltinDecoration>(); + EXPECT_EQ(builtin->value(), ast::Builtin::kFragCoord); + + EXPECT_EQ( + p->builder().Diagnostics().str(), + R"(test.wgsl:1:9 warning: use of deprecated language feature: use 'position' instead of 'frag_coord' +builtin(frag_coord) + ^^^^^^^^^^ +)"); +} + } // namespace } // namespace wgsl } // namespace reader
diff --git a/src/transform/canonicalize_entry_point_io.h b/src/transform/canonicalize_entry_point_io.h index 479cd0c..4298459 100644 --- a/src/transform/canonicalize_entry_point_io.h +++ b/src/transform/canonicalize_entry_point_io.h
@@ -34,7 +34,7 @@ /// }; /// /// [[stage(fragment)]] -/// fn frag_main([[builtin(frag_coord)]] coord : vec4<f32>, +/// fn frag_main([[builtin(position)]] coord : vec4<f32>, /// locations : Locations) -> [[location(0)]] f32 { /// var col : f32 = (coord.x * locations.loc1); /// return col; @@ -49,7 +49,7 @@ /// }; /// /// struct frag_main_in { -/// [[builtin(frag_coord)]] coord : vec4<f32>; +/// [[builtin(position)]] coord : vec4<f32>; /// [[location(1)]] loc1 : f32; /// [[location(2)]] loc2 : vec4<u32> /// };
diff --git a/src/transform/canonicalize_entry_point_io_test.cc b/src/transform/canonicalize_entry_point_io_test.cc index ba7b827..923a06f 100644 --- a/src/transform/canonicalize_entry_point_io_test.cc +++ b/src/transform/canonicalize_entry_point_io_test.cc
@@ -25,7 +25,7 @@ TEST_F(CanonicalizeEntryPointIOTest, Parameters) { auto* src = R"( [[stage(fragment)]] -fn frag_main([[builtin(frag_coord)]] coord : vec4<f32>, +fn frag_main([[builtin(position)]] coord : vec4<f32>, [[location(1)]] loc1 : f32, [[location(2)]] loc2 : vec4<u32>) { var col : f32 = (coord.x * loc1); @@ -34,7 +34,7 @@ auto* expect = R"( struct tint_symbol_1 { - [[builtin(frag_coord)]] + [[builtin(position)]] coord : vec4<f32>; [[location(1)]] loc1 : f32; @@ -89,7 +89,7 @@ TEST_F(CanonicalizeEntryPointIOTest, Parameters_EmptyBody) { auto* src = R"( [[stage(fragment)]] -fn frag_main([[builtin(frag_coord)]] coord : vec4<f32>, +fn frag_main([[builtin(position)]] coord : vec4<f32>, [[location(1)]] loc1 : f32, [[location(2)]] loc2 : vec4<u32>) { } @@ -97,7 +97,7 @@ auto* expect = R"( struct tint_symbol_1 { - [[builtin(frag_coord)]] + [[builtin(position)]] coord : vec4<f32>; [[location(1)]] loc1 : f32; @@ -118,7 +118,7 @@ TEST_F(CanonicalizeEntryPointIOTest, StructParameters) { auto* src = R"( struct FragBuiltins { - [[builtin(frag_coord)]] coord : vec4<f32>; + [[builtin(position)]] coord : vec4<f32>; }; struct FragLocations { [[location(1)]] loc1 : f32; @@ -144,7 +144,7 @@ }; struct tint_symbol_1 { - [[builtin(frag_coord)]] + [[builtin(position)]] coord : vec4<f32>; [[location(1)]] loc1 : f32; @@ -451,7 +451,7 @@ [[block]] struct FragmentInput { [[size(16), location(1)]] value : f32; - [[builtin(frag_coord)]] [[align(32)]] coord : vec4<f32>; + [[builtin(position)]] [[align(32)]] coord : vec4<f32>; }; struct FragmentOutput { @@ -481,7 +481,7 @@ struct tint_symbol_1 { [[location(1)]] value : f32; - [[builtin(frag_coord)]] + [[builtin(position)]] coord : vec4<f32>; };
diff --git a/src/transform/spirv.cc b/src/transform/spirv.cc index 6adc931..4e0bed9 100644 --- a/src/transform/spirv.cc +++ b/src/transform/spirv.cc
@@ -68,7 +68,7 @@ // // [[stage(fragment)]] // fn frag_main( - // [[builtin(frag_coord)]] coord : vec4<f32>, + // [[builtin(position)]] coord : vec4<f32>, // samples : FragmentInput // ) -> FragmentOutput { // var output : FragmentOutput = FragmentOutput(1.0, @@ -88,7 +88,7 @@ // mask_out : u32; // }; // - // [[builtin(frag_coord)]] var<in> coord : vec4<f32>, + // [[builtin(position)]] var<in> coord : vec4<f32>, // [[builtin(sample_index)]] var<in> sample_index : u32, // [[builtin(sample_mask_in)]] var<in> sample_mask_in : u32, // [[builtin(frag_depth)]] var<out> depth: f32;
diff --git a/src/transform/spirv_test.cc b/src/transform/spirv_test.cc index f784435..45e0128 100644 --- a/src/transform/spirv_test.cc +++ b/src/transform/spirv_test.cc
@@ -25,7 +25,7 @@ TEST_F(SpirvTest, HandleEntryPointIOTypes_Parameters) { auto* src = R"( [[stage(fragment)]] -fn frag_main([[builtin(frag_coord)]] coord : vec4<f32>, +fn frag_main([[builtin(position)]] coord : vec4<f32>, [[location(1)]] loc1 : f32) { var col : f32 = (coord.x * loc1); } @@ -38,7 +38,7 @@ )"; auto* expect = R"( -[[builtin(frag_coord)]] var<in> tint_symbol : vec4<f32>; +[[builtin(position)]] var<in> tint_symbol : vec4<f32>; [[location(1)]] var<in> tint_symbol_1 : f32; @@ -192,7 +192,7 @@ TEST_F(SpirvTest, HandleEntryPointIOTypes_StructParameters) { auto* src = R"( struct FragmentInput { - [[builtin(frag_coord)]] coord : vec4<f32>; + [[builtin(position)]] coord : vec4<f32>; [[location(1)]] value : f32; }; @@ -208,7 +208,7 @@ value : f32; }; -[[builtin(frag_coord)]] var<in> tint_symbol : vec4<f32>; +[[builtin(position)]] var<in> tint_symbol : vec4<f32>; [[location(1)]] var<in> tint_symbol_1 : f32; @@ -392,7 +392,7 @@ [[block]] struct FragmentInput { [[size(16), location(1)]] value : f32; - [[builtin(frag_coord)]] [[align(32)]] coord : vec4<f32>; + [[builtin(position)]] [[align(32)]] coord : vec4<f32>; }; struct FragmentOutput { @@ -421,7 +421,7 @@ [[location(1)]] var<in> tint_symbol : f32; -[[builtin(frag_coord)]] var<in> tint_symbol_1 : vec4<f32>; +[[builtin(position)]] var<in> tint_symbol_1 : vec4<f32>; [[location(1)]] var<out> tint_symbol_4 : f32;
diff --git a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc index 2c65dc4..acaef38 100644 --- a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc +++ b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
@@ -268,7 +268,7 @@ TEST_F(HlslGeneratorImplTest_EntryPoint, Emit_Function_EntryPointData_Builtins) { - // [[builtin frag_coord]] var<in> coord : vec4<f32>; + // [[builtin position]] var<in> coord : vec4<f32>; // [[builtin frag_depth]] var<out> depth : f32; // // struct main_in { @@ -281,7 +281,7 @@ Global("coord", ty.vec4<f32>(), ast::StorageClass::kInput, nullptr, ast::DecorationList{ - create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord), + create<ast::BuiltinDecoration>(ast::Builtin::kPosition), }); Global("depth", ty.f32(), ast::StorageClass::kOutput, nullptr,
diff --git a/src/writer/hlsl/generator_impl_function_test.cc b/src/writer/hlsl/generator_impl_function_test.cc index 0282d72..37af244 100644 --- a/src/writer/hlsl/generator_impl_function_test.cc +++ b/src/writer/hlsl/generator_impl_function_test.cc
@@ -144,7 +144,7 @@ // } auto* coord_in = Param("coord", ty.vec4<f32>(), - {create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord)}); + {create<ast::BuiltinDecoration>(ast::Builtin::kPosition)}); Func("frag_main", ast::VariableList{coord_in}, ty.f32(), {create<ast::ReturnStatement>(MemberAccessor("coord", "x"))}, {create<ast::StageDecoration>(ast::PipelineStage::kFragment)}, @@ -675,7 +675,7 @@ Emit_Decoration_Called_By_EntryPoints_WithBuiltinGlobals_And_Params) { // NOLINT Global("coord", ty.vec4<f32>(), ast::StorageClass::kInput, nullptr, ast::DecorationList{ - create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord), + create<ast::BuiltinDecoration>(ast::Builtin::kPosition), }); Global("depth", ty.f32(), ast::StorageClass::kOutput, nullptr,
diff --git a/src/writer/msl/generator_impl_function_entry_point_data_test.cc b/src/writer/msl/generator_impl_function_entry_point_data_test.cc index fa22462..46bf201 100644 --- a/src/writer/msl/generator_impl_function_entry_point_data_test.cc +++ b/src/writer/msl/generator_impl_function_entry_point_data_test.cc
@@ -234,7 +234,7 @@ // Output builtins go in the output struct, input builtins will be passed // as input parameters to the entry point function. - // [[builtin frag_coord]] var<in> coord : vec4<f32>; + // [[builtin position]] var<in> coord : vec4<f32>; // [[builtin frag_depth]] var<out> depth : f32; // // struct main_out { @@ -243,7 +243,7 @@ Global("coord", ty.vec4<f32>(), ast::StorageClass::kInput, nullptr, ast::DecorationList{ - create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord)}); + create<ast::BuiltinDecoration>(ast::Builtin::kPosition)}); Global("depth", ty.f32(), ast::StorageClass::kOutput, nullptr, ast::DecorationList{
diff --git a/src/writer/msl/generator_impl_function_test.cc b/src/writer/msl/generator_impl_function_test.cc index 406df03..87001b3 100644 --- a/src/writer/msl/generator_impl_function_test.cc +++ b/src/writer/msl/generator_impl_function_test.cc
@@ -129,7 +129,7 @@ // } auto* coord_in = Param("coord", ty.vec4<f32>(), - {create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord)}); + {create<ast::BuiltinDecoration>(ast::Builtin::kPosition)}); Func("frag_main", ast::VariableList{coord_in}, ty.f32(), {create<ast::ReturnStatement>(MemberAccessor("coord", "x"))}, {create<ast::StageDecoration>(ast::PipelineStage::kFragment)}, @@ -496,7 +496,7 @@ Emit_Decoration_Called_By_EntryPoints_WithBuiltinGlobals_And_Params) { // NOLINT Global("coord", ty.vec4<f32>(), ast::StorageClass::kInput, nullptr, ast::DecorationList{ - create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord)}); + create<ast::BuiltinDecoration>(ast::Builtin::kPosition)}); Global("depth", ty.f32(), ast::StorageClass::kOutput, nullptr, ast::DecorationList{
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 69a0361..50278ca 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc
@@ -788,7 +788,8 @@ if (auto* builtin = deco->As<ast::BuiltinDecoration>()) { push_annot(spv::Op::OpDecorate, {Operand::Int(var_id), Operand::Int(SpvDecorationBuiltIn), - Operand::Int(ConvertBuiltin(builtin->value()))}); + Operand::Int(ConvertBuiltin(builtin->value(), + var->declared_storage_class()))}); } else if (auto* location = deco->As<ast::LocationDecoration>()) { push_annot(spv::Op::OpDecorate, {Operand::Int(var_id), Operand::Int(SpvDecorationLocation), @@ -3274,10 +3275,18 @@ return SpvStorageClassMax; } -SpvBuiltIn Builder::ConvertBuiltin(ast::Builtin builtin) { +SpvBuiltIn Builder::ConvertBuiltin(ast::Builtin builtin, + ast::StorageClass storage) { switch (builtin) { case ast::Builtin::kPosition: - return SpvBuiltInPosition; + if (storage == ast::StorageClass::kInput) { + return SpvBuiltInFragCoord; + } else if (storage == ast::StorageClass::kOutput) { + return SpvBuiltInPosition; + } else { + TINT_ICE(builder_.Diagnostics()) << "invalid storage class for builtin"; + break; + } case ast::Builtin::kVertexIndex: return SpvBuiltInVertexIndex; case ast::Builtin::kInstanceIndex:
diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h index f254dc6..16b25e9 100644 --- a/src/writer/spirv/builder.h +++ b/src/writer/spirv/builder.h
@@ -204,8 +204,9 @@ SpvStorageClass ConvertStorageClass(ast::StorageClass klass) const; /// Converts a builtin to a SPIR-V builtin and pushes a capability if needed. /// @param builtin the builtin to convert + /// @param storage the storage class that this builtin is being used with /// @returns the SPIR-V builtin or SpvBuiltInMax on error. - SpvBuiltIn ConvertBuiltin(ast::Builtin builtin); + SpvBuiltIn ConvertBuiltin(ast::Builtin builtin, ast::StorageClass storage); /// Generates a label for the given id. Emits an error and returns false if /// we're currently outside a function.
diff --git a/src/writer/spirv/builder_entry_point_test.cc b/src/writer/spirv/builder_entry_point_test.cc index 41f52c2..3e02d1a 100644 --- a/src/writer/spirv/builder_entry_point_test.cc +++ b/src/writer/spirv/builder_entry_point_test.cc
@@ -38,15 +38,14 @@ TEST_F(BuilderTest, EntryPoint_Parameters) { // [[stage(fragment)]] - // fn frag_main([[builtin(frag_coord)]] coord : vec4<f32>, + // fn frag_main([[builtin(position)]] coord : vec4<f32>, // [[location(1)]] loc1 : f32) { // var col : f32 = (coord.x * loc1); // } auto* f32 = ty.f32(); auto* vec4 = ty.vec4<float>(); - auto* coord = - Param("coord", vec4, - {create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord)}); + auto* coord = Param( + "coord", vec4, {create<ast::BuiltinDecoration>(ast::Builtin::kPosition)}); auto* loc1 = Param("loc1", f32, {create<ast::LocationDecoration>(1u)}); auto* mul = Mul(Expr(MemberAccessor("coord", "x")), Expr("loc1")); auto* col = Var("col", f32, ast::StorageClass::kFunction, mul, {}); @@ -180,11 +179,12 @@ TEST_F(BuilderTest, EntryPoint_SharedStruct) { // struct Interface { // [[location(1)]] value : f32; + // [[builtin(position)]] pos : vec4<f32>; // }; // // [[stage(vertex)]] // fn vert_main() -> Interface { - // return Interface(42.0); + // return Interface(42.0, vec4<f32>()); // } // // [[stage(fragment)]] @@ -194,10 +194,13 @@ auto* interface = Structure( "Interface", - {Member("value", ty.f32(), - ast::DecorationList{create<ast::LocationDecoration>(1u)})}); + { + Member("value", ty.f32(), ast::DecorationList{Location(1u)}), + Member("pos", ty.vec4<f32>(), + ast::DecorationList{Builtin(ast::Builtin::kPosition)}), + }); - auto* vert_retval = Construct(interface, 42.f); + auto* vert_retval = Construct(interface, 42.f, Construct(ty.vec4<f32>())); Func("vert_main", ast::VariableList{}, interface, {create<ast::ReturnStatement>(vert_retval)}, {create<ast::StageDecoration>(ast::PipelineStage::kVertex)}); @@ -214,63 +217,78 @@ EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %16 "vert_main" %1 -OpEntryPoint Fragment %25 "frag_main" %5 %7 -OpExecutionMode %25 OriginUpperLeft -OpExecutionMode %25 DepthReplacing +OpEntryPoint Vertex %23 "vert_main" %1 %5 +OpEntryPoint Fragment %32 "frag_main" %9 %11 %13 +OpExecutionMode %32 OriginUpperLeft +OpExecutionMode %32 DepthReplacing OpName %1 "tint_symbol_1" -OpName %5 "tint_symbol_3" -OpName %7 "tint_symbol_6" -OpName %10 "Interface" -OpMemberName %10 0 "value" -OpName %11 "tint_symbol_2" -OpName %12 "tint_symbol" -OpName %16 "vert_main" -OpName %22 "tint_symbol_7" -OpName %23 "tint_symbol_5" -OpName %25 "frag_main" +OpName %5 "tint_symbol_2" +OpName %9 "tint_symbol_4" +OpName %11 "tint_symbol_5" +OpName %13 "tint_symbol_8" +OpName %16 "Interface" +OpMemberName %16 0 "value" +OpMemberName %16 1 "pos" +OpName %17 "tint_symbol_3" +OpName %18 "tint_symbol" +OpName %23 "vert_main" +OpName %29 "tint_symbol_9" +OpName %30 "tint_symbol_7" +OpName %32 "frag_main" OpDecorate %1 Location 1 -OpDecorate %5 Location 1 -OpDecorate %7 BuiltIn FragDepth -OpMemberDecorate %10 0 Offset 0 +OpDecorate %5 BuiltIn Position +OpDecorate %9 Location 1 +OpDecorate %11 BuiltIn FragCoord +OpDecorate %13 BuiltIn FragDepth +OpMemberDecorate %16 0 Offset 0 +OpMemberDecorate %16 1 Offset 16 %3 = OpTypeFloat 32 %2 = OpTypePointer Output %3 %4 = OpConstantNull %3 %1 = OpVariable %2 Output %4 -%6 = OpTypePointer Input %3 -%5 = OpVariable %6 Input -%7 = OpVariable %2 Output %4 -%9 = OpTypeVoid -%10 = OpTypeStruct %3 -%8 = OpTypeFunction %9 %10 -%15 = OpTypeFunction %9 -%19 = OpConstant %3 42 -%20 = OpConstantComposite %10 %19 -%21 = OpTypeFunction %9 %3 -%11 = OpFunction %9 None %8 -%12 = OpFunctionParameter %10 -%13 = OpLabel -%14 = OpCompositeExtract %3 %12 0 -OpStore %1 %14 +%7 = OpTypeVector %3 4 +%6 = OpTypePointer Output %7 +%8 = OpConstantNull %7 +%5 = OpVariable %6 Output %8 +%10 = OpTypePointer Input %3 +%9 = OpVariable %10 Input +%12 = OpTypePointer Input %7 +%11 = OpVariable %12 Input +%13 = OpVariable %2 Output %4 +%15 = OpTypeVoid +%16 = OpTypeStruct %3 %7 +%14 = OpTypeFunction %15 %16 +%22 = OpTypeFunction %15 +%26 = OpConstant %3 42 +%27 = OpConstantComposite %16 %26 %8 +%28 = OpTypeFunction %15 %3 +%17 = OpFunction %15 None %14 +%18 = OpFunctionParameter %16 +%19 = OpLabel +%20 = OpCompositeExtract %3 %18 0 +OpStore %1 %20 +%21 = OpCompositeExtract %7 %18 1 +OpStore %5 %21 OpReturn OpFunctionEnd -%16 = OpFunction %9 None %15 -%17 = OpLabel -%18 = OpFunctionCall %9 %11 %20 -OpReturn -OpFunctionEnd -%22 = OpFunction %9 None %21 -%23 = OpFunctionParameter %3 +%23 = OpFunction %15 None %22 %24 = OpLabel -OpStore %7 %23 +%25 = OpFunctionCall %15 %17 %27 OpReturn OpFunctionEnd -%25 = OpFunction %9 None %15 -%26 = OpLabel -%27 = OpLoad %3 %5 -%28 = OpCompositeConstruct %10 %27 -%30 = OpCompositeExtract %3 %28 0 -%29 = OpFunctionCall %9 %22 %30 +%29 = OpFunction %15 None %28 +%30 = OpFunctionParameter %3 +%31 = OpLabel +OpStore %13 %30 +OpReturn +OpFunctionEnd +%32 = OpFunction %15 None %22 +%33 = OpLabel +%34 = OpLoad %3 %9 +%35 = OpLoad %7 %11 +%36 = OpCompositeConstruct %16 %34 %35 +%38 = OpCompositeExtract %3 %36 0 +%37 = OpFunctionCall %15 %29 %38 OpReturn OpFunctionEnd )");
diff --git a/src/writer/spirv/builder_global_variable_test.cc b/src/writer/spirv/builder_global_variable_test.cc index 464b69c..3b63687 100644 --- a/src/writer/spirv/builder_global_variable_test.cc +++ b/src/writer/spirv/builder_global_variable_test.cc
@@ -324,6 +324,7 @@ struct BuiltinData { ast::Builtin builtin; + ast::StorageClass storage; SpvBuiltIn result; }; inline std::ostream& operator<<(std::ostream& out, BuiltinData data) { @@ -336,31 +337,43 @@ spirv::Builder& b = Build(); - EXPECT_EQ(b.ConvertBuiltin(params.builtin), params.result); + EXPECT_EQ(b.ConvertBuiltin(params.builtin, params.storage), params.result); } INSTANTIATE_TEST_SUITE_P( BuilderTest_Type, BuiltinDataTest, testing::Values( - BuiltinData{ast::Builtin::kNone, SpvBuiltInMax}, - BuiltinData{ast::Builtin::kPosition, SpvBuiltInPosition}, + BuiltinData{ast::Builtin::kNone, ast::StorageClass::kNone, + SpvBuiltInMax}, + BuiltinData{ast::Builtin::kPosition, ast::StorageClass::kInput, + SpvBuiltInFragCoord}, + BuiltinData{ast::Builtin::kPosition, ast::StorageClass::kOutput, + SpvBuiltInPosition}, BuiltinData{ ast::Builtin::kVertexIndex, + ast::StorageClass::kInput, SpvBuiltInVertexIndex, }, - BuiltinData{ast::Builtin::kInstanceIndex, SpvBuiltInInstanceIndex}, - BuiltinData{ast::Builtin::kFrontFacing, SpvBuiltInFrontFacing}, - BuiltinData{ast::Builtin::kFragCoord, SpvBuiltInFragCoord}, - BuiltinData{ast::Builtin::kFragDepth, SpvBuiltInFragDepth}, - BuiltinData{ast::Builtin::kLocalInvocationId, + BuiltinData{ast::Builtin::kInstanceIndex, ast::StorageClass::kInput, + SpvBuiltInInstanceIndex}, + BuiltinData{ast::Builtin::kFrontFacing, ast::StorageClass::kInput, + SpvBuiltInFrontFacing}, + BuiltinData{ast::Builtin::kFragCoord, ast::StorageClass::kInput, + SpvBuiltInFragCoord}, + BuiltinData{ast::Builtin::kFragDepth, ast::StorageClass::kOutput, + SpvBuiltInFragDepth}, + BuiltinData{ast::Builtin::kLocalInvocationId, ast::StorageClass::kInput, SpvBuiltInLocalInvocationId}, BuiltinData{ast::Builtin::kLocalInvocationIndex, - SpvBuiltInLocalInvocationIndex}, + ast::StorageClass::kInput, SpvBuiltInLocalInvocationIndex}, BuiltinData{ast::Builtin::kGlobalInvocationId, - SpvBuiltInGlobalInvocationId}, - BuiltinData{ast::Builtin::kSampleIndex, SpvBuiltInSampleId}, - BuiltinData{ast::Builtin::kSampleMaskIn, SpvBuiltInSampleMask}, - BuiltinData{ast::Builtin::kSampleMaskOut, SpvBuiltInSampleMask})); + ast::StorageClass::kInput, SpvBuiltInGlobalInvocationId}, + BuiltinData{ast::Builtin::kSampleIndex, ast::StorageClass::kInput, + SpvBuiltInSampleId}, + BuiltinData{ast::Builtin::kSampleMaskIn, ast::StorageClass::kInput, + SpvBuiltInSampleMask}, + BuiltinData{ast::Builtin::kSampleMaskOut, ast::StorageClass::kOutput, + SpvBuiltInSampleMask})); TEST_F(BuilderTest, GlobalVar_DeclReadOnly) { // struct A {
diff --git a/src/writer/wgsl/generator_impl_function_test.cc b/src/writer/wgsl/generator_impl_function_test.cc index 98f3a8d..05bc689 100644 --- a/src/writer/wgsl/generator_impl_function_test.cc +++ b/src/writer/wgsl/generator_impl_function_test.cc
@@ -143,9 +143,8 @@ TEST_F(WgslGeneratorImplTest, Emit_Function_EntryPoint_Parameters) { auto* vec4 = ty.vec4<f32>(); - auto* coord = - Param("coord", vec4, - {create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord)}); + auto* coord = Param( + "coord", vec4, {create<ast::BuiltinDecoration>(ast::Builtin::kPosition)}); auto* loc1 = Param("loc1", ty.f32(), {create<ast::LocationDecoration>(1u)}); auto* func = Func("frag_main", ast::VariableList{coord, loc1}, ty.void_(), @@ -160,7 +159,7 @@ ASSERT_TRUE(gen.EmitFunction(func)); EXPECT_EQ(gen.result(), R"( [[stage(fragment)]] - fn frag_main([[builtin(frag_coord)]] coord : vec4<f32>, [[location(1)]] loc1 : f32) { + fn frag_main([[builtin(position)]] coord : vec4<f32>, [[location(1)]] loc1 : f32) { } )"); }