[spirv-writer] First pass at entry point interface

This CL adds the first simple pass at adding interface variables into
the entry point command. It simply lists all Input/Output module scoped
variables onto all entry points.

Bug: tint:28
Change-Id: I962462d783f3b97bb3da32fd9890ceb90808942b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/20963
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
dan sinclair 2020-05-04 19:42:43 +00:00 committed by dan sinclair
parent 6ca2699eaf
commit 5b43c58f02
2 changed files with 60 additions and 4 deletions

View File

@ -266,8 +266,26 @@ bool Builder::GenerateEntryPoint(ast::EntryPoint* ep) {
return false;
}
push_preamble(spv::Op::OpEntryPoint,
{Operand::Int(stage), Operand::Int(id), Operand::String(name)});
std::vector<Operand> operands = {Operand::Int(stage), Operand::Int(id),
Operand::String(name)};
// TODO(dsinclair): This could be made smarter by only listing the
// input/output variables which are used by the entry point instead of just
// listing all module scoped variables of type input/output.
for (const auto& var : mod_->global_variables()) {
if (var->storage_class() != ast::StorageClass::kInput &&
var->storage_class() != ast::StorageClass::kOutput) {
continue;
}
uint32_t var_id;
if (!scope_stack_.get(var->name(), &var_id)) {
error_ = "unable to find ID for global variable: " + var->name();
return false;
}
operands.push_back(Operand::Int(var_id));
}
push_preamble(spv::Op::OpEntryPoint, operands);
return true;
}

View File

@ -19,6 +19,8 @@
#include "spirv/unified1/spirv.hpp11"
#include "src/ast/entry_point.h"
#include "src/ast/pipeline_stage.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/variable.h"
#include "src/writer/spirv/builder.h"
#include "src/writer/spirv/spv_dump.h"
@ -103,8 +105,44 @@ INSTANTIATE_TEST_SUITE_P(
EntryPointStageData{ast::PipelineStage::kCompute,
SpvExecutionModelGLCompute}));
// TODO(http://crbug.com/tint/28)
TEST_F(BuilderTest, DISABLED_EntryPoint_WithInterfaceIds) {}
TEST_F(BuilderTest, EntryPoint_WithInterfaceIds) {
ast::type::F32Type f32;
auto v_in =
std::make_unique<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
auto v_out = std::make_unique<ast::Variable>(
"my_out", ast::StorageClass::kOutput, &f32);
auto v_wg = std::make_unique<ast::Variable>(
"my_wg", ast::StorageClass::kWorkgroup, &f32);
ast::EntryPoint ep(ast::PipelineStage::kVertex, "", "main");
ast::Module mod;
Builder b(&mod);
EXPECT_TRUE(b.GenerateGlobalVariable(v_in.get())) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v_out.get())) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v_wg.get())) << b.error();
mod.AddGlobalVariable(std::move(v_in));
mod.AddGlobalVariable(std::move(v_out));
mod.AddGlobalVariable(std::move(v_wg));
b.set_func_name_to_id("main", 3);
ASSERT_TRUE(b.GenerateEntryPoint(&ep));
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in"
OpName %4 "my_out"
OpName %6 "my_wg"
)");
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Input %3
%1 = OpVariable %2 Input
%5 = OpTypePointer Output %3
%4 = OpVariable %5 Output
%7 = OpTypePointer Workgroup %3
%6 = OpVariable %7 Workgroup
)");
EXPECT_EQ(DumpInstructions(b.preamble()),
R"(OpEntryPoint Vertex %3 "main" %1 %4
)");
}
TEST_F(BuilderTest, ExecutionModel_Fragment_OriginUpperLeft) {
ast::EntryPoint ep(ast::PipelineStage::kFragment, "main", "frag_main");