[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:
parent
7cac245abc
commit
540ab2160b
|
@ -162,6 +162,11 @@ bool Builder::Build() {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
for (const auto& ep : mod_->entry_points()) {
|
||||
if (!GenerateExecutionModes(ep.get())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -249,10 +254,8 @@ bool Builder::GenerateEntryPoint(ast::EntryPoint* ep) {
|
|||
if (name.empty()) {
|
||||
name = ep->function_name();
|
||||
}
|
||||
|
||||
auto id = id_for_func_name(ep->function_name());
|
||||
const auto id = id_for_entry_point(ep);
|
||||
if (id == 0) {
|
||||
error_ = "unable to find ID for function: " + ep->function_name();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -268,6 +271,22 @@ bool Builder::GenerateEntryPoint(ast::EntryPoint* ep) {
|
|||
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) {
|
||||
if (expr->IsArrayAccessor()) {
|
||||
return GenerateAccessorExpression(expr->AsArrayAccessor());
|
||||
|
|
|
@ -98,6 +98,19 @@ class Builder {
|
|||
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
|
||||
/// given callback
|
||||
/// @param cb the callback to execute
|
||||
|
@ -182,6 +195,10 @@ class Builder {
|
|||
/// @param ep the entry point
|
||||
/// @returns true if the instruction was generated, false otherwise
|
||||
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
|
||||
/// @param expr the expression to generate
|
||||
/// @returns the resulting ID of the exp = {};ression or 0 on error
|
||||
|
|
|
@ -106,6 +106,20 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
// TODO(http://crbug.com/tint/28)
|
||||
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 spirv
|
||||
} // namespace writer
|
||||
|
|
Loading…
Reference in New Issue