local_access_chain_convert_test.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. // Copyright (c) 2017 Valve Corporation
  2. // Copyright (c) 2017 LunarG Inc.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. #include <string>
  16. #include "test/opt/pass_fixture.h"
  17. #include "test/opt/pass_utils.h"
  18. namespace spvtools {
  19. namespace opt {
  20. namespace {
  21. using LocalAccessChainConvertTest = PassTest<::testing::Test>;
  22. TEST_F(LocalAccessChainConvertTest, StructOfVecsOfFloatConverted) {
  23. // #version 140
  24. //
  25. // in vec4 BaseColor;
  26. //
  27. // struct S_t {
  28. // vec4 v0;
  29. // vec4 v1;
  30. // };
  31. //
  32. // void main()
  33. // {
  34. // S_t s0;
  35. // s0.v1 = BaseColor;
  36. // gl_FragColor = s0.v1;
  37. // }
  38. const std::string predefs_before =
  39. R"(OpCapability Shader
  40. %1 = OpExtInstImport "GLSL.std.450"
  41. OpMemoryModel Logical GLSL450
  42. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  43. OpExecutionMode %main OriginUpperLeft
  44. OpSource GLSL 140
  45. OpName %main "main"
  46. OpName %S_t "S_t"
  47. OpMemberName %S_t 0 "v0"
  48. OpMemberName %S_t 1 "v1"
  49. OpName %s0 "s0"
  50. OpName %BaseColor "BaseColor"
  51. OpName %gl_FragColor "gl_FragColor"
  52. %void = OpTypeVoid
  53. %8 = OpTypeFunction %void
  54. %float = OpTypeFloat 32
  55. %v4float = OpTypeVector %float 4
  56. %S_t = OpTypeStruct %v4float %v4float
  57. %_ptr_Function_S_t = OpTypePointer Function %S_t
  58. %int = OpTypeInt 32 1
  59. %int_1 = OpConstant %int 1
  60. %_ptr_Input_v4float = OpTypePointer Input %v4float
  61. %BaseColor = OpVariable %_ptr_Input_v4float Input
  62. %_ptr_Function_v4float = OpTypePointer Function %v4float
  63. %_ptr_Output_v4float = OpTypePointer Output %v4float
  64. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  65. )";
  66. const std::string before =
  67. R"(
  68. ; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor
  69. ; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0
  70. ; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1
  71. ; CHECK: OpStore %s0 [[ex1]]
  72. ; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0
  73. ; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1
  74. ; CHECK: OpStore %gl_FragColor [[ex2]]
  75. %main = OpFunction %void None %8
  76. %17 = OpLabel
  77. %s0 = OpVariable %_ptr_Function_S_t Function
  78. %18 = OpLoad %v4float %BaseColor
  79. %19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1
  80. OpStore %19 %18
  81. %20 = OpAccessChain %_ptr_Function_v4float %s0 %int_1
  82. %21 = OpLoad %v4float %20
  83. OpStore %gl_FragColor %21
  84. OpReturn
  85. OpFunctionEnd
  86. )";
  87. SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before,
  88. true);
  89. }
  90. TEST_F(LocalAccessChainConvertTest, InBoundsAccessChainsConverted) {
  91. // #version 140
  92. //
  93. // in vec4 BaseColor;
  94. //
  95. // struct S_t {
  96. // vec4 v0;
  97. // vec4 v1;
  98. // };
  99. //
  100. // void main()
  101. // {
  102. // S_t s0;
  103. // s0.v1 = BaseColor;
  104. // gl_FragColor = s0.v1;
  105. // }
  106. const std::string predefs_before =
  107. R"(OpCapability Shader
  108. %1 = OpExtInstImport "GLSL.std.450"
  109. OpMemoryModel Logical GLSL450
  110. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  111. OpExecutionMode %main OriginUpperLeft
  112. OpSource GLSL 140
  113. OpName %main "main"
  114. OpName %S_t "S_t"
  115. OpMemberName %S_t 0 "v0"
  116. OpMemberName %S_t 1 "v1"
  117. OpName %s0 "s0"
  118. OpName %BaseColor "BaseColor"
  119. OpName %gl_FragColor "gl_FragColor"
  120. %void = OpTypeVoid
  121. %8 = OpTypeFunction %void
  122. %float = OpTypeFloat 32
  123. %v4float = OpTypeVector %float 4
  124. %S_t = OpTypeStruct %v4float %v4float
  125. %_ptr_Function_S_t = OpTypePointer Function %S_t
  126. %int = OpTypeInt 32 1
  127. %int_1 = OpConstant %int 1
  128. %_ptr_Input_v4float = OpTypePointer Input %v4float
  129. %BaseColor = OpVariable %_ptr_Input_v4float Input
  130. %_ptr_Function_v4float = OpTypePointer Function %v4float
  131. %_ptr_Output_v4float = OpTypePointer Output %v4float
  132. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  133. )";
  134. const std::string before =
  135. R"(
  136. ; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor
  137. ; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0
  138. ; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1
  139. ; CHECK: OpStore %s0 [[ex1]]
  140. ; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0
  141. ; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1
  142. ; CHECK: OpStore %gl_FragColor [[ex2]]
  143. %main = OpFunction %void None %8
  144. %17 = OpLabel
  145. %s0 = OpVariable %_ptr_Function_S_t Function
  146. %18 = OpLoad %v4float %BaseColor
  147. %19 = OpInBoundsAccessChain %_ptr_Function_v4float %s0 %int_1
  148. OpStore %19 %18
  149. %20 = OpInBoundsAccessChain %_ptr_Function_v4float %s0 %int_1
  150. %21 = OpLoad %v4float %20
  151. OpStore %gl_FragColor %21
  152. OpReturn
  153. OpFunctionEnd
  154. )";
  155. SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before,
  156. true);
  157. }
  158. TEST_F(LocalAccessChainConvertTest, TwoUsesofSingleChainConverted) {
  159. // #version 140
  160. //
  161. // in vec4 BaseColor;
  162. //
  163. // struct S_t {
  164. // vec4 v0;
  165. // vec4 v1;
  166. // };
  167. //
  168. // void main()
  169. // {
  170. // S_t s0;
  171. // s0.v1 = BaseColor;
  172. // gl_FragColor = s0.v1;
  173. // }
  174. const std::string predefs_before =
  175. R"(OpCapability Shader
  176. %1 = OpExtInstImport "GLSL.std.450"
  177. OpMemoryModel Logical GLSL450
  178. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  179. OpExecutionMode %main OriginUpperLeft
  180. OpSource GLSL 140
  181. OpName %main "main"
  182. OpName %S_t "S_t"
  183. OpMemberName %S_t 0 "v0"
  184. OpMemberName %S_t 1 "v1"
  185. OpName %s0 "s0"
  186. OpName %BaseColor "BaseColor"
  187. OpName %gl_FragColor "gl_FragColor"
  188. %void = OpTypeVoid
  189. %8 = OpTypeFunction %void
  190. %float = OpTypeFloat 32
  191. %v4float = OpTypeVector %float 4
  192. %S_t = OpTypeStruct %v4float %v4float
  193. %_ptr_Function_S_t = OpTypePointer Function %S_t
  194. %int = OpTypeInt 32 1
  195. %int_1 = OpConstant %int 1
  196. %_ptr_Input_v4float = OpTypePointer Input %v4float
  197. %BaseColor = OpVariable %_ptr_Input_v4float Input
  198. %_ptr_Function_v4float = OpTypePointer Function %v4float
  199. %_ptr_Output_v4float = OpTypePointer Output %v4float
  200. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  201. )";
  202. const std::string before =
  203. R"(
  204. ; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor
  205. ; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0
  206. ; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1
  207. ; CHECK: OpStore %s0 [[ex1]]
  208. ; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0
  209. ; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1
  210. ; CHECK: OpStore %gl_FragColor [[ex2]]
  211. %main = OpFunction %void None %8
  212. %17 = OpLabel
  213. %s0 = OpVariable %_ptr_Function_S_t Function
  214. %18 = OpLoad %v4float %BaseColor
  215. %19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1
  216. OpStore %19 %18
  217. %20 = OpLoad %v4float %19
  218. OpStore %gl_FragColor %20
  219. OpReturn
  220. OpFunctionEnd
  221. )";
  222. SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before,
  223. true);
  224. }
  225. TEST_F(LocalAccessChainConvertTest, OpaqueConverted) {
  226. // SPIR-V not representable in GLSL; not generatable from HLSL
  227. // at the moment
  228. const std::string predefs =
  229. R"(
  230. OpCapability Shader
  231. %1 = OpExtInstImport "GLSL.std.450"
  232. OpMemoryModel Logical GLSL450
  233. OpEntryPoint Fragment %main "main" %outColor %texCoords
  234. OpExecutionMode %main OriginUpperLeft
  235. OpSource GLSL 140
  236. OpName %main "main"
  237. OpName %S_t "S_t"
  238. OpMemberName %S_t 0 "v0"
  239. OpMemberName %S_t 1 "v1"
  240. OpMemberName %S_t 2 "smp"
  241. OpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;"
  242. OpName %s "s"
  243. OpName %outColor "outColor"
  244. OpName %sampler15 "sampler15"
  245. OpName %s0 "s0"
  246. OpName %texCoords "texCoords"
  247. OpName %param "param"
  248. OpDecorate %sampler15 DescriptorSet 0
  249. %void = OpTypeVoid
  250. %12 = OpTypeFunction %void
  251. %float = OpTypeFloat 32
  252. %v2float = OpTypeVector %float 2
  253. %v4float = OpTypeVector %float 4
  254. %_ptr_Output_v4float = OpTypePointer Output %v4float
  255. %outColor = OpVariable %_ptr_Output_v4float Output
  256. %17 = OpTypeImage %float 2D 0 0 0 1 Unknown
  257. %18 = OpTypeSampledImage %17
  258. %S_t = OpTypeStruct %v2float %v2float %18
  259. %_ptr_Function_S_t = OpTypePointer Function %S_t
  260. %20 = OpTypeFunction %void %_ptr_Function_S_t
  261. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  262. %_ptr_Function_18 = OpTypePointer Function %18
  263. %sampler15 = OpVariable %_ptr_UniformConstant_18 UniformConstant
  264. %int = OpTypeInt 32 1
  265. %int_0 = OpConstant %int 0
  266. %int_2 = OpConstant %int 2
  267. %_ptr_Function_v2float = OpTypePointer Function %v2float
  268. %_ptr_Input_v2float = OpTypePointer Input %v2float
  269. %texCoords = OpVariable %_ptr_Input_v2float Input
  270. )";
  271. const std::string before =
  272. R"(
  273. ; CHECK: [[l1:%\w+]] = OpLoad %S_t %param
  274. ; CHECK: [[e1:%\w+]] = OpCompositeExtract {{%\w+}} [[l1]] 2
  275. ; CHECK: [[l2:%\w+]] = OpLoad %S_t %param
  276. ; CHECK: [[e2:%\w+]] = OpCompositeExtract {{%\w+}} [[l2]] 0
  277. ; CHECK: OpImageSampleImplicitLod {{%\w+}} [[e1]] [[e2]]
  278. %main = OpFunction %void None %12
  279. %28 = OpLabel
  280. %s0 = OpVariable %_ptr_Function_S_t Function
  281. %param = OpVariable %_ptr_Function_S_t Function
  282. %29 = OpLoad %v2float %texCoords
  283. %30 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
  284. OpStore %30 %29
  285. %31 = OpLoad %18 %sampler15
  286. %32 = OpAccessChain %_ptr_Function_18 %s0 %int_2
  287. OpStore %32 %31
  288. %33 = OpLoad %S_t %s0
  289. OpStore %param %33
  290. %34 = OpAccessChain %_ptr_Function_18 %param %int_2
  291. %35 = OpLoad %18 %34
  292. %36 = OpAccessChain %_ptr_Function_v2float %param %int_0
  293. %37 = OpLoad %v2float %36
  294. %38 = OpImageSampleImplicitLod %v4float %35 %37
  295. OpStore %outColor %38
  296. OpReturn
  297. OpFunctionEnd
  298. )";
  299. const std::string remain =
  300. R"(%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %20
  301. %s = OpFunctionParameter %_ptr_Function_S_t
  302. %39 = OpLabel
  303. %40 = OpAccessChain %_ptr_Function_18 %s %int_2
  304. %41 = OpLoad %18 %40
  305. %42 = OpAccessChain %_ptr_Function_v2float %s %int_0
  306. %43 = OpLoad %v2float %42
  307. %44 = OpImageSampleImplicitLod %v4float %41 %43
  308. OpStore %outColor %44
  309. OpReturn
  310. OpFunctionEnd
  311. )";
  312. SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs + before + remain,
  313. true);
  314. }
  315. TEST_F(LocalAccessChainConvertTest, NestedStructsConverted) {
  316. // #version 140
  317. //
  318. // in vec4 BaseColor;
  319. //
  320. // struct S1_t {
  321. // vec4 v1;
  322. // };
  323. //
  324. // struct S2_t {
  325. // vec4 v2;
  326. // S1_t s1;
  327. // };
  328. //
  329. // void main()
  330. // {
  331. // S2_t s2;
  332. // s2.s1.v1 = BaseColor;
  333. // gl_FragColor = s2.s1.v1;
  334. // }
  335. const std::string predefs_before =
  336. R"(OpCapability Shader
  337. %1 = OpExtInstImport "GLSL.std.450"
  338. OpMemoryModel Logical GLSL450
  339. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  340. OpExecutionMode %main OriginUpperLeft
  341. OpSource GLSL 140
  342. OpName %main "main"
  343. OpName %S1_t "S1_t"
  344. OpMemberName %S1_t 0 "v1"
  345. OpName %S2_t "S2_t"
  346. OpMemberName %S2_t 0 "v2"
  347. OpMemberName %S2_t 1 "s1"
  348. OpName %s2 "s2"
  349. OpName %BaseColor "BaseColor"
  350. OpName %gl_FragColor "gl_FragColor"
  351. %void = OpTypeVoid
  352. %9 = OpTypeFunction %void
  353. %float = OpTypeFloat 32
  354. %v4float = OpTypeVector %float 4
  355. %S1_t = OpTypeStruct %v4float
  356. %S2_t = OpTypeStruct %v4float %S1_t
  357. %_ptr_Function_S2_t = OpTypePointer Function %S2_t
  358. %int = OpTypeInt 32 1
  359. %int_1 = OpConstant %int 1
  360. %int_0 = OpConstant %int 0
  361. %_ptr_Input_v4float = OpTypePointer Input %v4float
  362. %BaseColor = OpVariable %_ptr_Input_v4float Input
  363. %_ptr_Function_v4float = OpTypePointer Function %v4float
  364. %_ptr_Output_v4float = OpTypePointer Output %v4float
  365. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  366. )";
  367. const std::string before =
  368. R"(
  369. ; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor
  370. ; CHECK: [[ld1:%\w+]] = OpLoad %S2_t %s2
  371. ; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S2_t [[st_id]] [[ld1]] 1 0
  372. ; CHECK: OpStore %s2 [[ex1]]
  373. ; CHECK: [[ld2:%\w+]] = OpLoad %S2_t %s2
  374. ; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1 0
  375. ; CHECK: OpStore %gl_FragColor [[ex2]]
  376. %main = OpFunction %void None %9
  377. %19 = OpLabel
  378. %s2 = OpVariable %_ptr_Function_S2_t Function
  379. %20 = OpLoad %v4float %BaseColor
  380. %21 = OpAccessChain %_ptr_Function_v4float %s2 %int_1 %int_0
  381. OpStore %21 %20
  382. %22 = OpAccessChain %_ptr_Function_v4float %s2 %int_1 %int_0
  383. %23 = OpLoad %v4float %22
  384. OpStore %gl_FragColor %23
  385. OpReturn
  386. OpFunctionEnd
  387. )";
  388. SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before,
  389. true);
  390. }
  391. TEST_F(LocalAccessChainConvertTest, SomeAccessChainsHaveNoUse) {
  392. // Based on HLSL source code:
  393. // struct S {
  394. // float f;
  395. // };
  396. // float main(float input : A) : B {
  397. // S local = { input };
  398. // return local.f;
  399. // }
  400. const std::string predefs = R"(OpCapability Shader
  401. OpMemoryModel Logical GLSL450
  402. OpEntryPoint Vertex %main "main" %in_var_A %out_var_B
  403. OpName %main "main"
  404. OpName %in_var_A "in.var.A"
  405. OpName %out_var_B "out.var.B"
  406. OpName %S "S"
  407. OpName %local "local"
  408. %int = OpTypeInt 32 1
  409. %void = OpTypeVoid
  410. %8 = OpTypeFunction %void
  411. %float = OpTypeFloat 32
  412. %_ptr_Function_float = OpTypePointer Function %float
  413. %_ptr_Input_float = OpTypePointer Input %float
  414. %_ptr_Output_float = OpTypePointer Output %float
  415. %S = OpTypeStruct %float
  416. %_ptr_Function_S = OpTypePointer Function %S
  417. %int_0 = OpConstant %int 0
  418. %in_var_A = OpVariable %_ptr_Input_float Input
  419. %out_var_B = OpVariable %_ptr_Output_float Output
  420. %main = OpFunction %void None %8
  421. %15 = OpLabel
  422. %local = OpVariable %_ptr_Function_S Function
  423. %16 = OpLoad %float %in_var_A
  424. %17 = OpCompositeConstruct %S %16
  425. OpStore %local %17
  426. )";
  427. const std::string before =
  428. R"(
  429. ; CHECK: [[ld:%\w+]] = OpLoad %S %local
  430. ; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0
  431. ; CHECK: OpStore %out_var_B [[ex]]
  432. %18 = OpAccessChain %_ptr_Function_float %local %int_0
  433. %19 = OpAccessChain %_ptr_Function_float %local %int_0
  434. %20 = OpLoad %float %18
  435. OpStore %out_var_B %20
  436. OpReturn
  437. OpFunctionEnd
  438. )";
  439. SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs + before, true);
  440. }
  441. TEST_F(LocalAccessChainConvertTest,
  442. StructOfVecsOfFloatConvertedWithDecorationOnLoad) {
  443. // #version 140
  444. //
  445. // in vec4 BaseColor;
  446. //
  447. // struct S_t {
  448. // vec4 v0;
  449. // vec4 v1;
  450. // };
  451. //
  452. // void main()
  453. // {
  454. // S_t s0;
  455. // s0.v1 = BaseColor;
  456. // gl_FragColor = s0.v1;
  457. // }
  458. const std::string predefs_before =
  459. R"(OpCapability Shader
  460. %1 = OpExtInstImport "GLSL.std.450"
  461. OpMemoryModel Logical GLSL450
  462. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  463. OpExecutionMode %main OriginUpperLeft
  464. OpSource GLSL 140
  465. OpName %main "main"
  466. OpName %S_t "S_t"
  467. OpMemberName %S_t 0 "v0"
  468. OpMemberName %S_t 1 "v1"
  469. OpName %s0 "s0"
  470. OpName %BaseColor "BaseColor"
  471. OpName %gl_FragColor "gl_FragColor"
  472. OpDecorate %21 RelaxedPrecision
  473. %void = OpTypeVoid
  474. %8 = OpTypeFunction %void
  475. %float = OpTypeFloat 32
  476. %v4float = OpTypeVector %float 4
  477. %S_t = OpTypeStruct %v4float %v4float
  478. %_ptr_Function_S_t = OpTypePointer Function %S_t
  479. %int = OpTypeInt 32 1
  480. %int_1 = OpConstant %int 1
  481. %_ptr_Input_v4float = OpTypePointer Input %v4float
  482. %BaseColor = OpVariable %_ptr_Input_v4float Input
  483. %_ptr_Function_v4float = OpTypePointer Function %v4float
  484. %_ptr_Output_v4float = OpTypePointer Output %v4float
  485. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  486. )";
  487. const std::string before =
  488. R"(
  489. ; CHECK: OpDecorate
  490. ; CHECK: OpDecorate [[ld2:%\w+]] RelaxedPrecision
  491. ; CHECK-NOT: OpDecorate
  492. ; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor
  493. ; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0
  494. ; CHECK: [[ins:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1
  495. ; CHECK: OpStore %s0 [[ins]]
  496. ; CHECK: [[ld2]] = OpLoad %S_t %s0
  497. ; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1
  498. ; CHECK: OpStore %gl_FragColor [[ex2]]
  499. %main = OpFunction %void None %8
  500. %17 = OpLabel
  501. %s0 = OpVariable %_ptr_Function_S_t Function
  502. %18 = OpLoad %v4float %BaseColor
  503. %19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1
  504. OpStore %19 %18
  505. %20 = OpAccessChain %_ptr_Function_v4float %s0 %int_1
  506. %21 = OpLoad %v4float %20
  507. OpStore %gl_FragColor %21
  508. OpReturn
  509. OpFunctionEnd
  510. )";
  511. SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before,
  512. true);
  513. }
  514. TEST_F(LocalAccessChainConvertTest,
  515. StructOfVecsOfFloatConvertedWithDecorationOnStore) {
  516. // #version 140
  517. //
  518. // in vec4 BaseColor;
  519. //
  520. // struct S_t {
  521. // vec4 v0;
  522. // vec4 v1;
  523. // };
  524. //
  525. // void main()
  526. // {
  527. // S_t s0;
  528. // s0.v1 = BaseColor;
  529. // gl_FragColor = s0.v1;
  530. // }
  531. const std::string predefs_before =
  532. R"(OpCapability Shader
  533. %1 = OpExtInstImport "GLSL.std.450"
  534. OpMemoryModel Logical GLSL450
  535. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  536. OpExecutionMode %main OriginUpperLeft
  537. OpSource GLSL 140
  538. OpName %main "main"
  539. OpName %S_t "S_t"
  540. OpMemberName %S_t 0 "v0"
  541. OpMemberName %S_t 1 "v1"
  542. OpName %s0 "s0"
  543. OpName %BaseColor "BaseColor"
  544. OpName %gl_FragColor "gl_FragColor"
  545. OpDecorate %s0 RelaxedPrecision
  546. %void = OpTypeVoid
  547. %8 = OpTypeFunction %void
  548. %float = OpTypeFloat 32
  549. %v4float = OpTypeVector %float 4
  550. %S_t = OpTypeStruct %v4float %v4float
  551. %_ptr_Function_S_t = OpTypePointer Function %S_t
  552. %int = OpTypeInt 32 1
  553. %int_1 = OpConstant %int 1
  554. %_ptr_Input_v4float = OpTypePointer Input %v4float
  555. %BaseColor = OpVariable %_ptr_Input_v4float Input
  556. %_ptr_Function_v4float = OpTypePointer Function %v4float
  557. %_ptr_Output_v4float = OpTypePointer Output %v4float
  558. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  559. )";
  560. const std::string before =
  561. R"(
  562. ; CHECK: OpDecorate
  563. ; CHECK: OpDecorate [[ld1:%\w+]] RelaxedPrecision
  564. ; CHECK: OpDecorate [[ins:%\w+]] RelaxedPrecision
  565. ; CHECK-NOT: OpDecorate
  566. ; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor
  567. ; CHECK: [[ld1]] = OpLoad %S_t %s0
  568. ; CHECK: [[ins]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1
  569. ; CHECK: OpStore %s0 [[ins]]
  570. ; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0
  571. ; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1
  572. ; CHECK: OpStore %gl_FragColor [[ex2]]
  573. %main = OpFunction %void None %8
  574. %17 = OpLabel
  575. %s0 = OpVariable %_ptr_Function_S_t Function
  576. %18 = OpLoad %v4float %BaseColor
  577. %19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1
  578. OpStore %19 %18
  579. %20 = OpAccessChain %_ptr_Function_v4float %s0 %int_1
  580. %21 = OpLoad %v4float %20
  581. OpStore %gl_FragColor %21
  582. OpReturn
  583. OpFunctionEnd
  584. )";
  585. SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before,
  586. true);
  587. }
  588. TEST_F(LocalAccessChainConvertTest, DynamicallyIndexedVarNotConverted) {
  589. // #version 140
  590. //
  591. // in vec4 BaseColor;
  592. // flat in int Idx;
  593. // in float Bi;
  594. //
  595. // struct S_t {
  596. // vec4 v0;
  597. // vec4 v1;
  598. // };
  599. //
  600. // void main()
  601. // {
  602. // S_t s0;
  603. // s0.v1 = BaseColor;
  604. // s0.v1[Idx] = Bi;
  605. // gl_FragColor = s0.v1;
  606. // }
  607. const std::string assembly =
  608. R"(OpCapability Shader
  609. %1 = OpExtInstImport "GLSL.std.450"
  610. OpMemoryModel Logical GLSL450
  611. OpEntryPoint Fragment %main "main" %BaseColor %Idx %Bi %gl_FragColor
  612. OpExecutionMode %main OriginUpperLeft
  613. OpSource GLSL 140
  614. OpName %main "main"
  615. OpName %S_t "S_t"
  616. OpMemberName %S_t 0 "v0"
  617. OpMemberName %S_t 1 "v1"
  618. OpName %s0 "s0"
  619. OpName %BaseColor "BaseColor"
  620. OpName %Idx "Idx"
  621. OpName %Bi "Bi"
  622. OpName %gl_FragColor "gl_FragColor"
  623. OpDecorate %Idx Flat
  624. %void = OpTypeVoid
  625. %10 = OpTypeFunction %void
  626. %float = OpTypeFloat 32
  627. %v4float = OpTypeVector %float 4
  628. %S_t = OpTypeStruct %v4float %v4float
  629. %_ptr_Function_S_t = OpTypePointer Function %S_t
  630. %int = OpTypeInt 32 1
  631. %int_1 = OpConstant %int 1
  632. %_ptr_Input_v4float = OpTypePointer Input %v4float
  633. %BaseColor = OpVariable %_ptr_Input_v4float Input
  634. %_ptr_Function_v4float = OpTypePointer Function %v4float
  635. %_ptr_Input_int = OpTypePointer Input %int
  636. %Idx = OpVariable %_ptr_Input_int Input
  637. %_ptr_Input_float = OpTypePointer Input %float
  638. %Bi = OpVariable %_ptr_Input_float Input
  639. %_ptr_Function_float = OpTypePointer Function %float
  640. %_ptr_Output_v4float = OpTypePointer Output %v4float
  641. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  642. %main = OpFunction %void None %10
  643. %22 = OpLabel
  644. %s0 = OpVariable %_ptr_Function_S_t Function
  645. %23 = OpLoad %v4float %BaseColor
  646. %24 = OpAccessChain %_ptr_Function_v4float %s0 %int_1
  647. OpStore %24 %23
  648. %25 = OpLoad %int %Idx
  649. %26 = OpLoad %float %Bi
  650. %27 = OpAccessChain %_ptr_Function_float %s0 %int_1 %25
  651. OpStore %27 %26
  652. %28 = OpAccessChain %_ptr_Function_v4float %s0 %int_1
  653. %29 = OpLoad %v4float %28
  654. OpStore %gl_FragColor %29
  655. OpReturn
  656. OpFunctionEnd
  657. )";
  658. SinglePassRunAndCheck<LocalAccessChainConvertPass>(assembly, assembly, false,
  659. true);
  660. }
  661. // TODO(greg-lunarg): Add tests to verify handling of these cases:
  662. //
  663. // Assorted vector and matrix types
  664. // Assorted struct array types
  665. // Assorted scalar types
  666. // Assorted non-target types
  667. // OpInBoundsAccessChain
  668. // Others?
  669. } // namespace
  670. } // namespace opt
  671. } // namespace spvtools