inline_opaque_test.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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 InlineOpaqueTest = PassTest<::testing::Test>;
  22. TEST_F(InlineOpaqueTest, InlineCallWithStructArgContainingSampledImage) {
  23. // Function with opaque argument is inlined.
  24. // TODO(greg-lunarg): Add HLSL code
  25. const std::string predefs_1 =
  26. R"(OpCapability Shader
  27. %1 = OpExtInstImport "GLSL.std.450"
  28. OpMemoryModel Logical GLSL450
  29. OpEntryPoint Fragment %main "main" %outColor %texCoords
  30. OpExecutionMode %main OriginUpperLeft
  31. OpSource GLSL 140
  32. OpName %main "main"
  33. OpName %S_t "S_t"
  34. OpMemberName %S_t 0 "v0"
  35. OpMemberName %S_t 1 "v1"
  36. OpMemberName %S_t 2 "smp"
  37. OpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;"
  38. OpName %s "s"
  39. OpName %outColor "outColor"
  40. OpName %sampler15 "sampler15"
  41. OpName %s0 "s0"
  42. OpName %texCoords "texCoords"
  43. OpName %param "param"
  44. )";
  45. const std::string name = R"(OpName %return_value "return_value"
  46. )";
  47. const std::string predefs_2 = R"(OpDecorate %sampler15 DescriptorSet 0
  48. %void = OpTypeVoid
  49. %13 = OpTypeFunction %void
  50. %float = OpTypeFloat 32
  51. %v2float = OpTypeVector %float 2
  52. %v4float = OpTypeVector %float 4
  53. %_ptr_Output_v4float = OpTypePointer Output %v4float
  54. %outColor = OpVariable %_ptr_Output_v4float Output
  55. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  56. %19 = OpTypeSampledImage %18
  57. %S_t = OpTypeStruct %v2float %v2float %19
  58. %_ptr_Function_S_t = OpTypePointer Function %S_t
  59. %21 = OpTypeFunction %void %_ptr_Function_S_t
  60. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  61. %_ptr_Function_19 = OpTypePointer Function %19
  62. %sampler15 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  63. %int = OpTypeInt 32 1
  64. %int_0 = OpConstant %int 0
  65. %int_2 = OpConstant %int 2
  66. %_ptr_Function_v2float = OpTypePointer Function %v2float
  67. %_ptr_Input_v2float = OpTypePointer Input %v2float
  68. %texCoords = OpVariable %_ptr_Input_v2float Input
  69. )";
  70. const std::string before =
  71. R"(%main = OpFunction %void None %13
  72. %29 = OpLabel
  73. %s0 = OpVariable %_ptr_Function_S_t Function
  74. %param = OpVariable %_ptr_Function_S_t Function
  75. %30 = OpLoad %v2float %texCoords
  76. %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
  77. OpStore %31 %30
  78. %32 = OpLoad %19 %sampler15
  79. %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
  80. OpStore %33 %32
  81. %34 = OpLoad %S_t %s0
  82. OpStore %param %34
  83. %return_value = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
  84. OpReturn
  85. OpFunctionEnd
  86. )";
  87. const std::string after =
  88. R"(%main = OpFunction %void None %13
  89. %29 = OpLabel
  90. %s0 = OpVariable %_ptr_Function_S_t Function
  91. %param = OpVariable %_ptr_Function_S_t Function
  92. %30 = OpLoad %v2float %texCoords
  93. %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
  94. OpStore %31 %30
  95. %32 = OpLoad %19 %sampler15
  96. %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
  97. OpStore %33 %32
  98. %34 = OpLoad %S_t %s0
  99. OpStore %param %34
  100. %42 = OpAccessChain %_ptr_Function_19 %param %int_2
  101. %43 = OpLoad %19 %42
  102. %44 = OpAccessChain %_ptr_Function_v2float %param %int_0
  103. %45 = OpLoad %v2float %44
  104. %46 = OpImageSampleImplicitLod %v4float %43 %45
  105. OpStore %outColor %46
  106. OpReturn
  107. OpFunctionEnd
  108. )";
  109. const std::string post_defs =
  110. R"(%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %21
  111. %s = OpFunctionParameter %_ptr_Function_S_t
  112. %35 = OpLabel
  113. %36 = OpAccessChain %_ptr_Function_19 %s %int_2
  114. %37 = OpLoad %19 %36
  115. %38 = OpAccessChain %_ptr_Function_v2float %s %int_0
  116. %39 = OpLoad %v2float %38
  117. %40 = OpImageSampleImplicitLod %v4float %37 %39
  118. OpStore %outColor %40
  119. OpReturn
  120. OpFunctionEnd
  121. )";
  122. SinglePassRunAndCheck<InlineOpaquePass>(
  123. predefs_1 + name + predefs_2 + before + post_defs,
  124. predefs_1 + predefs_2 + after + post_defs, true, true);
  125. }
  126. TEST_F(InlineOpaqueTest, InlineOpaqueReturn) {
  127. // Function with opaque return value is inlined.
  128. // TODO(greg-lunarg): Add HLSL code
  129. const std::string predefs =
  130. R"(OpCapability Shader
  131. %1 = OpExtInstImport "GLSL.std.450"
  132. OpMemoryModel Logical GLSL450
  133. OpEntryPoint Fragment %main "main" %texCoords %outColor
  134. OpExecutionMode %main OriginUpperLeft
  135. OpSource GLSL 140
  136. OpName %main "main"
  137. OpName %foo_ "foo("
  138. OpName %texCoords "texCoords"
  139. OpName %outColor "outColor"
  140. OpName %sampler15 "sampler15"
  141. OpName %sampler16 "sampler16"
  142. OpDecorate %sampler15 DescriptorSet 0
  143. OpDecorate %sampler16 DescriptorSet 0
  144. %void = OpTypeVoid
  145. %9 = OpTypeFunction %void
  146. %float = OpTypeFloat 32
  147. %v2float = OpTypeVector %float 2
  148. %bool = OpTypeBool
  149. %false = OpConstantFalse %bool
  150. %_ptr_Input_v2float = OpTypePointer Input %v2float
  151. %texCoords = OpVariable %_ptr_Input_v2float Input
  152. %float_0 = OpConstant %float 0
  153. %16 = OpConstantComposite %v2float %float_0 %float_0
  154. %v4float = OpTypeVector %float 4
  155. %_ptr_Output_v4float = OpTypePointer Output %v4float
  156. %outColor = OpVariable %_ptr_Output_v4float Output
  157. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  158. %20 = OpTypeSampledImage %19
  159. %21 = OpTypeFunction %20
  160. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  161. %_ptr_Function_20 = OpTypePointer Function %20
  162. %sampler15 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  163. %sampler16 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  164. )";
  165. const std::string before =
  166. R"(%main = OpFunction %void None %9
  167. %24 = OpLabel
  168. %25 = OpVariable %_ptr_Function_20 Function
  169. %26 = OpFunctionCall %20 %foo_
  170. OpStore %25 %26
  171. %27 = OpLoad %20 %25
  172. %28 = OpLoad %v2float %texCoords
  173. %29 = OpImageSampleImplicitLod %v4float %27 %28
  174. OpStore %outColor %29
  175. OpReturn
  176. OpFunctionEnd
  177. )";
  178. const std::string after =
  179. R"(%main = OpFunction %void None %9
  180. %24 = OpLabel
  181. %34 = OpVariable %_ptr_Function_20 Function
  182. %35 = OpVariable %_ptr_Function_20 Function
  183. %25 = OpVariable %_ptr_Function_20 Function
  184. %37 = OpLoad %20 %sampler16
  185. OpStore %34 %37
  186. %38 = OpLoad %20 %34
  187. OpStore %35 %38
  188. %26 = OpLoad %20 %35
  189. OpStore %25 %26
  190. %27 = OpLoad %20 %25
  191. %28 = OpLoad %v2float %texCoords
  192. %29 = OpImageSampleImplicitLod %v4float %27 %28
  193. OpStore %outColor %29
  194. OpReturn
  195. OpFunctionEnd
  196. )";
  197. const std::string post_defs =
  198. R"(%foo_ = OpFunction %20 None %21
  199. %30 = OpLabel
  200. %31 = OpVariable %_ptr_Function_20 Function
  201. %32 = OpLoad %20 %sampler16
  202. OpStore %31 %32
  203. %33 = OpLoad %20 %31
  204. OpReturnValue %33
  205. OpFunctionEnd
  206. )";
  207. SinglePassRunAndCheck<InlineOpaquePass>(
  208. predefs + before + post_defs, predefs + after + post_defs, true, true);
  209. }
  210. TEST_F(InlineOpaqueTest, InlineInNonEntryPointFunction) {
  211. // This demonstrates opaque inlining in a function that is not
  212. // an entry point function (main2) but is in the call tree of an
  213. // entry point function (main).
  214. // TODO(greg-lunarg): Add HLSL code
  215. const std::string predefs =
  216. R"(OpCapability Shader
  217. %1 = OpExtInstImport "GLSL.std.450"
  218. OpMemoryModel Logical GLSL450
  219. OpEntryPoint Fragment %main "main" %outColor %texCoords
  220. OpExecutionMode %main OriginUpperLeft
  221. OpSource GLSL 140
  222. OpName %main "main"
  223. OpName %main2 "main2"
  224. OpName %S_t "S_t"
  225. OpMemberName %S_t 0 "v0"
  226. OpMemberName %S_t 1 "v1"
  227. OpMemberName %S_t 2 "smp"
  228. OpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;"
  229. OpName %s "s"
  230. OpName %outColor "outColor"
  231. OpName %sampler15 "sampler15"
  232. OpName %s0 "s0"
  233. OpName %texCoords "texCoords"
  234. OpName %param "param"
  235. OpDecorate %sampler15 DescriptorSet 0
  236. %void = OpTypeVoid
  237. %13 = OpTypeFunction %void
  238. %float = OpTypeFloat 32
  239. %v2float = OpTypeVector %float 2
  240. %v4float = OpTypeVector %float 4
  241. %_ptr_Output_v4float = OpTypePointer Output %v4float
  242. %outColor = OpVariable %_ptr_Output_v4float Output
  243. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  244. %19 = OpTypeSampledImage %18
  245. %S_t = OpTypeStruct %v2float %v2float %19
  246. %_ptr_Function_S_t = OpTypePointer Function %S_t
  247. %21 = OpTypeFunction %void %_ptr_Function_S_t
  248. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  249. %_ptr_Function_19 = OpTypePointer Function %19
  250. %sampler15 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  251. %int = OpTypeInt 32 1
  252. %int_0 = OpConstant %int 0
  253. %int_2 = OpConstant %int 2
  254. %_ptr_Function_v2float = OpTypePointer Function %v2float
  255. %_ptr_Input_v2float = OpTypePointer Input %v2float
  256. %texCoords = OpVariable %_ptr_Input_v2float Input
  257. )";
  258. const std::string before =
  259. R"(%main2 = OpFunction %void None %13
  260. %29 = OpLabel
  261. %s0 = OpVariable %_ptr_Function_S_t Function
  262. %param = OpVariable %_ptr_Function_S_t Function
  263. %30 = OpLoad %v2float %texCoords
  264. %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
  265. OpStore %31 %30
  266. %32 = OpLoad %19 %sampler15
  267. %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
  268. OpStore %33 %32
  269. %34 = OpLoad %S_t %s0
  270. OpStore %param %34
  271. %35 = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
  272. OpReturn
  273. OpFunctionEnd
  274. )";
  275. const std::string after =
  276. R"(%main2 = OpFunction %void None %13
  277. %29 = OpLabel
  278. %s0 = OpVariable %_ptr_Function_S_t Function
  279. %param = OpVariable %_ptr_Function_S_t Function
  280. %30 = OpLoad %v2float %texCoords
  281. %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
  282. OpStore %31 %30
  283. %32 = OpLoad %19 %sampler15
  284. %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
  285. OpStore %33 %32
  286. %34 = OpLoad %S_t %s0
  287. OpStore %param %34
  288. %45 = OpAccessChain %_ptr_Function_19 %param %int_2
  289. %46 = OpLoad %19 %45
  290. %47 = OpAccessChain %_ptr_Function_v2float %param %int_0
  291. %48 = OpLoad %v2float %47
  292. %49 = OpImageSampleImplicitLod %v4float %46 %48
  293. OpStore %outColor %49
  294. OpReturn
  295. OpFunctionEnd
  296. )";
  297. const std::string post_defs =
  298. R"(%main = OpFunction %void None %13
  299. %36 = OpLabel
  300. %37 = OpFunctionCall %void %main2
  301. OpReturn
  302. OpFunctionEnd
  303. %foo_struct_S_t_vf2_vf21_ = OpFunction %void None %21
  304. %s = OpFunctionParameter %_ptr_Function_S_t
  305. %38 = OpLabel
  306. %39 = OpAccessChain %_ptr_Function_19 %s %int_2
  307. %40 = OpLoad %19 %39
  308. %41 = OpAccessChain %_ptr_Function_v2float %s %int_0
  309. %42 = OpLoad %v2float %41
  310. %43 = OpImageSampleImplicitLod %v4float %40 %42
  311. OpStore %outColor %43
  312. OpReturn
  313. OpFunctionEnd
  314. )";
  315. SinglePassRunAndCheck<InlineOpaquePass>(
  316. predefs + before + post_defs, predefs + after + post_defs, true, true);
  317. }
  318. TEST_F(InlineOpaqueTest, NoInlineNoOpaque) {
  319. // Function without opaque interface is not inlined.
  320. // #version 140
  321. //
  322. // in vec4 BaseColor;
  323. //
  324. // float foo(vec4 bar)
  325. // {
  326. // return bar.x + bar.y;
  327. // }
  328. //
  329. // void main()
  330. // {
  331. // vec4 color = vec4(foo(BaseColor));
  332. // gl_FragColor = color;
  333. // }
  334. const std::string assembly =
  335. R"(OpCapability Shader
  336. %1 = OpExtInstImport "GLSL.std.450"
  337. OpMemoryModel Logical GLSL450
  338. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  339. OpExecutionMode %main OriginUpperLeft
  340. OpSource GLSL 140
  341. OpName %main "main"
  342. OpName %foo_vf4_ "foo(vf4;"
  343. OpName %bar "bar"
  344. OpName %color "color"
  345. OpName %BaseColor "BaseColor"
  346. OpName %param "param"
  347. OpName %gl_FragColor "gl_FragColor"
  348. %void = OpTypeVoid
  349. %10 = OpTypeFunction %void
  350. %float = OpTypeFloat 32
  351. %v4float = OpTypeVector %float 4
  352. %_ptr_Function_v4float = OpTypePointer Function %v4float
  353. %14 = OpTypeFunction %float %_ptr_Function_v4float
  354. %uint = OpTypeInt 32 0
  355. %uint_0 = OpConstant %uint 0
  356. %_ptr_Function_float = OpTypePointer Function %float
  357. %uint_1 = OpConstant %uint 1
  358. %_ptr_Input_v4float = OpTypePointer Input %v4float
  359. %BaseColor = OpVariable %_ptr_Input_v4float Input
  360. %_ptr_Output_v4float = OpTypePointer Output %v4float
  361. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  362. %main = OpFunction %void None %10
  363. %21 = OpLabel
  364. %color = OpVariable %_ptr_Function_v4float Function
  365. %param = OpVariable %_ptr_Function_v4float Function
  366. %22 = OpLoad %v4float %BaseColor
  367. OpStore %param %22
  368. %23 = OpFunctionCall %float %foo_vf4_ %param
  369. %24 = OpCompositeConstruct %v4float %23 %23 %23 %23
  370. OpStore %color %24
  371. %25 = OpLoad %v4float %color
  372. OpStore %gl_FragColor %25
  373. OpReturn
  374. OpFunctionEnd
  375. %foo_vf4_ = OpFunction %float None %14
  376. %bar = OpFunctionParameter %_ptr_Function_v4float
  377. %26 = OpLabel
  378. %27 = OpAccessChain %_ptr_Function_float %bar %uint_0
  379. %28 = OpLoad %float %27
  380. %29 = OpAccessChain %_ptr_Function_float %bar %uint_1
  381. %30 = OpLoad %float %29
  382. %31 = OpFAdd %float %28 %30
  383. OpReturnValue %31
  384. OpFunctionEnd
  385. )";
  386. SinglePassRunAndCheck<InlineOpaquePass>(assembly, assembly, true, true);
  387. }
  388. } // namespace
  389. } // namespace opt
  390. } // namespace spvtools