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, found end of stream."));
48 }
49 
TEST_F(OpMemoryBarrier,BadInvalidScopeId)50 TEST_F(OpMemoryBarrier, BadInvalidScopeId) {
51   const std::string input = "OpMemoryBarrier 99\n";
52   EXPECT_THAT(CompileFailure(input), Eq("Expected id to start with %."));
53 }
54 
TEST_F(OpMemoryBarrier,BadMissingMemorySemanticsId)55 TEST_F(OpMemoryBarrier, BadMissingMemorySemanticsId) {
56   const std::string input = "OpMemoryBarrier %scope\n";
57   EXPECT_THAT(CompileFailure(input),
58               Eq("Expected operand, found end of stream."));
59 }
60 
TEST_F(OpMemoryBarrier,BadInvalidMemorySemanticsId)61 TEST_F(OpMemoryBarrier, BadInvalidMemorySemanticsId) {
62   const std::string input = "OpMemoryBarrier %scope 14\n";
63   EXPECT_THAT(CompileFailure(input), Eq("Expected id to start with %."));
64 }
65 
66 // TODO(dneto): OpControlBarrier
67 // TODO(dneto): OpGroupAsyncCopy
68 // TODO(dneto): OpGroupWaitEvents
69 // TODO(dneto): OpGroupAll
70 // TODO(dneto): OpGroupAny
71 // TODO(dneto): OpGroupBroadcast
72 // TODO(dneto): OpGroupIAdd
73 // TODO(dneto): OpGroupFAdd
74 // TODO(dneto): OpGroupFMin
75 // TODO(dneto): OpGroupUMin
76 // TODO(dneto): OpGroupSMin
77 // TODO(dneto): OpGroupFMax
78 // TODO(dneto): OpGroupUMax
79 // TODO(dneto): OpGroupSMax
80 
81 using NamedMemoryBarrierTest = spvtest::TextToBinaryTest;
82 
83 // OpMemoryNamedBarrier is not in 1.0, but it is enabled by a capability.
84 // We should be able to assemble it.  Validation checks are in another test
85 // file.
TEST_F(NamedMemoryBarrierTest,OpcodeAssemblesInV10)86 TEST_F(NamedMemoryBarrierTest, OpcodeAssemblesInV10) {
87   EXPECT_THAT(
88       CompiledInstructions("OpMemoryNamedBarrier %bar %scope %semantics",
89                            SPV_ENV_UNIVERSAL_1_0),
90       ElementsAre(spvOpcodeMake(4, SpvOpMemoryNamedBarrier), _, _, _));
91 }
92 
TEST_F(NamedMemoryBarrierTest,ArgumentCount)93 TEST_F(NamedMemoryBarrierTest, ArgumentCount) {
94   EXPECT_THAT(CompileFailure("OpMemoryNamedBarrier", SPV_ENV_UNIVERSAL_1_1),
95               Eq("Expected operand, found end of stream."));
96   EXPECT_THAT(
97       CompileFailure("OpMemoryNamedBarrier %bar", SPV_ENV_UNIVERSAL_1_1),
98       Eq("Expected operand, found end of stream."));
99   EXPECT_THAT(
100       CompileFailure("OpMemoryNamedBarrier %bar %scope", SPV_ENV_UNIVERSAL_1_1),
101       Eq("Expected operand, found end of stream."));
102   EXPECT_THAT(
103       CompiledInstructions("OpMemoryNamedBarrier %bar %scope %semantics",
104                            SPV_ENV_UNIVERSAL_1_1),
105       ElementsAre(spvOpcodeMake(4, SpvOpMemoryNamedBarrier), _, _, _));
106   EXPECT_THAT(
107       CompileFailure("OpMemoryNamedBarrier %bar %scope %semantics %extra",
108                      SPV_ENV_UNIVERSAL_1_1),
109       Eq("Expected '=', found end of stream."));
110 }
111 
TEST_F(NamedMemoryBarrierTest,ArgumentTypes)112 TEST_F(NamedMemoryBarrierTest, ArgumentTypes) {
113   EXPECT_THAT(CompileFailure("OpMemoryNamedBarrier 123 %scope %semantics",
114                              SPV_ENV_UNIVERSAL_1_1),
115               Eq("Expected id to start with %."));
116   EXPECT_THAT(CompileFailure("OpMemoryNamedBarrier %bar %scope \"semantics\"",
117                              SPV_ENV_UNIVERSAL_1_1),
118               Eq("Expected id to start with %."));
119 }
120 
121 using TypeNamedBarrierTest = spvtest::TextToBinaryTest;
122 
TEST_F(TypeNamedBarrierTest,OpcodeAssemblesInV10)123 TEST_F(TypeNamedBarrierTest, OpcodeAssemblesInV10) {
124   EXPECT_THAT(
125       CompiledInstructions("%t = OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_0),
126       ElementsAre(spvOpcodeMake(2, SpvOpTypeNamedBarrier), _));
127 }
128 
TEST_F(TypeNamedBarrierTest,ArgumentCount)129 TEST_F(TypeNamedBarrierTest, ArgumentCount) {
130   EXPECT_THAT(CompileFailure("OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_1),
131               Eq("Expected <result-id> at the beginning of an instruction, "
132                  "found 'OpTypeNamedBarrier'."));
133   EXPECT_THAT(
134       CompiledInstructions("%t = OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_1),
135       ElementsAre(spvOpcodeMake(2, SpvOpTypeNamedBarrier), _));
136   EXPECT_THAT(
137       CompileFailure("%t = OpTypeNamedBarrier 1 2 3", SPV_ENV_UNIVERSAL_1_1),
138       Eq("Expected <opcode> or <result-id> at the beginning of an instruction, "
139          "found '1'."));
140 }
141 
142 using NamedBarrierInitializeTest = spvtest::TextToBinaryTest;
143 
TEST_F(NamedBarrierInitializeTest,OpcodeAssemblesInV10)144 TEST_F(NamedBarrierInitializeTest, OpcodeAssemblesInV10) {
145   EXPECT_THAT(
146       CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count",
147                            SPV_ENV_UNIVERSAL_1_0),
148       ElementsAre(spvOpcodeMake(4, SpvOpNamedBarrierInitialize), _, _, _));
149 }
150 
TEST_F(NamedBarrierInitializeTest,ArgumentCount)151 TEST_F(NamedBarrierInitializeTest, ArgumentCount) {
152   EXPECT_THAT(
153       CompileFailure("%bar = OpNamedBarrierInitialize", SPV_ENV_UNIVERSAL_1_1),
154       Eq("Expected operand, found end of stream."));
155   EXPECT_THAT(CompileFailure("%bar = OpNamedBarrierInitialize %ype",
156                              SPV_ENV_UNIVERSAL_1_1),
157               Eq("Expected operand, found end of stream."));
158   EXPECT_THAT(
159       CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count",
160                            SPV_ENV_UNIVERSAL_1_1),
161       ElementsAre(spvOpcodeMake(4, SpvOpNamedBarrierInitialize), _, _, _));
162   EXPECT_THAT(
163       CompileFailure("%bar = OpNamedBarrierInitialize %type %count \"extra\"",
164                      SPV_ENV_UNIVERSAL_1_1),
165       Eq("Expected <opcode> or <result-id> at the beginning of an instruction, "
166          "found '\"extra\"'."));
167 }
168 
169 }  // namespace
170 }  // namespace spvtools
171