spirv-reader: builtin in/out keep their signedness as private vars
Update the plan for pipeline I/O. Bug: tint:508 Change-Id: I263d954403134a78106b3372ec9df3d9d868ef1d Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54462 Auto-Submit: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: David Neto <dneto@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
27067f5c1e
commit
ba403cdf8f
|
@ -36,19 +36,22 @@ inputs and outputs, and two functions:
|
||||||
is the same as the original SPIR-V entry point.
|
is the same as the original SPIR-V entry point.
|
||||||
- Original input variables are mapped to pseudo-in Private variables
|
- Original input variables are mapped to pseudo-in Private variables
|
||||||
with the same store types, but no other attributes or properties copied.
|
with the same store types, but no other attributes or properties copied.
|
||||||
|
In Vulkan, Input variables don't have initalizers.
|
||||||
- Original output variables are mapped to pseudo-out Private variables
|
- Original output variables are mapped to pseudo-out Private variables
|
||||||
with the same store types, but no other attributes or properties are copied.
|
with the same store types and optional initializer, but no other attributes
|
||||||
|
or properties are copied.
|
||||||
- A wrapper entry point function whose arguments correspond in type, location
|
- A wrapper entry point function whose arguments correspond in type, location
|
||||||
and builtin attributes the original input variables, and whose return type is
|
and builtin attributes the original input variables, and whose return type is
|
||||||
a structure containing members correspond in type, location, and builtin
|
a structure containing members correspond in type, location, and builtin
|
||||||
attributes to the original output variables.
|
attributes to the original output variables.
|
||||||
The body of the wrapper function the following phases:
|
The body of the wrapper function the following phases:
|
||||||
- Copy formal parameter values into pseudo-in variables.
|
- Copy formal parameter values into pseudo-in variables.
|
||||||
- Use stores to initialize pseudo-out variables:
|
- Insert a bitcast if the WGSL builtin variable has different signedness
|
||||||
- If the original variable had an initializer, store that value.
|
from the SPIR-V declared type.
|
||||||
- Otherwise, store a zero value for the store type.
|
|
||||||
- Execute the inner function.
|
- Execute the inner function.
|
||||||
- Copy pseudo-out variables into the return structure.
|
- Copy pseudo-out variables into the return structure.
|
||||||
|
- Insert a bitcast if the WGSL builtin variable has different signedness
|
||||||
|
from the SPIR-V declared type.
|
||||||
- Return the return structure.
|
- Return the return structure.
|
||||||
|
|
||||||
- Replace uses of the the original input/output variables to the pseudo-in and
|
- Replace uses of the the original input/output variables to the pseudo-in and
|
||||||
|
|
|
@ -957,6 +957,8 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In Vulkan SPIR-V, Input variables must not have an initializer.
|
||||||
|
|
||||||
const auto var_name = namer_.GetName(var_id);
|
const auto var_name = namer_.GetName(var_id);
|
||||||
const auto var_sym = builder_.Symbols().Register(var_name);
|
const auto var_sym = builder_.Symbols().Register(var_name);
|
||||||
const auto param_name = namer_.MakeDerivedName(var_name + "_param");
|
const auto param_name = namer_.MakeDerivedName(var_name + "_param");
|
||||||
|
|
|
@ -80,6 +80,7 @@ std::string CommonTypes() {
|
||||||
%float_1p5 = OpConstant %float 1.5
|
%float_1p5 = OpConstant %float 1.5
|
||||||
%uint_1 = OpConstant %uint 1
|
%uint_1 = OpConstant %uint 1
|
||||||
%int_m1 = OpConstant %int -1
|
%int_m1 = OpConstant %int -1
|
||||||
|
%int_14 = OpConstant %int 14
|
||||||
%uint_2 = OpConstant %uint 2
|
%uint_2 = OpConstant %uint 2
|
||||||
|
|
||||||
%v2bool = OpTypeVector %bool 2
|
%v2bool = OpTypeVector %bool 2
|
||||||
|
@ -4018,6 +4019,157 @@ TEST_F(SpvModuleScopeVarParserTest, OutputVarsConvertedToPrivate) {
|
||||||
EXPECT_THAT(got, HasSubstr(expected)) << got;
|
EXPECT_THAT(got, HasSubstr(expected)) << got;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvModuleScopeVarParserTest,
|
||||||
|
OutputVarsConvertedToPrivate_WithInitializer) {
|
||||||
|
const auto assembly = Preamble() + FragMain() + CommonTypes() + R"(
|
||||||
|
%ptr_out_uint = OpTypePointer Output %uint
|
||||||
|
%1 = OpVariable %ptr_out_uint Output %uint_1
|
||||||
|
)" + MainBody();
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/508): Remove this when everything is converted
|
||||||
|
// to HLSL style pipeline IO.
|
||||||
|
p->SetHLSLStylePipelineIO();
|
||||||
|
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto got = p->program().to_str();
|
||||||
|
const std::string expected =
|
||||||
|
R"(Variable{
|
||||||
|
x_1
|
||||||
|
private
|
||||||
|
undefined
|
||||||
|
__u32
|
||||||
|
{
|
||||||
|
ScalarConstructor[not set]{1u}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
EXPECT_THAT(got, HasSubstr(expected)) << got;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvModuleScopeVarParserTest,
|
||||||
|
Builtin_Output_Initializer_SameSignednessAsWGSL) {
|
||||||
|
// Only outputs can have initializers.
|
||||||
|
// WGSL sample_mask store type is u32.
|
||||||
|
const auto assembly = Preamble() + FragMain() + R"(
|
||||||
|
OpDecorate %1 BuiltIn SampleMask
|
||||||
|
)" + CommonTypes() + R"(
|
||||||
|
%ptr_ty = OpTypePointer Output %uint
|
||||||
|
%1 = OpVariable %ptr_ty Output %uint_1
|
||||||
|
)" + MainBody();
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/508): Remove this when everything is converted
|
||||||
|
// to HLSL style pipeline IO.
|
||||||
|
p->SetHLSLStylePipelineIO();
|
||||||
|
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto got = p->program().to_str();
|
||||||
|
const std::string expected =
|
||||||
|
R"(Variable{
|
||||||
|
x_1
|
||||||
|
private
|
||||||
|
undefined
|
||||||
|
__u32
|
||||||
|
{
|
||||||
|
ScalarConstructor[not set]{1u}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
EXPECT_THAT(got, HasSubstr(expected)) << got;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvModuleScopeVarParserTest,
|
||||||
|
Builtin_Output_Initializer_OppositeSignednessAsWGSL) {
|
||||||
|
// Only outputs can have initializers.
|
||||||
|
// WGSL sample_mask store type is u32. Use i32 in SPIR-V
|
||||||
|
const auto assembly = Preamble() + FragMain() + R"(
|
||||||
|
OpDecorate %1 BuiltIn SampleMask
|
||||||
|
)" + CommonTypes() + R"(
|
||||||
|
%ptr_ty = OpTypePointer Output %int
|
||||||
|
%1 = OpVariable %ptr_ty Output %int_14
|
||||||
|
)" + MainBody();
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/508): Remove this when everything is converted
|
||||||
|
// to HLSL style pipeline IO.
|
||||||
|
p->SetHLSLStylePipelineIO();
|
||||||
|
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto got = p->program().to_str();
|
||||||
|
const std::string expected =
|
||||||
|
R"(Variable{
|
||||||
|
x_1
|
||||||
|
private
|
||||||
|
undefined
|
||||||
|
__i32
|
||||||
|
{
|
||||||
|
ScalarConstructor[not set]{14}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
EXPECT_THAT(got, HasSubstr(expected)) << got;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvModuleScopeVarParserTest, Builtin_Input_SameSignednessAsWGSL) {
|
||||||
|
// WGSL vertex_index store type is u32.
|
||||||
|
const auto assembly = Preamble() + FragMain() + R"(
|
||||||
|
OpDecorate %1 BuiltIn VertexIndex
|
||||||
|
)" + CommonTypes() + R"(
|
||||||
|
%ptr_ty = OpTypePointer Input %uint
|
||||||
|
%1 = OpVariable %ptr_ty Input
|
||||||
|
)" + MainBody();
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/508): Remove this when everything is converted
|
||||||
|
// to HLSL style pipeline IO.
|
||||||
|
p->SetHLSLStylePipelineIO();
|
||||||
|
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto got = p->program().to_str();
|
||||||
|
const std::string expected =
|
||||||
|
R"(Variable{
|
||||||
|
x_1
|
||||||
|
private
|
||||||
|
undefined
|
||||||
|
__u32
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
EXPECT_THAT(got, HasSubstr(expected)) << got;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvModuleScopeVarParserTest, Builtin_Input_OppositeSignednessAsWGSL) {
|
||||||
|
// WGSL vertex_index store type is u32. Use i32 in SPIR-V.
|
||||||
|
const auto assembly = Preamble() + FragMain() + R"(
|
||||||
|
OpDecorate %1 BuiltIn VertexIndex
|
||||||
|
)" + CommonTypes() + R"(
|
||||||
|
%ptr_ty = OpTypePointer Input %int
|
||||||
|
%1 = OpVariable %ptr_ty Input
|
||||||
|
)" + MainBody();
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/508): Remove this when everything is converted
|
||||||
|
// to HLSL style pipeline IO.
|
||||||
|
p->SetHLSLStylePipelineIO();
|
||||||
|
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto got = p->program().to_str();
|
||||||
|
const std::string expected =
|
||||||
|
R"(Variable{
|
||||||
|
x_1
|
||||||
|
private
|
||||||
|
undefined
|
||||||
|
__i32
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
EXPECT_THAT(got, HasSubstr(expected)) << got;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) {
|
TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) {
|
||||||
const auto assembly = CommonCapabilities() + R"(
|
const auto assembly = CommonCapabilities() + R"(
|
||||||
OpEntryPoint Vertex %main "main" %1 %2 %3 %4
|
OpEntryPoint Vertex %main "main" %1 %2 %3 %4
|
||||||
|
@ -4136,6 +4288,12 @@ TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) {
|
||||||
EXPECT_THAT(got, HasSubstr(expected)) << got;
|
EXPECT_THAT(got, HasSubstr(expected)) << got;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(dneto): pipeline IO: convert signedness on builtin inputs in the wrapper
|
||||||
|
// body
|
||||||
|
// TODO(dneto): pipeline IO: convert signedness on builtin outputs in the
|
||||||
|
// wrapper body
|
||||||
|
// TODO(dneto): pipeline IO: flatten structures, and distribute locations
|
||||||
|
|
||||||
// TODO(dneto): Test passing pointer to SampleMask as function parameter,
|
// TODO(dneto): Test passing pointer to SampleMask as function parameter,
|
||||||
// both input case and output case.
|
// both input case and output case.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue