ir/spirv-writer: Add support for scalar types
Also add a test helper header with some base classes that derive from the IR builder. Bug: tint:1906 Change-Id: If642bc64a50b6cae10363018a8dea8547ab9f542 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131441 Commit-Queue: James Price <jrprice@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
b169165633
commit
02b5b224e3
|
@ -1858,7 +1858,10 @@ if (tint_build_unittests) {
|
|||
]
|
||||
|
||||
if (tint_build_ir) {
|
||||
sources += [ "writer/spirv/generator_impl_ir_test.cc" ]
|
||||
sources += [
|
||||
"writer/spirv/generator_impl_ir_test.cc",
|
||||
"writer/spirv/generator_impl_type_test.cc",
|
||||
]
|
||||
deps += [ ":libtint_ir_src" ]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1228,6 +1228,8 @@ if(TINT_BUILD_TESTS)
|
|||
if(${TINT_BUILD_IR})
|
||||
list(APPEND TINT_TEST_SRCS
|
||||
writer/spirv/generator_impl_ir_test.cc
|
||||
writer/spirv/generator_impl_type_test.cc
|
||||
writer/spirv/test_helper_ir.h
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
|
||||
#include "spirv/unified1/spirv.h"
|
||||
#include "src/tint/ir/module.h"
|
||||
#include "src/tint/switch.h"
|
||||
#include "src/tint/type/bool.h"
|
||||
#include "src/tint/type/f16.h"
|
||||
#include "src/tint/type/f32.h"
|
||||
#include "src/tint/type/i32.h"
|
||||
#include "src/tint/type/type.h"
|
||||
#include "src/tint/type/u32.h"
|
||||
#include "src/tint/type/void.h"
|
||||
#include "src/tint/writer/spirv/module.h"
|
||||
|
||||
namespace tint::writer::spirv {
|
||||
|
@ -45,4 +53,30 @@ bool GeneratorImplIr::Generate() {
|
|||
return true;
|
||||
}
|
||||
|
||||
uint32_t GeneratorImplIr::Type(const type::Type* ty) {
|
||||
return types_.GetOrCreate(ty, [&]() {
|
||||
auto id = module_.NextId();
|
||||
Switch(
|
||||
ty, //
|
||||
[&](const type::Void*) { module_.PushType(spv::Op::OpTypeVoid, {id}); },
|
||||
[&](const type::Bool*) { module_.PushType(spv::Op::OpTypeBool, {id}); },
|
||||
[&](const type::I32*) {
|
||||
module_.PushType(spv::Op::OpTypeInt, {id, 32u, 1u});
|
||||
},
|
||||
[&](const type::U32*) {
|
||||
module_.PushType(spv::Op::OpTypeInt, {id, 32u, 0u});
|
||||
},
|
||||
[&](const type::F32*) {
|
||||
module_.PushType(spv::Op::OpTypeFloat, {id, 32u});
|
||||
},
|
||||
[&](const type::F16*) {
|
||||
module_.PushType(spv::Op::OpTypeFloat, {id, 16u});
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Writer, diagnostics_) << "unhandled type: " << ty->FriendlyName();
|
||||
});
|
||||
return id;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace tint::writer::spirv
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "src/tint/diagnostic/diagnostic.h"
|
||||
#include "src/tint/utils/hashmap.h"
|
||||
#include "src/tint/writer/spirv/binary_writer.h"
|
||||
#include "src/tint/writer/spirv/module.h"
|
||||
|
||||
|
@ -25,6 +26,9 @@
|
|||
namespace tint::ir {
|
||||
class Module;
|
||||
} // namespace tint::ir
|
||||
namespace tint::type {
|
||||
class Type;
|
||||
} // namespace tint::type
|
||||
|
||||
namespace tint::writer::spirv {
|
||||
|
||||
|
@ -49,12 +53,20 @@ class GeneratorImplIr {
|
|||
/// @returns the list of diagnostics raised by the generator
|
||||
diag::List Diagnostics() const { return diagnostics_; }
|
||||
|
||||
/// Get the result ID of the type `ty`, emitting a type declaration instruction if necessary.
|
||||
/// @param ty the type to get the ID for
|
||||
/// @returns the result ID of the type
|
||||
uint32_t Type(const type::Type* ty);
|
||||
|
||||
private:
|
||||
const ir::Module* ir_;
|
||||
spirv::Module module_;
|
||||
BinaryWriter writer_;
|
||||
diag::List diagnostics_;
|
||||
|
||||
/// The map of types to their result IDs.
|
||||
utils::Hashmap<const type::Type*, uint32_t, 8> types_;
|
||||
|
||||
bool zero_init_workgroup_memory_ = false;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,22 +12,14 @@
|
|||
// 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"
|
||||
#include "src/tint/writer/spirv/test_helper_ir.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());
|
||||
ASSERT_TRUE(generator_.Generate()) << generator_.Diagnostics().str();
|
||||
auto got = Disassemble(generator_.Result());
|
||||
EXPECT_EQ(got, R"(OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
)");
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
// 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/type/bool.h"
|
||||
#include "src/tint/type/f16.h"
|
||||
#include "src/tint/type/f32.h"
|
||||
#include "src/tint/type/i32.h"
|
||||
#include "src/tint/type/type.h"
|
||||
#include "src/tint/type/u32.h"
|
||||
#include "src/tint/type/void.h"
|
||||
#include "src/tint/writer/spirv/test_helper_ir.h"
|
||||
|
||||
namespace tint::writer::spirv {
|
||||
namespace {
|
||||
|
||||
TEST_F(SpvGeneratorImplTest, Type_Void) {
|
||||
auto id = generator_.Type(ir.types.Get<type::Void>());
|
||||
EXPECT_EQ(id, 1u);
|
||||
EXPECT_EQ(DumpTypes(), "%1 = OpTypeVoid\n");
|
||||
}
|
||||
|
||||
TEST_F(SpvGeneratorImplTest, Type_Bool) {
|
||||
auto id = generator_.Type(ir.types.Get<type::Bool>());
|
||||
EXPECT_EQ(id, 1u);
|
||||
EXPECT_EQ(DumpTypes(), "%1 = OpTypeBool\n");
|
||||
}
|
||||
|
||||
TEST_F(SpvGeneratorImplTest, Type_I32) {
|
||||
auto id = generator_.Type(ir.types.Get<type::I32>());
|
||||
EXPECT_EQ(id, 1u);
|
||||
EXPECT_EQ(DumpTypes(), "%1 = OpTypeInt 32 1\n");
|
||||
}
|
||||
|
||||
TEST_F(SpvGeneratorImplTest, Type_U32) {
|
||||
auto id = generator_.Type(ir.types.Get<type::U32>());
|
||||
EXPECT_EQ(id, 1u);
|
||||
EXPECT_EQ(DumpTypes(), "%1 = OpTypeInt 32 0\n");
|
||||
}
|
||||
|
||||
TEST_F(SpvGeneratorImplTest, Type_F32) {
|
||||
auto id = generator_.Type(ir.types.Get<type::F32>());
|
||||
EXPECT_EQ(id, 1u);
|
||||
EXPECT_EQ(DumpTypes(), "%1 = OpTypeFloat 32\n");
|
||||
}
|
||||
|
||||
TEST_F(SpvGeneratorImplTest, Type_F16) {
|
||||
auto id = generator_.Type(ir.types.Get<type::F16>());
|
||||
EXPECT_EQ(id, 1u);
|
||||
EXPECT_EQ(DumpTypes(), "%1 = OpTypeFloat 16\n");
|
||||
}
|
||||
|
||||
// Test that we do can emit multiple types.
|
||||
// Includes types with the same opcode but different parameters.
|
||||
TEST_F(SpvGeneratorImplTest, Type_Multiple) {
|
||||
EXPECT_EQ(generator_.Type(ir.types.Get<type::I32>()), 1u);
|
||||
EXPECT_EQ(generator_.Type(ir.types.Get<type::U32>()), 2u);
|
||||
EXPECT_EQ(generator_.Type(ir.types.Get<type::F32>()), 3u);
|
||||
EXPECT_EQ(generator_.Type(ir.types.Get<type::F16>()), 4u);
|
||||
EXPECT_EQ(DumpTypes(), R"(%1 = OpTypeInt 32 1
|
||||
%2 = OpTypeInt 32 0
|
||||
%3 = OpTypeFloat 32
|
||||
%4 = OpTypeFloat 16
|
||||
)");
|
||||
}
|
||||
|
||||
// Test that we do not emit the same type more than once.
|
||||
TEST_F(SpvGeneratorImplTest, Type_Deduplicate) {
|
||||
auto* i32 = ir.types.Get<type::I32>();
|
||||
EXPECT_EQ(generator_.Type(i32), 1u);
|
||||
EXPECT_EQ(generator_.Type(i32), 1u);
|
||||
EXPECT_EQ(generator_.Type(i32), 1u);
|
||||
EXPECT_EQ(DumpTypes(), "%1 = OpTypeInt 32 1\n");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::writer::spirv
|
|
@ -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.
|
||||
|
||||
#ifndef SRC_TINT_WRITER_SPIRV_TEST_HELPER_IR_H_
|
||||
#define SRC_TINT_WRITER_SPIRV_TEST_HELPER_IR_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/tint/ir/builder.h"
|
||||
#include "src/tint/writer/spirv/generator_impl_ir.h"
|
||||
#include "src/tint/writer/spirv/spv_dump.h"
|
||||
|
||||
namespace tint::writer::spirv {
|
||||
|
||||
/// Base helper class for testing the SPIR-V generator implementation.
|
||||
template <typename BASE>
|
||||
class SpvGeneratorTestHelperBase : public ir::Builder, public BASE {
|
||||
public:
|
||||
SpvGeneratorTestHelperBase() : generator_(&ir, false) {}
|
||||
|
||||
protected:
|
||||
/// The SPIR-V generator.
|
||||
GeneratorImplIr generator_;
|
||||
|
||||
/// @returns the disassembled types from the generated module.
|
||||
std::string DumpTypes() { return DumpInstructions(generator_.Module().Types()); }
|
||||
};
|
||||
|
||||
using SpvGeneratorImplTest = SpvGeneratorTestHelperBase<testing::Test>;
|
||||
|
||||
template <typename T>
|
||||
using SpvGeneratorImplTestWithParam = SpvGeneratorTestHelperBase<testing::TestWithParam<T>>;
|
||||
|
||||
} // namespace tint::writer::spirv
|
||||
|
||||
#endif // SRC_TINT_WRITER_SPIRV_TEST_HELPER_IR_H_
|
Loading…
Reference in New Issue