1fd4e5da5Sopenharmony_ci// Copyright (c) 2021 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#include <vector> 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 18fd4e5da5Sopenharmony_ci#include "source/opt/convert_to_sampled_image_pass.h" 19fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 20fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 21fd4e5da5Sopenharmony_ci 22fd4e5da5Sopenharmony_cinamespace spvtools { 23fd4e5da5Sopenharmony_cinamespace opt { 24fd4e5da5Sopenharmony_cinamespace { 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciusing testing::Eq; 27fd4e5da5Sopenharmony_ciusing VectorOfDescriptorSetAndBindingPairs = 28fd4e5da5Sopenharmony_ci std::vector<DescriptorSetAndBinding>; 29fd4e5da5Sopenharmony_ci 30fd4e5da5Sopenharmony_cistruct DescriptorSetAndBindingStringParsingTestCase { 31fd4e5da5Sopenharmony_ci const char* descriptor_set_binding_str; 32fd4e5da5Sopenharmony_ci bool expect_success; 33fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs expected_descriptor_set_binding_pairs; 34fd4e5da5Sopenharmony_ci}; 35fd4e5da5Sopenharmony_ci 36fd4e5da5Sopenharmony_ciusing DescriptorSetAndBindingStringParsingTest = 37fd4e5da5Sopenharmony_ci ::testing::TestWithParam<DescriptorSetAndBindingStringParsingTestCase>; 38fd4e5da5Sopenharmony_ci 39fd4e5da5Sopenharmony_ciTEST_P(DescriptorSetAndBindingStringParsingTest, TestCase) { 40fd4e5da5Sopenharmony_ci const auto& tc = GetParam(); 41fd4e5da5Sopenharmony_ci auto actual_descriptor_set_binding_pairs = 42fd4e5da5Sopenharmony_ci ConvertToSampledImagePass::ParseDescriptorSetBindingPairsString( 43fd4e5da5Sopenharmony_ci tc.descriptor_set_binding_str); 44fd4e5da5Sopenharmony_ci if (tc.expect_success) { 45fd4e5da5Sopenharmony_ci EXPECT_NE(nullptr, actual_descriptor_set_binding_pairs); 46fd4e5da5Sopenharmony_ci if (actual_descriptor_set_binding_pairs) { 47fd4e5da5Sopenharmony_ci EXPECT_THAT(*actual_descriptor_set_binding_pairs, 48fd4e5da5Sopenharmony_ci Eq(tc.expected_descriptor_set_binding_pairs)); 49fd4e5da5Sopenharmony_ci } 50fd4e5da5Sopenharmony_ci } else { 51fd4e5da5Sopenharmony_ci EXPECT_EQ(nullptr, actual_descriptor_set_binding_pairs); 52fd4e5da5Sopenharmony_ci } 53fd4e5da5Sopenharmony_ci} 54fd4e5da5Sopenharmony_ci 55fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 56fd4e5da5Sopenharmony_ci ValidString, DescriptorSetAndBindingStringParsingTest, 57fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector< 58fd4e5da5Sopenharmony_ci DescriptorSetAndBindingStringParsingTestCase>{ 59fd4e5da5Sopenharmony_ci // 0. empty vector 60fd4e5da5Sopenharmony_ci {"", true, VectorOfDescriptorSetAndBindingPairs({})}, 61fd4e5da5Sopenharmony_ci // 1. one pair 62fd4e5da5Sopenharmony_ci {"100:1024", true, 63fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs({DescriptorSetAndBinding{100, 64fd4e5da5Sopenharmony_ci 1024}})}, 65fd4e5da5Sopenharmony_ci // 2. two pairs 66fd4e5da5Sopenharmony_ci {"100:1024 200:2048", true, 67fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs( 68fd4e5da5Sopenharmony_ci {DescriptorSetAndBinding{100, 1024}, 69fd4e5da5Sopenharmony_ci DescriptorSetAndBinding{200, 2048}})}, 70fd4e5da5Sopenharmony_ci // 3. spaces between entries 71fd4e5da5Sopenharmony_ci {"100:1024 \n \r \t \v \f 200:2048", true, 72fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs( 73fd4e5da5Sopenharmony_ci {DescriptorSetAndBinding{100, 1024}, 74fd4e5da5Sopenharmony_ci DescriptorSetAndBinding{200, 2048}})}, 75fd4e5da5Sopenharmony_ci // 4. \t, \n, \r and spaces before spec id 76fd4e5da5Sopenharmony_ci {" \n \r\t \t \v \f 100:1024", true, 77fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs({DescriptorSetAndBinding{100, 78fd4e5da5Sopenharmony_ci 1024}})}, 79fd4e5da5Sopenharmony_ci // 5. \t, \n, \r and spaces after value string 80fd4e5da5Sopenharmony_ci {"100:1024 \n \r\t \t \v \f ", true, 81fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs({DescriptorSetAndBinding{100, 82fd4e5da5Sopenharmony_ci 1024}})}, 83fd4e5da5Sopenharmony_ci // 6. maximum spec id 84fd4e5da5Sopenharmony_ci {"4294967295:0", true, 85fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs({DescriptorSetAndBinding{ 86fd4e5da5Sopenharmony_ci 4294967295, 0}})}, 87fd4e5da5Sopenharmony_ci // 7. minimum spec id 88fd4e5da5Sopenharmony_ci {"0:100", true, 89fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs({DescriptorSetAndBinding{0, 90fd4e5da5Sopenharmony_ci 100}})}, 91fd4e5da5Sopenharmony_ci // 8. multiple entries 92fd4e5da5Sopenharmony_ci {"101:1 102:2 103:3 104:4 200:201 9999:1000", true, 93fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs( 94fd4e5da5Sopenharmony_ci {DescriptorSetAndBinding{101, 1}, DescriptorSetAndBinding{102, 2}, 95fd4e5da5Sopenharmony_ci DescriptorSetAndBinding{103, 3}, DescriptorSetAndBinding{104, 4}, 96fd4e5da5Sopenharmony_ci DescriptorSetAndBinding{200, 201}, 97fd4e5da5Sopenharmony_ci DescriptorSetAndBinding{9999, 1000}})}, 98fd4e5da5Sopenharmony_ci })); 99fd4e5da5Sopenharmony_ci 100fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 101fd4e5da5Sopenharmony_ci InvalidString, DescriptorSetAndBindingStringParsingTest, 102fd4e5da5Sopenharmony_ci ::testing::ValuesIn( 103fd4e5da5Sopenharmony_ci std::vector<DescriptorSetAndBindingStringParsingTestCase>{ 104fd4e5da5Sopenharmony_ci // 0. missing default value 105fd4e5da5Sopenharmony_ci {"100:", false, VectorOfDescriptorSetAndBindingPairs{}}, 106fd4e5da5Sopenharmony_ci // 1. descriptor set is not an integer 107fd4e5da5Sopenharmony_ci {"100.0:200", false, VectorOfDescriptorSetAndBindingPairs{}}, 108fd4e5da5Sopenharmony_ci // 2. descriptor set is not a number 109fd4e5da5Sopenharmony_ci {"something_not_a_number:1", false, 110fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs{}}, 111fd4e5da5Sopenharmony_ci // 3. only descriptor set number 112fd4e5da5Sopenharmony_ci {"100", false, VectorOfDescriptorSetAndBindingPairs{}}, 113fd4e5da5Sopenharmony_ci // 4. empty descriptor set 114fd4e5da5Sopenharmony_ci {":3", false, VectorOfDescriptorSetAndBindingPairs{}}, 115fd4e5da5Sopenharmony_ci // 5. only colon 116fd4e5da5Sopenharmony_ci {":", false, VectorOfDescriptorSetAndBindingPairs{}}, 117fd4e5da5Sopenharmony_ci // 6. descriptor set overflow 118fd4e5da5Sopenharmony_ci {"4294967296:200", false, VectorOfDescriptorSetAndBindingPairs{}}, 119fd4e5da5Sopenharmony_ci // 7. descriptor set less than 0 120fd4e5da5Sopenharmony_ci {"-1:200", false, VectorOfDescriptorSetAndBindingPairs{}}, 121fd4e5da5Sopenharmony_ci // 8. nullptr 122fd4e5da5Sopenharmony_ci {nullptr, false, VectorOfDescriptorSetAndBindingPairs{}}, 123fd4e5da5Sopenharmony_ci // 9. only a number is invalid 124fd4e5da5Sopenharmony_ci {"1234", false, VectorOfDescriptorSetAndBindingPairs{}}, 125fd4e5da5Sopenharmony_ci // 10. invalid entry separator 126fd4e5da5Sopenharmony_ci {"12:34;23:14", false, VectorOfDescriptorSetAndBindingPairs{}}, 127fd4e5da5Sopenharmony_ci // 11. invalid descriptor set and default value separator 128fd4e5da5Sopenharmony_ci {"12@34", false, VectorOfDescriptorSetAndBindingPairs{}}, 129fd4e5da5Sopenharmony_ci // 12. spaces before colon 130fd4e5da5Sopenharmony_ci {"100 :1024", false, VectorOfDescriptorSetAndBindingPairs{}}, 131fd4e5da5Sopenharmony_ci // 13. spaces after colon 132fd4e5da5Sopenharmony_ci {"100: 1024", false, VectorOfDescriptorSetAndBindingPairs{}}, 133fd4e5da5Sopenharmony_ci // 14. descriptor set represented in hex float format is invalid 134fd4e5da5Sopenharmony_ci {"0x3p10:200", false, VectorOfDescriptorSetAndBindingPairs{}}, 135fd4e5da5Sopenharmony_ci })); 136fd4e5da5Sopenharmony_ci 137fd4e5da5Sopenharmony_cistd::string BuildShader(const char* shader_decorate_instructions, 138fd4e5da5Sopenharmony_ci const char* shader_image_and_sampler_variables, 139fd4e5da5Sopenharmony_ci const char* shader_body) { 140fd4e5da5Sopenharmony_ci // Base HLSL code: 141fd4e5da5Sopenharmony_ci // 142fd4e5da5Sopenharmony_ci // SamplerState sam : register(s2); 143fd4e5da5Sopenharmony_ci // Texture2D <float4> texture : register(t5); 144fd4e5da5Sopenharmony_ci // 145fd4e5da5Sopenharmony_ci // float4 main() : SV_TARGET { 146fd4e5da5Sopenharmony_ci // return texture.SampleLevel(sam, float2(1, 2), 10, 2); 147fd4e5da5Sopenharmony_ci // } 148fd4e5da5Sopenharmony_ci std::stringstream ss; 149fd4e5da5Sopenharmony_ci ss << R"( 150fd4e5da5Sopenharmony_ci OpCapability Shader 151fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 152fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %out_var_SV_TARGET 153fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 154fd4e5da5Sopenharmony_ci OpSource HLSL 600 155fd4e5da5Sopenharmony_ci OpName %type_sampler "type.sampler" 156fd4e5da5Sopenharmony_ci OpName %type_2d_image "type.2d.image" 157fd4e5da5Sopenharmony_ci OpName %out_var_SV_TARGET "out.var.SV_TARGET" 158fd4e5da5Sopenharmony_ci OpName %main "main" 159fd4e5da5Sopenharmony_ci OpName %type_sampled_image "type.sampled.image" 160fd4e5da5Sopenharmony_ci OpDecorate %out_var_SV_TARGET Location 0 161fd4e5da5Sopenharmony_ci )"; 162fd4e5da5Sopenharmony_ci ss << shader_decorate_instructions; 163fd4e5da5Sopenharmony_ci ss << R"( 164fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 165fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 166fd4e5da5Sopenharmony_ci %float_2 = OpConstant %float 2 167fd4e5da5Sopenharmony_ci %v2float = OpTypeVector %float 2 168fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %v2float %float_1 %float_2 169fd4e5da5Sopenharmony_ci %float_10 = OpConstant %float 10 170fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 171fd4e5da5Sopenharmony_ci %int_2 = OpConstant %int 2 172fd4e5da5Sopenharmony_ci %v2int = OpTypeVector %int 2 173fd4e5da5Sopenharmony_ci %17 = OpConstantComposite %v2int %int_2 %int_2 174fd4e5da5Sopenharmony_ci%type_sampler = OpTypeSampler 175fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler 176fd4e5da5Sopenharmony_ci%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown 177fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image 178fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 179fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 180fd4e5da5Sopenharmony_ci %void = OpTypeVoid 181fd4e5da5Sopenharmony_ci %23 = OpTypeFunction %void 182fd4e5da5Sopenharmony_ci%type_sampled_image = OpTypeSampledImage %type_2d_image 183fd4e5da5Sopenharmony_ci )"; 184fd4e5da5Sopenharmony_ci ss << shader_image_and_sampler_variables; 185fd4e5da5Sopenharmony_ci ss << R"( 186fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 187fd4e5da5Sopenharmony_ci %main = OpFunction %void None %23 188fd4e5da5Sopenharmony_ci %24 = OpLabel 189fd4e5da5Sopenharmony_ci )"; 190fd4e5da5Sopenharmony_ci ss << shader_body; 191fd4e5da5Sopenharmony_ci ss << R"( 192fd4e5da5Sopenharmony_ci OpReturn 193fd4e5da5Sopenharmony_ci OpFunctionEnd 194fd4e5da5Sopenharmony_ci )"; 195fd4e5da5Sopenharmony_ci return ss.str(); 196fd4e5da5Sopenharmony_ci} 197fd4e5da5Sopenharmony_ci 198fd4e5da5Sopenharmony_ciusing ConvertToSampledImageTest = PassTest<::testing::Test>; 199fd4e5da5Sopenharmony_ci 200fd4e5da5Sopenharmony_ciTEST_F(ConvertToSampledImageTest, Texture2DAndSamplerToSampledImage) { 201fd4e5da5Sopenharmony_ci const std::string shader = BuildShader( 202fd4e5da5Sopenharmony_ci R"( 203fd4e5da5Sopenharmony_ci OpDecorate %sam DescriptorSet 0 204fd4e5da5Sopenharmony_ci OpDecorate %sam Binding 5 205fd4e5da5Sopenharmony_ci OpDecorate %texture DescriptorSet 0 206fd4e5da5Sopenharmony_ci OpDecorate %texture Binding 5 207fd4e5da5Sopenharmony_ci )", 208fd4e5da5Sopenharmony_ci R"( 209fd4e5da5Sopenharmony_ci ; CHECK-NOT: OpVariable %_ptr_UniformConstant_type_2d_image 210fd4e5da5Sopenharmony_ci 211fd4e5da5Sopenharmony_ci ; CHECK: [[tex:%\w+]] = OpVariable %_ptr_UniformConstant_type_sampled_image UniformConstant 212fd4e5da5Sopenharmony_ci %sam = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant 213fd4e5da5Sopenharmony_ci %texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant 214fd4e5da5Sopenharmony_ci )", 215fd4e5da5Sopenharmony_ci R"( 216fd4e5da5Sopenharmony_ci ; CHECK: [[load:%\w+]] = OpLoad %type_sampled_image [[tex]] 217fd4e5da5Sopenharmony_ci ; CHECK: OpImageSampleExplicitLod %v4float [[load]] 218fd4e5da5Sopenharmony_ci %25 = OpLoad %type_2d_image %texture 219fd4e5da5Sopenharmony_ci %26 = OpLoad %type_sampler %sam 220fd4e5da5Sopenharmony_ci %27 = OpSampledImage %type_sampled_image %25 %26 221fd4e5da5Sopenharmony_ci %28 = OpImageSampleExplicitLod %v4float %27 %12 Lod|ConstOffset %float_10 %17 222fd4e5da5Sopenharmony_ci OpStore %out_var_SV_TARGET %28 223fd4e5da5Sopenharmony_ci )"); 224fd4e5da5Sopenharmony_ci 225fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndMatch<ConvertToSampledImagePass>( 226fd4e5da5Sopenharmony_ci shader, /* do_validate = */ true, 227fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs{DescriptorSetAndBinding{0, 5}}); 228fd4e5da5Sopenharmony_ci 229fd4e5da5Sopenharmony_ci EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); 230fd4e5da5Sopenharmony_ci} 231fd4e5da5Sopenharmony_ci 232fd4e5da5Sopenharmony_ciTEST_F(ConvertToSampledImageTest, Texture2DToSampledImage) { 233fd4e5da5Sopenharmony_ci const std::string shader = BuildShader( 234fd4e5da5Sopenharmony_ci R"( 235fd4e5da5Sopenharmony_ci OpDecorate %sam DescriptorSet 0 236fd4e5da5Sopenharmony_ci OpDecorate %sam Binding 2 237fd4e5da5Sopenharmony_ci OpDecorate %texture DescriptorSet 0 238fd4e5da5Sopenharmony_ci OpDecorate %texture Binding 5 239fd4e5da5Sopenharmony_ci )", 240fd4e5da5Sopenharmony_ci R"( 241fd4e5da5Sopenharmony_ci ; CHECK: [[tex:%\w+]] = OpVariable %_ptr_UniformConstant_type_sampled_image UniformConstant 242fd4e5da5Sopenharmony_ci %sam = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant 243fd4e5da5Sopenharmony_ci %texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant 244fd4e5da5Sopenharmony_ci )", 245fd4e5da5Sopenharmony_ci R"( 246fd4e5da5Sopenharmony_ci ; CHECK: [[load:%\w+]] = OpLoad %type_sampled_image [[tex]] 247fd4e5da5Sopenharmony_ci ; CHECK: [[image_extraction:%\w+]] = OpImage %type_2d_image [[load]] 248fd4e5da5Sopenharmony_ci ; CHECK: OpSampledImage %type_sampled_image [[image_extraction]] 249fd4e5da5Sopenharmony_ci %25 = OpLoad %type_2d_image %texture 250fd4e5da5Sopenharmony_ci %26 = OpLoad %type_sampler %sam 251fd4e5da5Sopenharmony_ci %27 = OpSampledImage %type_sampled_image %25 %26 252fd4e5da5Sopenharmony_ci %28 = OpImageSampleExplicitLod %v4float %27 %12 Lod|ConstOffset %float_10 %17 253fd4e5da5Sopenharmony_ci OpStore %out_var_SV_TARGET %28 254fd4e5da5Sopenharmony_ci )"); 255fd4e5da5Sopenharmony_ci 256fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndMatch<ConvertToSampledImagePass>( 257fd4e5da5Sopenharmony_ci shader, /* do_validate = */ true, 258fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs{DescriptorSetAndBinding{0, 5}}); 259fd4e5da5Sopenharmony_ci 260fd4e5da5Sopenharmony_ci EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); 261fd4e5da5Sopenharmony_ci} 262fd4e5da5Sopenharmony_ci 263fd4e5da5Sopenharmony_ciTEST_F(ConvertToSampledImageTest, SamplerToSampledImage) { 264fd4e5da5Sopenharmony_ci const std::string shader = BuildShader( 265fd4e5da5Sopenharmony_ci R"( 266fd4e5da5Sopenharmony_ci OpDecorate %sam DescriptorSet 0 267fd4e5da5Sopenharmony_ci OpDecorate %sam Binding 2 268fd4e5da5Sopenharmony_ci OpDecorate %texture DescriptorSet 0 269fd4e5da5Sopenharmony_ci OpDecorate %texture Binding 5 270fd4e5da5Sopenharmony_ci )", 271fd4e5da5Sopenharmony_ci R"( 272fd4e5da5Sopenharmony_ci %sam = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant 273fd4e5da5Sopenharmony_ci %texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant 274fd4e5da5Sopenharmony_ci )", 275fd4e5da5Sopenharmony_ci R"( 276fd4e5da5Sopenharmony_ci %25 = OpLoad %type_2d_image %texture 277fd4e5da5Sopenharmony_ci %26 = OpLoad %type_sampler %sam 278fd4e5da5Sopenharmony_ci %27 = OpSampledImage %type_sampled_image %25 %26 279fd4e5da5Sopenharmony_ci %28 = OpImageSampleExplicitLod %v4float %27 %12 Lod|ConstOffset %float_10 %17 280fd4e5da5Sopenharmony_ci OpStore %out_var_SV_TARGET %28 281fd4e5da5Sopenharmony_ci )"); 282fd4e5da5Sopenharmony_ci 283fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<ConvertToSampledImagePass>( 284fd4e5da5Sopenharmony_ci shader, /* skip_nop = */ false, 285fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs{DescriptorSetAndBinding{0, 2}}); 286fd4e5da5Sopenharmony_ci 287fd4e5da5Sopenharmony_ci EXPECT_EQ(std::get<1>(result), Pass::Status::Failure); 288fd4e5da5Sopenharmony_ci} 289fd4e5da5Sopenharmony_ci 290fd4e5da5Sopenharmony_ciTEST_F(ConvertToSampledImageTest, TwoImagesWithDuplicatedDescriptorSetBinding) { 291fd4e5da5Sopenharmony_ci const std::string shader = BuildShader( 292fd4e5da5Sopenharmony_ci R"( 293fd4e5da5Sopenharmony_ci OpDecorate %sam DescriptorSet 0 294fd4e5da5Sopenharmony_ci OpDecorate %sam Binding 2 295fd4e5da5Sopenharmony_ci OpDecorate %texture0 DescriptorSet 0 296fd4e5da5Sopenharmony_ci OpDecorate %texture0 Binding 5 297fd4e5da5Sopenharmony_ci OpDecorate %texture1 DescriptorSet 0 298fd4e5da5Sopenharmony_ci OpDecorate %texture1 Binding 5 299fd4e5da5Sopenharmony_ci )", 300fd4e5da5Sopenharmony_ci R"( 301fd4e5da5Sopenharmony_ci %sam = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant 302fd4e5da5Sopenharmony_ci %texture0 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant 303fd4e5da5Sopenharmony_ci %texture1 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant 304fd4e5da5Sopenharmony_ci )", 305fd4e5da5Sopenharmony_ci R"( 306fd4e5da5Sopenharmony_ci %25 = OpLoad %type_2d_image %texture0 307fd4e5da5Sopenharmony_ci %26 = OpLoad %type_sampler %sam 308fd4e5da5Sopenharmony_ci %27 = OpSampledImage %type_sampled_image %25 %26 309fd4e5da5Sopenharmony_ci %28 = OpImageSampleExplicitLod %v4float %27 %12 Lod|ConstOffset %float_10 %17 310fd4e5da5Sopenharmony_ci OpStore %out_var_SV_TARGET %28 311fd4e5da5Sopenharmony_ci )"); 312fd4e5da5Sopenharmony_ci 313fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<ConvertToSampledImagePass>( 314fd4e5da5Sopenharmony_ci shader, /* skip_nop = */ false, 315fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs{DescriptorSetAndBinding{0, 5}}); 316fd4e5da5Sopenharmony_ci 317fd4e5da5Sopenharmony_ci EXPECT_EQ(std::get<1>(result), Pass::Status::Failure); 318fd4e5da5Sopenharmony_ci} 319fd4e5da5Sopenharmony_ci 320fd4e5da5Sopenharmony_ciTEST_F(ConvertToSampledImageTest, 321fd4e5da5Sopenharmony_ci TwoSamplersWithDuplicatedDescriptorSetBinding) { 322fd4e5da5Sopenharmony_ci const std::string shader = BuildShader( 323fd4e5da5Sopenharmony_ci R"( 324fd4e5da5Sopenharmony_ci OpDecorate %sam0 DescriptorSet 0 325fd4e5da5Sopenharmony_ci OpDecorate %sam0 Binding 2 326fd4e5da5Sopenharmony_ci OpDecorate %sam1 DescriptorSet 0 327fd4e5da5Sopenharmony_ci OpDecorate %sam1 Binding 2 328fd4e5da5Sopenharmony_ci OpDecorate %texture DescriptorSet 0 329fd4e5da5Sopenharmony_ci OpDecorate %texture Binding 5 330fd4e5da5Sopenharmony_ci )", 331fd4e5da5Sopenharmony_ci R"( 332fd4e5da5Sopenharmony_ci %sam0 = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant 333fd4e5da5Sopenharmony_ci %sam1 = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant 334fd4e5da5Sopenharmony_ci %texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant 335fd4e5da5Sopenharmony_ci )", 336fd4e5da5Sopenharmony_ci R"( 337fd4e5da5Sopenharmony_ci %25 = OpLoad %type_2d_image %texture 338fd4e5da5Sopenharmony_ci %26 = OpLoad %type_sampler %sam0 339fd4e5da5Sopenharmony_ci %27 = OpSampledImage %type_sampled_image %25 %26 340fd4e5da5Sopenharmony_ci %28 = OpImageSampleExplicitLod %v4float %27 %12 Lod|ConstOffset %float_10 %17 341fd4e5da5Sopenharmony_ci OpStore %out_var_SV_TARGET %28 342fd4e5da5Sopenharmony_ci )"); 343fd4e5da5Sopenharmony_ci 344fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<ConvertToSampledImagePass>( 345fd4e5da5Sopenharmony_ci shader, /* skip_nop = */ false, 346fd4e5da5Sopenharmony_ci VectorOfDescriptorSetAndBindingPairs{DescriptorSetAndBinding{0, 2}}); 347fd4e5da5Sopenharmony_ci 348fd4e5da5Sopenharmony_ci EXPECT_EQ(std::get<1>(result), Pass::Status::Failure); 349fd4e5da5Sopenharmony_ci} 350fd4e5da5Sopenharmony_ci 351fd4e5da5Sopenharmony_ci} // namespace 352fd4e5da5Sopenharmony_ci} // namespace opt 353fd4e5da5Sopenharmony_ci} // namespace spvtools 354