[spirv-writer] Fragment shaders use OriginUpperLeft

Fixes a validation error

Change-Id: Ie003ac61a10f87f3d0c42ad8cb162da50c1c416b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/20740
Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
David Neto 2020-05-01 19:02:25 +00:00 committed by dan sinclair
parent 7cac245abc
commit 540ab2160b
3 changed files with 53 additions and 3 deletions

View File

@ -162,6 +162,11 @@ bool Builder::Build() {
return false; return false;
} }
} }
for (const auto& ep : mod_->entry_points()) {
if (!GenerateExecutionModes(ep.get())) {
return false;
}
}
return true; return true;
} }
@ -249,10 +254,8 @@ bool Builder::GenerateEntryPoint(ast::EntryPoint* ep) {
if (name.empty()) { if (name.empty()) {
name = ep->function_name(); name = ep->function_name();
} }
const auto id = id_for_entry_point(ep);
auto id = id_for_func_name(ep->function_name());
if (id == 0) { if (id == 0) {
error_ = "unable to find ID for function: " + ep->function_name();
return false; return false;
} }
@ -268,6 +271,22 @@ bool Builder::GenerateEntryPoint(ast::EntryPoint* ep) {
return true; return true;
} }
bool Builder::GenerateExecutionModes(ast::EntryPoint* ep) {
const auto id = id_for_entry_point(ep);
if (id == 0) {
return false;
}
// WGSL fragment shader origin is upper left
if (ep->stage() == ast::PipelineStage::kFragment) {
push_preamble(
spv::Op::OpExecutionMode,
{Operand::Int(id), Operand::Int(SpvExecutionModeOriginUpperLeft)});
}
return true;
}
uint32_t Builder::GenerateExpression(ast::Expression* expr) { uint32_t Builder::GenerateExpression(ast::Expression* expr) {
if (expr->IsArrayAccessor()) { if (expr->IsArrayAccessor()) {
return GenerateAccessorExpression(expr->AsArrayAccessor()); return GenerateAccessorExpression(expr->AsArrayAccessor());

View File

@ -98,6 +98,19 @@ class Builder {
return func_name_to_id_[name]; return func_name_to_id_[name];
} }
/// Retrieves the id for an entry point function, or 0 if not found.
/// Emits an error if not found.
/// @param ep the entry point
/// @returns 0 on error
uint32_t id_for_entry_point(ast::EntryPoint* ep) {
auto id = id_for_func_name(ep->function_name());
if (id == 0) {
error_ = "unable to find ID for function: " + ep->function_name();
return 0;
}
return id;
}
/// Iterates over all the instructions in the correct order and calls the /// Iterates over all the instructions in the correct order and calls the
/// given callback /// given callback
/// @param cb the callback to execute /// @param cb the callback to execute
@ -182,6 +195,10 @@ class Builder {
/// @param ep the entry point /// @param ep the entry point
/// @returns true if the instruction was generated, false otherwise /// @returns true if the instruction was generated, false otherwise
bool GenerateEntryPoint(ast::EntryPoint* ep); bool GenerateEntryPoint(ast::EntryPoint* ep);
/// Generates execution modes for an entry point
/// @param ep the entry point
/// @returns false on failure
bool GenerateExecutionModes(ast::EntryPoint* ep);
/// Generates an expression /// Generates an expression
/// @param expr the expression to generate /// @param expr the expression to generate
/// @returns the resulting ID of the exp = {};ression or 0 on error /// @returns the resulting ID of the exp = {};ression or 0 on error

View File

@ -106,6 +106,20 @@ INSTANTIATE_TEST_SUITE_P(
// TODO(http://crbug.com/tint/28) // TODO(http://crbug.com/tint/28)
TEST_F(BuilderTest, DISABLED_EntryPoint_WithInterfaceIds) {} TEST_F(BuilderTest, DISABLED_EntryPoint_WithInterfaceIds) {}
TEST_F(BuilderTest, ExecutionModel_Fragment_OriginUpperLeft) {
ast::EntryPoint ep(ast::PipelineStage::kFragment, "main", "frag_main");
ast::Module mod;
Builder b(&mod);
b.set_func_name_to_id("frag_main", 2);
ASSERT_TRUE(b.GenerateExecutionModes(&ep));
auto preamble = b.preamble();
ASSERT_EQ(preamble.size(), 1u);
EXPECT_EQ(DumpInstruction(preamble[0]), R"(OpExecutionMode %2 OriginUpperLeft
)");
}
} // namespace } // namespace
} // namespace spirv } // namespace spirv
} // namespace writer } // namespace writer