[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:
parent
6ca2699eaf
commit
5b43c58f02
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue