mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-13 00:26:00 +00:00
tint/writer/spirv: Add path for generating from IR
This adds a GeneratorImplIr class and an option to the SPIR-V writer to use it instead of the AST-based GeneratorImpl class. The Tint exe now has a --use-ir flag which will use this path. Bug: tint:1906 Change-Id: I34cc5c7468c8faf4a808669da8c44551ad01da8f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131341 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: James Price <jrprice@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
1164fe7475
commit
8f9ea96c20
@ -974,6 +974,17 @@ libtint_source_set("libtint_spv_writer_src") {
|
|||||||
":libtint_utils_src",
|
":libtint_utils_src",
|
||||||
":libtint_writer_src",
|
":libtint_writer_src",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (tint_build_ir) {
|
||||||
|
sources += [
|
||||||
|
"writer/spirv/generator_impl_ir.cc",
|
||||||
|
"writer/spirv/generator_impl_ir.h",
|
||||||
|
]
|
||||||
|
deps += [
|
||||||
|
":libtint_ir_builder_src",
|
||||||
|
":libtint_ir_src",
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
libtint_source_set("libtint_wgsl_reader_src") {
|
libtint_source_set("libtint_wgsl_reader_src") {
|
||||||
@ -1845,6 +1856,11 @@ if (tint_build_unittests) {
|
|||||||
":tint_unittests_ast_src",
|
":tint_unittests_ast_src",
|
||||||
"${tint_spirv_tools_dir}/:spvtools",
|
"${tint_spirv_tools_dir}/:spvtools",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (tint_build_ir) {
|
||||||
|
sources += [ "writer/spirv/generator_impl_ir_test.cc" ]
|
||||||
|
deps += [ ":libtint_ir_src" ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tint_unittests_source_set("tint_unittests_wgsl_reader_src") {
|
tint_unittests_source_set("tint_unittests_wgsl_reader_src") {
|
||||||
|
@ -650,6 +650,13 @@ if(${TINT_BUILD_SPV_WRITER})
|
|||||||
writer/spirv/operand.h
|
writer/spirv/operand.h
|
||||||
writer/spirv/scalar_constant.h
|
writer/spirv/scalar_constant.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(${TINT_BUILD_IR})
|
||||||
|
list(APPEND TINT_LIB_SRCS
|
||||||
|
writer/spirv/generator_impl_ir.cc
|
||||||
|
writer/spirv/generator_impl_ir.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${TINT_BUILD_WGSL_WRITER})
|
if(${TINT_BUILD_WGSL_WRITER})
|
||||||
@ -1217,6 +1224,12 @@ if(TINT_BUILD_TESTS)
|
|||||||
writer/spirv/spv_dump.h
|
writer/spirv/spv_dump.h
|
||||||
writer/spirv/test_helper.h
|
writer/spirv/test_helper.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(${TINT_BUILD_IR})
|
||||||
|
list(APPEND TINT_TEST_SRCS
|
||||||
|
writer/spirv/generator_impl_ir_test.cc
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${TINT_BUILD_WGSL_WRITER})
|
if(${TINT_BUILD_WGSL_WRITER})
|
||||||
|
@ -111,6 +111,7 @@ struct Options {
|
|||||||
#if TINT_BUILD_IR
|
#if TINT_BUILD_IR
|
||||||
bool dump_ir = false;
|
bool dump_ir = false;
|
||||||
bool dump_ir_graph = false;
|
bool dump_ir_graph = false;
|
||||||
|
bool use_ir = false;
|
||||||
#endif // TINT_BUILD_IR
|
#endif // TINT_BUILD_IR
|
||||||
|
|
||||||
#if TINT_BUILD_SYNTAX_TREE_WRITER
|
#if TINT_BUILD_SYNTAX_TREE_WRITER
|
||||||
@ -388,6 +389,8 @@ bool ParseArgs(const std::vector<std::string>& args, Options* opts) {
|
|||||||
opts->dump_ir = true;
|
opts->dump_ir = true;
|
||||||
} else if (arg == "--dump-ir-graph") {
|
} else if (arg == "--dump-ir-graph") {
|
||||||
opts->dump_ir_graph = true;
|
opts->dump_ir_graph = true;
|
||||||
|
} else if (arg == "--use-ir") {
|
||||||
|
opts->use_ir = true;
|
||||||
#endif // TINT_BUILD_IR
|
#endif // TINT_BUILD_IR
|
||||||
#if TINT_BUILD_SYNTAX_TREE_WRITER
|
#if TINT_BUILD_SYNTAX_TREE_WRITER
|
||||||
} else if (arg == "--dump-ast") {
|
} else if (arg == "--dump-ast") {
|
||||||
@ -548,6 +551,9 @@ bool GenerateSpirv(const tint::Program* program, const Options& options) {
|
|||||||
gen_options.disable_workgroup_init = options.disable_workgroup_init;
|
gen_options.disable_workgroup_init = options.disable_workgroup_init;
|
||||||
gen_options.external_texture_options.bindings_map =
|
gen_options.external_texture_options.bindings_map =
|
||||||
tint::cmd::GenerateExternalTextureBindings(program);
|
tint::cmd::GenerateExternalTextureBindings(program);
|
||||||
|
#if TINT_BUILD_IR
|
||||||
|
gen_options.use_tint_ir = options.use_ir;
|
||||||
|
#endif
|
||||||
auto result = tint::writer::spirv::Generate(program, gen_options);
|
auto result = tint::writer::spirv::Generate(program, gen_options);
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
tint::cmd::PrintWGSL(std::cerr, *program);
|
tint::cmd::PrintWGSL(std::cerr, *program);
|
||||||
@ -1023,7 +1029,8 @@ int main(int argc, const char** argv) {
|
|||||||
#if TINT_BUILD_IR
|
#if TINT_BUILD_IR
|
||||||
usage +=
|
usage +=
|
||||||
" --dump-ir -- Writes the IR to stdout\n"
|
" --dump-ir -- Writes the IR to stdout\n"
|
||||||
" --dump-ir-graph -- Writes the IR graph to 'tint.dot' as a dot graph\n";
|
" --dump-ir-graph -- Writes the IR graph to 'tint.dot' as a dot graph\n"
|
||||||
|
" --use-ir -- Use the IR for writers and transforms when possible\n";
|
||||||
#endif // TINT_BUILD_IR
|
#endif // TINT_BUILD_IR
|
||||||
#if TINT_BUILD_SYNTAX_TREE_WRITER
|
#if TINT_BUILD_SYNTAX_TREE_WRITER
|
||||||
usage += " --dump-ast -- Writes the AST to stdout\n";
|
usage += " --dump-ast -- Writes the AST to stdout\n";
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "src/tint/writer/spirv/generator_impl.h"
|
#include "src/tint/writer/spirv/generator_impl.h"
|
||||||
|
#if TINT_BUILD_IR
|
||||||
|
#include "src/tint/ir/converter.h" // nogncheck
|
||||||
|
#include "src/tint/writer/spirv/generator_impl_ir.h" // nogncheck
|
||||||
|
#endif // TINT_BUILD_IR
|
||||||
|
|
||||||
namespace tint::writer::spirv {
|
namespace tint::writer::spirv {
|
||||||
|
|
||||||
@ -31,23 +35,41 @@ Result Generate(const Program* program, const Options& options) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanitize the program.
|
|
||||||
auto sanitized_result = Sanitize(program, options);
|
|
||||||
if (!sanitized_result.program.IsValid()) {
|
|
||||||
result.success = false;
|
|
||||||
result.error = sanitized_result.program.Diagnostics().str();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the SPIR-V code.
|
|
||||||
bool zero_initialize_workgroup_memory =
|
bool zero_initialize_workgroup_memory =
|
||||||
!options.disable_workgroup_init && options.use_zero_initialize_workgroup_memory_extension;
|
!options.disable_workgroup_init && options.use_zero_initialize_workgroup_memory_extension;
|
||||||
|
|
||||||
auto impl = std::make_unique<GeneratorImpl>(&sanitized_result.program,
|
#if TINT_BUILD_IR
|
||||||
zero_initialize_workgroup_memory);
|
if (options.use_tint_ir) {
|
||||||
result.success = impl->Generate();
|
// Convert the AST program to an IR module.
|
||||||
result.error = impl->Diagnostics().str();
|
auto ir = ir::Converter::FromProgram(program);
|
||||||
result.spirv = std::move(impl->Result());
|
if (!ir) {
|
||||||
|
result.error = "IR converter: " + ir.Failure();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the SPIR-V code.
|
||||||
|
auto impl = std::make_unique<GeneratorImplIr>(&ir.Get(), zero_initialize_workgroup_memory);
|
||||||
|
result.success = impl->Generate();
|
||||||
|
result.error = impl->Diagnostics().str();
|
||||||
|
result.spirv = std::move(impl->Result());
|
||||||
|
} else // NOLINT(readability/braces)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// Sanitize the program.
|
||||||
|
auto sanitized_result = Sanitize(program, options);
|
||||||
|
if (!sanitized_result.program.IsValid()) {
|
||||||
|
result.success = false;
|
||||||
|
result.error = sanitized_result.program.Diagnostics().str();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the SPIR-V code.
|
||||||
|
auto impl = std::make_unique<GeneratorImpl>(&sanitized_result.program,
|
||||||
|
zero_initialize_workgroup_memory);
|
||||||
|
result.success = impl->Generate();
|
||||||
|
result.error = impl->Diagnostics().str();
|
||||||
|
result.spirv = std::move(impl->Result());
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,11 @@ struct Options {
|
|||||||
/// VK_KHR_zero_initialize_workgroup_memory is enabled.
|
/// VK_KHR_zero_initialize_workgroup_memory is enabled.
|
||||||
bool use_zero_initialize_workgroup_memory_extension = false;
|
bool use_zero_initialize_workgroup_memory_extension = false;
|
||||||
|
|
||||||
|
#if TINT_BUILD_IR
|
||||||
|
/// Set to `true` to generate SPIR-V via the Tint IR instead of from the AST.
|
||||||
|
bool use_tint_ir = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
|
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
|
||||||
TINT_REFLECT(disable_robustness,
|
TINT_REFLECT(disable_robustness,
|
||||||
emit_vertex_point_size,
|
emit_vertex_point_size,
|
||||||
|
48
src/tint/writer/spirv/generator_impl_ir.cc
Normal file
48
src/tint/writer/spirv/generator_impl_ir.cc
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2023 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "src/tint/writer/spirv/generator_impl_ir.h"
|
||||||
|
|
||||||
|
#include "spirv/unified1/spirv.h"
|
||||||
|
#include "src/tint/ir/module.h"
|
||||||
|
#include "src/tint/writer/spirv/module.h"
|
||||||
|
|
||||||
|
namespace tint::writer::spirv {
|
||||||
|
|
||||||
|
GeneratorImplIr::GeneratorImplIr(const ir::Module* module, bool zero_init_workgroup_mem)
|
||||||
|
: ir_(module), zero_init_workgroup_memory_(zero_init_workgroup_mem) {}
|
||||||
|
|
||||||
|
bool GeneratorImplIr::Generate() {
|
||||||
|
// TODO(crbug.com/tint/1906): Check supported extensions.
|
||||||
|
|
||||||
|
module_.PushCapability(SpvCapabilityShader);
|
||||||
|
module_.PushMemoryModel(spv::Op::OpMemoryModel, {U32Operand(SpvAddressingModelLogical),
|
||||||
|
U32Operand(SpvMemoryModelGLSL450)});
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1906): Emit extensions.
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1906): Emit variables.
|
||||||
|
(void)zero_init_workgroup_memory_;
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1906): Emit functions.
|
||||||
|
(void)ir_;
|
||||||
|
|
||||||
|
// Serialize the module into binary SPIR-V.
|
||||||
|
writer_.WriteHeader(module_.IdBound());
|
||||||
|
writer_.WriteModule(&module_);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tint::writer::spirv
|
63
src/tint/writer/spirv/generator_impl_ir.h
Normal file
63
src/tint/writer/spirv/generator_impl_ir.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright 2023 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef SRC_TINT_WRITER_SPIRV_GENERATOR_IMPL_IR_H_
|
||||||
|
#define SRC_TINT_WRITER_SPIRV_GENERATOR_IMPL_IR_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/tint/diagnostic/diagnostic.h"
|
||||||
|
#include "src/tint/writer/spirv/binary_writer.h"
|
||||||
|
#include "src/tint/writer/spirv/module.h"
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
namespace tint::ir {
|
||||||
|
class Module;
|
||||||
|
} // namespace tint::ir
|
||||||
|
|
||||||
|
namespace tint::writer::spirv {
|
||||||
|
|
||||||
|
/// Implementation class for SPIR-V generator
|
||||||
|
class GeneratorImplIr {
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// @param module the Tint IR module to generate
|
||||||
|
/// @param zero_init_workgroup_memory `true` to initialize all the variables in the Workgroup
|
||||||
|
/// storage class with OpConstantNull
|
||||||
|
GeneratorImplIr(const ir::Module* module, bool zero_init_workgroup_memory);
|
||||||
|
|
||||||
|
/// @returns true on successful generation; false otherwise
|
||||||
|
bool Generate();
|
||||||
|
|
||||||
|
/// @returns the module that this generator has produced
|
||||||
|
spirv::Module& Module() { return module_; }
|
||||||
|
|
||||||
|
/// @returns the generated SPIR-V binary data
|
||||||
|
const std::vector<uint32_t>& Result() const { return writer_.result(); }
|
||||||
|
|
||||||
|
/// @returns the list of diagnostics raised by the generator
|
||||||
|
diag::List Diagnostics() const { return diagnostics_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ir::Module* ir_;
|
||||||
|
spirv::Module module_;
|
||||||
|
BinaryWriter writer_;
|
||||||
|
diag::List diagnostics_;
|
||||||
|
|
||||||
|
bool zero_init_workgroup_memory_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace tint::writer::spirv
|
||||||
|
|
||||||
|
#endif // SRC_TINT_WRITER_SPIRV_GENERATOR_IMPL_IR_H_
|
37
src/tint/writer/spirv/generator_impl_ir_test.cc
Normal file
37
src/tint/writer/spirv/generator_impl_ir_test.cc
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2023 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "src/tint/ir/module.h"
|
||||||
|
#include "src/tint/writer/spirv/generator_impl_ir.h"
|
||||||
|
#include "src/tint/writer/spirv/spv_dump.h"
|
||||||
|
|
||||||
|
namespace tint::writer::spirv {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using SpvGeneratorImplTest = testing::Test;
|
||||||
|
|
||||||
|
TEST_F(SpvGeneratorImplTest, ModuleHeader) {
|
||||||
|
ir::Module module;
|
||||||
|
GeneratorImplIr generator(&module, false);
|
||||||
|
ASSERT_TRUE(generator.Generate()) << generator.Diagnostics().str();
|
||||||
|
auto got = Disassemble(generator.Result());
|
||||||
|
EXPECT_EQ(got, R"(OpCapability Shader
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace tint::writer::spirv
|
@ -18,7 +18,6 @@
|
|||||||
#include "src/tint/writer/spirv/binary_writer.h"
|
#include "src/tint/writer/spirv/binary_writer.h"
|
||||||
|
|
||||||
namespace tint::writer::spirv {
|
namespace tint::writer::spirv {
|
||||||
namespace {
|
|
||||||
|
|
||||||
std::string Disassemble(const std::vector<uint32_t>& data) {
|
std::string Disassemble(const std::vector<uint32_t>& data) {
|
||||||
std::string spv_errors;
|
std::string spv_errors;
|
||||||
@ -56,8 +55,6 @@ std::string Disassemble(const std::vector<uint32_t>& data) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
std::string DumpBuilder(Builder& builder) {
|
std::string DumpBuilder(Builder& builder) {
|
||||||
BinaryWriter writer;
|
BinaryWriter writer;
|
||||||
writer.WriteHeader(builder.Module().IdBound());
|
writer.WriteHeader(builder.Module().IdBound());
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
|
|
||||||
namespace tint::writer::spirv {
|
namespace tint::writer::spirv {
|
||||||
|
|
||||||
|
/// Disassembles SPIR-V binary data into its textual form.
|
||||||
|
/// @param data the SPIR-V binary data
|
||||||
|
/// @returns the disassembled SPIR-V string
|
||||||
|
std::string Disassemble(const std::vector<uint32_t>& data);
|
||||||
|
|
||||||
/// Dumps the given builder to a SPIR-V disassembly string
|
/// Dumps the given builder to a SPIR-V disassembly string
|
||||||
/// @param builder the builder to convert
|
/// @param builder the builder to convert
|
||||||
/// @returns the builder as a SPIR-V disassembly string
|
/// @returns the builder as a SPIR-V disassembly string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user