1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci// Test validation of constants. 16fd4e5da5Sopenharmony_ci// 17fd4e5da5Sopenharmony_ci// This file contains newer tests. Older tests may be in other files such as 18fd4e5da5Sopenharmony_ci// val_id_test.cpp. 19fd4e5da5Sopenharmony_ci 20fd4e5da5Sopenharmony_ci#include <string> 21fd4e5da5Sopenharmony_ci#include <vector> 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 24fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h" 25fd4e5da5Sopenharmony_ci#include "test/val/val_code_generator.h" 26fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h" 27fd4e5da5Sopenharmony_ci 28fd4e5da5Sopenharmony_cinamespace spvtools { 29fd4e5da5Sopenharmony_cinamespace val { 30fd4e5da5Sopenharmony_cinamespace { 31fd4e5da5Sopenharmony_ci 32fd4e5da5Sopenharmony_ciusing ::testing::Combine; 33fd4e5da5Sopenharmony_ciusing ::testing::Eq; 34fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 35fd4e5da5Sopenharmony_ciusing ::testing::Values; 36fd4e5da5Sopenharmony_ciusing ::testing::ValuesIn; 37fd4e5da5Sopenharmony_ci 38fd4e5da5Sopenharmony_ciusing ValidateConstant = spvtest::ValidateBase<bool>; 39fd4e5da5Sopenharmony_ci 40fd4e5da5Sopenharmony_ci#define kBasicTypes \ 41fd4e5da5Sopenharmony_ci "%bool = OpTypeBool " \ 42fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0 " \ 43fd4e5da5Sopenharmony_ci "%uint2 = OpTypeVector %uint 2 " \ 44fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32 " \ 45fd4e5da5Sopenharmony_ci "%_ptr_uint = OpTypePointer Workgroup %uint " \ 46fd4e5da5Sopenharmony_ci "%uint_0 = OpConstantNull %uint " \ 47fd4e5da5Sopenharmony_ci "%uint2_0 = OpConstantNull %uint " \ 48fd4e5da5Sopenharmony_ci "%float_0 = OpConstantNull %float " \ 49fd4e5da5Sopenharmony_ci "%false = OpConstantFalse %bool " \ 50fd4e5da5Sopenharmony_ci "%true = OpConstantTrue %bool " \ 51fd4e5da5Sopenharmony_ci "%null = OpConstantNull %_ptr_uint " 52fd4e5da5Sopenharmony_ci 53fd4e5da5Sopenharmony_ci#define kShaderPreamble \ 54fd4e5da5Sopenharmony_ci "OpCapability Shader\n" \ 55fd4e5da5Sopenharmony_ci "OpCapability Linkage\n" \ 56fd4e5da5Sopenharmony_ci "OpMemoryModel Logical Simple\n" 57fd4e5da5Sopenharmony_ci 58fd4e5da5Sopenharmony_ci#define kKernelPreamble \ 59fd4e5da5Sopenharmony_ci "OpCapability Kernel\n" \ 60fd4e5da5Sopenharmony_ci "OpCapability Linkage\n" \ 61fd4e5da5Sopenharmony_ci "OpCapability Addresses\n" \ 62fd4e5da5Sopenharmony_ci "OpMemoryModel Physical32 OpenCL\n" 63fd4e5da5Sopenharmony_ci 64fd4e5da5Sopenharmony_cistruct ConstantOpCase { 65fd4e5da5Sopenharmony_ci spv_target_env env; 66fd4e5da5Sopenharmony_ci std::string assembly; 67fd4e5da5Sopenharmony_ci bool expect_success; 68fd4e5da5Sopenharmony_ci std::string expect_err; 69fd4e5da5Sopenharmony_ci}; 70fd4e5da5Sopenharmony_ci 71fd4e5da5Sopenharmony_ciusing ValidateConstantOp = spvtest::ValidateBase<ConstantOpCase>; 72fd4e5da5Sopenharmony_ci 73fd4e5da5Sopenharmony_ciTEST_P(ValidateConstantOp, Samples) { 74fd4e5da5Sopenharmony_ci const auto env = GetParam().env; 75fd4e5da5Sopenharmony_ci CompileSuccessfully(GetParam().assembly, env); 76fd4e5da5Sopenharmony_ci const auto result = ValidateInstructions(env); 77fd4e5da5Sopenharmony_ci if (GetParam().expect_success) { 78fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, result); 79fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), Eq("")); 80fd4e5da5Sopenharmony_ci } else { 81fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, result); 82fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), HasSubstr(GetParam().expect_err)); 83fd4e5da5Sopenharmony_ci } 84fd4e5da5Sopenharmony_ci} 85fd4e5da5Sopenharmony_ci 86fd4e5da5Sopenharmony_ci#define GOOD_SHADER_10(STR) \ 87fd4e5da5Sopenharmony_ci { SPV_ENV_UNIVERSAL_1_0, kShaderPreamble kBasicTypes STR, true, "" } 88fd4e5da5Sopenharmony_ci#define GOOD_KERNEL_10(STR) \ 89fd4e5da5Sopenharmony_ci { SPV_ENV_UNIVERSAL_1_0, kKernelPreamble kBasicTypes STR, true, "" } 90fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 91fd4e5da5Sopenharmony_ci UniversalInShader, ValidateConstantOp, 92fd4e5da5Sopenharmony_ci ValuesIn(std::vector<ConstantOpCase>{ 93fd4e5da5Sopenharmony_ci // TODO(dneto): Conversions must change width. 94fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint SConvert %uint_0"), 95fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %float FConvert %float_0"), 96fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint SNegate %uint_0"), 97fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint Not %uint_0"), 98fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint IAdd %uint_0 %uint_0"), 99fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint ISub %uint_0 %uint_0"), 100fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint IMul %uint_0 %uint_0"), 101fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint UDiv %uint_0 %uint_0"), 102fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint SDiv %uint_0 %uint_0"), 103fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint UMod %uint_0 %uint_0"), 104fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint SRem %uint_0 %uint_0"), 105fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint SMod %uint_0 %uint_0"), 106fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 107fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint ShiftRightLogical %uint_0 %uint_0"), 108fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 109fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint ShiftRightArithmetic %uint_0 %uint_0"), 110fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 111fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint ShiftLeftLogical %uint_0 %uint_0"), 112fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %uint BitwiseOr %uint_0 %uint_0"), 113fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 114fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint BitwiseXor %uint_0 %uint_0"), 115fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 116fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint2 VectorShuffle %uint2_0 %uint2_0 1 3"), 117fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 118fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint CompositeExtract %uint2_0 1"), 119fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 120fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint2 CompositeInsert %uint_0 %uint2_0 1"), 121fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalOr %true %false"), 122fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalNot %true"), 123fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalAnd %true %false"), 124fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalEqual %true %false"), 125fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 126fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool LogicalNotEqual %true %false"), 127fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 128fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint Select %true %uint_0 %uint_0"), 129fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %bool IEqual %uint_0 %uint_0"), 130fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %bool INotEqual %uint_0 %uint_0"), 131fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %bool ULessThan %uint_0 %uint_0"), 132fd4e5da5Sopenharmony_ci GOOD_SHADER_10("%v = OpSpecConstantOp %bool SLessThan %uint_0 %uint_0"), 133fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 134fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool ULessThanEqual %uint_0 %uint_0"), 135fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 136fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool SLessThanEqual %uint_0 %uint_0"), 137fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 138fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool UGreaterThan %uint_0 %uint_0"), 139fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 140fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool UGreaterThanEqual %uint_0 %uint_0"), 141fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 142fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool SGreaterThan %uint_0 %uint_0"), 143fd4e5da5Sopenharmony_ci GOOD_SHADER_10( 144fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool SGreaterThanEqual %uint_0 %uint_0"), 145fd4e5da5Sopenharmony_ci })); 146fd4e5da5Sopenharmony_ci 147fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 148fd4e5da5Sopenharmony_ci UniversalInKernel, ValidateConstantOp, 149fd4e5da5Sopenharmony_ci ValuesIn(std::vector<ConstantOpCase>{ 150fd4e5da5Sopenharmony_ci // TODO(dneto): Conversions must change width. 151fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SConvert %uint_0"), 152fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float FConvert %float_0"), 153fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SNegate %uint_0"), 154fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint Not %uint_0"), 155fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint IAdd %uint_0 %uint_0"), 156fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint ISub %uint_0 %uint_0"), 157fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint IMul %uint_0 %uint_0"), 158fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint UDiv %uint_0 %uint_0"), 159fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SDiv %uint_0 %uint_0"), 160fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint UMod %uint_0 %uint_0"), 161fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SRem %uint_0 %uint_0"), 162fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SMod %uint_0 %uint_0"), 163fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 164fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint ShiftRightLogical %uint_0 %uint_0"), 165fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 166fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint ShiftRightArithmetic %uint_0 %uint_0"), 167fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 168fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint ShiftLeftLogical %uint_0 %uint_0"), 169fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint BitwiseOr %uint_0 %uint_0"), 170fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 171fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint BitwiseXor %uint_0 %uint_0"), 172fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 173fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint2 VectorShuffle %uint2_0 %uint2_0 1 3"), 174fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 175fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint CompositeExtract %uint2_0 1"), 176fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 177fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint2 CompositeInsert %uint_0 %uint2_0 1"), 178fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalOr %true %false"), 179fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalNot %true"), 180fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalAnd %true %false"), 181fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalEqual %true %false"), 182fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 183fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool LogicalNotEqual %true %false"), 184fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 185fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint Select %true %uint_0 %uint_0"), 186fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %bool IEqual %uint_0 %uint_0"), 187fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %bool INotEqual %uint_0 %uint_0"), 188fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %bool ULessThan %uint_0 %uint_0"), 189fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %bool SLessThan %uint_0 %uint_0"), 190fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 191fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool ULessThanEqual %uint_0 %uint_0"), 192fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 193fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool SLessThanEqual %uint_0 %uint_0"), 194fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 195fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool UGreaterThan %uint_0 %uint_0"), 196fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 197fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool UGreaterThanEqual %uint_0 %uint_0"), 198fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 199fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool SGreaterThan %uint_0 %uint_0"), 200fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 201fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %bool SGreaterThanEqual %uint_0 %uint_0"), 202fd4e5da5Sopenharmony_ci })); 203fd4e5da5Sopenharmony_ci 204fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 205fd4e5da5Sopenharmony_ci UConvert, ValidateConstantOp, 206fd4e5da5Sopenharmony_ci ValuesIn(std::vector<ConstantOpCase>{ 207fd4e5da5Sopenharmony_ci // TODO(dneto): Conversions must change width. 208fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_0, 209fd4e5da5Sopenharmony_ci kKernelPreamble kBasicTypes 210fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 211fd4e5da5Sopenharmony_ci true, ""}, 212fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_1, 213fd4e5da5Sopenharmony_ci kKernelPreamble kBasicTypes 214fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 215fd4e5da5Sopenharmony_ci true, ""}, 216fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_3, 217fd4e5da5Sopenharmony_ci kKernelPreamble kBasicTypes 218fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 219fd4e5da5Sopenharmony_ci true, ""}, 220fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_3, 221fd4e5da5Sopenharmony_ci kKernelPreamble kBasicTypes 222fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 223fd4e5da5Sopenharmony_ci true, ""}, 224fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_4, 225fd4e5da5Sopenharmony_ci kKernelPreamble kBasicTypes 226fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 227fd4e5da5Sopenharmony_ci true, ""}, 228fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_0, 229fd4e5da5Sopenharmony_ci kShaderPreamble kBasicTypes 230fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 231fd4e5da5Sopenharmony_ci false, 232fd4e5da5Sopenharmony_ci "Prior to SPIR-V 1.4, specialization constant operation " 233fd4e5da5Sopenharmony_ci "UConvert requires Kernel capability"}, 234fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_1, 235fd4e5da5Sopenharmony_ci kShaderPreamble kBasicTypes 236fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 237fd4e5da5Sopenharmony_ci false, 238fd4e5da5Sopenharmony_ci "Prior to SPIR-V 1.4, specialization constant operation " 239fd4e5da5Sopenharmony_ci "UConvert requires Kernel capability"}, 240fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_3, 241fd4e5da5Sopenharmony_ci kShaderPreamble kBasicTypes 242fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 243fd4e5da5Sopenharmony_ci false, 244fd4e5da5Sopenharmony_ci "Prior to SPIR-V 1.4, specialization constant operation " 245fd4e5da5Sopenharmony_ci "UConvert requires Kernel capability"}, 246fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_3, 247fd4e5da5Sopenharmony_ci kShaderPreamble kBasicTypes 248fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 249fd4e5da5Sopenharmony_ci false, 250fd4e5da5Sopenharmony_ci "Prior to SPIR-V 1.4, specialization constant operation " 251fd4e5da5Sopenharmony_ci "UConvert requires Kernel capability"}, 252fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_4, 253fd4e5da5Sopenharmony_ci kShaderPreamble kBasicTypes 254fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 255fd4e5da5Sopenharmony_ci true, ""}, 256fd4e5da5Sopenharmony_ci })); 257fd4e5da5Sopenharmony_ci 258fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 259fd4e5da5Sopenharmony_ci KernelInKernel, ValidateConstantOp, 260fd4e5da5Sopenharmony_ci ValuesIn(std::vector<ConstantOpCase>{ 261fd4e5da5Sopenharmony_ci // TODO(dneto): Conversions must change width. 262fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint ConvertFToS %float_0"), 263fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float ConvertSToF %uint_0"), 264fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint ConvertFToU %float_0"), 265fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float ConvertUToF %uint_0"), 266fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint UConvert %uint_0"), 267fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 268fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %_ptr_uint GenericCastToPtr %null"), 269fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 270fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %_ptr_uint PtrCastToGeneric %null"), 271fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %uint Bitcast %uint_0"), 272fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float FNegate %float_0"), 273fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float FAdd %float_0 %float_0"), 274fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float FSub %float_0 %float_0"), 275fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float FMul %float_0 %float_0"), 276fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float FDiv %float_0 %float_0"), 277fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float FRem %float_0 %float_0"), 278fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %float FMod %float_0 %float_0"), 279fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 280fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %_ptr_uint AccessChain %null %uint_0"), 281fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %_ptr_uint InBoundsAccessChain " 282fd4e5da5Sopenharmony_ci "%null %uint_0"), 283fd4e5da5Sopenharmony_ci GOOD_KERNEL_10( 284fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %_ptr_uint PtrAccessChain %null %uint_0"), 285fd4e5da5Sopenharmony_ci GOOD_KERNEL_10("%v = OpSpecConstantOp %_ptr_uint " 286fd4e5da5Sopenharmony_ci "InBoundsPtrAccessChain %null %uint_0"), 287fd4e5da5Sopenharmony_ci })); 288fd4e5da5Sopenharmony_ci 289fd4e5da5Sopenharmony_ci#define BAD_SHADER_10(STR, NAME) \ 290fd4e5da5Sopenharmony_ci { \ 291fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_0, kShaderPreamble kBasicTypes STR, false, \ 292fd4e5da5Sopenharmony_ci "Specialization constant operation " NAME \ 293fd4e5da5Sopenharmony_ci " requires Kernel capability" \ 294fd4e5da5Sopenharmony_ci } 295fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 296fd4e5da5Sopenharmony_ci KernelInShader, ValidateConstantOp, 297fd4e5da5Sopenharmony_ci ValuesIn(std::vector<ConstantOpCase>{ 298fd4e5da5Sopenharmony_ci // TODO(dneto): Conversions must change width. 299fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %uint ConvertFToS %float_0", 300fd4e5da5Sopenharmony_ci "ConvertFToS"), 301fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %float ConvertSToF %uint_0", 302fd4e5da5Sopenharmony_ci "ConvertSToF"), 303fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %uint ConvertFToU %float_0", 304fd4e5da5Sopenharmony_ci "ConvertFToU"), 305fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %float ConvertUToF %uint_0", 306fd4e5da5Sopenharmony_ci "ConvertUToF"), 307fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint GenericCastToPtr %null", 308fd4e5da5Sopenharmony_ci "GenericCastToPtr"), 309fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint PtrCastToGeneric %null", 310fd4e5da5Sopenharmony_ci "PtrCastToGeneric"), 311fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %uint Bitcast %uint_0", "Bitcast"), 312fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %float FNegate %float_0", 313fd4e5da5Sopenharmony_ci "FNegate"), 314fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %float FAdd %float_0 %float_0", 315fd4e5da5Sopenharmony_ci "FAdd"), 316fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %float FSub %float_0 %float_0", 317fd4e5da5Sopenharmony_ci "FSub"), 318fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %float FMul %float_0 %float_0", 319fd4e5da5Sopenharmony_ci "FMul"), 320fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %float FDiv %float_0 %float_0", 321fd4e5da5Sopenharmony_ci "FDiv"), 322fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %float FRem %float_0 %float_0", 323fd4e5da5Sopenharmony_ci "FRem"), 324fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %float FMod %float_0 %float_0", 325fd4e5da5Sopenharmony_ci "FMod"), 326fd4e5da5Sopenharmony_ci BAD_SHADER_10( 327fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %_ptr_uint AccessChain %null %uint_0", 328fd4e5da5Sopenharmony_ci "AccessChain"), 329fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint InBoundsAccessChain " 330fd4e5da5Sopenharmony_ci "%null %uint_0", 331fd4e5da5Sopenharmony_ci "InBoundsAccessChain"), 332fd4e5da5Sopenharmony_ci BAD_SHADER_10( 333fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %_ptr_uint PtrAccessChain %null %uint_0", 334fd4e5da5Sopenharmony_ci "PtrAccessChain"), 335fd4e5da5Sopenharmony_ci BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint " 336fd4e5da5Sopenharmony_ci "InBoundsPtrAccessChain %null %uint_0", 337fd4e5da5Sopenharmony_ci "InBoundsPtrAccessChain"), 338fd4e5da5Sopenharmony_ci })); 339fd4e5da5Sopenharmony_ci 340fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 341fd4e5da5Sopenharmony_ci UConvertInAMD_gpu_shader_int16, ValidateConstantOp, 342fd4e5da5Sopenharmony_ci ValuesIn(std::vector<ConstantOpCase>{ 343fd4e5da5Sopenharmony_ci // SPV_AMD_gpu_shader_int16 should enable UConvert for OpSpecConstantOp 344fd4e5da5Sopenharmony_ci // https://github.com/KhronosGroup/glslang/issues/848 345fd4e5da5Sopenharmony_ci {SPV_ENV_UNIVERSAL_1_0, 346fd4e5da5Sopenharmony_ci "OpCapability Shader " 347fd4e5da5Sopenharmony_ci "OpCapability Linkage ; So we don't need to define a function\n" 348fd4e5da5Sopenharmony_ci "OpExtension \"SPV_AMD_gpu_shader_int16\" " 349fd4e5da5Sopenharmony_ci "OpMemoryModel Logical Simple " kBasicTypes 350fd4e5da5Sopenharmony_ci "%v = OpSpecConstantOp %uint UConvert %uint_0", 351fd4e5da5Sopenharmony_ci true, ""}, 352fd4e5da5Sopenharmony_ci })); 353fd4e5da5Sopenharmony_ci 354fd4e5da5Sopenharmony_ciTEST_F(ValidateConstant, SpecConstantUConvert1p3Binary1p4EnvBad) { 355fd4e5da5Sopenharmony_ci const std::string spirv = R"( 356fd4e5da5Sopenharmony_ciOpCapability Shader 357fd4e5da5Sopenharmony_ciOpCapability Linkage 358fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 359fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 360fd4e5da5Sopenharmony_ci%int0 = OpConstant %int 0 361fd4e5da5Sopenharmony_ci%const = OpSpecConstantOp %int UConvert %int0 362fd4e5da5Sopenharmony_ci)"; 363fd4e5da5Sopenharmony_ci 364fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3); 365fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 366fd4e5da5Sopenharmony_ci EXPECT_THAT( 367fd4e5da5Sopenharmony_ci getDiagnosticString(), 368fd4e5da5Sopenharmony_ci HasSubstr( 369fd4e5da5Sopenharmony_ci "Prior to SPIR-V 1.4, specialization constant operation UConvert " 370fd4e5da5Sopenharmony_ci "requires Kernel capability or extension SPV_AMD_gpu_shader_int16")); 371fd4e5da5Sopenharmony_ci} 372fd4e5da5Sopenharmony_ci 373fd4e5da5Sopenharmony_ciusing SmallStorageConstants = spvtest::ValidateBase<std::string>; 374fd4e5da5Sopenharmony_ci 375fd4e5da5Sopenharmony_ciCodeGenerator GetSmallStorageCodeGenerator() { 376fd4e5da5Sopenharmony_ci CodeGenerator generator; 377fd4e5da5Sopenharmony_ci generator.capabilities_ = R"( 378fd4e5da5Sopenharmony_ciOpCapability Shader 379fd4e5da5Sopenharmony_ciOpCapability Linkage 380fd4e5da5Sopenharmony_ciOpCapability UniformAndStorageBuffer16BitAccess 381fd4e5da5Sopenharmony_ciOpCapability StoragePushConstant16 382fd4e5da5Sopenharmony_ciOpCapability StorageInputOutput16 383fd4e5da5Sopenharmony_ciOpCapability UniformAndStorageBuffer8BitAccess 384fd4e5da5Sopenharmony_ciOpCapability StoragePushConstant8 385fd4e5da5Sopenharmony_ci)"; 386fd4e5da5Sopenharmony_ci generator.extensions_ = R"( 387fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage" 388fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_8bit_storage" 389fd4e5da5Sopenharmony_ci)"; 390fd4e5da5Sopenharmony_ci generator.memory_model_ = "OpMemoryModel Logical GLSL450\n"; 391fd4e5da5Sopenharmony_ci generator.types_ = R"( 392fd4e5da5Sopenharmony_ci%short = OpTypeInt 16 0 393fd4e5da5Sopenharmony_ci%short2 = OpTypeVector %short 2 394fd4e5da5Sopenharmony_ci%char = OpTypeInt 8 0 395fd4e5da5Sopenharmony_ci%char2 = OpTypeVector %char 2 396fd4e5da5Sopenharmony_ci%half = OpTypeFloat 16 397fd4e5da5Sopenharmony_ci%half2 = OpTypeVector %half 2 398fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 399fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 400fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 401fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 402fd4e5da5Sopenharmony_ci)"; 403fd4e5da5Sopenharmony_ci return generator; 404fd4e5da5Sopenharmony_ci} 405fd4e5da5Sopenharmony_ci 406fd4e5da5Sopenharmony_ciTEST_P(SmallStorageConstants, SmallConstant) { 407fd4e5da5Sopenharmony_ci std::string constant = GetParam(); 408fd4e5da5Sopenharmony_ci CodeGenerator generator = GetSmallStorageCodeGenerator(); 409fd4e5da5Sopenharmony_ci generator.after_types_ += constant + "\n"; 410fd4e5da5Sopenharmony_ci CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3); 411fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 412fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 413fd4e5da5Sopenharmony_ci HasSubstr("Cannot form constants of 8- or 16-bit types")); 414fd4e5da5Sopenharmony_ci} 415fd4e5da5Sopenharmony_ci 416fd4e5da5Sopenharmony_ci// Constant composites would be caught through scalar constants. 417fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 418fd4e5da5Sopenharmony_ci SmallConstants, SmallStorageConstants, 419fd4e5da5Sopenharmony_ci Values("%c = OpConstant %char 0", "%c = OpConstantNull %char2", 420fd4e5da5Sopenharmony_ci "%c = OpConstant %short 0", "%c = OpConstantNull %short", 421fd4e5da5Sopenharmony_ci "%c = OpConstant %half 0", "%c = OpConstantNull %half", 422fd4e5da5Sopenharmony_ci "%c = OpSpecConstant %char 0", "%c = OpSpecConstant %short 0", 423fd4e5da5Sopenharmony_ci "%c = OpSpecConstant %half 0", 424fd4e5da5Sopenharmony_ci "%c = OpSpecConstantOp %char SConvert %int_0", 425fd4e5da5Sopenharmony_ci "%c = OpSpecConstantOp %short SConvert %int_0", 426fd4e5da5Sopenharmony_ci "%c = OpSpecConstantOp %half FConvert %float_0")); 427fd4e5da5Sopenharmony_ci 428fd4e5da5Sopenharmony_ciTEST_F(ValidateConstant, NullPointerTo16BitStorageOk) { 429fd4e5da5Sopenharmony_ci std::string spirv = R"( 430fd4e5da5Sopenharmony_ciOpCapability Shader 431fd4e5da5Sopenharmony_ciOpCapability VariablePointersStorageBuffer 432fd4e5da5Sopenharmony_ciOpCapability UniformAndStorageBuffer16BitAccess 433fd4e5da5Sopenharmony_ciOpCapability Linkage 434fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage" 435fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 436fd4e5da5Sopenharmony_ci%half = OpTypeFloat 16 437fd4e5da5Sopenharmony_ci%ptr_ssbo_half = OpTypePointer StorageBuffer %half 438fd4e5da5Sopenharmony_ci%null_ptr = OpConstantNull %ptr_ssbo_half 439fd4e5da5Sopenharmony_ci)"; 440fd4e5da5Sopenharmony_ci 441fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3); 442fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 443fd4e5da5Sopenharmony_ci} 444fd4e5da5Sopenharmony_ci 445fd4e5da5Sopenharmony_ciTEST_F(ValidateConstant, NullMatrix) { 446fd4e5da5Sopenharmony_ci std::string spirv = R"( 447fd4e5da5Sopenharmony_ciOpCapability Shader 448fd4e5da5Sopenharmony_ciOpCapability Linkage 449fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 450fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 451fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2 452fd4e5da5Sopenharmony_ci%mat2x2 = OpTypeMatrix %v2float 2 453fd4e5da5Sopenharmony_ci%null_vector = OpConstantNull %v2float 454fd4e5da5Sopenharmony_ci%null_matrix = OpConstantComposite %mat2x2 %null_vector %null_vector 455fd4e5da5Sopenharmony_ci)"; 456fd4e5da5Sopenharmony_ci 457fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 458fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 459fd4e5da5Sopenharmony_ci} 460fd4e5da5Sopenharmony_ci 461fd4e5da5Sopenharmony_ciTEST_F(ValidateConstant, NullPhysicalStorageBuffer) { 462fd4e5da5Sopenharmony_ci std::string spirv = R"( 463fd4e5da5Sopenharmony_ciOpCapability Shader 464fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses 465fd4e5da5Sopenharmony_ciOpCapability Linkage 466fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_physical_storage_buffer" 467fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450 468fd4e5da5Sopenharmony_ciOpName %ptr "ptr" 469fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 470fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %int 471fd4e5da5Sopenharmony_ci%null = OpConstantNull %ptr 472fd4e5da5Sopenharmony_ci)"; 473fd4e5da5Sopenharmony_ci 474fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 475fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 476fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 477fd4e5da5Sopenharmony_ci HasSubstr("OpConstantNull Result Type <id> '1[%ptr]' cannot have " 478fd4e5da5Sopenharmony_ci "a null value")); 479fd4e5da5Sopenharmony_ci} 480fd4e5da5Sopenharmony_ci 481fd4e5da5Sopenharmony_ciTEST_F(ValidateConstant, VectorMismatchedConstituents) { 482fd4e5da5Sopenharmony_ci std::string spirv = kShaderPreamble kBasicTypes R"( 483fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 484fd4e5da5Sopenharmony_ci%int_0 = OpConstantNull %int 485fd4e5da5Sopenharmony_ci%const_vector = OpConstantComposite %uint2 %uint_0 %int_0 486fd4e5da5Sopenharmony_ci)"; 487fd4e5da5Sopenharmony_ci 488fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 489fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 490fd4e5da5Sopenharmony_ci EXPECT_THAT( 491fd4e5da5Sopenharmony_ci getDiagnosticString(), 492fd4e5da5Sopenharmony_ci HasSubstr( 493fd4e5da5Sopenharmony_ci "OpConstantComposite Constituent <id> '13[%13]'s type " 494fd4e5da5Sopenharmony_ci "does not match Result Type <id> '3[%v2uint]'s vector element type")); 495fd4e5da5Sopenharmony_ci} 496fd4e5da5Sopenharmony_ci 497fd4e5da5Sopenharmony_ci} // namespace 498fd4e5da5Sopenharmony_ci} // namespace val 499fd4e5da5Sopenharmony_ci} // namespace spvtools 500