mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-26 01:31:06 +00:00
d35a78db57
Fixes #4960 * Switches to using enum classes with an underlying type to avoid undefined behaviour
433 lines
17 KiB
C++
433 lines
17 KiB
C++
// Copyright (c) 2015-2016 The Khronos Group Inc.
|
|
//
|
|
// 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.
|
|
|
|
// Assembler tests for instructions in the "Memory Instructions" section of
|
|
// the SPIR-V spec.
|
|
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "gmock/gmock.h"
|
|
#include "test/test_fixture.h"
|
|
#include "test/unit_spirv.h"
|
|
|
|
namespace spvtools {
|
|
namespace {
|
|
|
|
using spvtest::EnumCase;
|
|
using spvtest::MakeInstruction;
|
|
using spvtest::TextToBinaryTest;
|
|
using ::testing::Eq;
|
|
using ::testing::HasSubstr;
|
|
|
|
// Test assembly of Memory Access masks
|
|
|
|
using MemoryAccessTest = spvtest::TextToBinaryTestBase<
|
|
::testing::TestWithParam<EnumCase<spv::MemoryAccessMask>>>;
|
|
|
|
TEST_P(MemoryAccessTest, AnySingleMemoryAccessMask) {
|
|
std::stringstream input;
|
|
input << "OpStore %ptr %value " << GetParam().name();
|
|
for (auto operand : GetParam().operands()) input << " " << operand;
|
|
EXPECT_THAT(
|
|
CompiledInstructions(input.str()),
|
|
Eq(MakeInstruction(spv::Op::OpStore, {1, 2, (uint32_t)GetParam().value()},
|
|
GetParam().operands())));
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
TextToBinaryMemoryAccessTest, MemoryAccessTest,
|
|
::testing::ValuesIn(std::vector<EnumCase<spv::MemoryAccessMask>>{
|
|
{spv::MemoryAccessMask::MaskNone, "None", {}},
|
|
{spv::MemoryAccessMask::Volatile, "Volatile", {}},
|
|
{spv::MemoryAccessMask::Aligned, "Aligned", {16}},
|
|
{spv::MemoryAccessMask::Nontemporal, "Nontemporal", {}},
|
|
}));
|
|
|
|
TEST_F(TextToBinaryTest, CombinedMemoryAccessMask) {
|
|
const std::string input = "OpStore %ptr %value Volatile|Aligned 16";
|
|
const uint32_t expected_mask = uint32_t(spv::MemoryAccessMask::Volatile |
|
|
spv::MemoryAccessMask::Aligned);
|
|
EXPECT_THAT(expected_mask, Eq(3u));
|
|
EXPECT_THAT(CompiledInstructions(input),
|
|
Eq(MakeInstruction(spv::Op::OpStore, {1, 2, expected_mask, 16})));
|
|
}
|
|
|
|
// Test Storage Class enum values
|
|
|
|
using StorageClassTest = spvtest::TextToBinaryTestBase<
|
|
::testing::TestWithParam<EnumCase<spv::StorageClass>>>;
|
|
|
|
TEST_P(StorageClassTest, AnyStorageClass) {
|
|
const std::string input = "%1 = OpVariable %2 " + GetParam().name();
|
|
EXPECT_THAT(CompiledInstructions(input),
|
|
Eq(MakeInstruction(spv::Op::OpVariable,
|
|
{1, 2, (uint32_t)GetParam().value()})));
|
|
}
|
|
|
|
// clang-format off
|
|
#define CASE(NAME) { spv::StorageClass::NAME, #NAME, {} }
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
TextToBinaryStorageClassTest, StorageClassTest,
|
|
::testing::ValuesIn(std::vector<EnumCase<spv::StorageClass>>{
|
|
CASE(UniformConstant),
|
|
CASE(Input),
|
|
CASE(Uniform),
|
|
CASE(Output),
|
|
CASE(Workgroup),
|
|
CASE(CrossWorkgroup),
|
|
CASE(Private),
|
|
CASE(Function),
|
|
CASE(Generic),
|
|
CASE(PushConstant),
|
|
CASE(AtomicCounter),
|
|
CASE(Image),
|
|
}));
|
|
#undef CASE
|
|
// clang-format on
|
|
|
|
using MemoryRoundTripTest = RoundTripTest;
|
|
|
|
// OpPtrEqual appeared in SPIR-V 1.4
|
|
|
|
TEST_F(MemoryRoundTripTest, OpPtrEqualGood) {
|
|
std::string spirv = "%2 = OpPtrEqual %1 %3 %4\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4),
|
|
Eq(MakeInstruction(spv::Op::OpPtrEqual, {1, 2, 3, 4})));
|
|
std::string disassembly = EncodeAndDecodeSuccessfully(
|
|
spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpPtrEqualV13Bad) {
|
|
std::string spirv = "%2 = OpPtrEqual %1 %3 %4\n";
|
|
std::string err = CompileFailure(spirv, SPV_ENV_UNIVERSAL_1_3);
|
|
EXPECT_THAT(err, HasSubstr("Invalid Opcode name 'OpPtrEqual'"));
|
|
}
|
|
|
|
// OpPtrNotEqual appeared in SPIR-V 1.4
|
|
|
|
TEST_F(MemoryRoundTripTest, OpPtrNotEqualGood) {
|
|
std::string spirv = "%2 = OpPtrNotEqual %1 %3 %4\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4),
|
|
Eq(MakeInstruction(spv::Op::OpPtrNotEqual, {1, 2, 3, 4})));
|
|
std::string disassembly = EncodeAndDecodeSuccessfully(
|
|
spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpPtrNotEqualV13Bad) {
|
|
std::string spirv = "%2 = OpPtrNotEqual %1 %3 %4\n";
|
|
std::string err = CompileFailure(spirv, SPV_ENV_UNIVERSAL_1_3);
|
|
EXPECT_THAT(err, HasSubstr("Invalid Opcode name 'OpPtrNotEqual'"));
|
|
}
|
|
|
|
// OpPtrDiff appeared in SPIR-V 1.4
|
|
|
|
TEST_F(MemoryRoundTripTest, OpPtrDiffGood) {
|
|
std::string spirv = "%2 = OpPtrDiff %1 %3 %4\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4),
|
|
Eq(MakeInstruction(spv::Op::OpPtrDiff, {1, 2, 3, 4})));
|
|
std::string disassembly = EncodeAndDecodeSuccessfully(
|
|
spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpPtrDiffV13Good) {
|
|
// OpPtrDiff is enabled by a capability as well, so we can assemble
|
|
// it even in older SPIR-V environments. We do that so we can
|
|
// write tests.
|
|
std::string spirv = "%2 = OpPtrDiff %1 %3 %4\n";
|
|
std::string disassembly = EncodeAndDecodeSuccessfully(
|
|
spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4);
|
|
}
|
|
|
|
// OpCopyMemory
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryNoMemAccessGood) {
|
|
std::string spirv = "OpCopyMemory %1 %2\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryTooFewArgsBad) {
|
|
std::string spirv = "OpCopyMemory %1\n";
|
|
std::string err = CompileFailure(spirv);
|
|
EXPECT_THAT(err, HasSubstr("Expected operand for OpCopyMemory instruction, "
|
|
"but found the end of the stream."));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryTooManyArgsBad) {
|
|
std::string spirv = "OpCopyMemory %1 %2 %3\n";
|
|
std::string err = CompileFailure(spirv);
|
|
EXPECT_THAT(err, HasSubstr("Invalid memory access operand '%3'"));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNoneGood) {
|
|
std::string spirv = "OpCopyMemory %1 %2 None\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 0})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVolatileGood) {
|
|
std::string spirv = "OpCopyMemory %1 %2 Volatile\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 1})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAligned8Good) {
|
|
std::string spirv = "OpCopyMemory %1 %2 Aligned 8\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 2, 8})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNontemporalGood) {
|
|
std::string spirv = "OpCopyMemory %1 %2 Nontemporal\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 4})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAvGood) {
|
|
std::string spirv = "OpCopyMemory %1 %2 MakePointerAvailable %3\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 8, 3})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVisGood) {
|
|
std::string spirv = "OpCopyMemory %1 %2 MakePointerVisible %3\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 16, 3})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNonPrivateGood) {
|
|
std::string spirv = "OpCopyMemory %1 %2 NonPrivatePointer\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 32})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessMixedGood) {
|
|
std::string spirv =
|
|
"OpCopyMemory %1 %2 "
|
|
"Volatile|Aligned|Nontemporal|MakePointerAvailable|"
|
|
"MakePointerVisible|NonPrivatePointer 16 %3 %4\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 63, 16, 3, 4})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV13Good) {
|
|
std::string spirv = "OpCopyMemory %1 %2 Volatile Volatile\n";
|
|
// Note: This will assemble but should not validate for SPIR-V 1.3
|
|
EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_3),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 1, 1})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV14Good) {
|
|
std::string spirv = "OpCopyMemory %1 %2 Volatile Volatile\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 1, 1})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessMixedV14Good) {
|
|
std::string spirv =
|
|
"OpCopyMemory %1 %2 Volatile|Nontemporal|"
|
|
"MakePointerVisible %3 "
|
|
"Aligned|MakePointerAvailable|NonPrivatePointer 16 %4\n";
|
|
EXPECT_THAT(
|
|
CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 21, 3, 42, 16, 4})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
// OpCopyMemorySized
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedNoMemAccessGood) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTooFewArgsBad) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2\n";
|
|
std::string err = CompileFailure(spirv);
|
|
EXPECT_THAT(err, HasSubstr("Expected operand for OpCopyMemorySized "
|
|
"instruction, but found the end of the stream."));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTooManyArgsBad) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 %4\n";
|
|
std::string err = CompileFailure(spirv);
|
|
EXPECT_THAT(err, HasSubstr("Invalid memory access operand '%4'"));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNoneGood) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 None\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 0})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVolatileGood) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 1})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAligned8Good) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 Aligned 8\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 2, 8})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNontemporalGood) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 Nontemporal\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 4})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAvGood) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerAvailable %4\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 8, 4})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVisGood) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerVisible %4\n";
|
|
EXPECT_THAT(
|
|
CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 16, 4})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNonPrivateGood) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 NonPrivatePointer\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 32})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessMixedGood) {
|
|
std::string spirv =
|
|
"OpCopyMemorySized %1 %2 %3 "
|
|
"Volatile|Aligned|Nontemporal|MakePointerAvailable|"
|
|
"MakePointerVisible|NonPrivatePointer 16 %4 %5\n";
|
|
EXPECT_THAT(
|
|
CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 63, 16, 4, 5})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV13Good) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile Volatile\n";
|
|
// Note: This will assemble but should not validate for SPIR-V 1.3
|
|
EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_3),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 1, 1})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV14Good) {
|
|
std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile Volatile\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 1, 1})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessMixedV14Good) {
|
|
std::string spirv =
|
|
"OpCopyMemorySized %1 %2 %3 Volatile|Nontemporal|"
|
|
"MakePointerVisible %4 "
|
|
"Aligned|MakePointerAvailable|NonPrivatePointer 16 %5\n";
|
|
EXPECT_THAT(CompiledInstructions(spirv),
|
|
Eq(MakeInstruction(spv::Op::OpCopyMemorySized,
|
|
{1, 2, 3, 21, 4, 42, 16, 5})));
|
|
std::string disassembly =
|
|
EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
|
|
EXPECT_THAT(disassembly, Eq(spirv));
|
|
}
|
|
|
|
// TODO(dneto): OpVariable with initializers
|
|
// TODO(dneto): OpImageTexelPointer
|
|
// TODO(dneto): OpLoad
|
|
// TODO(dneto): OpStore
|
|
// TODO(dneto): OpAccessChain
|
|
// TODO(dneto): OpInBoundsAccessChain
|
|
// TODO(dneto): OpPtrAccessChain
|
|
// TODO(dneto): OpArrayLength
|
|
// TODO(dneto): OpGenercPtrMemSemantics
|
|
|
|
} // namespace
|
|
} // namespace spvtools
|