• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2020 Google LLC
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 // Tests for OpExtension validator rules.
16 
17 #include <string>
18 #include <vector>
19 
20 #include "gmock/gmock.h"
21 #include "source/enum_string_mapping.h"
22 #include "source/extensions.h"
23 #include "source/spirv_target_env.h"
24 #include "test/test_fixture.h"
25 #include "test/unit_spirv.h"
26 #include "test/val/val_fixtures.h"
27 
28 namespace spvtools {
29 namespace val {
30 namespace {
31 
32 using ::testing::HasSubstr;
33 using ::testing::Values;
34 using ::testing::ValuesIn;
35 
36 using ValidateSpvKHRTerminateInvocation = spvtest::ValidateBase<bool>;
37 
TEST_F(ValidateSpvKHRTerminateInvocation,Valid)38 TEST_F(ValidateSpvKHRTerminateInvocation, Valid) {
39   const std::string str = R"(
40     OpCapability Shader
41     OpExtension "SPV_KHR_terminate_invocation"
42     OpMemoryModel Logical Simple
43     OpEntryPoint Fragment %main "main"
44     OpExecutionMode %main OriginUpperLeft
45 
46     %void    = OpTypeVoid
47     %void_fn = OpTypeFunction %void
48 
49     %main = OpFunction %void None %void_fn
50     %entry = OpLabel
51     OpTerminateInvocation
52     OpFunctionEnd
53 )";
54   CompileSuccessfully(str.c_str());
55   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
56 }
57 
TEST_F(ValidateSpvKHRTerminateInvocation,RequiresExtension)58 TEST_F(ValidateSpvKHRTerminateInvocation, RequiresExtension) {
59   const std::string str = R"(
60     OpCapability Shader
61     OpMemoryModel Logical Simple
62     OpEntryPoint Fragment %main "main"
63     OpExecutionMode %main OriginUpperLeft
64 
65     %void    = OpTypeVoid
66     %void_fn = OpTypeFunction %void
67 
68     %main = OpFunction %void None %void_fn
69     %entry = OpLabel
70     OpTerminateInvocation
71     OpFunctionEnd
72 )";
73   CompileSuccessfully(str.c_str());
74   EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
75   EXPECT_THAT(getDiagnosticString(),
76               HasSubstr("TerminateInvocation requires one of the following "
77                         "extensions: SPV_KHR_terminate_invocation"));
78 }
79 
TEST_F(ValidateSpvKHRTerminateInvocation,RequiresShaderCapability)80 TEST_F(ValidateSpvKHRTerminateInvocation, RequiresShaderCapability) {
81   const std::string str = R"(
82     OpCapability Kernel
83     OpCapability Addresses
84     OpExtension "SPV_KHR_terminate_invocation"
85     OpMemoryModel Physical32 OpenCL
86     OpEntryPoint Kernel %main "main"
87 
88     %void    = OpTypeVoid
89     %void_fn = OpTypeFunction %void
90 
91     %main = OpFunction %void None %void_fn
92     %entry = OpLabel
93     OpTerminateInvocation
94     OpFunctionEnd
95 )";
96   CompileSuccessfully(str.c_str());
97   EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
98   EXPECT_THAT(
99       getDiagnosticString(),
100       HasSubstr(
101           "TerminateInvocation requires one of these capabilities: Shader \n"));
102 }
103 
TEST_F(ValidateSpvKHRTerminateInvocation,RequiresFragmentShader)104 TEST_F(ValidateSpvKHRTerminateInvocation, RequiresFragmentShader) {
105   const std::string str = R"(
106     OpCapability Shader
107     OpExtension "SPV_KHR_terminate_invocation"
108     OpMemoryModel Logical Simple
109     OpEntryPoint GLCompute %main "main"
110 
111     %void    = OpTypeVoid
112     %void_fn = OpTypeFunction %void
113 
114     %main = OpFunction %void None %void_fn
115     %entry = OpLabel
116     OpTerminateInvocation
117     OpFunctionEnd
118 )";
119   CompileSuccessfully(str.c_str());
120   EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
121   EXPECT_THAT(
122       getDiagnosticString(),
123       HasSubstr("OpTerminateInvocation requires Fragment execution model"));
124 }
125 
TEST_F(ValidateSpvKHRTerminateInvocation,IsTerminatorInstruction)126 TEST_F(ValidateSpvKHRTerminateInvocation, IsTerminatorInstruction) {
127   const std::string str = R"(
128     OpCapability Shader
129     OpExtension "SPV_KHR_terminate_invocation"
130     OpMemoryModel Logical Simple
131     OpEntryPoint GLCompute %main "main"
132 
133     %void    = OpTypeVoid
134     %void_fn = OpTypeFunction %void
135 
136     %main = OpFunction %void None %void_fn
137     %entry = OpLabel
138     OpTerminateInvocation
139     OpReturn
140     OpFunctionEnd
141 )";
142   CompileSuccessfully(str.c_str());
143   EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
144   EXPECT_THAT(getDiagnosticString(),
145               HasSubstr("Return must appear in a block"));
146 }
147 
148 }  // namespace
149 }  // namespace val
150 }  // namespace spvtools
151