mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-10 22:17:51 +00:00
Migrate from using ast::Module to Program
Enforce all places where Dawn passes in or returns a ast::Module, now takes a `const Program* ` or returns a `Program`. As the end goal of all this is to have immutable Programs, all Program inputs take a pointer instead of moving the actual object. As consumers of a Program are now all const, we have to const_cast to work around all the places we've been incorrectly mutating a ast::Module. These const_casts are temporary, and will be fixed in the next set of changes. Depends on https://dawn-review.googlesource.com/c/dawn/+/38522 Bug: tint:390 Change-Id: Ie05b112b16134937d1b601e9b713ea4ec4e1c677 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38541 Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
@@ -55,9 +55,9 @@ namespace transform {
|
||||
BoundArrayAccessors::BoundArrayAccessors() = default;
|
||||
BoundArrayAccessors::~BoundArrayAccessors() = default;
|
||||
|
||||
Transform::Output BoundArrayAccessors::Run(ast::Module* in) {
|
||||
Transform::Output BoundArrayAccessors::Run(const Program* in) {
|
||||
Output out;
|
||||
CloneContext(&out.module, in)
|
||||
CloneContext(&out.program, in)
|
||||
.ReplaceAll([&](CloneContext* ctx, ast::ArrayAccessorExpression* expr) {
|
||||
return Transform(expr, ctx, &out.diagnostics);
|
||||
})
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "src/ast/array_accessor_expression.h"
|
||||
#include "src/ast/expression.h"
|
||||
#include "src/ast/module.h"
|
||||
#include "src/ast/statement.h"
|
||||
#include "src/program.h"
|
||||
#include "src/scope_stack.h"
|
||||
#include "src/transform/transform.h"
|
||||
|
||||
@@ -38,13 +38,13 @@ class BoundArrayAccessors : public Transform {
|
||||
/// Destructor
|
||||
~BoundArrayAccessors() override;
|
||||
|
||||
/// Runs the transform on `module`, returning the transformation result.
|
||||
/// Runs the transform on `program`, returning the transformation result.
|
||||
/// @note Users of Tint should register the transform with transform manager
|
||||
/// and invoke its Run(), instead of directly calling the transform's Run().
|
||||
/// Calling Run() directly does not perform module state cleanup operations.
|
||||
/// @param module the source module to transform
|
||||
/// Calling Run() directly does not perform program state cleanup operations.
|
||||
/// @param program the source program to transform
|
||||
/// @returns the transformation result
|
||||
Output Run(ast::Module* module) override;
|
||||
Output Run(const Program* program) override;
|
||||
|
||||
private:
|
||||
ast::ArrayAccessorExpression* Transform(ast::ArrayAccessorExpression* expr,
|
||||
|
||||
@@ -38,42 +38,42 @@ const char kPointSizeVar[] = "tint_pointsize";
|
||||
EmitVertexPointSize::EmitVertexPointSize() = default;
|
||||
EmitVertexPointSize::~EmitVertexPointSize() = default;
|
||||
|
||||
Transform::Output EmitVertexPointSize::Run(ast::Module* in) {
|
||||
Transform::Output EmitVertexPointSize::Run(const Program* in) {
|
||||
Output out;
|
||||
|
||||
if (!in->Functions().HasStage(ast::PipelineStage::kVertex)) {
|
||||
// If the module doesn't have any vertex stages, then there's nothing to do.
|
||||
out.module = in->Clone();
|
||||
out.program = in->Clone();
|
||||
return out;
|
||||
}
|
||||
|
||||
auto* f32 = out.module.create<type::F32>();
|
||||
auto* f32 = out.program.create<type::F32>();
|
||||
|
||||
// Declare the pointsize builtin output variable.
|
||||
auto* pointsize_var = out.module.create<ast::Variable>(
|
||||
Source{}, // source
|
||||
out.module.RegisterSymbol(kPointSizeVar), // symbol
|
||||
ast::StorageClass::kOutput, // storage_class
|
||||
f32, // type
|
||||
false, // is_const
|
||||
nullptr, // constructor
|
||||
auto* pointsize_var = out.program.create<ast::Variable>(
|
||||
Source{}, // source
|
||||
out.program.RegisterSymbol(kPointSizeVar), // symbol
|
||||
ast::StorageClass::kOutput, // storage_class
|
||||
f32, // type
|
||||
false, // is_const
|
||||
nullptr, // constructor
|
||||
ast::VariableDecorationList{
|
||||
// decorations
|
||||
out.module.create<ast::BuiltinDecoration>(Source{},
|
||||
ast::Builtin::kPointSize),
|
||||
out.program.create<ast::BuiltinDecoration>(Source{},
|
||||
ast::Builtin::kPointSize),
|
||||
});
|
||||
out.module.AddGlobalVariable(pointsize_var);
|
||||
out.program.AddGlobalVariable(pointsize_var);
|
||||
|
||||
// Build the AST expression & statement for assigning pointsize one.
|
||||
auto* one = out.module.create<ast::ScalarConstructorExpression>(
|
||||
Source{}, out.module.create<ast::FloatLiteral>(Source{}, f32, 1.0f));
|
||||
auto* pointsize_ident = out.module.create<ast::IdentifierExpression>(
|
||||
Source{}, out.module.RegisterSymbol(kPointSizeVar));
|
||||
auto* pointsize_assign = out.module.create<ast::AssignmentStatement>(
|
||||
auto* one = out.program.create<ast::ScalarConstructorExpression>(
|
||||
Source{}, out.program.create<ast::FloatLiteral>(Source{}, f32, 1.0f));
|
||||
auto* pointsize_ident = out.program.create<ast::IdentifierExpression>(
|
||||
Source{}, out.program.RegisterSymbol(kPointSizeVar));
|
||||
auto* pointsize_assign = out.program.create<ast::AssignmentStatement>(
|
||||
Source{}, pointsize_ident, one);
|
||||
|
||||
// Add the pointsize assignment statement to the front of all vertex stages.
|
||||
CloneContext(&out.module, in)
|
||||
CloneContext(&out.program, in)
|
||||
.ReplaceAll(
|
||||
[&](CloneContext* ctx, ast::Function* func) -> ast::Function* {
|
||||
if (func->pipeline_stage() != ast::PipelineStage::kVertex) {
|
||||
|
||||
@@ -21,10 +21,10 @@ namespace tint {
|
||||
namespace transform {
|
||||
|
||||
/// EmitVertexPointSize is a Transform that adds a PointSize builtin global
|
||||
/// output variable to the module which is assigned 1.0 as the new first
|
||||
/// output variable to the program which is assigned 1.0 as the new first
|
||||
/// statement for all vertex stage entry points.
|
||||
/// If the module does not contain a vertex pipeline stage entry point then then
|
||||
/// this transform is a no-op.
|
||||
/// If the program does not contain a vertex pipeline stage entry point then
|
||||
/// then this transform is a no-op.
|
||||
class EmitVertexPointSize : public Transform {
|
||||
public:
|
||||
/// Constructor
|
||||
@@ -32,13 +32,13 @@ class EmitVertexPointSize : public Transform {
|
||||
/// Destructor
|
||||
~EmitVertexPointSize() override;
|
||||
|
||||
/// Runs the transform on `module`, returning the transformation result.
|
||||
/// Runs the transform on `program`, returning the transformation result.
|
||||
/// @note Users of Tint should register the transform with transform manager
|
||||
/// and invoke its Run(), instead of directly calling the transform's Run().
|
||||
/// Calling Run() directly does not perform module state cleanup operations.
|
||||
/// @param module the source module to transform
|
||||
/// Calling Run() directly does not perform program state cleanup operations.
|
||||
/// @param program the source program to transform
|
||||
/// @returns the transformation result
|
||||
Output Run(ast::Module* module) override;
|
||||
Output Run(const Program* program) override;
|
||||
};
|
||||
|
||||
} // namespace transform
|
||||
|
||||
@@ -81,11 +81,11 @@ FirstIndexOffset::FirstIndexOffset(uint32_t binding, uint32_t group)
|
||||
|
||||
FirstIndexOffset::~FirstIndexOffset() = default;
|
||||
|
||||
Transform::Output FirstIndexOffset::Run(ast::Module* in) {
|
||||
Transform::Output FirstIndexOffset::Run(const Program* in) {
|
||||
// First do a quick check to see if the transform has already been applied.
|
||||
for (ast::Variable* var : in->global_variables()) {
|
||||
if (auto* dec_var = var->As<ast::Variable>()) {
|
||||
if (dec_var->symbol() == in->RegisterSymbol(kBufferName)) {
|
||||
if (dec_var->symbol() == in->GetSymbol(kBufferName)) {
|
||||
diag::Diagnostic err;
|
||||
err.message = "First index offset transform has already been applied.";
|
||||
err.severity = diag::Severity::Error;
|
||||
@@ -99,7 +99,8 @@ Transform::Output FirstIndexOffset::Run(ast::Module* in) {
|
||||
// Running TypeDeterminer as we require local_referenced_builtin_variables()
|
||||
// to be populated. TODO(bclayton) - it should not be necessary to re-run the
|
||||
// type determiner if semantic information is already generated. Remove.
|
||||
TypeDeterminer td(in);
|
||||
// TODO(https://crbug.com/tint/390): Remove this const_cast hack!
|
||||
TypeDeterminer td(const_cast<Program*>(in));
|
||||
if (!td.Determine()) {
|
||||
diag::Diagnostic err;
|
||||
err.severity = diag::Severity::Error;
|
||||
@@ -115,9 +116,9 @@ Transform::Output FirstIndexOffset::Run(ast::Module* in) {
|
||||
// Lazilly construct the UniformBuffer on first call to
|
||||
// maybe_create_buffer_var()
|
||||
ast::Variable* buffer_var = nullptr;
|
||||
auto maybe_create_buffer_var = [&](ast::Module* mod) {
|
||||
auto maybe_create_buffer_var = [&](Program* program) {
|
||||
if (buffer_var == nullptr) {
|
||||
buffer_var = AddUniformBuffer(mod);
|
||||
buffer_var = AddUniformBuffer(program);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -126,7 +127,7 @@ Transform::Output FirstIndexOffset::Run(ast::Module* in) {
|
||||
// these builtins.
|
||||
|
||||
Output out;
|
||||
CloneContext(&out.module, in)
|
||||
CloneContext(&out.program, in)
|
||||
.ReplaceAll([&](CloneContext* ctx, ast::Variable* var) -> ast::Variable* {
|
||||
for (ast::VariableDecoration* dec : var->decorations()) {
|
||||
if (auto* blt_dec = dec->As<ast::BuiltinDecoration>()) {
|
||||
@@ -194,16 +195,16 @@ uint32_t FirstIndexOffset::GetFirstInstanceOffset() {
|
||||
return instance_index_offset_;
|
||||
}
|
||||
|
||||
ast::Variable* FirstIndexOffset::AddUniformBuffer(ast::Module* mod) {
|
||||
auto* u32_type = mod->create<type::U32>();
|
||||
ast::Variable* FirstIndexOffset::AddUniformBuffer(Program* dst) {
|
||||
auto* u32_type = dst->create<type::U32>();
|
||||
ast::StructMemberList members;
|
||||
uint32_t offset = 0;
|
||||
if (has_vertex_index_) {
|
||||
ast::StructMemberDecorationList member_dec;
|
||||
member_dec.push_back(
|
||||
mod->create<ast::StructMemberOffsetDecoration>(Source{}, offset));
|
||||
members.push_back(mod->create<ast::StructMember>(
|
||||
Source{}, mod->RegisterSymbol(kFirstVertexName), u32_type,
|
||||
dst->create<ast::StructMemberOffsetDecoration>(Source{}, offset));
|
||||
members.push_back(dst->create<ast::StructMember>(
|
||||
Source{}, dst->RegisterSymbol(kFirstVertexName), u32_type,
|
||||
std::move(member_dec)));
|
||||
vertex_index_offset_ = offset;
|
||||
offset += 4;
|
||||
@@ -212,36 +213,36 @@ ast::Variable* FirstIndexOffset::AddUniformBuffer(ast::Module* mod) {
|
||||
if (has_instance_index_) {
|
||||
ast::StructMemberDecorationList member_dec;
|
||||
member_dec.push_back(
|
||||
mod->create<ast::StructMemberOffsetDecoration>(Source{}, offset));
|
||||
members.push_back(mod->create<ast::StructMember>(
|
||||
Source{}, mod->RegisterSymbol(kFirstInstanceName), u32_type,
|
||||
dst->create<ast::StructMemberOffsetDecoration>(Source{}, offset));
|
||||
members.push_back(dst->create<ast::StructMember>(
|
||||
Source{}, dst->RegisterSymbol(kFirstInstanceName), u32_type,
|
||||
std::move(member_dec)));
|
||||
instance_index_offset_ = offset;
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
ast::StructDecorationList decos;
|
||||
decos.push_back(mod->create<ast::StructBlockDecoration>(Source{}));
|
||||
decos.push_back(dst->create<ast::StructBlockDecoration>(Source{}));
|
||||
|
||||
auto* struct_type = mod->create<type::Struct>(
|
||||
mod->RegisterSymbol(kStructName),
|
||||
mod->create<ast::Struct>(Source{}, std::move(members), std::move(decos)));
|
||||
auto* struct_type = dst->create<type::Struct>(
|
||||
dst->RegisterSymbol(kStructName),
|
||||
dst->create<ast::Struct>(Source{}, std::move(members), std::move(decos)));
|
||||
|
||||
auto* idx_var = mod->create<ast::Variable>(
|
||||
auto* idx_var = dst->create<ast::Variable>(
|
||||
Source{}, // source
|
||||
mod->RegisterSymbol(kBufferName), // symbol
|
||||
dst->RegisterSymbol(kBufferName), // symbol
|
||||
ast::StorageClass::kUniform, // storage_class
|
||||
struct_type, // type
|
||||
false, // is_const
|
||||
nullptr, // constructor
|
||||
ast::VariableDecorationList{
|
||||
mod->create<ast::BindingDecoration>(Source{}, binding_),
|
||||
mod->create<ast::GroupDecoration>(Source{}, group_),
|
||||
dst->create<ast::BindingDecoration>(Source{}, binding_),
|
||||
dst->create<ast::GroupDecoration>(Source{}, group_),
|
||||
}); // decorations
|
||||
|
||||
mod->AddGlobalVariable(idx_var);
|
||||
dst->AddGlobalVariable(idx_var);
|
||||
|
||||
mod->AddConstructedType(struct_type);
|
||||
dst->AddConstructedType(struct_type);
|
||||
|
||||
return idx_var;
|
||||
}
|
||||
@@ -250,28 +251,28 @@ ast::VariableDeclStatement* FirstIndexOffset::CreateFirstIndexOffset(
|
||||
const std::string& original_name,
|
||||
const std::string& field_name,
|
||||
ast::Variable* buffer_var,
|
||||
ast::Module* mod) {
|
||||
Program* dst) {
|
||||
auto* buffer =
|
||||
mod->create<ast::IdentifierExpression>(Source{}, buffer_var->symbol());
|
||||
dst->create<ast::IdentifierExpression>(Source{}, buffer_var->symbol());
|
||||
|
||||
auto lhs_name = kIndexOffsetPrefix + original_name;
|
||||
auto* constructor = mod->create<ast::BinaryExpression>(
|
||||
auto* constructor = dst->create<ast::BinaryExpression>(
|
||||
Source{}, ast::BinaryOp::kAdd,
|
||||
mod->create<ast::IdentifierExpression>(Source{},
|
||||
mod->RegisterSymbol(lhs_name)),
|
||||
mod->create<ast::MemberAccessorExpression>(
|
||||
dst->create<ast::IdentifierExpression>(Source{},
|
||||
dst->RegisterSymbol(lhs_name)),
|
||||
dst->create<ast::MemberAccessorExpression>(
|
||||
Source{}, buffer,
|
||||
mod->create<ast::IdentifierExpression>(
|
||||
Source{}, mod->RegisterSymbol(field_name))));
|
||||
dst->create<ast::IdentifierExpression>(
|
||||
Source{}, dst->RegisterSymbol(field_name))));
|
||||
auto* var =
|
||||
mod->create<ast::Variable>(Source{}, // source
|
||||
mod->RegisterSymbol(original_name), // symbol
|
||||
dst->create<ast::Variable>(Source{}, // source
|
||||
dst->RegisterSymbol(original_name), // symbol
|
||||
ast::StorageClass::kNone, // storage_class
|
||||
mod->create<type::U32>(), // type
|
||||
dst->create<type::U32>(), // type
|
||||
true, // is_const
|
||||
constructor, // constructor
|
||||
ast::VariableDecorationList{}); // decorations
|
||||
return mod->create<ast::VariableDeclStatement>(Source{}, var);
|
||||
return dst->create<ast::VariableDeclStatement>(Source{}, var);
|
||||
}
|
||||
|
||||
} // namespace transform
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/module.h"
|
||||
#include "src/ast/variable_decl_statement.h"
|
||||
#include "src/program.h"
|
||||
#include "src/symbol.h"
|
||||
#include "src/transform/transform.h"
|
||||
|
||||
@@ -68,13 +68,13 @@ class FirstIndexOffset : public Transform {
|
||||
FirstIndexOffset(uint32_t binding, uint32_t group);
|
||||
~FirstIndexOffset() override;
|
||||
|
||||
/// Runs the transform on `module`, returning the transformation result.
|
||||
/// Runs the transform on `program`, returning the transformation result.
|
||||
/// @note Users of Tint should register the transform with transform manager
|
||||
/// and invoke its Run(), instead of directly calling the transform's Run().
|
||||
/// Calling Run() directly does not perform module state cleanup operations.
|
||||
/// @param module the source module to transform
|
||||
/// Calling Run() directly does not perform program state cleanup operations.
|
||||
/// @param program the source program to transform
|
||||
/// @returns the transformation result
|
||||
Output Run(ast::Module* module) override;
|
||||
Output Run(const Program* program) override;
|
||||
|
||||
/// @returns whether shader uses vertex_index
|
||||
bool HasVertexIndex();
|
||||
@@ -89,19 +89,19 @@ class FirstIndexOffset : public Transform {
|
||||
uint32_t GetFirstInstanceOffset();
|
||||
|
||||
private:
|
||||
/// Adds uniform buffer with firstVertex/Instance to module
|
||||
/// Adds uniform buffer with firstVertex/Instance to `program`
|
||||
/// @returns variable of new uniform buffer
|
||||
ast::Variable* AddUniformBuffer(ast::Module* mod);
|
||||
ast::Variable* AddUniformBuffer(Program* program);
|
||||
/// Adds constant with modified original_name builtin to func
|
||||
/// @param original_name the name of the original builtin used in function
|
||||
/// @param field_name name of field in firstVertex/Instance buffer
|
||||
/// @param buffer_var variable of firstVertex/Instance buffer
|
||||
/// @param module the target module to contain the new ast nodes
|
||||
/// @param program the target program to contain the new ast nodes
|
||||
ast::VariableDeclStatement* CreateFirstIndexOffset(
|
||||
const std::string& original_name,
|
||||
const std::string& field_name,
|
||||
ast::Variable* buffer_var,
|
||||
ast::Module* module);
|
||||
Program* program);
|
||||
|
||||
uint32_t binding_;
|
||||
uint32_t group_;
|
||||
|
||||
@@ -22,23 +22,23 @@ namespace transform {
|
||||
Manager::Manager() = default;
|
||||
Manager::~Manager() = default;
|
||||
|
||||
Transform::Output Manager::Run(ast::Module* module) {
|
||||
Transform::Output Manager::Run(const Program* program) {
|
||||
Output out;
|
||||
if (!transforms_.empty()) {
|
||||
for (auto& transform : transforms_) {
|
||||
auto res = transform->Run(module);
|
||||
out.module = std::move(res.module);
|
||||
auto res = transform->Run(program);
|
||||
out.program = std::move(res.program);
|
||||
out.diagnostics.add(std::move(res.diagnostics));
|
||||
if (out.diagnostics.contains_errors()) {
|
||||
return out;
|
||||
}
|
||||
module = &out.module;
|
||||
program = &out.program;
|
||||
}
|
||||
} else {
|
||||
out.module = module->Clone();
|
||||
out.program = program->Clone();
|
||||
}
|
||||
|
||||
TypeDeterminer td(&out.module);
|
||||
TypeDeterminer td(&out.program);
|
||||
if (!td.Determine()) {
|
||||
diag::Diagnostic err;
|
||||
err.severity = diag::Severity::Error;
|
||||
|
||||
@@ -41,18 +41,10 @@ class Manager : public Transform {
|
||||
transforms_.push_back(std::move(transform));
|
||||
}
|
||||
|
||||
/// Runs the transforms on `module`, returning the transformation result.
|
||||
/// @param module the source module to transform
|
||||
/// @returns the transformed module and diagnostics
|
||||
Output Run(ast::Module* module) override;
|
||||
|
||||
/// Runs the transform on `program`, returning the transformation result.
|
||||
/// @note Users of Tint should register the transform with transform manager
|
||||
/// and invoke its Run(), instead of directly calling the transform's Run().
|
||||
/// Calling Run() directly does not perform program state cleanup operations.
|
||||
/// Runs the transforms on `program`, returning the transformation result.
|
||||
/// @param program the source program to transform
|
||||
/// @returns the transformation result
|
||||
Output Run(Program* program) { return Run(&program->module); }
|
||||
/// @returns the transformed program and diagnostics
|
||||
Output Run(const Program* program) override;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Transform>> transforms_;
|
||||
|
||||
@@ -46,8 +46,8 @@ class TransformTest : public testing::Test {
|
||||
return "WGSL reader failed:\n" + parser.error();
|
||||
}
|
||||
|
||||
auto module = parser.module();
|
||||
TypeDeterminer td(&module);
|
||||
auto program = parser.program();
|
||||
TypeDeterminer td(&program);
|
||||
if (!td.Determine()) {
|
||||
return "Type determination failed:\n" + td.error();
|
||||
}
|
||||
@@ -56,7 +56,7 @@ class TransformTest : public testing::Test {
|
||||
for (auto& transform : transforms) {
|
||||
manager.append(std::move(transform));
|
||||
}
|
||||
auto result = manager.Run(&module);
|
||||
auto result = manager.Run(&program);
|
||||
|
||||
if (result.diagnostics.contains_errors()) {
|
||||
diag::Formatter::Style style;
|
||||
@@ -65,10 +65,10 @@ class TransformTest : public testing::Test {
|
||||
diag::Formatter(style).format(result.diagnostics);
|
||||
}
|
||||
|
||||
// Release the source module to ensure there's no uncloned data in result
|
||||
{ auto tmp = std::move(module); }
|
||||
// Release the source program to ensure there's no uncloned data in result
|
||||
{ auto tmp = std::move(program); }
|
||||
|
||||
writer::wgsl::Generator generator(std::move(result.module));
|
||||
writer::wgsl::Generator generator(&result.program);
|
||||
if (!generator.Generate()) {
|
||||
return "WGSL writer failed:\n" + generator.error();
|
||||
}
|
||||
|
||||
@@ -23,22 +23,16 @@ namespace transform {
|
||||
|
||||
Transform::Output::Output() = default;
|
||||
|
||||
Transform::Output::Output(ast::Module&& mod) : program{std::move(mod)} {}
|
||||
Transform::Output::Output(Program&& p) : program(std::move(p)) {}
|
||||
|
||||
Transform::Output::Output(ast::Module&& mod, diag::List&& d)
|
||||
: program{std::move(mod)}, diagnostics(std::move(d)) {}
|
||||
Transform::Output::Output(Program&& p, diag::List&& d)
|
||||
: program(std::move(p)), diagnostics(std::move(d)) {}
|
||||
|
||||
Transform::Output::~Output() = default;
|
||||
|
||||
Transform::Output::Output(Output&& rhs)
|
||||
: program(std::move(rhs.program)),
|
||||
diagnostics(std::move(rhs.diagnostics)) {}
|
||||
Transform::Output::Output(Output&&) = default;
|
||||
|
||||
Transform::Output& Transform::Output::operator=(Output&& rhs) {
|
||||
program = std::move(rhs.program);
|
||||
diagnostics = std::move(rhs.diagnostics);
|
||||
return *this;
|
||||
}
|
||||
Transform::Output& Transform::Output::operator=(Output&& rhs) = default;
|
||||
|
||||
Transform::Transform() = default;
|
||||
|
||||
|
||||
@@ -19,14 +19,13 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "src/ast/module.h"
|
||||
#include "src/diagnostic/diagnostic.h"
|
||||
#include "src/program.h"
|
||||
|
||||
namespace tint {
|
||||
namespace transform {
|
||||
|
||||
/// Interface for ast::Module transforms
|
||||
/// Interface for Program transforms
|
||||
class Transform {
|
||||
public:
|
||||
/// Constructor
|
||||
@@ -40,13 +39,13 @@ class Transform {
|
||||
Output();
|
||||
|
||||
/// Constructor
|
||||
/// @param module the module to move into this Output
|
||||
explicit Output(ast::Module&& module);
|
||||
/// @param program the program to move into this Output
|
||||
explicit Output(Program&& program);
|
||||
|
||||
/// Constructor
|
||||
/// @param module the module to move into this Output
|
||||
/// @param program the program to move into this Output
|
||||
/// @param diags the list of diagnostics to move into this Output
|
||||
Output(ast::Module&& module, diag::List&& diags);
|
||||
Output(Program&& program, diag::List&& diags);
|
||||
|
||||
/// Move constructor
|
||||
/// @param output the output to move into this Output
|
||||
@@ -64,25 +63,15 @@ class Transform {
|
||||
Program program;
|
||||
/// Diagnostics raised while running the Transform.
|
||||
diag::List diagnostics;
|
||||
/// The transformed module. May be empty on error.
|
||||
ast::Module& module{program.module};
|
||||
};
|
||||
|
||||
/// Runs the transform on `module`, returning the transformation result.
|
||||
/// @note Users of Tint should register the transform with transform manager
|
||||
/// and invoke its Run(), instead of directly calling the transform's Run().
|
||||
/// Calling Run() directly does not perform module state cleanup operations.
|
||||
/// @param module the source module to transform
|
||||
/// @returns the transformation result
|
||||
virtual Output Run(ast::Module* module) = 0;
|
||||
|
||||
/// Runs the transform on `program`, returning the transformation result.
|
||||
/// @note Users of Tint should register the transform with transform manager
|
||||
/// and invoke its Run(), instead of directly calling the transform's Run().
|
||||
/// Calling Run() directly does not perform program state cleanup operations.
|
||||
/// @param program the source program to transform
|
||||
/// @returns the transformation result
|
||||
Output Run(Program* program) { return Run(&program->module); }
|
||||
virtual Output Run(const Program* program) = 0;
|
||||
|
||||
protected:
|
||||
/// Clones the function `in` adding `statements` to the beginning of the
|
||||
|
||||
@@ -73,7 +73,7 @@ void VertexPulling::SetPullingBufferBindingSet(uint32_t number) {
|
||||
cfg.pulling_group = number;
|
||||
}
|
||||
|
||||
Transform::Output VertexPulling::Run(ast::Module* in) {
|
||||
Transform::Output VertexPulling::Run(const Program* in) {
|
||||
// Check SetVertexState was called
|
||||
if (!cfg.vertex_state_set) {
|
||||
diag::Diagnostic err;
|
||||
@@ -103,13 +103,13 @@ Transform::Output VertexPulling::Run(ast::Module* in) {
|
||||
// following stages will pass
|
||||
Output out;
|
||||
|
||||
State state{in, &out.module, cfg};
|
||||
State state{in, &out.program, cfg};
|
||||
state.FindOrInsertVertexIndexIfUsed();
|
||||
state.FindOrInsertInstanceIndexIfUsed();
|
||||
state.ConvertVertexInputVariablesToPrivate();
|
||||
state.AddVertexStorageBuffers();
|
||||
|
||||
CloneContext(&out.module, in)
|
||||
CloneContext(&out.program, in)
|
||||
.ReplaceAll([&](CloneContext* ctx, ast::Function* f) -> ast::Function* {
|
||||
if (f == func) {
|
||||
return CloneWithStatementsAtStart(
|
||||
@@ -126,7 +126,7 @@ VertexPulling::Config::Config() = default;
|
||||
VertexPulling::Config::Config(const Config&) = default;
|
||||
VertexPulling::Config::~Config() = default;
|
||||
|
||||
VertexPulling::State::State(ast::Module* i, ast::Module* o, const Config& c)
|
||||
VertexPulling::State::State(const Program* i, Program* o, const Config& c)
|
||||
: in(i), out(o), cfg(c) {}
|
||||
|
||||
VertexPulling::State::State(const State&) = default;
|
||||
@@ -231,7 +231,8 @@ void VertexPulling::State::FindOrInsertInstanceIndexIfUsed() {
|
||||
}
|
||||
|
||||
void VertexPulling::State::ConvertVertexInputVariablesToPrivate() {
|
||||
for (auto*& v : in->global_variables()) {
|
||||
// TODO(https://crbug.com/tint/390): Remove this const_cast hack!
|
||||
for (auto*& v : const_cast<Program*>(in)->global_variables()) {
|
||||
if (v->storage_class() != ast::StorageClass::kInput) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
#include "src/ast/expression.h"
|
||||
#include "src/ast/function.h"
|
||||
#include "src/ast/module.h"
|
||||
#include "src/ast/statement.h"
|
||||
#include "src/ast/variable.h"
|
||||
#include "src/program.h"
|
||||
#include "src/transform/transform.h"
|
||||
|
||||
namespace tint {
|
||||
@@ -114,7 +114,7 @@ struct VertexBufferLayoutDescriptor {
|
||||
/// attributes
|
||||
using VertexStateDescriptor = std::vector<VertexBufferLayoutDescriptor>;
|
||||
|
||||
/// Converts a module to use vertex pulling
|
||||
/// Converts a program to use vertex pulling
|
||||
///
|
||||
/// Variables which accept vertex input are var<in> with a location decoration.
|
||||
/// This transform will convert those to be assigned from storage buffers
|
||||
@@ -159,13 +159,13 @@ class VertexPulling : public Transform {
|
||||
/// @param number the group number we will use
|
||||
void SetPullingBufferBindingGroup(uint32_t number);
|
||||
|
||||
/// Runs the transform on `module`, returning the transformation result.
|
||||
/// Runs the transform on `program`, returning the transformation result.
|
||||
/// @note Users of Tint should register the transform with transform manager
|
||||
/// and invoke its Run(), instead of directly calling the transform's Run().
|
||||
/// Calling Run() directly does not perform module state cleanup operations.
|
||||
/// @param module the source module to transform
|
||||
/// Calling Run() directly does not perform program state cleanup operations.
|
||||
/// @param program the source program to transform
|
||||
/// @returns the transformation result
|
||||
Output Run(ast::Module* module) override;
|
||||
Output Run(const Program* program) override;
|
||||
|
||||
private:
|
||||
struct Config {
|
||||
@@ -183,7 +183,7 @@ class VertexPulling : public Transform {
|
||||
Config cfg;
|
||||
|
||||
struct State {
|
||||
State(ast::Module* in, ast::Module* out, const Config& c);
|
||||
State(const Program* in, Program* out, const Config& c);
|
||||
explicit State(const State&);
|
||||
~State();
|
||||
|
||||
@@ -263,8 +263,8 @@ class VertexPulling : public Transform {
|
||||
type::Type* GetI32Type() const;
|
||||
type::Type* GetF32Type() const;
|
||||
|
||||
ast::Module* const in;
|
||||
ast::Module* const out;
|
||||
const Program* const in;
|
||||
Program* const out;
|
||||
Config const cfg;
|
||||
|
||||
std::unordered_map<uint32_t, ast::Variable*> location_to_var;
|
||||
|
||||
Reference in New Issue
Block a user