mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-13 15:16:16 +00:00
writers: Use the new sem::Module::DependencyOrderedDeclarations
As the resolver currently enforces in-order declarations, this does not change the declaration order from iterating over the ast::Module::GlobalDeclarations. The MSL backend has been changed to use the sem::Module::DependencyOrderedDeclarations list instead of looping over different declaration types separately. Bug: tint:1266 Change-Id: I698d612032285311017bfceab3c42adae1928a0e Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/79767 Reviewed-by: James Price <jrprice@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include "src/sem/depth_texture_type.h"
|
||||
#include "src/sem/function.h"
|
||||
#include "src/sem/member_accessor_expression.h"
|
||||
#include "src/sem/module.h"
|
||||
#include "src/sem/multisampled_texture_type.h"
|
||||
#include "src/sem/sampled_texture_type.h"
|
||||
#include "src/sem/statement.h"
|
||||
@@ -147,7 +148,8 @@ bool GeneratorImpl::Generate() {
|
||||
|
||||
line();
|
||||
|
||||
for (auto* decl : builder_.AST().GlobalDeclarations()) {
|
||||
auto* mod = builder_.Sem().Module();
|
||||
for (auto* decl : mod->DependencyOrderedDeclarations()) {
|
||||
if (decl->Is<ast::Alias>()) {
|
||||
continue; // Ignore aliases.
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "src/sem/depth_texture_type.h"
|
||||
#include "src/sem/function.h"
|
||||
#include "src/sem/member_accessor_expression.h"
|
||||
#include "src/sem/module.h"
|
||||
#include "src/sem/multisampled_texture_type.h"
|
||||
#include "src/sem/sampled_texture_type.h"
|
||||
#include "src/sem/statement.h"
|
||||
@@ -223,7 +224,8 @@ bool GeneratorImpl::Generate() {
|
||||
const TypeInfo* last_kind = nullptr;
|
||||
size_t last_padding_line = 0;
|
||||
|
||||
for (auto* decl : builder_.AST().GlobalDeclarations()) {
|
||||
auto* mod = builder_.Sem().Module();
|
||||
for (auto* decl : mod->DependencyOrderedDeclarations()) {
|
||||
if (decl->Is<ast::Alias>()) {
|
||||
continue; // Ignore aliases.
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "src/sem/i32_type.h"
|
||||
#include "src/sem/matrix_type.h"
|
||||
#include "src/sem/member_accessor_expression.h"
|
||||
#include "src/sem/module.h"
|
||||
#include "src/sem/multisampled_texture_type.h"
|
||||
#include "src/sem/pointer_type.h"
|
||||
#include "src/sem/reference_type.h"
|
||||
@@ -207,44 +208,46 @@ bool GeneratorImpl::Generate() {
|
||||
|
||||
auto helpers_insertion_point = current_buffer_->lines.size();
|
||||
|
||||
for (auto* const type_decl : program_->AST().TypeDecls()) {
|
||||
if (!type_decl->Is<ast::Alias>()) {
|
||||
if (!EmitTypeDecl(TypeOf(type_decl))) {
|
||||
return false;
|
||||
}
|
||||
auto* mod = builder_.Sem().Module();
|
||||
for (auto* decl : mod->DependencyOrderedDeclarations()) {
|
||||
bool ok = Switch(
|
||||
decl, //
|
||||
[&](const ast::Struct* str) {
|
||||
TINT_DEFER(line());
|
||||
return EmitTypeDecl(TypeOf(str));
|
||||
},
|
||||
[&](const ast::Alias*) {
|
||||
return true; // folded away by the writer
|
||||
},
|
||||
[&](const ast::Variable* var) {
|
||||
if (var->is_const) {
|
||||
TINT_DEFER(line());
|
||||
return EmitProgramConstVariable(var);
|
||||
}
|
||||
// These are pushed into the entry point by sanitizer transforms.
|
||||
TINT_ICE(Writer, diagnostics_)
|
||||
<< "module-scope variables should have been handled by the MSL "
|
||||
"sanitizer";
|
||||
return false;
|
||||
},
|
||||
[&](const ast::Function* func) {
|
||||
TINT_DEFER(line());
|
||||
if (func->IsEntryPoint()) {
|
||||
return EmitEntryPointFunction(func);
|
||||
}
|
||||
return EmitFunction(func);
|
||||
},
|
||||
[&](Default) {
|
||||
// These are pushed into the entry point by sanitizer transforms.
|
||||
TINT_ICE(Writer, diagnostics_)
|
||||
<< "unhandled type: " << decl->TypeInfo().name;
|
||||
return false;
|
||||
});
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!program_->AST().TypeDecls().empty()) {
|
||||
line();
|
||||
}
|
||||
|
||||
for (auto* var : program_->AST().GlobalVariables()) {
|
||||
if (var->is_const) {
|
||||
if (!EmitProgramConstVariable(var)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// These are pushed into the entry point by sanitizer transforms.
|
||||
TINT_ICE(Writer, diagnostics_) << "module-scope variables should have "
|
||||
"been handled by the MSL sanitizer";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* func : program_->AST().Functions()) {
|
||||
if (!func->IsEntryPoint()) {
|
||||
if (!EmitFunction(func)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!EmitEntryPointFunction(func)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
line();
|
||||
}
|
||||
|
||||
if (!invariant_define_name_.empty()) {
|
||||
// 'invariant' attribute requires MSL 2.1 or higher.
|
||||
// WGSL can ignore the invariant attribute on pre MSL 2.1 devices.
|
||||
@@ -1555,11 +1558,12 @@ bool GeneratorImpl::EmitLiteral(std::ostream& out,
|
||||
return true;
|
||||
},
|
||||
[&](const ast::SintLiteralExpression* l) {
|
||||
// MSL (and C++) parse `-2147483648` as a `long` because it parses unary
|
||||
// minus and `2147483648` as separate tokens, and the latter doesn't
|
||||
// fit into an (32-bit) `int`. WGSL, OTOH, parses this as an `i32`. To
|
||||
// avoid issues with `long` to `int` casts, emit `(2147483647 - 1)`
|
||||
// instead, which ensures the expression type is `int`.
|
||||
// MSL (and C++) parse `-2147483648` as a `long` because it parses
|
||||
// unary minus and `2147483648` as separate tokens, and the latter
|
||||
// doesn't fit into an (32-bit) `int`. WGSL, OTOH, parses this as an
|
||||
// `i32`. To avoid issues with `long` to `int` casts, emit
|
||||
// `(2147483647 - 1)` instead, which ensures the expression type is
|
||||
// `int`.
|
||||
const auto int_min = std::numeric_limits<int32_t>::min();
|
||||
if (l->ValueAsI32() == int_min) {
|
||||
out << "(" << int_min + 1 << " - 1)";
|
||||
@@ -1741,8 +1745,8 @@ std::string GeneratorImpl::interpolation_to_attribute(
|
||||
bool GeneratorImpl::EmitEntryPointFunction(const ast::Function* func) {
|
||||
auto func_name = program_->Symbols().NameFor(func->symbol);
|
||||
|
||||
// Returns the binding index of a variable, requiring that the group attribute
|
||||
// have a value of zero.
|
||||
// Returns the binding index of a variable, requiring that the group
|
||||
// attribute have a value of zero.
|
||||
const uint32_t kInvalidBindingIndex = std::numeric_limits<uint32_t>::max();
|
||||
auto get_binding_index = [&](const ast::Variable* var) -> uint32_t {
|
||||
auto bp = var->BindingPoint();
|
||||
@@ -1923,14 +1927,14 @@ bool GeneratorImpl::EmitForLoop(const ast::ForLoopStatement* stmt) {
|
||||
}
|
||||
}
|
||||
|
||||
// If the for-loop has a multi-statement conditional and / or continuing, then
|
||||
// we cannot emit this as a regular for-loop in MSL. Instead we need to
|
||||
// If the for-loop has a multi-statement conditional and / or continuing,
|
||||
// then we cannot emit this as a regular for-loop in MSL. Instead we need to
|
||||
// generate a `while(true)` loop.
|
||||
bool emit_as_loop = cond_pre.lines.size() > 0 || cont_buf.lines.size() > 1;
|
||||
|
||||
// If the for-loop has multi-statement initializer, or is going to be emitted
|
||||
// as a `while(true)` loop, then declare the initializer statement(s) before
|
||||
// the loop in a new block.
|
||||
// If the for-loop has multi-statement initializer, or is going to be
|
||||
// emitted as a `while(true)` loop, then declare the initializer
|
||||
// statement(s) before the loop in a new block.
|
||||
bool nest_in_block =
|
||||
init_buf.lines.size() > 1 || (stmt->initializer && emit_as_loop);
|
||||
if (nest_in_block) {
|
||||
|
||||
@@ -107,6 +107,7 @@ using namespace metal;
|
||||
struct tint_symbol_1 {
|
||||
float foo [[user(locn0)]];
|
||||
};
|
||||
|
||||
struct tint_symbol_2 {
|
||||
float value [[color(1)]];
|
||||
};
|
||||
@@ -207,15 +208,12 @@ struct Interface {
|
||||
float col2;
|
||||
float4 pos;
|
||||
};
|
||||
|
||||
struct tint_symbol {
|
||||
float col1 [[user(locn1)]];
|
||||
float col2 [[user(locn2)]];
|
||||
float4 pos [[position]];
|
||||
};
|
||||
struct tint_symbol_2 {
|
||||
float col1 [[user(locn1)]];
|
||||
float col2 [[user(locn2)]];
|
||||
};
|
||||
|
||||
Interface vert_main_inner() {
|
||||
Interface const tint_symbol_3 = {.col1=0.5f, .col2=0.25f, .pos=float4()};
|
||||
@@ -231,6 +229,11 @@ vertex tint_symbol vert_main() {
|
||||
return wrapper_result;
|
||||
}
|
||||
|
||||
struct tint_symbol_2 {
|
||||
float col1 [[user(locn1)]];
|
||||
float col2 [[user(locn2)]];
|
||||
};
|
||||
|
||||
void frag_main_inner(Interface colors) {
|
||||
float const r = colors.col1;
|
||||
float const g = colors.col2;
|
||||
@@ -285,18 +288,16 @@ using namespace metal;
|
||||
struct VertexOutput {
|
||||
float4 pos;
|
||||
};
|
||||
struct tint_symbol {
|
||||
float4 pos [[position]];
|
||||
};
|
||||
struct tint_symbol_1 {
|
||||
float4 pos [[position]];
|
||||
};
|
||||
|
||||
VertexOutput foo(float x) {
|
||||
VertexOutput const tint_symbol_2 = {.pos=float4(x, x, x, 1.0f)};
|
||||
return tint_symbol_2;
|
||||
}
|
||||
|
||||
struct tint_symbol {
|
||||
float4 pos [[position]];
|
||||
};
|
||||
|
||||
VertexOutput vert_main1_inner() {
|
||||
return foo(0.5f);
|
||||
}
|
||||
@@ -308,6 +309,10 @@ vertex tint_symbol vert_main1() {
|
||||
return wrapper_result;
|
||||
}
|
||||
|
||||
struct tint_symbol_1 {
|
||||
float4 pos [[position]];
|
||||
};
|
||||
|
||||
VertexOutput vert_main2_inner() {
|
||||
return foo(0.25f);
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ using namespace metal;
|
||||
struct tint_symbol {
|
||||
/* 0x0000 */ uint4 buffer_size[1];
|
||||
};
|
||||
|
||||
struct my_struct {
|
||||
float a[1];
|
||||
};
|
||||
@@ -103,6 +104,7 @@ using namespace metal;
|
||||
struct tint_symbol {
|
||||
/* 0x0000 */ uint4 buffer_size[1];
|
||||
};
|
||||
|
||||
struct my_struct {
|
||||
float z;
|
||||
float a[1];
|
||||
@@ -152,6 +154,7 @@ using namespace metal;
|
||||
struct tint_symbol {
|
||||
/* 0x0000 */ uint4 buffer_size[1];
|
||||
};
|
||||
|
||||
struct my_struct {
|
||||
float a[1];
|
||||
};
|
||||
@@ -208,6 +211,7 @@ using namespace metal;
|
||||
struct tint_symbol {
|
||||
/* 0x0000 */ uint4 buffer_size[2];
|
||||
};
|
||||
|
||||
struct my_struct {
|
||||
float a[1];
|
||||
};
|
||||
|
||||
@@ -190,6 +190,7 @@ using namespace metal;
|
||||
struct tint_array_wrapper {
|
||||
float2x2 arr[4];
|
||||
};
|
||||
|
||||
struct tint_symbol_3 {
|
||||
tint_array_wrapper m;
|
||||
};
|
||||
@@ -240,9 +241,11 @@ struct S1 {
|
||||
float2x2 m1;
|
||||
float4x4 m2;
|
||||
};
|
||||
|
||||
struct S2 {
|
||||
S1 s;
|
||||
};
|
||||
|
||||
struct tint_symbol_4 {
|
||||
S2 s;
|
||||
};
|
||||
@@ -316,11 +319,13 @@ struct tint_symbol_7 {
|
||||
float2x3 m2;
|
||||
float2x4 m3;
|
||||
};
|
||||
|
||||
struct tint_symbol_15 {
|
||||
float3x2 m4;
|
||||
float3x3 m5;
|
||||
float3x4 m6;
|
||||
};
|
||||
|
||||
struct tint_symbol_23 {
|
||||
float4x2 m7;
|
||||
float4x3 m8;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "src/sem/depth_texture_type.h"
|
||||
#include "src/sem/function.h"
|
||||
#include "src/sem/member_accessor_expression.h"
|
||||
#include "src/sem/module.h"
|
||||
#include "src/sem/multisampled_texture_type.h"
|
||||
#include "src/sem/reference_type.h"
|
||||
#include "src/sem/sampled_texture_type.h"
|
||||
@@ -308,9 +309,12 @@ bool Builder::Build() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* func : builder_.AST().Functions()) {
|
||||
if (!GenerateFunction(func)) {
|
||||
return false;
|
||||
auto* mod = builder_.Sem().Module();
|
||||
for (auto* decl : mod->DependencyOrderedDeclarations()) {
|
||||
if (auto* func = decl->As<ast::Function>()) {
|
||||
if (!GenerateFunction(func)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user