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
24 namespace spvtools {
25 namespace {
26
27 using spvtest::MakeInstruction;
28 using spvtest::TextToBinaryTest;
29 using ::testing::_;
30 using ::testing::ElementsAre;
31 using ::testing::Eq;
32
33 // Test OpMemoryBarrier
34
35 using OpMemoryBarrier = spvtest::TextToBinaryTest;
36
TEST_F(OpMemoryBarrier,Good)37 TEST_F(OpMemoryBarrier, Good) {
38 const std::string input = "OpMemoryBarrier %1 %2\n";
39 EXPECT_THAT(CompiledInstructions(input),
40 Eq(MakeInstruction(SpvOpMemoryBarrier, {1, 2})));
41 EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(input));
42 }
43
TEST_F(OpMemoryBarrier,BadMissingScopeId)44 TEST_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
TEST_F(OpMemoryBarrier,BadInvalidScopeId)51 TEST_F(OpMemoryBarrier, BadInvalidScopeId) {
52 const std::string input = "OpMemoryBarrier 99\n";
53 EXPECT_THAT(CompileFailure(input), Eq("Expected id to start with %."));
54 }
55
TEST_F(OpMemoryBarrier,BadMissingMemorySemanticsId)56 TEST_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
TEST_F(OpMemoryBarrier,BadInvalidMemorySemanticsId)63 TEST_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
83 using 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.
TEST_F(NamedMemoryBarrierTest,OpcodeAssemblesInV10)88 TEST_F(NamedMemoryBarrierTest, OpcodeAssemblesInV10) {
89 EXPECT_THAT(
90 CompiledInstructions("OpMemoryNamedBarrier %bar %scope %semantics",
91 SPV_ENV_UNIVERSAL_1_0),
92 ElementsAre(spvOpcodeMake(4, SpvOpMemoryNamedBarrier), _, _, _));
93 }
94
TEST_F(NamedMemoryBarrierTest,ArgumentCount)95 TEST_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, SpvOpMemoryNamedBarrier), _, _, _));
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
TEST_F(NamedMemoryBarrierTest,ArgumentTypes)117 TEST_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
126 using TypeNamedBarrierTest = spvtest::TextToBinaryTest;
127
TEST_F(TypeNamedBarrierTest,OpcodeAssemblesInV10)128 TEST_F(TypeNamedBarrierTest, OpcodeAssemblesInV10) {
129 EXPECT_THAT(
130 CompiledInstructions("%t = OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_0),
131 ElementsAre(spvOpcodeMake(2, SpvOpTypeNamedBarrier), _));
132 }
133
TEST_F(TypeNamedBarrierTest,ArgumentCount)134 TEST_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, SpvOpTypeNamedBarrier), _));
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
147 using NamedBarrierInitializeTest = spvtest::TextToBinaryTest;
148
TEST_F(NamedBarrierInitializeTest,OpcodeAssemblesInV10)149 TEST_F(NamedBarrierInitializeTest, OpcodeAssemblesInV10) {
150 EXPECT_THAT(
151 CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count",
152 SPV_ENV_UNIVERSAL_1_0),
153 ElementsAre(spvOpcodeMake(4, SpvOpNamedBarrierInitialize), _, _, _));
154 }
155
TEST_F(NamedBarrierInitializeTest,ArgumentCount)156 TEST_F(NamedBarrierInitializeTest, ArgumentCount) {
157 EXPECT_THAT(
158 CompileFailure("%bar = OpNamedBarrierInitialize", SPV_ENV_UNIVERSAL_1_1),
159 Eq("Expected operand for OpNamedBarrierInitialize instruction, but found "
160 "the end of the stream."));
161 EXPECT_THAT(CompileFailure("%bar = OpNamedBarrierInitialize %ype",
162 SPV_ENV_UNIVERSAL_1_1),
163 Eq("Expected operand for OpNamedBarrierInitialize instruction, "
164 "but found the end of the stream."));
165 EXPECT_THAT(
166 CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count",
167 SPV_ENV_UNIVERSAL_1_1),
168 ElementsAre(spvOpcodeMake(4, SpvOpNamedBarrierInitialize), _, _, _));
169 EXPECT_THAT(
170 CompileFailure("%bar = OpNamedBarrierInitialize %type %count \"extra\"",
171 SPV_ENV_UNIVERSAL_1_1),
172 Eq("Expected <opcode> or <result-id> at the beginning of an instruction, "
173 "found '\"extra\"'."));
174 }
175
176 } // namespace
177 } // namespace spvtools
178