Home | History | Annotate | Download | only in val
      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 // Validation tests for OpVariable storage class
     16 
     17 #include <sstream>
     18 #include <string>
     19 #include <tuple>
     20 
     21 #include "gmock/gmock.h"
     22 #include "test/val/val_fixtures.h"
     23 
     24 namespace spvtools {
     25 namespace val {
     26 namespace {
     27 
     28 using ::testing::HasSubstr;
     29 using ValidateStorage = spvtest::ValidateBase<std::string>;
     30 
     31 TEST_F(ValidateStorage, FunctionStorageInsideFunction) {
     32   char str[] = R"(
     33           OpCapability Shader
     34           OpCapability Linkage
     35           OpMemoryModel Logical GLSL450
     36 %intt   = OpTypeInt 32 1
     37 %voidt  = OpTypeVoid
     38 %vfunct = OpTypeFunction %voidt
     39 %ptrt   = OpTypePointer Function %intt
     40 %func   = OpFunction %voidt None %vfunct
     41 %funcl  = OpLabel
     42 %var    = OpVariable %ptrt Function
     43           OpReturn
     44           OpFunctionEnd
     45 )";
     46 
     47   CompileSuccessfully(str);
     48   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
     49 }
     50 
     51 TEST_F(ValidateStorage, FunctionStorageOutsideFunction) {
     52   char str[] = R"(
     53           OpCapability Shader
     54           OpCapability Linkage
     55           OpMemoryModel Logical GLSL450
     56 %intt   = OpTypeInt 32 1
     57 %voidt  = OpTypeVoid
     58 %vfunct = OpTypeFunction %voidt
     59 %ptrt   = OpTypePointer Function %intt
     60 %var    = OpVariable %ptrt Function
     61 %func   = OpFunction %voidt None %vfunct
     62 %funcl  = OpLabel
     63           OpReturn
     64           OpFunctionEnd
     65 )";
     66 
     67   CompileSuccessfully(str);
     68   ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
     69   EXPECT_THAT(getDiagnosticString(),
     70               HasSubstr("Variables can not have a function[7] storage class "
     71                         "outside of a function"));
     72 }
     73 
     74 TEST_F(ValidateStorage, OtherStorageOutsideFunction) {
     75   char str[] = R"(
     76               OpCapability Shader
     77               OpCapability Kernel
     78               OpCapability AtomicStorage
     79               OpCapability Linkage
     80               OpMemoryModel Logical GLSL450
     81 %intt       = OpTypeInt 32 0
     82 %voidt      = OpTypeVoid
     83 %vfunct     = OpTypeFunction %voidt
     84 %uniconptrt = OpTypePointer UniformConstant %intt
     85 %unicon     = OpVariable %uniconptrt UniformConstant
     86 %inputptrt  = OpTypePointer Input %intt
     87 %input      = OpVariable %inputptrt Input
     88 %unifptrt   = OpTypePointer Uniform %intt
     89 %unif       = OpVariable %unifptrt Uniform
     90 %outputptrt = OpTypePointer Output %intt
     91 %output     = OpVariable %outputptrt Output
     92 %wgroupptrt = OpTypePointer Workgroup %intt
     93 %wgroup     = OpVariable %wgroupptrt Workgroup
     94 %xwgrpptrt  = OpTypePointer CrossWorkgroup %intt
     95 %xwgrp      = OpVariable %xwgrpptrt CrossWorkgroup
     96 %privptrt   = OpTypePointer Private %intt
     97 %priv       = OpVariable %privptrt Private
     98 %pushcoptrt = OpTypePointer PushConstant %intt
     99 %pushco     = OpVariable %pushcoptrt PushConstant
    100 %atomcptrt  = OpTypePointer AtomicCounter %intt
    101 %atomct     = OpVariable %atomcptrt AtomicCounter
    102 %imageptrt  = OpTypePointer Image %intt
    103 %image      = OpVariable %imageptrt Image
    104 %func       = OpFunction %voidt None %vfunct
    105 %funcl      = OpLabel
    106               OpReturn
    107               OpFunctionEnd
    108 )";
    109 
    110   CompileSuccessfully(str);
    111   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    112 }
    113 
    114 // clang-format off
    115 TEST_P(ValidateStorage, OtherStorageInsideFunction) {
    116   std::stringstream ss;
    117   ss << R"(
    118           OpCapability Shader
    119           OpCapability Kernel
    120           OpCapability AtomicStorage
    121           OpCapability Linkage
    122           OpMemoryModel Logical GLSL450
    123 %intt   = OpTypeInt 32 0
    124 %voidt  = OpTypeVoid
    125 %vfunct = OpTypeFunction %voidt
    126 %ptrt   = OpTypePointer Function %intt
    127 %func   = OpFunction %voidt None %vfunct
    128 %funcl  = OpLabel
    129 %var    = OpVariable %ptrt )" << GetParam() << R"(
    130           OpReturn
    131           OpFunctionEnd
    132 )";
    133 
    134   CompileSuccessfully(ss.str());
    135   ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
    136   EXPECT_THAT(getDiagnosticString(), HasSubstr(
    137       "Variables must have a function[7] storage class inside of a function"));
    138 }
    139 
    140 INSTANTIATE_TEST_CASE_P(MatrixOp, ValidateStorage,
    141                         ::testing::Values(
    142                              "Input",
    143                              "Uniform",
    144                              "Output",
    145                              "Workgroup",
    146                              "CrossWorkgroup",
    147                              "Private",
    148                              "PushConstant",
    149                              "AtomicCounter",
    150                              "Image"),);
    151 // clang-format on
    152 
    153 TEST_F(ValidateStorage, GenericVariableOutsideFunction) {
    154   const auto str = R"(
    155           OpCapability Kernel
    156           OpCapability Linkage
    157           OpMemoryModel Logical OpenCL
    158 %intt   = OpTypeInt 32 0
    159 %ptrt   = OpTypePointer Function %intt
    160 %var    = OpVariable %ptrt Generic
    161 )";
    162   CompileSuccessfully(str);
    163   ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
    164   EXPECT_THAT(getDiagnosticString(),
    165               HasSubstr("OpVariable storage class cannot be Generic"));
    166 }
    167 
    168 TEST_F(ValidateStorage, GenericVariableInsideFunction) {
    169   const auto str = R"(
    170           OpCapability Shader
    171           OpCapability Linkage
    172           OpMemoryModel Logical GLSL450
    173 %intt   = OpTypeInt 32 1
    174 %voidt  = OpTypeVoid
    175 %vfunct = OpTypeFunction %voidt
    176 %ptrt   = OpTypePointer Function %intt
    177 %func   = OpFunction %voidt None %vfunct
    178 %funcl  = OpLabel
    179 %var    = OpVariable %ptrt Generic
    180           OpReturn
    181           OpFunctionEnd
    182 )";
    183   CompileSuccessfully(str);
    184   ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
    185   EXPECT_THAT(getDiagnosticString(),
    186               HasSubstr("OpVariable storage class cannot be Generic"));
    187 }
    188 
    189 }  // namespace
    190 }  // namespace val
    191 }  // namespace spvtools
    192