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.
|
||||
- Original input variables are mapped to pseudo-in Private variables
|
||||
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
|
||||
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
|
||||
and builtin attributes the original input variables, and whose return type is
|
||||
a structure containing members correspond in type, location, and builtin
|
||||
attributes to the original output variables.
|
||||
The body of the wrapper function the following phases:
|
||||
- Copy formal parameter values into pseudo-in variables.
|
||||
- Use stores to initialize pseudo-out variables:
|
||||
- If the original variable had an initializer, store that value.
|
||||
- Otherwise, store a zero value for the store type.
|
||||
- Insert a bitcast if the WGSL builtin variable has different signedness
|
||||
from the SPIR-V declared type.
|
||||
- Execute the inner function.
|
||||
- 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.
|
||||
|
||||
- Replace uses of the the original input/output variables to the pseudo-in and
|
||||
|
|
|
@ -957,6 +957,8 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||
continue;
|
||||
}
|
||||
|
||||
// In Vulkan SPIR-V, Input variables must not have an initializer.
|
||||
|
||||
const auto var_name = namer_.GetName(var_id);
|
||||
const auto var_sym = builder_.Symbols().Register(var_name);
|
||||
const auto param_name = namer_.MakeDerivedName(var_name + "_param");
|
||||
|
|
|
@ -80,6 +80,7 @@ std::string CommonTypes() {
|
|||
%float_1p5 = OpConstant %float 1.5
|
||||
%uint_1 = OpConstant %uint 1
|
||||
%int_m1 = OpConstant %int -1
|
||||
%int_14 = OpConstant %int 14
|
||||
%uint_2 = OpConstant %uint 2
|
||||
|
||||
%v2bool = OpTypeVector %bool 2
|
||||
|
@ -4018,6 +4019,157 @@ TEST_F(SpvModuleScopeVarParserTest, OutputVarsConvertedToPrivate) {
|
|||
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) {
|
||||
const auto assembly = CommonCapabilities() + R"(
|
||||
OpEntryPoint Vertex %main "main" %1 %2 %3 %4
|
||||
|
@ -4136,6 +4288,12 @@ TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) {
|
|||
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,
|
||||
// both input case and output case.
|
||||
|
||||
|
|
Loading…
Reference in New Issue