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) {
|
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" ]
|
deps += [ ":libtint_ir_src" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1228,6 +1228,8 @@ if(TINT_BUILD_TESTS)
|
||||||
if(${TINT_BUILD_IR})
|
if(${TINT_BUILD_IR})
|
||||||
list(APPEND TINT_TEST_SRCS
|
list(APPEND TINT_TEST_SRCS
|
||||||
writer/spirv/generator_impl_ir_test.cc
|
writer/spirv/generator_impl_ir_test.cc
|
||||||
|
writer/spirv/generator_impl_type_test.cc
|
||||||
|
writer/spirv/test_helper_ir.h
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -16,6 +16,14 @@
|
||||||
|
|
||||||
#include "spirv/unified1/spirv.h"
|
#include "spirv/unified1/spirv.h"
|
||||||
#include "src/tint/ir/module.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"
|
#include "src/tint/writer/spirv/module.h"
|
||||||
|
|
||||||
namespace tint::writer::spirv {
|
namespace tint::writer::spirv {
|
||||||
|
@ -45,4 +53,30 @@ bool GeneratorImplIr::Generate() {
|
||||||
return true;
|
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
|
} // namespace tint::writer::spirv
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/tint/diagnostic/diagnostic.h"
|
#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/binary_writer.h"
|
||||||
#include "src/tint/writer/spirv/module.h"
|
#include "src/tint/writer/spirv/module.h"
|
||||||
|
|
||||||
|
@ -25,6 +26,9 @@
|
||||||
namespace tint::ir {
|
namespace tint::ir {
|
||||||
class Module;
|
class Module;
|
||||||
} // namespace tint::ir
|
} // namespace tint::ir
|
||||||
|
namespace tint::type {
|
||||||
|
class Type;
|
||||||
|
} // namespace tint::type
|
||||||
|
|
||||||
namespace tint::writer::spirv {
|
namespace tint::writer::spirv {
|
||||||
|
|
||||||
|
@ -49,12 +53,20 @@ class GeneratorImplIr {
|
||||||
/// @returns the list of diagnostics raised by the generator
|
/// @returns the list of diagnostics raised by the generator
|
||||||
diag::List Diagnostics() const { return diagnostics_; }
|
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:
|
private:
|
||||||
const ir::Module* ir_;
|
const ir::Module* ir_;
|
||||||
spirv::Module module_;
|
spirv::Module module_;
|
||||||
BinaryWriter writer_;
|
BinaryWriter writer_;
|
||||||
diag::List diagnostics_;
|
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;
|
bool zero_init_workgroup_memory_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,22 +12,14 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "src/tint/writer/spirv/test_helper_ir.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 tint::writer::spirv {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using SpvGeneratorImplTest = testing::Test;
|
|
||||||
|
|
||||||
TEST_F(SpvGeneratorImplTest, ModuleHeader) {
|
TEST_F(SpvGeneratorImplTest, ModuleHeader) {
|
||||||
ir::Module module;
|
ASSERT_TRUE(generator_.Generate()) << generator_.Diagnostics().str();
|
||||||
GeneratorImplIr generator(&module, false);
|
auto got = Disassemble(generator_.Result());
|
||||||
ASSERT_TRUE(generator.Generate()) << generator.Diagnostics().str();
|
|
||||||
auto got = Disassemble(generator.Result());
|
|
||||||
EXPECT_EQ(got, R"(OpCapability Shader
|
EXPECT_EQ(got, R"(OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
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