mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-05 06:03:34 +00:00
Create SPIR-V writer skeleton.
This CL creates the skeleton for the SPIR-V writer. Bug: tint:5 Change-Id: I849d8766d32d48314a51096710272f9821e2c1c4 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/16641 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
3040f618a5
commit
e4392c9ab5
@ -48,6 +48,8 @@ if (${TINT_BUILD_SPV_PARSER})
|
|||||||
include_directories("${PROJECT_SOURCE_DIR}/third_party/spirv-tools/include")
|
include_directories("${PROJECT_SOURCE_DIR}/third_party/spirv-tools/include")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/third_party/spirv-headers/include")
|
||||||
|
|
||||||
if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") OR
|
if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") OR
|
||||||
("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") OR
|
("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") OR
|
||||||
(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") AND
|
(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") AND
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "src/reader/wgsl/parser.h"
|
#include "src/reader/wgsl/parser.h"
|
||||||
#include "src/type_determiner.h"
|
#include "src/type_determiner.h"
|
||||||
#include "src/validator.h"
|
#include "src/validator.h"
|
||||||
#include "src/writer/spv/generator.h"
|
#include "src/writer/spirv/generator.h"
|
||||||
#include "src/writer/wgsl/generator.h"
|
#include "src/writer/wgsl/generator.h"
|
||||||
#include "src/writer/writer.h"
|
#include "src/writer/writer.h"
|
||||||
|
|
||||||
@ -280,7 +280,8 @@ int main(int argc, const char** argv) {
|
|||||||
|
|
||||||
std::unique_ptr<tint::writer::Writer> writer;
|
std::unique_ptr<tint::writer::Writer> writer;
|
||||||
if (options.format == Format::kSpirv || options.format == Format::kSpvAsm) {
|
if (options.format == Format::kSpirv || options.format == Format::kSpvAsm) {
|
||||||
writer = std::make_unique<tint::writer::spv::Generator>(std::move(module));
|
writer =
|
||||||
|
std::make_unique<tint::writer::spirv::Generator>(std::move(module));
|
||||||
} else if (options.format == Format::kWgsl) {
|
} else if (options.format == Format::kWgsl) {
|
||||||
writer = std::make_unique<tint::writer::wgsl::Generator>(std::move(module));
|
writer = std::make_unique<tint::writer::wgsl::Generator>(std::move(module));
|
||||||
} else {
|
} else {
|
||||||
@ -294,12 +295,12 @@ int main(int argc, const char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.format == Format::kSpvAsm) {
|
if (options.format == Format::kSpvAsm) {
|
||||||
auto w = static_cast<tint::writer::spv::Generator*>(writer.get());
|
auto w = static_cast<tint::writer::spirv::Generator*>(writer.get());
|
||||||
auto str = Disassemble(w->result());
|
auto str = Disassemble(w->result());
|
||||||
// TODO(dsinclair): Write to file if output_file given
|
// TODO(dsinclair): Write to file if output_file given
|
||||||
std::cout << str << std::endl;
|
std::cout << str << std::endl;
|
||||||
} else if (options.format == Format::kSpirv) {
|
} else if (options.format == Format::kSpirv) {
|
||||||
// auto w = static_cast<tint::writer::spv::Generator*>(writer.get());
|
// auto w = static_cast<tint::writer::spirv::Generator*>(writer.get());
|
||||||
// TODO(dsincliair): Write to to file
|
// TODO(dsincliair): Write to to file
|
||||||
} else if (options.format == Format::kWgsl) {
|
} else if (options.format == Format::kWgsl) {
|
||||||
auto w = static_cast<tint::writer::wgsl::Generator*>(writer.get());
|
auto w = static_cast<tint::writer::wgsl::Generator*>(writer.get());
|
||||||
|
@ -177,8 +177,16 @@ set(TINT_LIB_SRCS
|
|||||||
validator_impl.cc
|
validator_impl.cc
|
||||||
validator_impl.h
|
validator_impl.h
|
||||||
# TODO(dsinclair): The writers should all be optional
|
# TODO(dsinclair): The writers should all be optional
|
||||||
writer/spv/generator.cc
|
writer/spirv/binary_writer.cc
|
||||||
writer/spv/generator.h
|
writer/spirv/binary_writer.h
|
||||||
|
writer/spirv/builder.cc
|
||||||
|
writer/spirv/builder.h
|
||||||
|
writer/spirv/generator.cc
|
||||||
|
writer/spirv/generator.h
|
||||||
|
writer/spirv/instruction.cc
|
||||||
|
writer/spirv/instruction.h
|
||||||
|
writer/spirv/operand.cc
|
||||||
|
writer/spirv/operand.h
|
||||||
writer/wgsl/generator.cc
|
writer/wgsl/generator.cc
|
||||||
writer/wgsl/generator.h
|
writer/wgsl/generator.h
|
||||||
writer/wgsl/generator_impl.cc
|
writer/wgsl/generator_impl.cc
|
||||||
@ -319,6 +327,10 @@ set(TINT_TEST_SRCS
|
|||||||
reader/wgsl/token_test.cc
|
reader/wgsl/token_test.cc
|
||||||
type_manager_test.cc
|
type_manager_test.cc
|
||||||
validator_impl_import_test.cc
|
validator_impl_import_test.cc
|
||||||
|
writer/spirv/binary_writer_test.cc
|
||||||
|
writer/spirv/builder_test.cc
|
||||||
|
writer/spirv/instruction_test.cc
|
||||||
|
writer/spirv/operand_test.cc
|
||||||
writer/wgsl/generator_impl_test.cc
|
writer/wgsl/generator_impl_test.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,11 +12,12 @@
|
|||||||
// 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 "src/reader/spv/parser_impl.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "source/opt/build_module.h"
|
#include "source/opt/build_module.h"
|
||||||
#include "spirv-tools/libspirv.hpp"
|
#include "spirv-tools/libspirv.hpp"
|
||||||
#include "src/reader/spirv/parser_impl.h"
|
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace reader {
|
namespace reader {
|
||||||
|
@ -12,12 +12,11 @@
|
|||||||
// 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 "src/reader/spirv/parser_impl.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
|
#include "src/reader/spirv/parser_impl.h"
|
||||||
#include "src/reader/spirv/spirv_tools_helpers_test.h"
|
#include "src/reader/spirv/spirv_tools_helpers_test.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
71
src/writer/spirv/binary_writer.cc
Normal file
71
src/writer/spirv/binary_writer.cc
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2020 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/writer/spirv/binary_writer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// TODO(dsinclair): Reserve a generator ID for Tint.
|
||||||
|
// https://github.com/KhronosGroup/SPIRV-Headers/blob/master/include/spirv/spir-v.xml#L75
|
||||||
|
const uint32_t kGeneratorId = 0;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
BinaryWriter::BinaryWriter() = default;
|
||||||
|
|
||||||
|
BinaryWriter::~BinaryWriter() = default;
|
||||||
|
|
||||||
|
bool BinaryWriter::Write(const Builder& builder) {
|
||||||
|
out_.resize(builder.total_size(), 0);
|
||||||
|
|
||||||
|
out_[idx_++] = spv::MagicNumber;
|
||||||
|
out_[idx_++] = 0x00010300; // Version 1.3
|
||||||
|
out_[idx_++] = kGeneratorId;
|
||||||
|
out_[idx_++] = builder.id_bound();
|
||||||
|
out_[idx_++] = 0;
|
||||||
|
|
||||||
|
builder.iterate([this](const Instruction& inst) {
|
||||||
|
out_[idx_++] =
|
||||||
|
inst.word_length() << 16 | static_cast<uint32_t>(inst.opcode());
|
||||||
|
|
||||||
|
for (const auto& op : inst.operands()) {
|
||||||
|
process_op(op);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::process_op(const Operand& op) {
|
||||||
|
if (op.IsFloat()) {
|
||||||
|
auto f = op.to_f();
|
||||||
|
memcpy(out_.data() + idx_, &f, 4);
|
||||||
|
} else if (op.IsInt()) {
|
||||||
|
out_[idx_] = op.to_i();
|
||||||
|
} else {
|
||||||
|
const auto& str = op.to_s();
|
||||||
|
// This depends on the vector being initialized to 0 values so the string
|
||||||
|
// is correctly padded.
|
||||||
|
memcpy(out_.data() + idx_, str.c_str(), str.size() + 1);
|
||||||
|
}
|
||||||
|
idx_ += op.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
53
src/writer/spirv/binary_writer.h
Normal file
53
src/writer/spirv/binary_writer.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2020 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_WRITER_SPIRV_BINARY_WRITER_H_
|
||||||
|
#define SRC_WRITER_SPIRV_BINARY_WRITER_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/writer/spirv/builder.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
/// Writer to convert from builder to SPIR-V binary
|
||||||
|
class BinaryWriter {
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
BinaryWriter();
|
||||||
|
~BinaryWriter();
|
||||||
|
|
||||||
|
/// Writes the given builder data into a binary
|
||||||
|
/// @param builder the builder to assemble from
|
||||||
|
/// @returns true on success
|
||||||
|
bool Write(const Builder& builder);
|
||||||
|
|
||||||
|
/// @returns the assembled SPIR-V
|
||||||
|
const std::vector<uint32_t>& result() const { return out_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void process_op(const Operand& op);
|
||||||
|
|
||||||
|
/// Word index of the next word to fill.
|
||||||
|
size_t idx_ = 0;
|
||||||
|
std::vector<uint32_t> out_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // SRC_WRITER_SPIRV_BINARY_WRITER_H_
|
117
src/writer/spirv/binary_writer_test.cc
Normal file
117
src/writer/spirv/binary_writer_test.cc
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright 2020 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/writer/spirv/binary_writer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "spirv/unified1/spirv.hpp11"
|
||||||
|
#include "src/writer/spirv/builder.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
using BinaryWriterTest = testing::Test;
|
||||||
|
|
||||||
|
TEST_F(BinaryWriterTest, Preamble) {
|
||||||
|
Builder b;
|
||||||
|
BinaryWriter bw;
|
||||||
|
ASSERT_TRUE(bw.Write(b));
|
||||||
|
|
||||||
|
auto res = bw.result();
|
||||||
|
ASSERT_EQ(res.size(), 5);
|
||||||
|
EXPECT_EQ(res[0], spv::MagicNumber);
|
||||||
|
EXPECT_EQ(res[1], 0x00010300); // SPIR-V 1.3
|
||||||
|
EXPECT_EQ(res[2], 0); // Generator ID
|
||||||
|
EXPECT_EQ(res[3], 1); // ID Bound
|
||||||
|
EXPECT_EQ(res[4], 0); // Reserved
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BinaryWriterTest, Float) {
|
||||||
|
Builder b;
|
||||||
|
b.push_preamble(spv::Op::OpNop, {Operand::Float(2.4f)});
|
||||||
|
BinaryWriter bw;
|
||||||
|
ASSERT_TRUE(bw.Write(b));
|
||||||
|
|
||||||
|
auto res = bw.result();
|
||||||
|
ASSERT_EQ(res.size(), 7);
|
||||||
|
float f;
|
||||||
|
memcpy(&f, res.data() + 6, 4);
|
||||||
|
EXPECT_EQ(f, 2.4f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BinaryWriterTest, Int) {
|
||||||
|
Builder b;
|
||||||
|
b.push_preamble(spv::Op::OpNop, {Operand::Int(2)});
|
||||||
|
BinaryWriter bw;
|
||||||
|
ASSERT_TRUE(bw.Write(b));
|
||||||
|
|
||||||
|
auto res = bw.result();
|
||||||
|
ASSERT_EQ(res.size(), 7);
|
||||||
|
EXPECT_EQ(res[6], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BinaryWriterTest, String) {
|
||||||
|
Builder b;
|
||||||
|
b.push_preamble(spv::Op::OpNop, {Operand::String("my_string")});
|
||||||
|
BinaryWriter bw;
|
||||||
|
ASSERT_TRUE(bw.Write(b));
|
||||||
|
|
||||||
|
auto res = bw.result();
|
||||||
|
ASSERT_EQ(res.size(), 9);
|
||||||
|
|
||||||
|
uint8_t* v = reinterpret_cast<uint8_t*>(res.data()) + (6 * 4);
|
||||||
|
EXPECT_EQ(v[0], 'm');
|
||||||
|
EXPECT_EQ(v[1], 'y');
|
||||||
|
EXPECT_EQ(v[2], '_');
|
||||||
|
EXPECT_EQ(v[3], 's');
|
||||||
|
EXPECT_EQ(v[4], 't');
|
||||||
|
EXPECT_EQ(v[5], 'r');
|
||||||
|
EXPECT_EQ(v[6], 'i');
|
||||||
|
EXPECT_EQ(v[7], 'n');
|
||||||
|
EXPECT_EQ(v[8], 'g');
|
||||||
|
EXPECT_EQ(v[9], '\0');
|
||||||
|
EXPECT_EQ(v[10], '\0');
|
||||||
|
EXPECT_EQ(v[11], '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BinaryWriterTest, String_Multiple4Length) {
|
||||||
|
Builder b;
|
||||||
|
b.push_preamble(spv::Op::OpNop, {Operand::String("mystring")});
|
||||||
|
BinaryWriter bw;
|
||||||
|
ASSERT_TRUE(bw.Write(b));
|
||||||
|
|
||||||
|
auto res = bw.result();
|
||||||
|
ASSERT_EQ(res.size(), 9);
|
||||||
|
|
||||||
|
uint8_t* v = reinterpret_cast<uint8_t*>(res.data()) + (6 * 4);
|
||||||
|
EXPECT_EQ(v[0], 'm');
|
||||||
|
EXPECT_EQ(v[1], 'y');
|
||||||
|
EXPECT_EQ(v[2], 's');
|
||||||
|
EXPECT_EQ(v[3], 't');
|
||||||
|
EXPECT_EQ(v[4], 'r');
|
||||||
|
EXPECT_EQ(v[5], 'i');
|
||||||
|
EXPECT_EQ(v[6], 'n');
|
||||||
|
EXPECT_EQ(v[7], 'g');
|
||||||
|
EXPECT_EQ(v[8], '\0');
|
||||||
|
EXPECT_EQ(v[9], '\0');
|
||||||
|
EXPECT_EQ(v[10], '\0');
|
||||||
|
EXPECT_EQ(v[11], '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
85
src/writer/spirv/builder.cc
Normal file
85
src/writer/spirv/builder.cc
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// Copyright 2020 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/writer/spirv/builder.h"
|
||||||
|
|
||||||
|
#include "spirv/unified1/spirv.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
uint32_t size_of(const std::vector<Instruction>& instructions) {
|
||||||
|
uint32_t size = 0;
|
||||||
|
for (const auto& inst : instructions)
|
||||||
|
size += inst.word_length();
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Builder::Builder() = default;
|
||||||
|
|
||||||
|
Builder::~Builder() = default;
|
||||||
|
|
||||||
|
bool Builder::Build(const ast::Module&) {
|
||||||
|
push_preamble(spv::Op::OpCapability, {Operand::Int(SpvCapabilityShader)});
|
||||||
|
push_preamble(spv::Op::OpExtInstImport,
|
||||||
|
{result_op(), Operand::String("GLSL.std.450")});
|
||||||
|
push_preamble(spv::Op::OpMemoryModel,
|
||||||
|
{Operand::Int(SpvAddressingModelLogical),
|
||||||
|
Operand::Int(SpvMemoryModelVulkanKHR)});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand Builder::result_op() {
|
||||||
|
return Operand::Int(next_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Builder::total_size() const {
|
||||||
|
// The 5 covers the magic, version, generator, id bound and reserved.
|
||||||
|
uint32_t size = 5;
|
||||||
|
|
||||||
|
size += size_of(preamble_);
|
||||||
|
size += size_of(debug_);
|
||||||
|
size += size_of(annotations_);
|
||||||
|
size += size_of(types_);
|
||||||
|
size += size_of(instructions_);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::iterate(std::function<void(const Instruction&)> cb) const {
|
||||||
|
for (const auto& inst : preamble_) {
|
||||||
|
cb(inst);
|
||||||
|
}
|
||||||
|
for (const auto& inst : debug_) {
|
||||||
|
cb(inst);
|
||||||
|
}
|
||||||
|
for (const auto& inst : annotations_) {
|
||||||
|
cb(inst);
|
||||||
|
}
|
||||||
|
for (const auto& inst : types_) {
|
||||||
|
cb(inst);
|
||||||
|
}
|
||||||
|
for (const auto& inst : instructions_) {
|
||||||
|
cb(inst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
112
src/writer/spirv/builder.h
Normal file
112
src/writer/spirv/builder.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// Copyright 2020 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_WRITER_SPIRV_BUILDER_H_
|
||||||
|
#define SRC_WRITER_SPIRV_BUILDER_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/ast/module.h"
|
||||||
|
#include "src/writer/spirv/instruction.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
/// Builder class to create SPIR-V instructions from a module.
|
||||||
|
class Builder {
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
Builder();
|
||||||
|
~Builder();
|
||||||
|
|
||||||
|
/// Generates the SPIR-V instructions for the given module
|
||||||
|
/// @param module the module to generate from
|
||||||
|
/// @returns true if the SPIR-V was successfully built
|
||||||
|
bool Build(const ast::Module& module);
|
||||||
|
|
||||||
|
/// @returns the number of uint32_t's needed to make up the results
|
||||||
|
uint32_t total_size() const;
|
||||||
|
|
||||||
|
/// @returns the id bound for this module
|
||||||
|
uint32_t id_bound() const { return next_id_; }
|
||||||
|
|
||||||
|
/// Iterates over all the instructions in the correct order and calls the
|
||||||
|
/// given callback
|
||||||
|
/// @param cb the callback to execute
|
||||||
|
void iterate(std::function<void(const Instruction&)> cb) const;
|
||||||
|
|
||||||
|
/// Adds an instruction to the preamble
|
||||||
|
/// @param op the op to set
|
||||||
|
/// @param operands the operands for the instruction
|
||||||
|
void push_preamble(spv::Op op, const std::vector<Operand>& operands) {
|
||||||
|
preamble_.push_back(Instruction{op, operands});
|
||||||
|
}
|
||||||
|
/// @returns the preamble
|
||||||
|
const std::vector<Instruction>& preamble() const { return preamble_; }
|
||||||
|
/// Adds an instruction to the debug
|
||||||
|
/// @param op the op to set
|
||||||
|
/// @param operands the operands for the instruction
|
||||||
|
void push_debug(spv::Op op, const std::vector<Operand>& operands) {
|
||||||
|
debug_.push_back(Instruction{op, operands});
|
||||||
|
}
|
||||||
|
/// @returns the debug instructions
|
||||||
|
const std::vector<Instruction>& debug() const { return debug_; }
|
||||||
|
/// Adds an instruction to the types
|
||||||
|
/// @param op the op to set
|
||||||
|
/// @param operands the operands for the instruction
|
||||||
|
void push_type(spv::Op op, const std::vector<Operand>& operands) {
|
||||||
|
types_.push_back(Instruction{op, operands});
|
||||||
|
}
|
||||||
|
/// @returns the type instructions
|
||||||
|
const std::vector<Instruction>& type() const { return types_; }
|
||||||
|
/// Adds an instruction to the instruction list
|
||||||
|
/// @param op the op to set
|
||||||
|
/// @param operands the operands for the instruction
|
||||||
|
void push_inst(spv::Op op, const std::vector<Operand>& operands) {
|
||||||
|
instructions_.push_back(Instruction{op, operands});
|
||||||
|
}
|
||||||
|
/// @returns the instruction list
|
||||||
|
const std::vector<Instruction>& inst() const { return instructions_; }
|
||||||
|
/// Adds an instruction to the annotations
|
||||||
|
/// @param op the op to set
|
||||||
|
/// @param operands the operands for the instruction
|
||||||
|
void push_annot(spv::Op op, const std::vector<Operand>& operands) {
|
||||||
|
annotations_.push_back(Instruction{op, operands});
|
||||||
|
}
|
||||||
|
/// @returns the annotations
|
||||||
|
const std::vector<Instruction>& annot() const { return annotations_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Operand result_op();
|
||||||
|
uint32_t next_id() {
|
||||||
|
auto id = next_id_;
|
||||||
|
next_id_ += 1;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t next_id_ = 1;
|
||||||
|
std::vector<Instruction> preamble_;
|
||||||
|
std::vector<Instruction> debug_;
|
||||||
|
std::vector<Instruction> types_;
|
||||||
|
std::vector<Instruction> instructions_;
|
||||||
|
std::vector<Instruction> annotations_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // SRC_WRITER_SPIRV_BUILDER_H_
|
40
src/writer/spirv/builder_test.cc
Normal file
40
src/writer/spirv/builder_test.cc
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2020 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/writer/spirv/builder.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "spirv/unified1/spirv.hpp11"
|
||||||
|
#include "src/ast/module.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
using BuilderTest = testing::Test;
|
||||||
|
|
||||||
|
TEST_F(BuilderTest, InsertsPreamble) {
|
||||||
|
ast::Module m;
|
||||||
|
Builder b;
|
||||||
|
ASSERT_TRUE(b.Build(m));
|
||||||
|
ASSERT_EQ(b.preamble().size(), 3);
|
||||||
|
auto pre = b.preamble();
|
||||||
|
EXPECT_EQ(pre[0].opcode(), spv::Op::OpCapability);
|
||||||
|
EXPECT_EQ(pre[1].opcode(), spv::Op::OpExtInstImport);
|
||||||
|
EXPECT_EQ(pre[2].opcode(), spv::Op::OpMemoryModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
@ -12,22 +12,25 @@
|
|||||||
// 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 "src/writer/spv/generator.h"
|
#include "src/writer/spirv/generator.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace writer {
|
namespace writer {
|
||||||
namespace spv {
|
namespace spirv {
|
||||||
|
|
||||||
Generator::Generator(ast::Module module) : writer::Writer(std::move(module)) {}
|
Generator::Generator(ast::Module module) : writer::Writer(std::move(module)) {}
|
||||||
|
|
||||||
Generator::~Generator() = default;
|
Generator::~Generator() = default;
|
||||||
|
|
||||||
bool Generator::Generate() {
|
bool Generator::Generate() {
|
||||||
return true;
|
if (!builder_.Build(module_))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return writer_.Write(builder_);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace spv
|
} // namespace spirv
|
||||||
} // namespace writer
|
} // namespace writer
|
||||||
} // namespace tint
|
} // namespace tint
|
@ -12,16 +12,19 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
#ifndef SRC_WRITER_SPV_GENERATOR_H_
|
#ifndef SRC_WRITER_SPIRV_GENERATOR_H_
|
||||||
#define SRC_WRITER_SPV_GENERATOR_H_
|
#define SRC_WRITER_SPIRV_GENERATOR_H_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/ast/module.h"
|
||||||
|
#include "src/writer/spirv/binary_writer.h"
|
||||||
|
#include "src/writer/spirv/builder.h"
|
||||||
#include "src/writer/writer.h"
|
#include "src/writer/writer.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace writer {
|
namespace writer {
|
||||||
namespace spv {
|
namespace spirv {
|
||||||
|
|
||||||
/// Class to generate SPIR-V from a Tint module
|
/// Class to generate SPIR-V from a Tint module
|
||||||
class Generator : public writer::Writer {
|
class Generator : public writer::Writer {
|
||||||
@ -36,14 +39,15 @@ class Generator : public writer::Writer {
|
|||||||
bool Generate() override;
|
bool Generate() override;
|
||||||
|
|
||||||
/// @returns the result data
|
/// @returns the result data
|
||||||
const std::vector<uint32_t>& result() const { return result_; }
|
const std::vector<uint32_t>& result() const { return writer_.result(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint32_t> result_;
|
Builder builder_;
|
||||||
|
BinaryWriter writer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace spv
|
} // namespace spirv
|
||||||
} // namespace writer
|
} // namespace writer
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_WRITER_SPV_GENERATOR_H_
|
#endif // SRC_WRITER_SPIRV_GENERATOR_H_
|
38
src/writer/spirv/instruction.cc
Normal file
38
src/writer/spirv/instruction.cc
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2020 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/writer/spirv/instruction.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
Instruction::Instruction(spv::Op op, std::vector<Operand> operands)
|
||||||
|
: op_(op), operands_(std::move(operands)) {}
|
||||||
|
|
||||||
|
Instruction::~Instruction() = default;
|
||||||
|
|
||||||
|
uint32_t Instruction::word_length() const {
|
||||||
|
uint32_t size = 1; // Initial 1 for the op and size
|
||||||
|
for (const auto& op : operands_) {
|
||||||
|
size += op.length();
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
56
src/writer/spirv/instruction.h
Normal file
56
src/writer/spirv/instruction.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright 2020 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_WRITER_SPIRV_INSTRUCTION_H_
|
||||||
|
#define SRC_WRITER_SPIRV_INSTRUCTION_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "spirv/unified1/spirv.hpp11"
|
||||||
|
#include "src/writer/spirv/operand.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
/// A single SPIR-V instruction
|
||||||
|
class Instruction {
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// @param op the op to generate
|
||||||
|
/// @param operands the operand values for the instruction
|
||||||
|
Instruction(spv::Op op, std::vector<Operand> operands);
|
||||||
|
/// Copy Constructor
|
||||||
|
Instruction(const Instruction&) = default;
|
||||||
|
~Instruction();
|
||||||
|
|
||||||
|
/// @returns the instructions op
|
||||||
|
spv::Op opcode() const { return op_; }
|
||||||
|
|
||||||
|
/// @returns the instructions operands
|
||||||
|
const std::vector<Operand>& operands() const { return operands_; }
|
||||||
|
|
||||||
|
/// @returns the number of uint32_t's needed to hold the instruction
|
||||||
|
uint32_t word_length() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
spv::Op op_ = spv::Op::OpNop;
|
||||||
|
std::vector<Operand> operands_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // SRC_WRITER_SPIRV_INSTRUCTION_H_
|
51
src/writer/spirv/instruction_test.cc
Normal file
51
src/writer/spirv/instruction_test.cc
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2020 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/writer/spirv/instruction.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "src/writer/spirv/operand.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
using InstructionTest = testing::Test;
|
||||||
|
|
||||||
|
TEST_F(InstructionTest, Create) {
|
||||||
|
Instruction i(spv::Op::OpEntryPoint, {Operand::Float(1.2f), Operand::Int(1),
|
||||||
|
Operand::String("my_str")});
|
||||||
|
EXPECT_EQ(i.opcode(), spv::Op::OpEntryPoint);
|
||||||
|
ASSERT_EQ(i.operands().size(), 3);
|
||||||
|
|
||||||
|
const auto& ops = i.operands();
|
||||||
|
EXPECT_TRUE(ops[0].IsFloat());
|
||||||
|
EXPECT_FLOAT_EQ(ops[0].to_f(), 1.2);
|
||||||
|
|
||||||
|
EXPECT_TRUE(ops[1].IsInt());
|
||||||
|
EXPECT_EQ(ops[1].to_i(), 1);
|
||||||
|
|
||||||
|
EXPECT_TRUE(ops[2].IsString());
|
||||||
|
EXPECT_EQ(ops[2].to_s(), "my_str");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionTest, Length) {
|
||||||
|
Instruction i(spv::Op::OpEntryPoint, {Operand::Float(1.2f), Operand::Int(1),
|
||||||
|
Operand::String("my_str")});
|
||||||
|
EXPECT_EQ(i.word_length(), 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
66
src/writer/spirv/operand.cc
Normal file
66
src/writer/spirv/operand.cc
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright 2020 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/writer/spirv/operand.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
// static
|
||||||
|
Operand Operand::Float(float val) {
|
||||||
|
Operand o(Kind::kFloat);
|
||||||
|
o.set_float(val);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Operand Operand::Int(uint32_t val) {
|
||||||
|
Operand o(Kind::kInt);
|
||||||
|
o.set_int(val);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Operand Operand::String(const std::string& val) {
|
||||||
|
Operand o(Kind::kString);
|
||||||
|
o.set_string(val);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand::Operand(Kind kind) : kind_(kind) {}
|
||||||
|
|
||||||
|
Operand::~Operand() = default;
|
||||||
|
|
||||||
|
uint32_t Operand::length() const {
|
||||||
|
uint32_t val = 0;
|
||||||
|
switch (kind_) {
|
||||||
|
case Kind::kFloat:
|
||||||
|
case Kind::kInt:
|
||||||
|
val = 1;
|
||||||
|
break;
|
||||||
|
case Kind::kString:
|
||||||
|
// SPIR-V always nul-terminates strings. The length is rounded up to a
|
||||||
|
// multiple of 4 bytes with 0 bytes padding the end.
|
||||||
|
val = static_cast<uint32_t>(ceil((str_val_.length() + 1) / 4.0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
90
src/writer/spirv/operand.h
Normal file
90
src/writer/spirv/operand.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Copyright 2020 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_WRITER_SPIRV_OPERAND_H_
|
||||||
|
#define SRC_WRITER_SPIRV_OPERAND_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
/// A single SPIR-V instruction operand
|
||||||
|
class Operand {
|
||||||
|
public:
|
||||||
|
/// The kind of the operand
|
||||||
|
// Note, the `kInt` will cover most cases as things like IDs in SPIR-V are
|
||||||
|
// just ints for the purpose of converting to binary.
|
||||||
|
enum Kind { kInt = 0, kFloat, kString };
|
||||||
|
|
||||||
|
/// Creates a float operand
|
||||||
|
/// @param val the float value
|
||||||
|
/// @returns the operand
|
||||||
|
static Operand Float(float val);
|
||||||
|
/// Creates an int operand
|
||||||
|
/// @param val the int value
|
||||||
|
/// @returns the operand
|
||||||
|
static Operand Int(uint32_t val);
|
||||||
|
/// Creates a string operand
|
||||||
|
/// @param val the string value
|
||||||
|
/// @returns the operand
|
||||||
|
static Operand String(const std::string& val);
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
/// @param kind the type of operand
|
||||||
|
explicit Operand(Kind kind);
|
||||||
|
/// Copy Constructor
|
||||||
|
Operand(const Operand&) = default;
|
||||||
|
~Operand();
|
||||||
|
|
||||||
|
/// Sets the float value
|
||||||
|
/// @param val the value to set
|
||||||
|
void set_float(float val) { float_val_ = val; }
|
||||||
|
/// Sets the int value
|
||||||
|
/// @param val the value to set
|
||||||
|
void set_int(uint32_t val) { int_val_ = val; }
|
||||||
|
/// Sets the string value
|
||||||
|
/// @param val the value to set
|
||||||
|
void set_string(const std::string& val) { str_val_ = val; }
|
||||||
|
|
||||||
|
/// @returns true if this is a float operand
|
||||||
|
bool IsFloat() const { return kind_ == Kind::kFloat; }
|
||||||
|
/// @returns true if this is an integer operand
|
||||||
|
bool IsInt() const { return kind_ == Kind::kInt; }
|
||||||
|
/// @returns true if this is a string operand
|
||||||
|
bool IsString() const { return kind_ == Kind::kString; }
|
||||||
|
|
||||||
|
/// @returns the number of uint32_t's needed for this operand
|
||||||
|
uint32_t length() const;
|
||||||
|
|
||||||
|
/// @returns the float value
|
||||||
|
float to_f() const { return float_val_; }
|
||||||
|
/// @returns the int value
|
||||||
|
uint32_t to_i() const { return int_val_; }
|
||||||
|
/// @returns the string value
|
||||||
|
const std::string& to_s() const { return str_val_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Kind kind_ = Kind::kInt;
|
||||||
|
float float_val_ = 0.0;
|
||||||
|
uint32_t int_val_ = 0;
|
||||||
|
std::string str_val_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // SRC_WRITER_SPIRV_OPERAND_H_
|
65
src/writer/spirv/operand_test.cc
Normal file
65
src/writer/spirv/operand_test.cc
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright 2020 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/writer/spirv/operand.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
using OperandTest = testing::Test;
|
||||||
|
|
||||||
|
TEST_F(OperandTest, CreateFloat) {
|
||||||
|
auto o = Operand::Float(1.2f);
|
||||||
|
EXPECT_TRUE(o.IsFloat());
|
||||||
|
EXPECT_FLOAT_EQ(o.to_f(), 1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OperandTest, CreateInt) {
|
||||||
|
auto o = Operand::Int(1);
|
||||||
|
EXPECT_TRUE(o.IsInt());
|
||||||
|
EXPECT_EQ(o.to_i(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OperandTest, CreateString) {
|
||||||
|
auto o = Operand::String("my string");
|
||||||
|
EXPECT_TRUE(o.IsString());
|
||||||
|
EXPECT_EQ(o.to_s(), "my string");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OperandTest, Length_Float) {
|
||||||
|
auto o = Operand::Float(1.2f);
|
||||||
|
EXPECT_EQ(o.length(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OperandTest, Length_Int) {
|
||||||
|
auto o = Operand::Int(1);
|
||||||
|
EXPECT_EQ(o.length(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OperandTest, Length_String) {
|
||||||
|
auto o = Operand::String("my string");
|
||||||
|
EXPECT_EQ(o.length(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OperandTest, Length_String_Empty) {
|
||||||
|
auto o = Operand::String("");
|
||||||
|
EXPECT_EQ(o.length(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
Loading…
x
Reference in New Issue
Block a user