tint/writer: Check extensions are supported
If they're not supported by the backend, print an error that includes the line that enables the extension Fixed: tint:1678 Change-Id: I3732bfba92a8f96c9e5613c5da6f0e197352508f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/105760 Auto-Submit: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
parent
aecf1a2ab5
commit
1a567780d9
|
@ -585,6 +585,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"writer/append_vector.h",
|
||||
"writer/array_length_from_uniform_options.cc",
|
||||
"writer/array_length_from_uniform_options.h",
|
||||
"writer/check_supported_extensions.cc",
|
||||
"writer/check_supported_extensions.h",
|
||||
"writer/flatten_bindings.cc",
|
||||
"writer/flatten_bindings.h",
|
||||
"writer/float_to_string.cc",
|
||||
|
@ -1271,6 +1273,7 @@ if (tint_build_unittests) {
|
|||
tint_unittests_source_set("tint_unittests_writer_src") {
|
||||
sources = [
|
||||
"writer/append_vector_test.cc",
|
||||
"writer/check_supported_extensions_test.cc",
|
||||
"writer/flatten_bindings_test.cc",
|
||||
"writer/float_to_string_test.cc",
|
||||
"writer/generate_external_texture_bindings_test.cc",
|
||||
|
|
|
@ -495,6 +495,8 @@ set(TINT_LIB_SRCS
|
|||
writer/append_vector.h
|
||||
writer/array_length_from_uniform_options.cc
|
||||
writer/array_length_from_uniform_options.h
|
||||
writer/check_supported_extensions.cc
|
||||
writer/check_supported_extensions.h
|
||||
writer/flatten_bindings.cc
|
||||
writer/flatten_bindings.h
|
||||
writer/float_to_string.cc
|
||||
|
@ -889,6 +891,7 @@ if(TINT_BUILD_TESTS)
|
|||
utils/unique_vector_test.cc
|
||||
utils/vector_test.cc
|
||||
writer/append_vector_test.cc
|
||||
writer/check_supported_extensions_test.cc
|
||||
writer/flatten_bindings_test.cc
|
||||
writer/float_to_string_test.cc
|
||||
writer/generate_external_texture_bindings_test.cc
|
||||
|
|
|
@ -1642,6 +1642,16 @@ class ProgramBuilder {
|
|||
return enable;
|
||||
}
|
||||
|
||||
/// Adds the extension to the list of enable directives at the top of the module.
|
||||
/// @param source the enable source
|
||||
/// @param ext the extension to enable
|
||||
/// @return an `ast::Enable` enabling the given extension.
|
||||
const ast::Enable* Enable(const Source& source, ast::Extension ext) {
|
||||
auto* enable = create<ast::Enable>(source, ext);
|
||||
AST().AddEnable(enable);
|
||||
return enable;
|
||||
}
|
||||
|
||||
/// @param name the variable name
|
||||
/// @param options the extra options passed to the ast::Var constructor
|
||||
/// Can be any of the following, in any order:
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2022 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/check_supported_extensions.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/ast/module.h"
|
||||
#include "src/tint/diagnostic/diagnostic.h"
|
||||
#include "src/tint/utils/hashset.h"
|
||||
#include "src/tint/utils/string.h"
|
||||
|
||||
namespace tint::writer {
|
||||
|
||||
bool CheckSupportedExtensions(std::string_view writer_name,
|
||||
const ast::Module& module,
|
||||
diag::List& diags,
|
||||
utils::VectorRef<ast::Extension> supported) {
|
||||
utils::Hashset<ast::Extension, 32> set;
|
||||
for (auto ext : supported) {
|
||||
set.Add(ext);
|
||||
}
|
||||
|
||||
for (auto* enable : module.Enables()) {
|
||||
auto ext = enable->extension;
|
||||
if (!set.Contains(ext)) {
|
||||
diags.add_error(diag::System::Writer,
|
||||
std::string(writer_name) + " backend does not support extension '" +
|
||||
utils::ToString(ext) + "'",
|
||||
enable->source);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace tint::writer
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2022 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_CHECK_SUPPORTED_EXTENSIONS_H_
|
||||
#define SRC_TINT_WRITER_CHECK_SUPPORTED_EXTENSIONS_H_
|
||||
|
||||
#include "src/tint/ast/extension.h"
|
||||
#include "src/tint/utils/vector.h"
|
||||
|
||||
namespace tint::ast {
|
||||
class Module;
|
||||
} // namespace tint::ast
|
||||
namespace tint::diag {
|
||||
class List;
|
||||
} // namespace tint::diag
|
||||
|
||||
namespace tint::writer {
|
||||
|
||||
/// Checks that all the extensions enabled in @p module are found in @p supported, raising an error
|
||||
/// diagnostic if an enabled extension is not supported.
|
||||
/// @param writer_name the name of the writer making this call
|
||||
/// @param module the AST module
|
||||
/// @param diags the diagnostics to append an error to, if needed.
|
||||
/// @returns true if all extensions in use are supported, otherwise returns false.
|
||||
bool CheckSupportedExtensions(std::string_view writer_name,
|
||||
const ast::Module& module,
|
||||
diag::List& diags,
|
||||
utils::VectorRef<ast::Extension> supported);
|
||||
|
||||
} // namespace tint::writer
|
||||
|
||||
#endif // SRC_TINT_WRITER_CHECK_SUPPORTED_EXTENSIONS_H_
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2022 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/check_supported_extensions.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
|
||||
namespace tint::writer {
|
||||
namespace {
|
||||
|
||||
class CheckSupportedExtensionsTest : public ::testing::Test, public ProgramBuilder {};
|
||||
|
||||
TEST_F(CheckSupportedExtensionsTest, Supported) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
ASSERT_TRUE(CheckSupportedExtensions("writer", AST(), Diagnostics(),
|
||||
utils::Vector{
|
||||
ast::Extension::kF16,
|
||||
ast::Extension::kChromiumExperimentalDp4A,
|
||||
}));
|
||||
}
|
||||
|
||||
TEST_F(CheckSupportedExtensionsTest, Unsupported) {
|
||||
Enable(Source{{12, 34}}, ast::Extension::kF16);
|
||||
|
||||
ASSERT_FALSE(CheckSupportedExtensions("writer", AST(), Diagnostics(),
|
||||
utils::Vector{
|
||||
ast::Extension::kChromiumExperimentalDp4A,
|
||||
}));
|
||||
EXPECT_EQ(Diagnostics().str(), "12:34 error: writer backend does not support extension 'f16'");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::writer
|
|
@ -72,6 +72,7 @@
|
|||
#include "src/tint/utils/scoped_assignment.h"
|
||||
#include "src/tint/utils/string.h"
|
||||
#include "src/tint/writer/append_vector.h"
|
||||
#include "src/tint/writer/check_supported_extensions.h"
|
||||
#include "src/tint/writer/float_to_string.h"
|
||||
#include "src/tint/writer/generate_external_texture_bindings.h"
|
||||
|
||||
|
@ -254,6 +255,16 @@ GeneratorImpl::GeneratorImpl(const Program* program) : TextGenerator(program) {}
|
|||
GeneratorImpl::~GeneratorImpl() = default;
|
||||
|
||||
bool GeneratorImpl::Generate() {
|
||||
if (!CheckSupportedExtensions("HLSL", program_->AST(), diagnostics_,
|
||||
utils::Vector{
|
||||
ast::Extension::kChromiumDisableUniformityAnalysis,
|
||||
ast::Extension::kChromiumExperimentalDp4A,
|
||||
ast::Extension::kChromiumExperimentalPushConstant,
|
||||
ast::Extension::kF16,
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const TypeInfo* last_kind = nullptr;
|
||||
size_t last_padding_line = 0;
|
||||
|
||||
|
|
|
@ -28,6 +28,15 @@ TEST_F(HlslGeneratorImplTest, InvalidProgram) {
|
|||
EXPECT_EQ(result.error, "input program is not valid");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest, UnsupportedExtension) {
|
||||
Enable(Source{{12, 34}}, ast::Extension::kUndefined);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
ASSERT_FALSE(gen.Generate());
|
||||
EXPECT_EQ(gen.error(), R"(12:34 error: HLSL backend does not support extension 'undefined')");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest, Generate) {
|
||||
Func("my_func", {}, ty.void_(), {});
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
#include "src/tint/utils/defer.h"
|
||||
#include "src/tint/utils/map.h"
|
||||
#include "src/tint/utils/scoped_assignment.h"
|
||||
#include "src/tint/writer/check_supported_extensions.h"
|
||||
#include "src/tint/writer/float_to_string.h"
|
||||
#include "src/tint/writer/generate_external_texture_bindings.h"
|
||||
|
||||
|
@ -278,6 +279,15 @@ GeneratorImpl::GeneratorImpl(const Program* program) : TextGenerator(program) {}
|
|||
GeneratorImpl::~GeneratorImpl() = default;
|
||||
|
||||
bool GeneratorImpl::Generate() {
|
||||
if (!CheckSupportedExtensions("MSL", program_->AST(), diagnostics_,
|
||||
utils::Vector{
|
||||
ast::Extension::kChromiumDisableUniformityAnalysis,
|
||||
ast::Extension::kChromiumExperimentalPushConstant,
|
||||
ast::Extension::kF16,
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line() << "#include <metal_stdlib>";
|
||||
line();
|
||||
line() << "using namespace metal;";
|
||||
|
|
|
@ -31,6 +31,15 @@ TEST_F(MslGeneratorImplTest, InvalidProgram) {
|
|||
EXPECT_EQ(result.error, "input program is not valid");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, UnsupportedExtension) {
|
||||
Enable(Source{{12, 34}}, ast::Extension::kUndefined);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
ASSERT_FALSE(gen.Generate());
|
||||
EXPECT_EQ(gen.error(), R"(12:34 error: MSL backend does not support extension 'undefined')");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Generate) {
|
||||
Func("my_func", utils::Empty, ty.void_(), utils::Empty,
|
||||
utils::Vector{
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "src/tint/utils/defer.h"
|
||||
#include "src/tint/utils/map.h"
|
||||
#include "src/tint/writer/append_vector.h"
|
||||
#include "src/tint/writer/check_supported_extensions.h"
|
||||
|
||||
namespace tint::writer::spirv {
|
||||
namespace {
|
||||
|
@ -259,6 +260,17 @@ Builder::Builder(const Program* program, bool zero_initialize_workgroup_memory)
|
|||
Builder::~Builder() = default;
|
||||
|
||||
bool Builder::Build() {
|
||||
if (!CheckSupportedExtensions("SPIR-V", builder_.AST(), builder_.Diagnostics(),
|
||||
utils::Vector{
|
||||
ast::Extension::kChromiumDisableUniformityAnalysis,
|
||||
ast::Extension::kChromiumExperimentalDp4A,
|
||||
ast::Extension::kChromiumExperimentalPushConstant,
|
||||
ast::Extension::kF16,
|
||||
})) {
|
||||
error_ = builder_.Diagnostics().str();
|
||||
return false;
|
||||
}
|
||||
|
||||
push_capability(SpvCapabilityShader);
|
||||
|
||||
push_memory_model(spv::Op::OpMemoryModel,
|
||||
|
|
|
@ -29,6 +29,15 @@ TEST_F(BuilderTest, InvalidProgram) {
|
|||
EXPECT_EQ(result.error, "input program is not valid");
|
||||
}
|
||||
|
||||
TEST_F(BuilderTest, UnsupportedExtension) {
|
||||
Enable(Source{{12, 34}}, ast::Extension::kUndefined);
|
||||
|
||||
auto program = std::make_unique<Program>(std::move(*this));
|
||||
auto result = Generate(program.get(), Options{});
|
||||
EXPECT_EQ(result.error,
|
||||
R"(12:34 error: SPIR-V backend does not support extension 'undefined')");
|
||||
}
|
||||
|
||||
TEST_F(BuilderTest, TracksIdBounds) {
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
|
|
Loading…
Reference in New Issue