eliminate_dead_io_components_test.cpp 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253
  1. // Copyright (c) 2022 The Khronos Group Inc.
  2. // Copyright (c) 2022 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 <vector>
  16. #include "test/opt/pass_fixture.h"
  17. #include "test/opt/pass_utils.h"
  18. namespace spvtools {
  19. namespace opt {
  20. namespace {
  21. using ElimDeadIOComponentsTest = PassTest<::testing::Test>;
  22. TEST_F(ElimDeadIOComponentsTest, ElimOneConstantIndex) {
  23. // Should reduce to uv[2]
  24. //
  25. // #version 450
  26. //
  27. // layout(location = 0) in vec4 uv[8];
  28. //
  29. // out gl_PerVertex {
  30. // vec4 gl_Position;
  31. // };
  32. //
  33. // void main()
  34. // {
  35. // gl_Position = uv[1];
  36. // }
  37. const std::string text = R"(
  38. OpCapability Shader
  39. %1 = OpExtInstImport "GLSL.std.450"
  40. OpMemoryModel Logical GLSL450
  41. OpEntryPoint Vertex %main "main" %_ %uv
  42. OpSource GLSL 450
  43. OpName %main "main"
  44. OpName %gl_PerVertex "gl_PerVertex"
  45. OpMemberName %gl_PerVertex 0 "gl_Position"
  46. OpName %_ ""
  47. OpName %uv "uv"
  48. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  49. OpDecorate %gl_PerVertex Block
  50. OpDecorate %uv Location 0
  51. %void = OpTypeVoid
  52. %3 = OpTypeFunction %void
  53. %float = OpTypeFloat 32
  54. %v4float = OpTypeVector %float 4
  55. %gl_PerVertex = OpTypeStruct %v4float
  56. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  57. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  58. %int = OpTypeInt 32 1
  59. %int_0 = OpConstant %int 0
  60. %uint = OpTypeInt 32 0
  61. %uint_8 = OpConstant %uint 8
  62. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  63. %_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8
  64. %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  65. %int_1 = OpConstant %int 1
  66. %_ptr_Input_v4float = OpTypePointer Input %v4float
  67. %_ptr_Output_v4float = OpTypePointer Output %v4float
  68. ;CHECK-NOT: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  69. ;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_2 Input
  70. %main = OpFunction %void None %3
  71. %5 = OpLabel
  72. %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1
  73. %21 = OpLoad %v4float %20
  74. %23 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  75. OpStore %23 %21
  76. OpReturn
  77. OpFunctionEnd
  78. )";
  79. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  80. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  81. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  82. text, true, spv::StorageClass::Input, false);
  83. }
  84. TEST_F(ElimDeadIOComponentsTest, ElimOneConstantIndexInBounds) {
  85. // Same as ElimOneConstantIndex but with OpInBoundsAccessChain
  86. const std::string text = R"(
  87. OpCapability Shader
  88. %1 = OpExtInstImport "GLSL.std.450"
  89. OpMemoryModel Logical GLSL450
  90. OpEntryPoint Vertex %main "main" %_ %uv
  91. OpSource GLSL 450
  92. OpName %main "main"
  93. OpName %gl_PerVertex "gl_PerVertex"
  94. OpMemberName %gl_PerVertex 0 "gl_Position"
  95. OpName %_ ""
  96. OpName %uv "uv"
  97. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  98. OpDecorate %gl_PerVertex Block
  99. OpDecorate %uv Location 0
  100. %void = OpTypeVoid
  101. %3 = OpTypeFunction %void
  102. %float = OpTypeFloat 32
  103. %v4float = OpTypeVector %float 4
  104. %gl_PerVertex = OpTypeStruct %v4float
  105. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  106. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  107. %int = OpTypeInt 32 1
  108. %int_0 = OpConstant %int 0
  109. %uint = OpTypeInt 32 0
  110. %uint_8 = OpConstant %uint 8
  111. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  112. %_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8
  113. %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  114. %int_1 = OpConstant %int 1
  115. %_ptr_Input_v4float = OpTypePointer Input %v4float
  116. %_ptr_Output_v4float = OpTypePointer Output %v4float
  117. ;CHECK-NOT: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  118. ;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_2 Input
  119. %main = OpFunction %void None %3
  120. %5 = OpLabel
  121. %20 = OpInBoundsAccessChain %_ptr_Input_v4float %uv %int_1
  122. %21 = OpLoad %v4float %20
  123. %23 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  124. OpStore %23 %21
  125. OpReturn
  126. OpFunctionEnd
  127. )";
  128. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  129. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  130. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  131. text, true, spv::StorageClass::Input, false);
  132. }
  133. TEST_F(ElimDeadIOComponentsTest, ElimTwoConstantIndices) {
  134. // Should reduce to uv[4]
  135. //
  136. // #version 450
  137. //
  138. // layout(location = 0) in vec4 uv[8];
  139. //
  140. // out gl_PerVertex {
  141. // vec4 gl_Position;
  142. // };
  143. //
  144. // void main()
  145. // {
  146. // gl_Position = uv[1] + uv[3];
  147. // }
  148. const std::string text = R"(
  149. OpCapability Shader
  150. %1 = OpExtInstImport "GLSL.std.450"
  151. OpMemoryModel Logical GLSL450
  152. OpEntryPoint Vertex %main "main" %_ %uv
  153. OpSource GLSL 450
  154. OpName %main "main"
  155. OpName %gl_PerVertex "gl_PerVertex"
  156. OpMemberName %gl_PerVertex 0 "gl_Position"
  157. OpName %_ ""
  158. OpName %uv "uv"
  159. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  160. OpDecorate %gl_PerVertex Block
  161. OpDecorate %uv Location 0
  162. %void = OpTypeVoid
  163. %3 = OpTypeFunction %void
  164. %float = OpTypeFloat 32
  165. %v4float = OpTypeVector %float 4
  166. %gl_PerVertex = OpTypeStruct %v4float
  167. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  168. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  169. %int = OpTypeInt 32 1
  170. %int_0 = OpConstant %int 0
  171. %uint = OpTypeInt 32 0
  172. %uint_8 = OpConstant %uint 8
  173. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  174. %_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8
  175. %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  176. %int_1 = OpConstant %int 1
  177. %_ptr_Input_v4float = OpTypePointer Input %v4float
  178. %int_3 = OpConstant %int 3
  179. %_ptr_Output_v4float = OpTypePointer Output %v4float
  180. ;CHECK-NOT: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  181. ;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_4 Input
  182. %main = OpFunction %void None %3
  183. %5 = OpLabel
  184. %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1
  185. %21 = OpLoad %v4float %20
  186. %23 = OpAccessChain %_ptr_Input_v4float %uv %int_3
  187. %24 = OpLoad %v4float %23
  188. %25 = OpFAdd %v4float %21 %24
  189. %27 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  190. OpStore %27 %25
  191. OpReturn
  192. OpFunctionEnd
  193. )";
  194. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  195. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  196. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  197. text, true, spv::StorageClass::Input, false);
  198. }
  199. TEST_F(ElimDeadIOComponentsTest, NoElimMaxConstantIndex) {
  200. // Should not reduce uv[8] because of max index of 7
  201. //
  202. // #version 450
  203. //
  204. // layout(location = 0) in vec4 uv[8];
  205. //
  206. // out gl_PerVertex {
  207. // vec4 gl_Position;
  208. // };
  209. //
  210. // void main()
  211. // {
  212. // gl_Position = uv[1] + uv[7];
  213. // }
  214. const std::string text = R"(
  215. OpCapability Shader
  216. %1 = OpExtInstImport "GLSL.std.450"
  217. OpMemoryModel Logical GLSL450
  218. OpEntryPoint Vertex %main "main" %_ %uv
  219. OpSource GLSL 450
  220. OpName %main "main"
  221. OpName %gl_PerVertex "gl_PerVertex"
  222. OpMemberName %gl_PerVertex 0 "gl_Position"
  223. OpName %_ ""
  224. OpName %uv "uv"
  225. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  226. OpDecorate %gl_PerVertex Block
  227. OpDecorate %uv Location 0
  228. %void = OpTypeVoid
  229. %3 = OpTypeFunction %void
  230. %float = OpTypeFloat 32
  231. %v4float = OpTypeVector %float 4
  232. %gl_PerVertex = OpTypeStruct %v4float
  233. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  234. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  235. %int = OpTypeInt 32 1
  236. %int_0 = OpConstant %int 0
  237. %uint = OpTypeInt 32 0
  238. %uint_8 = OpConstant %uint 8
  239. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  240. %_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8
  241. %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  242. %int_1 = OpConstant %int 1
  243. %_ptr_Input_v4float = OpTypePointer Input %v4float
  244. %int_7 = OpConstant %int 7
  245. %_ptr_Output_v4float = OpTypePointer Output %v4float
  246. ;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  247. %main = OpFunction %void None %3
  248. %5 = OpLabel
  249. %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1
  250. %21 = OpLoad %v4float %20
  251. %23 = OpAccessChain %_ptr_Input_v4float %uv %int_7
  252. %24 = OpLoad %v4float %23
  253. %25 = OpFAdd %v4float %21 %24
  254. %27 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  255. OpStore %27 %25
  256. OpReturn
  257. OpFunctionEnd
  258. )";
  259. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  260. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  261. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  262. text, true, spv::StorageClass::Input, false);
  263. }
  264. TEST_F(ElimDeadIOComponentsTest, NoElimNonConstantIndex) {
  265. // Should not reduce uv[8] because of non-constant index of ui
  266. //
  267. // #version 450
  268. //
  269. // layout(location = 0) in vec4 uv[8];
  270. //
  271. // out gl_PerVertex {
  272. // vec4 gl_Position;
  273. // };
  274. //
  275. // uniform ubname {
  276. // int ui;
  277. // } ubinst;
  278. //
  279. // void main()
  280. // {
  281. // gl_Position = uv[1] + uv[ubinst.ui];
  282. // }
  283. const std::string text = R"(
  284. OpCapability Shader
  285. %1 = OpExtInstImport "GLSL.std.450"
  286. OpMemoryModel Logical GLSL450
  287. OpEntryPoint Vertex %main "main" %_ %uv %ubinst
  288. OpSource GLSL 450
  289. OpName %main "main"
  290. OpName %gl_PerVertex "gl_PerVertex"
  291. OpMemberName %gl_PerVertex 0 "gl_Position"
  292. OpName %_ ""
  293. OpName %uv "uv"
  294. OpName %ubname "ubname"
  295. OpMemberName %ubname 0 "ui"
  296. OpName %ubinst "ubinst"
  297. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  298. OpDecorate %gl_PerVertex Block
  299. OpDecorate %uv Location 0
  300. OpMemberDecorate %ubname 0 Offset 0
  301. OpDecorate %ubname Block
  302. OpDecorate %ubinst DescriptorSet 0
  303. OpDecorate %ubinst Binding 0
  304. %void = OpTypeVoid
  305. %3 = OpTypeFunction %void
  306. %float = OpTypeFloat 32
  307. %v4float = OpTypeVector %float 4
  308. %gl_PerVertex = OpTypeStruct %v4float
  309. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  310. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  311. %int = OpTypeInt 32 1
  312. %int_0 = OpConstant %int 0
  313. %uint = OpTypeInt 32 0
  314. %uint_8 = OpConstant %uint 8
  315. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  316. %_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8
  317. %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  318. %int_1 = OpConstant %int 1
  319. %_ptr_Input_v4float = OpTypePointer Input %v4float
  320. %ubname = OpTypeStruct %int
  321. %_ptr_Uniform_ubname = OpTypePointer Uniform %ubname
  322. %ubinst = OpVariable %_ptr_Uniform_ubname Uniform
  323. %_ptr_Uniform_int = OpTypePointer Uniform %int
  324. %_ptr_Output_v4float = OpTypePointer Output %v4float
  325. ;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  326. %main = OpFunction %void None %3
  327. %5 = OpLabel
  328. %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1
  329. %21 = OpLoad %v4float %20
  330. %26 = OpAccessChain %_ptr_Uniform_int %ubinst %int_0
  331. %27 = OpLoad %int %26
  332. %28 = OpAccessChain %_ptr_Input_v4float %uv %27
  333. %29 = OpLoad %v4float %28
  334. %30 = OpFAdd %v4float %21 %29
  335. %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  336. OpStore %32 %30
  337. OpReturn
  338. OpFunctionEnd
  339. )";
  340. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  341. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  342. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  343. text, true, spv::StorageClass::Input, false);
  344. }
  345. TEST_F(ElimDeadIOComponentsTest, NoElimNonIndexedAccessChain) {
  346. // Should not change due to non-indexed access chain
  347. const std::string text = R"(
  348. OpCapability Shader
  349. %1 = OpExtInstImport "GLSL.std.450"
  350. OpMemoryModel Logical GLSL450
  351. OpEntryPoint Vertex %main "main" %_ %uv
  352. OpSource GLSL 450
  353. OpName %main "main"
  354. OpName %gl_PerVertex "gl_PerVertex"
  355. OpMemberName %gl_PerVertex 0 "gl_Position"
  356. OpName %_ ""
  357. OpName %uv "uv"
  358. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  359. OpDecorate %gl_PerVertex Block
  360. OpDecorate %uv Location 0
  361. %void = OpTypeVoid
  362. %3 = OpTypeFunction %void
  363. %float = OpTypeFloat 32
  364. %v4float = OpTypeVector %float 4
  365. %gl_PerVertex = OpTypeStruct %v4float
  366. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  367. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  368. %int = OpTypeInt 32 1
  369. %int_0 = OpConstant %int 0
  370. %uint = OpTypeInt 32 0
  371. %uint_8 = OpConstant %uint 8
  372. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  373. %_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8
  374. %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  375. %int_1 = OpConstant %int 1
  376. %_ptr_Input_v4float = OpTypePointer Input %v4float
  377. %_ptr_Output_v4float = OpTypePointer Output %v4float
  378. ;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input
  379. %main = OpFunction %void None %3
  380. %5 = OpLabel
  381. %20 = OpAccessChain %_ptr_Input__arr_v4float_uint_8 %uv
  382. OpReturn
  383. OpFunctionEnd
  384. )";
  385. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  386. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  387. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  388. text, true, spv::StorageClass::Input, false);
  389. }
  390. TEST_F(ElimDeadIOComponentsTest, ElimStructMember) {
  391. // Should eliminate uv
  392. //
  393. // #version 450
  394. //
  395. // in Vertex {
  396. // vec4 Cd;
  397. // vec2 uv;
  398. // } iVert;
  399. //
  400. // out vec4 fragColor;
  401. //
  402. // void main()
  403. // {
  404. // vec4 color = vec4(iVert.Cd);
  405. // fragColor = color;
  406. // }
  407. const std::string text = R"(
  408. OpCapability Shader
  409. %1 = OpExtInstImport "GLSL.std.450"
  410. OpMemoryModel Logical GLSL450
  411. OpEntryPoint Fragment %main "main" %iVert %fragColor
  412. OpExecutionMode %main OriginUpperLeft
  413. OpSource GLSL 450
  414. OpName %main "main"
  415. OpName %Vertex "Vertex"
  416. OpMemberName %Vertex 0 "Cd"
  417. OpMemberName %Vertex 1 "uv"
  418. OpName %iVert "iVert"
  419. OpName %fragColor "fragColor"
  420. OpDecorate %Vertex Block
  421. OpDecorate %iVert Location 0
  422. OpDecorate %fragColor Location 0
  423. %void = OpTypeVoid
  424. %3 = OpTypeFunction %void
  425. %float = OpTypeFloat 32
  426. %v4float = OpTypeVector %float 4
  427. %v2float = OpTypeVector %float 2
  428. %Vertex = OpTypeStruct %v4float %v2float
  429. ; CHECK: %Vertex = OpTypeStruct %v4float %v2float
  430. ; CHECK: %Vertex_0 = OpTypeStruct %v4float
  431. %_ptr_Input_Vertex = OpTypePointer Input %Vertex
  432. ; CHECK: [[pty:%\w+]] = OpTypePointer Input %Vertex_0
  433. %iVert = OpVariable %_ptr_Input_Vertex Input
  434. ; CHECK: %iVert = OpVariable [[pty]] Input
  435. %int = OpTypeInt 32 1
  436. %int_0 = OpConstant %int 0
  437. %_ptr_Input_v4float = OpTypePointer Input %v4float
  438. %_ptr_Output_v4float = OpTypePointer Output %v4float
  439. %fragColor = OpVariable %_ptr_Output_v4float Output
  440. %main = OpFunction %void None %3
  441. %5 = OpLabel
  442. %17 = OpAccessChain %_ptr_Input_v4float %iVert %int_0
  443. %18 = OpLoad %v4float %17
  444. OpStore %fragColor %18
  445. OpReturn
  446. OpFunctionEnd
  447. )";
  448. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  449. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  450. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  451. text, true, spv::StorageClass::Input, false);
  452. }
  453. TEST_F(ElimDeadIOComponentsTest, ElimOutputStructMember) {
  454. // Should eliminate uv from Vertex and all but gl_Position from gl_PerVertex
  455. //
  456. // #version 450
  457. //
  458. // out Vertex {
  459. // vec4 Cd;
  460. // vec2 uv;
  461. // } oVert;
  462. //
  463. // in vec3 P;
  464. //
  465. // void main()
  466. // {
  467. // vec4 worldSpacePos = vec4(P, 1);
  468. // oVert.Cd = vec4(1, 0.5, 0, 1);
  469. // gl_Position = worldSpacePos;
  470. // }
  471. const std::string text = R"(
  472. OpCapability Shader
  473. %1 = OpExtInstImport "GLSL.std.450"
  474. OpMemoryModel Logical GLSL450
  475. OpEntryPoint Vertex %main "main" %P %oVert %_
  476. OpSource GLSL 450
  477. OpName %main "main"
  478. OpName %P "P"
  479. OpName %Vertex "Vertex"
  480. OpMemberName %Vertex 0 "Cd"
  481. OpMemberName %Vertex 1 "uv"
  482. OpName %oVert "oVert"
  483. OpName %gl_PerVertex "gl_PerVertex"
  484. OpMemberName %gl_PerVertex 0 "gl_Position"
  485. OpMemberName %gl_PerVertex 1 "gl_PointSize"
  486. OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
  487. OpMemberName %gl_PerVertex 3 "gl_CullDistance"
  488. OpName %_ ""
  489. OpDecorate %P Location 0
  490. OpDecorate %Vertex Block
  491. OpDecorate %oVert Location 0
  492. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  493. OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
  494. OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
  495. OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
  496. OpDecorate %gl_PerVertex Block
  497. %void = OpTypeVoid
  498. %3 = OpTypeFunction %void
  499. %float = OpTypeFloat 32
  500. %v4float = OpTypeVector %float 4
  501. %v3float = OpTypeVector %float 3
  502. %_ptr_Input_v3float = OpTypePointer Input %v3float
  503. %P = OpVariable %_ptr_Input_v3float Input
  504. %float_1 = OpConstant %float 1
  505. %v2float = OpTypeVector %float 2
  506. %Vertex = OpTypeStruct %v4float %v2float
  507. %_ptr_Output_Vertex = OpTypePointer Output %Vertex
  508. %oVert = OpVariable %_ptr_Output_Vertex Output
  509. %int = OpTypeInt 32 1
  510. %int_0 = OpConstant %int 0
  511. %float_0_5 = OpConstant %float 0.5
  512. %float_0 = OpConstant %float 0
  513. %27 = OpConstantComposite %v4float %float_1 %float_0_5 %float_0 %float_1
  514. %_ptr_Output_v4float = OpTypePointer Output %v4float
  515. %uint = OpTypeInt 32 0
  516. %uint_1 = OpConstant %uint 1
  517. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  518. %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  519. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  520. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  521. ; CHECK: %Vertex = OpTypeStruct %v4float %v2float
  522. ; CHECK: %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  523. ; CHECK: %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  524. ; CHECK: [[sty:%\w+]] = OpTypeStruct %v4float
  525. ; CHECK: [[pty:%\w+]] = OpTypePointer Output [[sty]]
  526. ; CHECK: %oVert = OpVariable [[pty]] Output
  527. ; CHECK: [[sty2:%\w+]] = OpTypeStruct %v4float
  528. ; CHECK: [[pty2:%\w+]] = OpTypePointer Output [[sty2]]
  529. ; CHECK: %_ = OpVariable [[pty2]] Output
  530. %main = OpFunction %void None %3
  531. %5 = OpLabel
  532. %13 = OpLoad %v3float %P
  533. %15 = OpCompositeExtract %float %13 0
  534. %16 = OpCompositeExtract %float %13 1
  535. %17 = OpCompositeExtract %float %13 2
  536. %18 = OpCompositeConstruct %v4float %15 %16 %17 %float_1
  537. %29 = OpAccessChain %_ptr_Output_v4float %oVert %int_0
  538. OpStore %29 %27
  539. %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  540. OpStore %37 %18
  541. OpReturn
  542. OpFunctionEnd
  543. )";
  544. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  545. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  546. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  547. text, true, spv::StorageClass::Output, false);
  548. }
  549. TEST_F(ElimDeadIOComponentsTest, ElimOutputArrayMembers) {
  550. // Should reduce to uv[2]
  551. //
  552. // #version 450
  553. //
  554. // layout(location = 0) out vec2 uv[8];
  555. //
  556. // void main()
  557. // {
  558. // uv[1] = vec2(1, 0.5);
  559. // }
  560. const std::string text = R"(
  561. OpCapability Shader
  562. %1 = OpExtInstImport "GLSL.std.450"
  563. OpMemoryModel Logical GLSL450
  564. OpEntryPoint Fragment %main "main" %uv
  565. OpExecutionMode %main OriginUpperLeft
  566. OpSource GLSL 450
  567. OpName %main "main"
  568. OpName %uv "uv"
  569. OpDecorate %uv Location 0
  570. %void = OpTypeVoid
  571. %3 = OpTypeFunction %void
  572. %float = OpTypeFloat 32
  573. %v2float = OpTypeVector %float 2
  574. %uint = OpTypeInt 32 0
  575. %uint_8 = OpConstant %uint 8
  576. %_arr_v2float_uint_8 = OpTypeArray %v2float %uint_8
  577. %_ptr_Output__arr_v2float_uint_8 = OpTypePointer Output %_arr_v2float_uint_8
  578. %uv = OpVariable %_ptr_Output__arr_v2float_uint_8 Output
  579. ;CHECK-NOT: %uv = OpVariable %_ptr_Output__arr_v2float_uint_8 Output
  580. ;CHECK: %uv = OpVariable %_ptr_Output__arr_v2float_uint_2 Output
  581. %int = OpTypeInt 32 1
  582. %int_1 = OpConstant %int 1
  583. %float_1 = OpConstant %float 1
  584. %float_0_5 = OpConstant %float 0.5
  585. %17 = OpConstantComposite %v2float %float_1 %float_0_5
  586. %_ptr_Output_v2float = OpTypePointer Output %v2float
  587. %main = OpFunction %void None %3
  588. %5 = OpLabel
  589. %19 = OpAccessChain %_ptr_Output_v2float %uv %int_1
  590. OpStore %19 %17
  591. OpReturn
  592. OpFunctionEnd
  593. )";
  594. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  595. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  596. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  597. text, true, spv::StorageClass::Output, false);
  598. }
  599. TEST_F(ElimDeadIOComponentsTest, VertexOnly) {
  600. // Should NOT eliminate uv
  601. //
  602. // #version 450
  603. //
  604. // in Vertex {
  605. // vec4 Cd;
  606. // vec2 uv;
  607. // } iVert;
  608. //
  609. // out vec4 fragColor;
  610. //
  611. // void main()
  612. // {
  613. // vec4 color = vec4(iVert.Cd);
  614. // fragColor = color;
  615. // }
  616. const std::string text = R"(
  617. OpCapability Shader
  618. %1 = OpExtInstImport "GLSL.std.450"
  619. OpMemoryModel Logical GLSL450
  620. OpEntryPoint Fragment %main "main" %iVert %fragColor
  621. OpExecutionMode %main OriginUpperLeft
  622. OpSource GLSL 450
  623. OpName %main "main"
  624. OpName %Vertex "Vertex"
  625. OpMemberName %Vertex 0 "Cd"
  626. OpMemberName %Vertex 1 "uv"
  627. OpName %iVert "iVert"
  628. OpName %fragColor "fragColor"
  629. OpDecorate %Vertex Block
  630. OpDecorate %iVert Location 0
  631. OpDecorate %fragColor Location 0
  632. %void = OpTypeVoid
  633. %3 = OpTypeFunction %void
  634. %float = OpTypeFloat 32
  635. %v4float = OpTypeVector %float 4
  636. %v2float = OpTypeVector %float 2
  637. %Vertex = OpTypeStruct %v4float %v2float
  638. ; CHECK: %Vertex = OpTypeStruct %v4float %v2float
  639. %_ptr_Input_Vertex = OpTypePointer Input %Vertex
  640. ; CHECK: %_ptr_Input_Vertex = OpTypePointer Input %Vertex
  641. %iVert = OpVariable %_ptr_Input_Vertex Input
  642. ; CHECK: %iVert = OpVariable %_ptr_Input_Vertex Input
  643. %int = OpTypeInt 32 1
  644. %int_0 = OpConstant %int 0
  645. %_ptr_Input_v4float = OpTypePointer Input %v4float
  646. %_ptr_Output_v4float = OpTypePointer Output %v4float
  647. %fragColor = OpVariable %_ptr_Output_v4float Output
  648. %main = OpFunction %void None %3
  649. %5 = OpLabel
  650. %17 = OpAccessChain %_ptr_Input_v4float %iVert %int_0
  651. %18 = OpLoad %v4float %17
  652. OpStore %fragColor %18
  653. OpReturn
  654. OpFunctionEnd
  655. )";
  656. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  657. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  658. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  659. text, true, spv::StorageClass::Input, true);
  660. }
  661. TEST_F(ElimDeadIOComponentsTest, TescInput) {
  662. // Eliminate PointSize, ClipDistance, CullDistance from gl_in[]
  663. //
  664. // #version 450
  665. //
  666. // layout (vertices = 4) out;
  667. //
  668. // void main()
  669. // {
  670. // vec4 pos = gl_in[gl_InvocationID].gl_Position;
  671. // gl_out[gl_InvocationID].gl_Position = pos;
  672. // }
  673. const std::string text = R"(
  674. OpCapability Tessellation
  675. %1 = OpExtInstImport "GLSL.std.450"
  676. OpMemoryModel Logical GLSL450
  677. OpEntryPoint TessellationControl %main "main" %gl_in %gl_InvocationID %gl_out
  678. OpExecutionMode %main OutputVertices 4
  679. OpSource GLSL 450
  680. OpName %main "main"
  681. OpName %pos "pos"
  682. OpName %gl_PerVertex "gl_PerVertex"
  683. OpMemberName %gl_PerVertex 0 "gl_Position"
  684. OpMemberName %gl_PerVertex 1 "gl_PointSize"
  685. OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
  686. OpMemberName %gl_PerVertex 3 "gl_CullDistance"
  687. OpName %gl_in "gl_in"
  688. OpName %gl_InvocationID "gl_InvocationID"
  689. OpName %gl_PerVertex_0 "gl_PerVertex"
  690. OpMemberName %gl_PerVertex_0 0 "gl_Position"
  691. OpName %gl_out "gl_out"
  692. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  693. OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
  694. OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
  695. OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
  696. OpDecorate %gl_PerVertex Block
  697. OpDecorate %gl_InvocationID BuiltIn InvocationId
  698. OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
  699. OpDecorate %gl_PerVertex_0 Block
  700. %void = OpTypeVoid
  701. %3 = OpTypeFunction %void
  702. %float = OpTypeFloat 32
  703. %v4float = OpTypeVector %float 4
  704. %_ptr_Function_v4float = OpTypePointer Function %v4float
  705. %uint = OpTypeInt 32 0
  706. %uint_1 = OpConstant %uint 1
  707. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  708. %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  709. %uint_32 = OpConstant %uint 32
  710. %_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32
  711. %_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32
  712. %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input
  713. %int = OpTypeInt 32 1
  714. %_ptr_Input_int = OpTypePointer Input %int
  715. %gl_InvocationID = OpVariable %_ptr_Input_int Input
  716. %int_0 = OpConstant %int 0
  717. %_ptr_Input_v4float = OpTypePointer Input %v4float
  718. %gl_PerVertex_0 = OpTypeStruct %v4float
  719. %uint_4 = OpConstant %uint 4
  720. %_arr_gl_PerVertex_0_uint_4 = OpTypeArray %gl_PerVertex_0 %uint_4
  721. %_ptr_Output__arr_gl_PerVertex_0_uint_4 = OpTypePointer Output %_arr_gl_PerVertex_0_uint_4
  722. %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_0_uint_4 Output
  723. %_ptr_Output_v4float = OpTypePointer Output %v4float
  724. ; CHECK: %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  725. ; CHECK: [[sty:%\w+]] = OpTypeStruct %v4float
  726. ; CHECK: [[asty:%\w+]] = OpTypeArray [[sty]] %uint_32
  727. ; CHECK: [[pasty:%\w+]] = OpTypePointer Input [[asty]]
  728. ; CHECK: %gl_in = OpVariable [[pasty]] Input
  729. %main = OpFunction %void None %3
  730. %5 = OpLabel
  731. %pos = OpVariable %_ptr_Function_v4float Function
  732. %21 = OpLoad %int %gl_InvocationID
  733. %24 = OpAccessChain %_ptr_Input_v4float %gl_in %21 %int_0
  734. %25 = OpLoad %v4float %24
  735. OpStore %pos %25
  736. %31 = OpLoad %int %gl_InvocationID
  737. %32 = OpLoad %v4float %pos
  738. %34 = OpAccessChain %_ptr_Output_v4float %gl_out %31 %int_0
  739. OpStore %34 %32
  740. OpReturn
  741. OpFunctionEnd
  742. )";
  743. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  744. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  745. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  746. text, true, spv::StorageClass::Input, false);
  747. }
  748. TEST_F(ElimDeadIOComponentsTest, TescOutput) {
  749. // Eliminate PointSize, ClipDistance, CullDistance from gl_out[]
  750. //
  751. // #version 450
  752. //
  753. // layout (vertices = 4) out;
  754. //
  755. // void main()
  756. // {
  757. // vec4 pos = gl_in[gl_InvocationID].gl_Position;
  758. // gl_out[gl_InvocationID].gl_Position = pos;
  759. // }
  760. const std::string text = R"(
  761. OpCapability Tessellation
  762. %1 = OpExtInstImport "GLSL.std.450"
  763. OpMemoryModel Logical GLSL450
  764. OpEntryPoint TessellationControl %main "main" %gl_in %gl_InvocationID %gl_out
  765. OpExecutionMode %main OutputVertices 4
  766. OpSource GLSL 450
  767. OpName %main "main"
  768. OpName %pos "pos"
  769. OpName %gl_PerVertex "gl_PerVertex"
  770. OpMemberName %gl_PerVertex 0 "gl_Position"
  771. OpName %gl_in "gl_in"
  772. OpName %gl_InvocationID "gl_InvocationID"
  773. OpName %gl_PerVertex_0 "gl_PerVertex"
  774. OpMemberName %gl_PerVertex_0 0 "gl_Position"
  775. OpMemberName %gl_PerVertex_0 1 "gl_PointSize"
  776. OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance"
  777. OpMemberName %gl_PerVertex_0 3 "gl_CullDistance"
  778. OpName %gl_out "gl_out"
  779. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  780. OpDecorate %gl_PerVertex Block
  781. OpDecorate %gl_InvocationID BuiltIn InvocationId
  782. OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
  783. OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
  784. OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
  785. OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance
  786. OpDecorate %gl_PerVertex_0 Block
  787. %void = OpTypeVoid
  788. %3 = OpTypeFunction %void
  789. %float = OpTypeFloat 32
  790. %v4float = OpTypeVector %float 4
  791. %_ptr_Function_v4float = OpTypePointer Function %v4float
  792. %uint = OpTypeInt 32 0
  793. %uint_1 = OpConstant %uint 1
  794. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  795. %gl_PerVertex = OpTypeStruct %v4float
  796. %uint_32 = OpConstant %uint 32
  797. %_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32
  798. %_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32
  799. %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input
  800. %int = OpTypeInt 32 1
  801. %_ptr_Input_int = OpTypePointer Input %int
  802. %gl_InvocationID = OpVariable %_ptr_Input_int Input
  803. %int_0 = OpConstant %int 0
  804. %_ptr_Input_v4float = OpTypePointer Input %v4float
  805. %gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  806. %uint_4 = OpConstant %uint 4
  807. %_arr_gl_PerVertex_0_uint_4 = OpTypeArray %gl_PerVertex_0 %uint_4
  808. %_ptr_Output__arr_gl_PerVertex_0_uint_4 = OpTypePointer Output %_arr_gl_PerVertex_0_uint_4
  809. %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_0_uint_4 Output
  810. %_ptr_Output_v4float = OpTypePointer Output %v4float
  811. ; CHECK: [[sty:%\w+]] = OpTypeStruct %v4float
  812. ; CHECK: [[asty:%\w+]] = OpTypeArray [[sty]] %uint_4
  813. ; CHECK: [[pasty:%\w+]] = OpTypePointer Output [[asty]]
  814. ; CHECK: %gl_out = OpVariable [[pasty]] Output
  815. %main = OpFunction %void None %3
  816. %5 = OpLabel
  817. %pos = OpVariable %_ptr_Function_v4float Function
  818. %21 = OpLoad %int %gl_InvocationID
  819. %24 = OpAccessChain %_ptr_Input_v4float %gl_in %21 %int_0
  820. %25 = OpLoad %v4float %24
  821. OpStore %pos %25
  822. %31 = OpLoad %int %gl_InvocationID
  823. %32 = OpLoad %v4float %pos
  824. %34 = OpAccessChain %_ptr_Output_v4float %gl_out %31 %int_0
  825. OpStore %34 %32
  826. OpReturn
  827. OpFunctionEnd
  828. )";
  829. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  830. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  831. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  832. text, true, spv::StorageClass::Output, false);
  833. }
  834. TEST_F(ElimDeadIOComponentsTest, TeseInput) {
  835. // Eliminate PointSize, ClipDistance, CullDistance from gl_in[]
  836. //
  837. // #version 450
  838. //
  839. // layout(triangles, ccw) in;
  840. // layout(fractional_odd_spacing) in;
  841. // layout(point_mode) in;
  842. //
  843. // void main()
  844. // {
  845. // vec4 p = gl_in[1].gl_Position;
  846. // gl_Position = p;
  847. // }
  848. const std::string text = R"(
  849. OpCapability Tessellation
  850. %1 = OpExtInstImport "GLSL.std.450"
  851. OpMemoryModel Logical GLSL450
  852. OpEntryPoint TessellationEvaluation %main "main" %gl_in %_
  853. OpExecutionMode %main Triangles
  854. OpExecutionMode %main SpacingFractionalOdd
  855. OpExecutionMode %main VertexOrderCcw
  856. OpExecutionMode %main PointMode
  857. OpSource GLSL 450
  858. OpName %main "main"
  859. OpName %p "p"
  860. OpName %gl_PerVertex "gl_PerVertex"
  861. OpMemberName %gl_PerVertex 0 "gl_Position"
  862. OpMemberName %gl_PerVertex 1 "gl_PointSize"
  863. OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
  864. OpMemberName %gl_PerVertex 3 "gl_CullDistance"
  865. OpName %gl_in "gl_in"
  866. OpName %gl_PerVertex_0 "gl_PerVertex"
  867. OpMemberName %gl_PerVertex_0 0 "gl_Position"
  868. OpName %_ ""
  869. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  870. OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
  871. OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
  872. OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
  873. OpDecorate %gl_PerVertex Block
  874. OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
  875. OpDecorate %gl_PerVertex_0 Block
  876. %void = OpTypeVoid
  877. %3 = OpTypeFunction %void
  878. %float = OpTypeFloat 32
  879. %v4float = OpTypeVector %float 4
  880. %_ptr_Function_v4float = OpTypePointer Function %v4float
  881. %uint = OpTypeInt 32 0
  882. %uint_1 = OpConstant %uint 1
  883. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  884. %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  885. %uint_32 = OpConstant %uint 32
  886. %_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32
  887. %_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32
  888. %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input
  889. %int = OpTypeInt 32 1
  890. %int_1 = OpConstant %int 1
  891. %int_0 = OpConstant %int 0
  892. %_ptr_Input_v4float = OpTypePointer Input %v4float
  893. %gl_PerVertex_0 = OpTypeStruct %v4float
  894. %_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0
  895. %_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output
  896. %_ptr_Output_v4float = OpTypePointer Output %v4float
  897. ; CHECK: %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  898. ; CHECK: [[sty:%\w+]] = OpTypeStruct %v4float
  899. ; CHECK: [[asty:%\w+]] = OpTypeArray [[sty]] %uint_32
  900. ; CHECK: [[pasty:%\w+]] = OpTypePointer Input [[asty]]
  901. ; CHECK: %gl_in = OpVariable [[pasty]] Input
  902. %main = OpFunction %void None %3
  903. %5 = OpLabel
  904. %p = OpVariable %_ptr_Function_v4float Function
  905. %22 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
  906. %23 = OpLoad %v4float %22
  907. OpStore %p %23
  908. %27 = OpLoad %v4float %p
  909. %29 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  910. OpStore %29 %27
  911. OpReturn
  912. OpFunctionEnd
  913. )";
  914. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  915. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  916. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  917. text, true, spv::StorageClass::Input, false);
  918. }
  919. TEST_F(ElimDeadIOComponentsTest, TeseOutput) {
  920. // Eliminate PointSize, ClipDistance, CullDistance from gl_out
  921. //
  922. // #version 450
  923. //
  924. // layout(triangles, ccw) in;
  925. // layout(fractional_odd_spacing) in;
  926. // layout(point_mode) in;
  927. //
  928. // void main()
  929. // {
  930. // vec4 p = gl_in[1].gl_Position;
  931. // gl_Position = p;
  932. // }
  933. const std::string text = R"(
  934. OpCapability Tessellation
  935. %1 = OpExtInstImport "GLSL.std.450"
  936. OpMemoryModel Logical GLSL450
  937. OpEntryPoint TessellationEvaluation %main "main" %gl_in %_
  938. OpExecutionMode %main Triangles
  939. OpExecutionMode %main SpacingFractionalOdd
  940. OpExecutionMode %main VertexOrderCcw
  941. OpExecutionMode %main PointMode
  942. OpSource GLSL 450
  943. OpName %main "main"
  944. OpName %p "p"
  945. OpName %gl_PerVertex "gl_PerVertex"
  946. OpMemberName %gl_PerVertex 0 "gl_Position"
  947. OpName %gl_in "gl_in"
  948. OpName %gl_PerVertex_0 "gl_PerVertex"
  949. OpMemberName %gl_PerVertex_0 0 "gl_Position"
  950. OpMemberName %gl_PerVertex_0 1 "gl_PointSize"
  951. OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance"
  952. OpMemberName %gl_PerVertex_0 3 "gl_CullDistance"
  953. OpName %_ ""
  954. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  955. OpDecorate %gl_PerVertex Block
  956. OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
  957. OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
  958. OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
  959. OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance
  960. OpDecorate %gl_PerVertex_0 Block
  961. %void = OpTypeVoid
  962. %3 = OpTypeFunction %void
  963. %float = OpTypeFloat 32
  964. %v4float = OpTypeVector %float 4
  965. %_ptr_Function_v4float = OpTypePointer Function %v4float
  966. %uint = OpTypeInt 32 0
  967. %uint_1 = OpConstant %uint 1
  968. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  969. %gl_PerVertex = OpTypeStruct %v4float
  970. %uint_32 = OpConstant %uint 32
  971. %_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32
  972. %_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32
  973. %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input
  974. %int = OpTypeInt 32 1
  975. %int_1 = OpConstant %int 1
  976. %int_0 = OpConstant %int 0
  977. %_ptr_Input_v4float = OpTypePointer Input %v4float
  978. %gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  979. %_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0
  980. %_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output
  981. %_ptr_Output_v4float = OpTypePointer Output %v4float
  982. ; CHECK: %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  983. ; CHECK: %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  984. %main = OpFunction %void None %3
  985. %5 = OpLabel
  986. %p = OpVariable %_ptr_Function_v4float Function
  987. %22 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
  988. %23 = OpLoad %v4float %22
  989. OpStore %p %23
  990. %27 = OpLoad %v4float %p
  991. %29 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  992. OpStore %29 %27
  993. OpReturn
  994. OpFunctionEnd
  995. )";
  996. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  997. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  998. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  999. text, true, spv::StorageClass::Output, false);
  1000. }
  1001. TEST_F(ElimDeadIOComponentsTest, GeomInput) {
  1002. // Eliminate PointSize, ClipDistance, CullDistance from gl_in[]
  1003. //
  1004. // #version 450
  1005. //
  1006. // layout(triangle_strip, max_vertices = 3) out;
  1007. // layout(triangles) in;
  1008. //
  1009. // void main()
  1010. // {
  1011. // for (int i = 0; i < 3; i++)
  1012. // {
  1013. // gl_Position = gl_in[i].gl_Position;
  1014. // EmitVertex();
  1015. // }
  1016. // EndPrimitive();
  1017. // }
  1018. const std::string text = R"(
  1019. OpCapability Geometry
  1020. %1 = OpExtInstImport "GLSL.std.450"
  1021. OpMemoryModel Logical GLSL450
  1022. OpEntryPoint Geometry %main "main" %_ %gl_in
  1023. OpExecutionMode %main Triangles
  1024. OpExecutionMode %main Invocations 1
  1025. OpExecutionMode %main OutputTriangleStrip
  1026. OpExecutionMode %main OutputVertices 3
  1027. OpSource GLSL 460
  1028. OpName %main "main"
  1029. OpName %i "i"
  1030. OpName %gl_PerVertex "gl_PerVertex"
  1031. OpMemberName %gl_PerVertex 0 "gl_Position"
  1032. OpName %_ ""
  1033. OpName %gl_PerVertex_0 "gl_PerVertex"
  1034. OpMemberName %gl_PerVertex_0 0 "gl_Position"
  1035. OpMemberName %gl_PerVertex_0 1 "gl_PointSize"
  1036. OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance"
  1037. OpMemberName %gl_PerVertex_0 3 "gl_CullDistance"
  1038. OpName %gl_in "gl_in"
  1039. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  1040. OpDecorate %gl_PerVertex Block
  1041. OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
  1042. OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
  1043. OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
  1044. OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance
  1045. OpDecorate %gl_PerVertex_0 Block
  1046. %void = OpTypeVoid
  1047. %3 = OpTypeFunction %void
  1048. %int = OpTypeInt 32 1
  1049. %_ptr_Function_int = OpTypePointer Function %int
  1050. %int_0 = OpConstant %int 0
  1051. %int_3 = OpConstant %int 3
  1052. %bool = OpTypeBool
  1053. %float = OpTypeFloat 32
  1054. %v4float = OpTypeVector %float 4
  1055. %uint = OpTypeInt 32 0
  1056. %uint_1 = OpConstant %uint 1
  1057. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  1058. %gl_PerVertex = OpTypeStruct %v4float
  1059. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  1060. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  1061. %gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  1062. %uint_3 = OpConstant %uint 3
  1063. %_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3
  1064. %_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3
  1065. %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input
  1066. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1067. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1068. %int_1 = OpConstant %int 1
  1069. ; CHECK: [[asty:%\w+]] = OpTypeArray %gl_PerVertex %uint_3
  1070. ; CHECK: [[pasty:%\w+]] = OpTypePointer Input [[asty]]
  1071. ; CHECK: %gl_in = OpVariable [[pasty]] Input
  1072. %main = OpFunction %void None %3
  1073. %5 = OpLabel
  1074. %i = OpVariable %_ptr_Function_int Function
  1075. OpStore %i %int_0
  1076. OpBranch %10
  1077. %10 = OpLabel
  1078. OpLoopMerge %12 %13 None
  1079. OpBranch %14
  1080. %14 = OpLabel
  1081. %15 = OpLoad %int %i
  1082. %18 = OpSLessThan %bool %15 %int_3
  1083. OpBranchConditional %18 %11 %12
  1084. %11 = OpLabel
  1085. %32 = OpLoad %int %i
  1086. %34 = OpAccessChain %_ptr_Input_v4float %gl_in %32 %int_0
  1087. %35 = OpLoad %v4float %34
  1088. %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  1089. OpStore %37 %35
  1090. OpEmitVertex
  1091. OpBranch %13
  1092. %13 = OpLabel
  1093. %38 = OpLoad %int %i
  1094. %40 = OpIAdd %int %38 %int_1
  1095. OpStore %i %40
  1096. OpBranch %10
  1097. %12 = OpLabel
  1098. OpEndPrimitive
  1099. OpReturn
  1100. OpFunctionEnd
  1101. )";
  1102. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  1103. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1104. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  1105. text, true, spv::StorageClass::Input, false);
  1106. }
  1107. TEST_F(ElimDeadIOComponentsTest, GeomOutput) {
  1108. // Eliminate PointSize, ClipDistance, CullDistance from gl_out
  1109. //
  1110. // #version 450
  1111. //
  1112. // layout(triangle_strip, max_vertices = 3) out;
  1113. // layout(triangles) in;
  1114. //
  1115. // void main()
  1116. // {
  1117. // for (int i = 0; i < 3; i++)
  1118. // {
  1119. // gl_Position = gl_in[i].gl_Position;
  1120. // EmitVertex();
  1121. // }
  1122. // EndPrimitive();
  1123. // }
  1124. const std::string text = R"(
  1125. OpCapability Geometry
  1126. %1 = OpExtInstImport "GLSL.std.450"
  1127. OpMemoryModel Logical GLSL450
  1128. OpEntryPoint Geometry %main "main" %_ %gl_in
  1129. OpExecutionMode %main Triangles
  1130. OpExecutionMode %main Invocations 1
  1131. OpExecutionMode %main OutputTriangleStrip
  1132. OpExecutionMode %main OutputVertices 3
  1133. OpSource GLSL 460
  1134. OpName %main "main"
  1135. OpName %i "i"
  1136. OpName %gl_PerVertex "gl_PerVertex"
  1137. OpMemberName %gl_PerVertex 0 "gl_Position"
  1138. OpMemberName %gl_PerVertex 1 "gl_PointSize"
  1139. OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
  1140. OpMemberName %gl_PerVertex 3 "gl_CullDistance"
  1141. OpName %_ ""
  1142. OpName %gl_PerVertex_0 "gl_PerVertex"
  1143. OpMemberName %gl_PerVertex_0 0 "gl_Position"
  1144. OpName %gl_in "gl_in"
  1145. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  1146. OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
  1147. OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
  1148. OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
  1149. OpDecorate %gl_PerVertex Block
  1150. OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
  1151. OpDecorate %gl_PerVertex_0 Block
  1152. %void = OpTypeVoid
  1153. %3 = OpTypeFunction %void
  1154. %int = OpTypeInt 32 1
  1155. %_ptr_Function_int = OpTypePointer Function %int
  1156. %int_0 = OpConstant %int 0
  1157. %int_3 = OpConstant %int 3
  1158. %bool = OpTypeBool
  1159. %float = OpTypeFloat 32
  1160. %v4float = OpTypeVector %float 4
  1161. %uint = OpTypeInt 32 0
  1162. %uint_1 = OpConstant %uint 1
  1163. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  1164. %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  1165. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  1166. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  1167. %gl_PerVertex_0 = OpTypeStruct %v4float
  1168. %uint_3 = OpConstant %uint 3
  1169. %_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3
  1170. %_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3
  1171. %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input
  1172. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1173. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1174. %int_1 = OpConstant %int 1
  1175. ; CHECK: %_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0
  1176. ; CHECK: %_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output
  1177. %main = OpFunction %void None %3
  1178. %5 = OpLabel
  1179. %i = OpVariable %_ptr_Function_int Function
  1180. OpStore %i %int_0
  1181. OpBranch %10
  1182. %10 = OpLabel
  1183. OpLoopMerge %12 %13 None
  1184. OpBranch %14
  1185. %14 = OpLabel
  1186. %15 = OpLoad %int %i
  1187. %18 = OpSLessThan %bool %15 %int_3
  1188. OpBranchConditional %18 %11 %12
  1189. %11 = OpLabel
  1190. %32 = OpLoad %int %i
  1191. %34 = OpAccessChain %_ptr_Input_v4float %gl_in %32 %int_0
  1192. %35 = OpLoad %v4float %34
  1193. %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  1194. OpStore %37 %35
  1195. OpEmitVertex
  1196. OpBranch %13
  1197. %13 = OpLabel
  1198. %38 = OpLoad %int %i
  1199. %40 = OpIAdd %int %38 %int_1
  1200. OpStore %i %40
  1201. OpBranch %10
  1202. %12 = OpLabel
  1203. OpEndPrimitive
  1204. OpReturn
  1205. OpFunctionEnd
  1206. )";
  1207. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  1208. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1209. SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
  1210. text, true, spv::StorageClass::Output, false);
  1211. }
  1212. } // namespace
  1213. } // namespace opt
  1214. } // namespace spvtools