1// Copyright (c) 2015-2016 The Khronos Group Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// Assembler tests for instructions in the "Barrier Instructions" section 16// of the SPIR-V spec. 17 18#include <string> 19 20#include "gmock/gmock.h" 21#include "test/test_fixture.h" 22#include "test/unit_spirv.h" 23 24namespace spvtools { 25namespace { 26 27using spvtest::MakeInstruction; 28using spvtest::TextToBinaryTest; 29using ::testing::_; 30using ::testing::ElementsAre; 31using ::testing::Eq; 32 33// Test OpMemoryBarrier 34 35using OpMemoryBarrier = spvtest::TextToBinaryTest; 36 37TEST_F(OpMemoryBarrier, Good) { 38 const std::string input = "OpMemoryBarrier %1 %2\n"; 39 EXPECT_THAT(CompiledInstructions(input), 40 Eq(MakeInstruction(spv::Op::OpMemoryBarrier, {1, 2}))); 41 EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(input)); 42} 43 44TEST_F(OpMemoryBarrier, BadMissingScopeId) { 45 const std::string input = "OpMemoryBarrier\n"; 46 EXPECT_THAT(CompileFailure(input), 47 Eq("Expected operand for OpMemoryBarrier instruction, but found " 48 "the end of the stream.")); 49} 50 51TEST_F(OpMemoryBarrier, BadInvalidScopeId) { 52 const std::string input = "OpMemoryBarrier 99\n"; 53 EXPECT_THAT(CompileFailure(input), Eq("Expected id to start with %.")); 54} 55 56TEST_F(OpMemoryBarrier, BadMissingMemorySemanticsId) { 57 const std::string input = "OpMemoryBarrier %scope\n"; 58 EXPECT_THAT(CompileFailure(input), 59 Eq("Expected operand for OpMemoryBarrier instruction, but found " 60 "the end of the stream.")); 61} 62 63TEST_F(OpMemoryBarrier, BadInvalidMemorySemanticsId) { 64 const std::string input = "OpMemoryBarrier %scope 14\n"; 65 EXPECT_THAT(CompileFailure(input), Eq("Expected id to start with %.")); 66} 67 68// TODO(dneto): OpControlBarrier 69// TODO(dneto): OpGroupAsyncCopy 70// TODO(dneto): OpGroupWaitEvents 71// TODO(dneto): OpGroupAll 72// TODO(dneto): OpGroupAny 73// TODO(dneto): OpGroupBroadcast 74// TODO(dneto): OpGroupIAdd 75// TODO(dneto): OpGroupFAdd 76// TODO(dneto): OpGroupFMin 77// TODO(dneto): OpGroupUMin 78// TODO(dneto): OpGroupSMin 79// TODO(dneto): OpGroupFMax 80// TODO(dneto): OpGroupUMax 81// TODO(dneto): OpGroupSMax 82 83using NamedMemoryBarrierTest = spvtest::TextToBinaryTest; 84 85// OpMemoryNamedBarrier is not in 1.0, but it is enabled by a capability. 86// We should be able to assemble it. Validation checks are in another test 87// file. 88TEST_F(NamedMemoryBarrierTest, OpcodeAssemblesInV10) { 89 EXPECT_THAT( 90 CompiledInstructions("OpMemoryNamedBarrier %bar %scope %semantics", 91 SPV_ENV_UNIVERSAL_1_0), 92 ElementsAre(spvOpcodeMake(4, spv::Op::OpMemoryNamedBarrier), _, _, _)); 93} 94 95TEST_F(NamedMemoryBarrierTest, ArgumentCount) { 96 EXPECT_THAT(CompileFailure("OpMemoryNamedBarrier", SPV_ENV_UNIVERSAL_1_1), 97 Eq("Expected operand for OpMemoryNamedBarrier instruction, but " 98 "found the end of the stream.")); 99 EXPECT_THAT( 100 CompileFailure("OpMemoryNamedBarrier %bar", SPV_ENV_UNIVERSAL_1_1), 101 Eq("Expected operand for OpMemoryNamedBarrier instruction, but found the " 102 "end of the stream.")); 103 EXPECT_THAT( 104 CompileFailure("OpMemoryNamedBarrier %bar %scope", SPV_ENV_UNIVERSAL_1_1), 105 Eq("Expected operand for OpMemoryNamedBarrier instruction, but found the " 106 "end of the stream.")); 107 EXPECT_THAT( 108 CompiledInstructions("OpMemoryNamedBarrier %bar %scope %semantics", 109 SPV_ENV_UNIVERSAL_1_1), 110 ElementsAre(spvOpcodeMake(4, spv::Op::OpMemoryNamedBarrier), _, _, _)); 111 EXPECT_THAT( 112 CompileFailure("OpMemoryNamedBarrier %bar %scope %semantics %extra", 113 SPV_ENV_UNIVERSAL_1_1), 114 Eq("Expected '=', found end of stream.")); 115} 116 117TEST_F(NamedMemoryBarrierTest, ArgumentTypes) { 118 EXPECT_THAT(CompileFailure("OpMemoryNamedBarrier 123 %scope %semantics", 119 SPV_ENV_UNIVERSAL_1_1), 120 Eq("Expected id to start with %.")); 121 EXPECT_THAT(CompileFailure("OpMemoryNamedBarrier %bar %scope \"semantics\"", 122 SPV_ENV_UNIVERSAL_1_1), 123 Eq("Expected id to start with %.")); 124} 125 126using TypeNamedBarrierTest = spvtest::TextToBinaryTest; 127 128TEST_F(TypeNamedBarrierTest, OpcodeAssemblesInV10) { 129 EXPECT_THAT( 130 CompiledInstructions("%t = OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_0), 131 ElementsAre(spvOpcodeMake(2, spv::Op::OpTypeNamedBarrier), _)); 132} 133 134TEST_F(TypeNamedBarrierTest, ArgumentCount) { 135 EXPECT_THAT(CompileFailure("OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_1), 136 Eq("Expected <result-id> at the beginning of an instruction, " 137 "found 'OpTypeNamedBarrier'.")); 138 EXPECT_THAT( 139 CompiledInstructions("%t = OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_1), 140 ElementsAre(spvOpcodeMake(2, spv::Op::OpTypeNamedBarrier), _)); 141 EXPECT_THAT( 142 CompileFailure("%t = OpTypeNamedBarrier 1 2 3", SPV_ENV_UNIVERSAL_1_1), 143 Eq("Expected <opcode> or <result-id> at the beginning of an instruction, " 144 "found '1'.")); 145} 146 147using NamedBarrierInitializeTest = spvtest::TextToBinaryTest; 148 149TEST_F(NamedBarrierInitializeTest, OpcodeAssemblesInV10) { 150 EXPECT_THAT( 151 CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count", 152 SPV_ENV_UNIVERSAL_1_0), 153 ElementsAre(spvOpcodeMake(4, spv::Op::OpNamedBarrierInitialize), _, _, 154 _)); 155} 156 157TEST_F(NamedBarrierInitializeTest, ArgumentCount) { 158 EXPECT_THAT( 159 CompileFailure("%bar = OpNamedBarrierInitialize", SPV_ENV_UNIVERSAL_1_1), 160 Eq("Expected operand for OpNamedBarrierInitialize instruction, but found " 161 "the end of the stream.")); 162 EXPECT_THAT(CompileFailure("%bar = OpNamedBarrierInitialize %ype", 163 SPV_ENV_UNIVERSAL_1_1), 164 Eq("Expected operand for OpNamedBarrierInitialize instruction, " 165 "but found the end of the stream.")); 166 EXPECT_THAT( 167 CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count", 168 SPV_ENV_UNIVERSAL_1_1), 169 ElementsAre(spvOpcodeMake(4, spv::Op::OpNamedBarrierInitialize), _, _, 170 _)); 171 EXPECT_THAT( 172 CompileFailure("%bar = OpNamedBarrierInitialize %type %count \"extra\"", 173 SPV_ENV_UNIVERSAL_1_1), 174 Eq("Expected <opcode> or <result-id> at the beginning of an instruction, " 175 "found '\"extra\"'.")); 176} 177 178} // namespace 179} // namespace spvtools 180