convert_relaxed_to_half_test.cpp 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787
  1. // Copyright (c) 2019 Valve Corporation
  2. // Copyright (c) 2019 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. // Convert Relaxed to Half tests
  16. #include <string>
  17. #include <vector>
  18. #include "test/opt/assembly_builder.h"
  19. #include "test/opt/pass_fixture.h"
  20. #include "test/opt/pass_utils.h"
  21. namespace spvtools {
  22. namespace opt {
  23. namespace {
  24. using ConvertToHalfTest = PassTest<::testing::Test>;
  25. TEST_F(ConvertToHalfTest, ConvertToHalfBasic) {
  26. // The resulting SPIR-V was processed with --relax-float-ops.
  27. //
  28. // clang-format off
  29. //
  30. // SamplerState g_sSamp : register(s0);
  31. // uniform Texture1D <float4> g_tTex1df4 : register(t0);
  32. //
  33. // struct PS_INPUT
  34. // {
  35. // float Tex0 : TEXCOORD0;
  36. // };
  37. //
  38. // struct PS_OUTPUT
  39. // {
  40. // float4 Color : SV_Target0;
  41. // };
  42. //
  43. // cbuffer cbuff{
  44. // float c;
  45. // }
  46. //
  47. // PS_OUTPUT main(PS_INPUT i)
  48. // {
  49. // PS_OUTPUT psout;
  50. // psout.Color = g_tTex1df4.Sample(g_sSamp, i.Tex0) * c;
  51. // return psout;
  52. // }
  53. //
  54. // clang-format on
  55. const std::string defs_before =
  56. R"(OpCapability Shader
  57. OpCapability Sampled1D
  58. %1 = OpExtInstImport "GLSL.std.450"
  59. OpMemoryModel Logical GLSL450
  60. OpEntryPoint Fragment %main "main" %i_Tex0 %_entryPointOutput_Color
  61. OpExecutionMode %main OriginUpperLeft
  62. OpSource HLSL 500
  63. OpName %main "main"
  64. OpName %g_tTex1df4 "g_tTex1df4"
  65. OpName %g_sSamp "g_sSamp"
  66. OpName %cbuff "cbuff"
  67. OpMemberName %cbuff 0 "c"
  68. OpName %_ ""
  69. OpName %i_Tex0 "i.Tex0"
  70. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  71. OpDecorate %g_tTex1df4 DescriptorSet 0
  72. OpDecorate %g_tTex1df4 Binding 0
  73. OpDecorate %g_sSamp DescriptorSet 0
  74. OpDecorate %g_sSamp Binding 0
  75. OpMemberDecorate %cbuff 0 Offset 0
  76. OpDecorate %cbuff Block
  77. OpDecorate %_ DescriptorSet 0
  78. OpDecorate %_ Binding 1
  79. OpDecorate %i_Tex0 Location 0
  80. OpDecorate %_entryPointOutput_Color Location 0
  81. OpDecorate %48 RelaxedPrecision
  82. OpDecorate %63 RelaxedPrecision
  83. OpDecorate %65 RelaxedPrecision
  84. OpDecorate %66 RelaxedPrecision
  85. %void = OpTypeVoid
  86. %3 = OpTypeFunction %void
  87. %float = OpTypeFloat 32
  88. %v4float = OpTypeVector %float 4
  89. %int = OpTypeInt 32 1
  90. %int_0 = OpConstant %int 0
  91. %19 = OpTypeImage %float 1D 0 0 0 1 Unknown
  92. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  93. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  94. %23 = OpTypeSampler
  95. %_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23
  96. %g_sSamp = OpVariable %_ptr_UniformConstant_23 UniformConstant
  97. %27 = OpTypeSampledImage %19
  98. %cbuff = OpTypeStruct %float
  99. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  100. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  101. %_ptr_Uniform_float = OpTypePointer Uniform %float
  102. %_ptr_Input_float = OpTypePointer Input %float
  103. %i_Tex0 = OpVariable %_ptr_Input_float Input
  104. %_ptr_Output_v4float = OpTypePointer Output %v4float
  105. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  106. )";
  107. const std::string defs_after =
  108. R"(OpCapability Shader
  109. OpCapability Sampled1D
  110. OpCapability Float16
  111. %1 = OpExtInstImport "GLSL.std.450"
  112. OpMemoryModel Logical GLSL450
  113. OpEntryPoint Fragment %main "main" %i_Tex0 %_entryPointOutput_Color
  114. OpExecutionMode %main OriginUpperLeft
  115. OpSource HLSL 500
  116. OpName %main "main"
  117. OpName %g_tTex1df4 "g_tTex1df4"
  118. OpName %g_sSamp "g_sSamp"
  119. OpName %cbuff "cbuff"
  120. OpMemberName %cbuff 0 "c"
  121. OpName %_ ""
  122. OpName %i_Tex0 "i.Tex0"
  123. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  124. OpDecorate %g_tTex1df4 DescriptorSet 0
  125. OpDecorate %g_tTex1df4 Binding 0
  126. OpDecorate %g_sSamp DescriptorSet 0
  127. OpDecorate %g_sSamp Binding 0
  128. OpMemberDecorate %cbuff 0 Offset 0
  129. OpDecorate %cbuff Block
  130. OpDecorate %_ DescriptorSet 0
  131. OpDecorate %_ Binding 1
  132. OpDecorate %i_Tex0 Location 0
  133. OpDecorate %_entryPointOutput_Color Location 0
  134. %void = OpTypeVoid
  135. %3 = OpTypeFunction %void
  136. %float = OpTypeFloat 32
  137. %v4float = OpTypeVector %float 4
  138. %int = OpTypeInt 32 1
  139. %int_0 = OpConstant %int 0
  140. %19 = OpTypeImage %float 1D 0 0 0 1 Unknown
  141. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  142. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  143. %23 = OpTypeSampler
  144. %_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23
  145. %g_sSamp = OpVariable %_ptr_UniformConstant_23 UniformConstant
  146. %27 = OpTypeSampledImage %19
  147. %cbuff = OpTypeStruct %float
  148. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  149. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  150. %_ptr_Uniform_float = OpTypePointer Uniform %float
  151. %_ptr_Input_float = OpTypePointer Input %float
  152. %i_Tex0 = OpVariable %_ptr_Input_float Input
  153. %_ptr_Output_v4float = OpTypePointer Output %v4float
  154. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  155. %half = OpTypeFloat 16
  156. %v4half = OpTypeVector %half 4
  157. )";
  158. const std::string func_before =
  159. R"(%main = OpFunction %void None %3
  160. %5 = OpLabel
  161. %48 = OpLoad %float %i_Tex0
  162. %58 = OpLoad %19 %g_tTex1df4
  163. %59 = OpLoad %23 %g_sSamp
  164. %60 = OpSampledImage %27 %58 %59
  165. %63 = OpImageSampleImplicitLod %v4float %60 %48
  166. %64 = OpAccessChain %_ptr_Uniform_float %_ %int_0
  167. %65 = OpLoad %float %64
  168. %66 = OpVectorTimesScalar %v4float %63 %65
  169. OpStore %_entryPointOutput_Color %66
  170. OpReturn
  171. OpFunctionEnd
  172. )";
  173. const std::string func_after =
  174. R"(%main = OpFunction %void None %3
  175. %5 = OpLabel
  176. %48 = OpLoad %float %i_Tex0
  177. %58 = OpLoad %19 %g_tTex1df4
  178. %59 = OpLoad %23 %g_sSamp
  179. %60 = OpSampledImage %27 %58 %59
  180. %63 = OpImageSampleImplicitLod %v4float %60 %48
  181. %64 = OpAccessChain %_ptr_Uniform_float %_ %int_0
  182. %65 = OpLoad %float %64
  183. %69 = OpFConvert %v4half %63
  184. %70 = OpFConvert %half %65
  185. %66 = OpVectorTimesScalar %v4half %69 %70
  186. %71 = OpFConvert %v4float %66
  187. OpStore %_entryPointOutput_Color %71
  188. OpReturn
  189. OpFunctionEnd
  190. )";
  191. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  192. SinglePassRunAndCheck<ConvertToHalfPass>(defs_before + func_before,
  193. defs_after + func_after, true, true);
  194. }
  195. TEST_F(ConvertToHalfTest, ConvertToHalfForLinkage) {
  196. const std::string before =
  197. R"(OpCapability Shader
  198. OpCapability Linkage
  199. OpMemoryModel Logical GLSL450
  200. OpSource HLSL 630
  201. OpName %type_cbuff "type.cbuff"
  202. OpMemberName %type_cbuff 0 "c"
  203. OpName %cbuff "cbuff"
  204. OpName %main "main"
  205. OpName %BaseColor "BaseColor"
  206. OpName %bb_entry "bb.entry"
  207. OpName %v "v"
  208. OpDecorate %main LinkageAttributes "main" Export
  209. OpDecorate %cbuff DescriptorSet 0
  210. OpDecorate %cbuff Binding 0
  211. OpMemberDecorate %type_cbuff 0 Offset 0
  212. OpDecorate %type_cbuff Block
  213. OpDecorate %18 RelaxedPrecision
  214. %int = OpTypeInt 32 1
  215. %int_0 = OpConstant %int 0
  216. %float = OpTypeFloat 32
  217. %type_cbuff = OpTypeStruct %float
  218. %_ptr_Uniform_type_cbuff = OpTypePointer Uniform %type_cbuff
  219. %v4float = OpTypeVector %float 4
  220. %_ptr_Function_v4float = OpTypePointer Function %v4float
  221. %9 = OpTypeFunction %v4float %_ptr_Function_v4float
  222. %_ptr_Uniform_float = OpTypePointer Uniform %float
  223. %cbuff = OpVariable %_ptr_Uniform_type_cbuff Uniform
  224. %main = OpFunction %v4float None %9
  225. %BaseColor = OpFunctionParameter %_ptr_Function_v4float
  226. %bb_entry = OpLabel
  227. %v = OpVariable %_ptr_Function_v4float Function
  228. %14 = OpLoad %v4float %BaseColor
  229. %16 = OpAccessChain %_ptr_Uniform_float %cbuff %int_0
  230. %17 = OpLoad %float %16
  231. %18 = OpVectorTimesScalar %v4float %14 %17
  232. OpStore %v %18
  233. %19 = OpLoad %v4float %v
  234. OpReturnValue %19
  235. OpFunctionEnd
  236. )";
  237. const std::string after =
  238. R"(OpCapability Shader
  239. OpCapability Linkage
  240. OpCapability Float16
  241. OpMemoryModel Logical GLSL450
  242. OpSource HLSL 630
  243. OpName %type_cbuff "type.cbuff"
  244. OpMemberName %type_cbuff 0 "c"
  245. OpName %cbuff "cbuff"
  246. OpName %main "main"
  247. OpName %BaseColor "BaseColor"
  248. OpName %bb_entry "bb.entry"
  249. OpName %v "v"
  250. OpDecorate %main LinkageAttributes "main" Export
  251. OpDecorate %cbuff DescriptorSet 0
  252. OpDecorate %cbuff Binding 0
  253. OpMemberDecorate %type_cbuff 0 Offset 0
  254. OpDecorate %type_cbuff Block
  255. %int = OpTypeInt 32 1
  256. %int_0 = OpConstant %int 0
  257. %float = OpTypeFloat 32
  258. %type_cbuff = OpTypeStruct %float
  259. %_ptr_Uniform_type_cbuff = OpTypePointer Uniform %type_cbuff
  260. %v4float = OpTypeVector %float 4
  261. %_ptr_Function_v4float = OpTypePointer Function %v4float
  262. %14 = OpTypeFunction %v4float %_ptr_Function_v4float
  263. %_ptr_Uniform_float = OpTypePointer Uniform %float
  264. %cbuff = OpVariable %_ptr_Uniform_type_cbuff Uniform
  265. %half = OpTypeFloat 16
  266. %v4half = OpTypeVector %half 4
  267. %main = OpFunction %v4float None %14
  268. %BaseColor = OpFunctionParameter %_ptr_Function_v4float
  269. %bb_entry = OpLabel
  270. %v = OpVariable %_ptr_Function_v4float Function
  271. %16 = OpLoad %v4float %BaseColor
  272. %17 = OpAccessChain %_ptr_Uniform_float %cbuff %int_0
  273. %18 = OpLoad %float %17
  274. %22 = OpFConvert %v4half %16
  275. %23 = OpFConvert %half %18
  276. %7 = OpVectorTimesScalar %v4half %22 %23
  277. %24 = OpFConvert %v4float %7
  278. OpStore %v %24
  279. %19 = OpLoad %v4float %v
  280. OpReturnValue %19
  281. OpFunctionEnd
  282. )";
  283. SinglePassRunAndCheck<ConvertToHalfPass>(before, after, true, true);
  284. }
  285. TEST_F(ConvertToHalfTest, ConvertToHalfWithDrefSample) {
  286. // The resulting SPIR-V was processed with --relax-float-ops.
  287. //
  288. // clang-format off
  289. //
  290. // SamplerComparisonState g_sSamp : register(s0);
  291. // uniform Texture1D <float4> g_tTex1df4 : register(t0);
  292. //
  293. // cbuffer cbuff{
  294. // float c1;
  295. // float c2;
  296. // };
  297. //
  298. // struct PS_INPUT
  299. // {
  300. // float Tex0 : TEXCOORD0;
  301. // float Tex1 : TEXCOORD1;
  302. // };
  303. //
  304. // struct PS_OUTPUT
  305. // {
  306. // float Color : SV_Target0;
  307. // };
  308. //
  309. // PS_OUTPUT main(PS_INPUT i)
  310. // {
  311. // PS_OUTPUT psout;
  312. // float txval10 = g_tTex1df4.SampleCmp(g_sSamp, i.Tex0 * 0.1, c1 + 0.1);
  313. // float txval11 = g_tTex1df4.SampleCmp(g_sSamp, i.Tex1 * 0.2, c2 + 0.2);
  314. // float t = txval10 + txval11;
  315. // float t2 = t / 2.0;
  316. // psout.Color = t2;
  317. // return psout;
  318. // }
  319. //
  320. // clang-format on
  321. const std::string defs_before =
  322. R"(OpCapability Shader
  323. OpCapability Sampled1D
  324. %1 = OpExtInstImport "GLSL.std.450"
  325. OpMemoryModel Logical GLSL450
  326. OpEntryPoint Fragment %main "main" %i_Tex0 %i_Tex1 %_entryPointOutput_Color
  327. OpExecutionMode %main OriginUpperLeft
  328. OpSource HLSL 500
  329. OpName %main "main"
  330. OpName %g_tTex1df4 "g_tTex1df4"
  331. OpName %g_sSamp "g_sSamp"
  332. OpName %cbuff "cbuff"
  333. OpMemberName %cbuff 0 "c1"
  334. OpMemberName %cbuff 1 "c2"
  335. OpName %_ ""
  336. OpName %i_Tex0 "i.Tex0"
  337. OpName %i_Tex1 "i.Tex1"
  338. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  339. OpDecorate %g_tTex1df4 DescriptorSet 0
  340. OpDecorate %g_tTex1df4 Binding 0
  341. OpDecorate %g_sSamp DescriptorSet 0
  342. OpDecorate %g_sSamp Binding 0
  343. OpMemberDecorate %cbuff 0 Offset 0
  344. OpMemberDecorate %cbuff 1 Offset 4
  345. OpDecorate %cbuff Block
  346. OpDecorate %_ DescriptorSet 0
  347. OpDecorate %_ Binding 1
  348. OpDecorate %i_Tex0 Location 0
  349. OpDecorate %i_Tex1 Location 1
  350. OpDecorate %_entryPointOutput_Color Location 0
  351. OpDecorate %100 RelaxedPrecision
  352. OpDecorate %76 RelaxedPrecision
  353. OpDecorate %79 RelaxedPrecision
  354. OpDecorate %98 RelaxedPrecision
  355. OpDecorate %101 RelaxedPrecision
  356. OpDecorate %110 RelaxedPrecision
  357. OpDecorate %102 RelaxedPrecision
  358. OpDecorate %112 RelaxedPrecision
  359. OpDecorate %104 RelaxedPrecision
  360. OpDecorate %113 RelaxedPrecision
  361. OpDecorate %114 RelaxedPrecision
  362. OpDecorate %116 RelaxedPrecision
  363. OpDecorate %119 RelaxedPrecision
  364. OpDecorate %121 RelaxedPrecision
  365. %void = OpTypeVoid
  366. %3 = OpTypeFunction %void
  367. %float = OpTypeFloat 32
  368. %16 = OpTypeImage %float 1D 1 0 0 1 Unknown
  369. %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
  370. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_16 UniformConstant
  371. %20 = OpTypeSampler
  372. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  373. %g_sSamp = OpVariable %_ptr_UniformConstant_20 UniformConstant
  374. %24 = OpTypeSampledImage %16
  375. %int = OpTypeInt 32 1
  376. %int_0 = OpConstant %int 0
  377. %float_0_100000001 = OpConstant %float 0.100000001
  378. %cbuff = OpTypeStruct %float %float
  379. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  380. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  381. %_ptr_Uniform_float = OpTypePointer Uniform %float
  382. %v2float = OpTypeVector %float 2
  383. %int_1 = OpConstant %int 1
  384. %float_0_200000003 = OpConstant %float 0.200000003
  385. %_ptr_Input_float = OpTypePointer Input %float
  386. %i_Tex0 = OpVariable %_ptr_Input_float Input
  387. %i_Tex1 = OpVariable %_ptr_Input_float Input
  388. %_ptr_Output_float = OpTypePointer Output %float
  389. %_entryPointOutput_Color = OpVariable %_ptr_Output_float Output
  390. %float_0_5 = OpConstant %float 0.5
  391. )";
  392. const std::string defs_after =
  393. R"(OpCapability Shader
  394. OpCapability Sampled1D
  395. OpCapability Float16
  396. %1 = OpExtInstImport "GLSL.std.450"
  397. OpMemoryModel Logical GLSL450
  398. OpEntryPoint Fragment %main "main" %i_Tex0 %i_Tex1 %_entryPointOutput_Color
  399. OpExecutionMode %main OriginUpperLeft
  400. OpSource HLSL 500
  401. OpName %main "main"
  402. OpName %g_tTex1df4 "g_tTex1df4"
  403. OpName %g_sSamp "g_sSamp"
  404. OpName %cbuff "cbuff"
  405. OpMemberName %cbuff 0 "c1"
  406. OpMemberName %cbuff 1 "c2"
  407. OpName %_ ""
  408. OpName %i_Tex0 "i.Tex0"
  409. OpName %i_Tex1 "i.Tex1"
  410. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  411. OpDecorate %g_tTex1df4 DescriptorSet 0
  412. OpDecorate %g_tTex1df4 Binding 0
  413. OpDecorate %g_sSamp DescriptorSet 0
  414. OpDecorate %g_sSamp Binding 0
  415. OpMemberDecorate %cbuff 0 Offset 0
  416. OpMemberDecorate %cbuff 1 Offset 4
  417. OpDecorate %cbuff Block
  418. OpDecorate %_ DescriptorSet 0
  419. OpDecorate %_ Binding 1
  420. OpDecorate %i_Tex0 Location 0
  421. OpDecorate %i_Tex1 Location 1
  422. OpDecorate %_entryPointOutput_Color Location 0
  423. %void = OpTypeVoid
  424. %25 = OpTypeFunction %void
  425. %float = OpTypeFloat 32
  426. %27 = OpTypeImage %float 1D 1 0 0 1 Unknown
  427. %_ptr_UniformConstant_27 = OpTypePointer UniformConstant %27
  428. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_27 UniformConstant
  429. %29 = OpTypeSampler
  430. %_ptr_UniformConstant_29 = OpTypePointer UniformConstant %29
  431. %g_sSamp = OpVariable %_ptr_UniformConstant_29 UniformConstant
  432. %31 = OpTypeSampledImage %27
  433. %int = OpTypeInt 32 1
  434. %int_0 = OpConstant %int 0
  435. %float_0_100000001 = OpConstant %float 0.100000001
  436. %cbuff = OpTypeStruct %float %float
  437. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  438. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  439. %_ptr_Uniform_float = OpTypePointer Uniform %float
  440. %v2float = OpTypeVector %float 2
  441. %int_1 = OpConstant %int 1
  442. %float_0_200000003 = OpConstant %float 0.200000003
  443. %_ptr_Input_float = OpTypePointer Input %float
  444. %i_Tex0 = OpVariable %_ptr_Input_float Input
  445. %i_Tex1 = OpVariable %_ptr_Input_float Input
  446. %_ptr_Output_float = OpTypePointer Output %float
  447. %_entryPointOutput_Color = OpVariable %_ptr_Output_float Output
  448. %float_0_5 = OpConstant %float 0.5
  449. %half = OpTypeFloat 16
  450. %v2half = OpTypeVector %half 2
  451. )";
  452. const std::string func_before =
  453. R"(%main = OpFunction %void None %3
  454. %5 = OpLabel
  455. %76 = OpLoad %float %i_Tex0
  456. %79 = OpLoad %float %i_Tex1
  457. %93 = OpLoad %16 %g_tTex1df4
  458. %94 = OpLoad %20 %g_sSamp
  459. %95 = OpSampledImage %24 %93 %94
  460. %98 = OpFMul %float %76 %float_0_100000001
  461. %99 = OpAccessChain %_ptr_Uniform_float %_ %int_0
  462. %100 = OpLoad %float %99
  463. %101 = OpFAdd %float %100 %float_0_100000001
  464. %102 = OpCompositeConstruct %v2float %98 %101
  465. %104 = OpImageSampleDrefImplicitLod %float %95 %102 %101
  466. %105 = OpLoad %16 %g_tTex1df4
  467. %106 = OpLoad %20 %g_sSamp
  468. %107 = OpSampledImage %24 %105 %106
  469. %110 = OpFMul %float %79 %float_0_200000003
  470. %111 = OpAccessChain %_ptr_Uniform_float %_ %int_1
  471. %112 = OpLoad %float %111
  472. %113 = OpFAdd %float %112 %float_0_200000003
  473. %114 = OpCompositeConstruct %v2float %110 %113
  474. %116 = OpImageSampleDrefImplicitLod %float %107 %114 %113
  475. %119 = OpFAdd %float %104 %116
  476. %121 = OpFMul %float %119 %float_0_5
  477. OpStore %_entryPointOutput_Color %121
  478. OpReturn
  479. OpFunctionEnd
  480. )";
  481. const std::string func_after =
  482. R"(%main = OpFunction %void None %25
  483. %43 = OpLabel
  484. %11 = OpLoad %float %i_Tex0
  485. %12 = OpLoad %float %i_Tex1
  486. %44 = OpLoad %27 %g_tTex1df4
  487. %45 = OpLoad %29 %g_sSamp
  488. %46 = OpSampledImage %31 %44 %45
  489. %53 = OpFConvert %half %11
  490. %54 = OpFConvert %half %float_0_100000001
  491. %13 = OpFMul %half %53 %54
  492. %47 = OpAccessChain %_ptr_Uniform_float %_ %int_0
  493. %10 = OpLoad %float %47
  494. %55 = OpFConvert %half %10
  495. %56 = OpFConvert %half %float_0_100000001
  496. %14 = OpFAdd %half %55 %56
  497. %16 = OpCompositeConstruct %v2half %13 %14
  498. %58 = OpFConvert %float %14
  499. %18 = OpImageSampleDrefImplicitLod %float %46 %16 %58
  500. %48 = OpLoad %27 %g_tTex1df4
  501. %49 = OpLoad %29 %g_sSamp
  502. %50 = OpSampledImage %31 %48 %49
  503. %59 = OpFConvert %half %12
  504. %60 = OpFConvert %half %float_0_200000003
  505. %15 = OpFMul %half %59 %60
  506. %51 = OpAccessChain %_ptr_Uniform_float %_ %int_1
  507. %17 = OpLoad %float %51
  508. %61 = OpFConvert %half %17
  509. %62 = OpFConvert %half %float_0_200000003
  510. %19 = OpFAdd %half %61 %62
  511. %20 = OpCompositeConstruct %v2half %15 %19
  512. %63 = OpFConvert %float %19
  513. %21 = OpImageSampleDrefImplicitLod %float %50 %20 %63
  514. %64 = OpFConvert %half %18
  515. %65 = OpFConvert %half %21
  516. %22 = OpFAdd %half %64 %65
  517. %66 = OpFConvert %half %float_0_5
  518. %23 = OpFMul %half %22 %66
  519. %67 = OpFConvert %float %23
  520. OpStore %_entryPointOutput_Color %67
  521. OpReturn
  522. OpFunctionEnd
  523. )";
  524. SinglePassRunAndCheck<ConvertToHalfPass>(defs_before + func_before,
  525. defs_after + func_after, true, true);
  526. }
  527. TEST_F(ConvertToHalfTest, ConvertToHalfWithVectorMatrixMult) {
  528. // The resulting SPIR-V was processed with --relax-float-ops.
  529. //
  530. // clang-format off
  531. //
  532. // SamplerState g_sSamp : register(s0);
  533. // uniform Texture1D <float4> g_tTex1df4 : register(t0);
  534. //
  535. // struct PS_OUTPUT
  536. // {
  537. // float4 Color : SV_Target0;
  538. // };
  539. //
  540. // cbuffer cbuff{
  541. // float4x4 M;
  542. // }
  543. //
  544. // PS_OUTPUT main()
  545. // {
  546. // PS_OUTPUT psout;
  547. // float4 txval10 = g_tTex1df4.Sample(g_sSamp, 0.1);
  548. // float4 t = mul(txval10, M);
  549. // psout.Color = t;
  550. // return psout;
  551. //}
  552. //
  553. // clang-format on
  554. const std::string defs_before =
  555. R"(OpCapability Shader
  556. OpCapability Sampled1D
  557. %1 = OpExtInstImport "GLSL.std.450"
  558. OpMemoryModel Logical GLSL450
  559. OpEntryPoint Fragment %main "main" %_entryPointOutput_Color
  560. OpExecutionMode %main OriginUpperLeft
  561. OpSource HLSL 500
  562. OpName %main "main"
  563. OpName %g_tTex1df4 "g_tTex1df4"
  564. OpName %g_sSamp "g_sSamp"
  565. OpName %cbuff "cbuff"
  566. OpMemberName %cbuff 0 "M"
  567. OpName %_ ""
  568. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  569. OpDecorate %g_tTex1df4 DescriptorSet 0
  570. OpDecorate %g_tTex1df4 Binding 0
  571. OpDecorate %g_sSamp DescriptorSet 0
  572. OpDecorate %g_sSamp Binding 0
  573. OpMemberDecorate %cbuff 0 RowMajor
  574. OpMemberDecorate %cbuff 0 Offset 0
  575. OpMemberDecorate %cbuff 0 MatrixStride 16
  576. OpDecorate %cbuff Block
  577. OpDecorate %_ DescriptorSet 0
  578. OpDecorate %_ Binding 1
  579. OpDecorate %_entryPointOutput_Color Location 0
  580. OpDecorate %56 RelaxedPrecision
  581. OpDecorate %58 RelaxedPrecision
  582. OpDecorate %60 RelaxedPrecision
  583. %void = OpTypeVoid
  584. %3 = OpTypeFunction %void
  585. %float = OpTypeFloat 32
  586. %v4float = OpTypeVector %float 4
  587. %14 = OpTypeImage %float 1D 0 0 0 1 Unknown
  588. %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
  589. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_14 UniformConstant
  590. %18 = OpTypeSampler
  591. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  592. %g_sSamp = OpVariable %_ptr_UniformConstant_18 UniformConstant
  593. %22 = OpTypeSampledImage %14
  594. %float_0_100000001 = OpConstant %float 0.100000001
  595. %mat4v4float = OpTypeMatrix %v4float 4
  596. %cbuff = OpTypeStruct %mat4v4float
  597. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  598. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  599. %int = OpTypeInt 32 1
  600. %int_0 = OpConstant %int 0
  601. %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
  602. %_ptr_Output_v4float = OpTypePointer Output %v4float
  603. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  604. )";
  605. const std::string defs_after =
  606. R"(OpCapability Shader
  607. OpCapability Sampled1D
  608. OpCapability Float16
  609. %1 = OpExtInstImport "GLSL.std.450"
  610. OpMemoryModel Logical GLSL450
  611. OpEntryPoint Fragment %main "main" %_entryPointOutput_Color
  612. OpExecutionMode %main OriginUpperLeft
  613. OpSource HLSL 500
  614. OpName %main "main"
  615. OpName %g_tTex1df4 "g_tTex1df4"
  616. OpName %g_sSamp "g_sSamp"
  617. OpName %cbuff "cbuff"
  618. OpMemberName %cbuff 0 "M"
  619. OpName %_ ""
  620. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  621. OpDecorate %g_tTex1df4 DescriptorSet 0
  622. OpDecorate %g_tTex1df4 Binding 0
  623. OpDecorate %g_sSamp DescriptorSet 0
  624. OpDecorate %g_sSamp Binding 0
  625. OpMemberDecorate %cbuff 0 RowMajor
  626. OpMemberDecorate %cbuff 0 Offset 0
  627. OpMemberDecorate %cbuff 0 MatrixStride 16
  628. OpDecorate %cbuff Block
  629. OpDecorate %_ DescriptorSet 0
  630. OpDecorate %_ Binding 1
  631. OpDecorate %_entryPointOutput_Color Location 0
  632. %void = OpTypeVoid
  633. %3 = OpTypeFunction %void
  634. %float = OpTypeFloat 32
  635. %v4float = OpTypeVector %float 4
  636. %14 = OpTypeImage %float 1D 0 0 0 1 Unknown
  637. %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
  638. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_14 UniformConstant
  639. %18 = OpTypeSampler
  640. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  641. %g_sSamp = OpVariable %_ptr_UniformConstant_18 UniformConstant
  642. %22 = OpTypeSampledImage %14
  643. %float_0_100000001 = OpConstant %float 0.100000001
  644. %mat4v4float = OpTypeMatrix %v4float 4
  645. %cbuff = OpTypeStruct %mat4v4float
  646. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  647. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  648. %int = OpTypeInt 32 1
  649. %int_0 = OpConstant %int 0
  650. %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
  651. %_ptr_Output_v4float = OpTypePointer Output %v4float
  652. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  653. %half = OpTypeFloat 16
  654. %v4half = OpTypeVector %half 4
  655. %mat4v4half = OpTypeMatrix %v4half 4
  656. )";
  657. const std::string func_before =
  658. R"(%main = OpFunction %void None %3
  659. %5 = OpLabel
  660. %53 = OpLoad %14 %g_tTex1df4
  661. %54 = OpLoad %18 %g_sSamp
  662. %55 = OpSampledImage %22 %53 %54
  663. %56 = OpImageSampleImplicitLod %v4float %55 %float_0_100000001
  664. %57 = OpAccessChain %_ptr_Uniform_mat4v4float %_ %int_0
  665. %58 = OpLoad %mat4v4float %57
  666. %60 = OpMatrixTimesVector %v4float %58 %56
  667. OpStore %_entryPointOutput_Color %60
  668. OpReturn
  669. OpFunctionEnd
  670. )";
  671. const std::string func_after =
  672. R"(%main = OpFunction %void None %3
  673. %5 = OpLabel
  674. %53 = OpLoad %14 %g_tTex1df4
  675. %54 = OpLoad %18 %g_sSamp
  676. %55 = OpSampledImage %22 %53 %54
  677. %56 = OpImageSampleImplicitLod %v4float %55 %float_0_100000001
  678. %57 = OpAccessChain %_ptr_Uniform_mat4v4float %_ %int_0
  679. %58 = OpLoad %mat4v4float %57
  680. %67 = OpCompositeExtract %v4float %58 0
  681. %68 = OpFConvert %v4half %67
  682. %69 = OpCompositeExtract %v4float %58 1
  683. %70 = OpFConvert %v4half %69
  684. %71 = OpCompositeExtract %v4float %58 2
  685. %72 = OpFConvert %v4half %71
  686. %73 = OpCompositeExtract %v4float %58 3
  687. %74 = OpFConvert %v4half %73
  688. %75 = OpCompositeConstruct %mat4v4half %68 %70 %72 %74
  689. %64 = OpCopyObject %mat4v4float %58
  690. %65 = OpFConvert %v4half %56
  691. %60 = OpMatrixTimesVector %v4half %75 %65
  692. %66 = OpFConvert %v4float %60
  693. OpStore %_entryPointOutput_Color %66
  694. OpReturn
  695. OpFunctionEnd
  696. )";
  697. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  698. SinglePassRunAndCheck<ConvertToHalfPass>(defs_before + func_before,
  699. defs_after + func_after, true, true);
  700. }
  701. TEST_F(ConvertToHalfTest, ConvertToHalfWithPhi) {
  702. // The resulting SPIR-V was processed with --relax-float-ops.
  703. //
  704. // clang-format off
  705. //
  706. // SamplerState g_sSamp : register(s0);
  707. // uniform Texture1D <float4> g_tTex1df4 : register(t0);
  708. //
  709. // struct PS_OUTPUT
  710. // {
  711. // float4 Color : SV_Target0;
  712. // };
  713. //
  714. // cbuffer cbuff{
  715. // bool b;
  716. // float4x4 M;
  717. // }
  718. //
  719. // PS_OUTPUT main()
  720. // {
  721. // PS_OUTPUT psout;
  722. // float4 t;
  723. //
  724. // if (b)
  725. // t = g_tTex1df4.Sample(g_sSamp, 0.1);
  726. // else
  727. // t = float4(0.0, 0.0, 0.0, 0.0);
  728. //
  729. // float4 t2 = t * 2.0;
  730. // psout.Color = t2;
  731. // return psout;
  732. // }
  733. //
  734. // clang-format on
  735. const std::string defs_before =
  736. R"(OpCapability Shader
  737. OpCapability Sampled1D
  738. %1 = OpExtInstImport "GLSL.std.450"
  739. OpMemoryModel Logical GLSL450
  740. OpEntryPoint Fragment %main "main" %_entryPointOutput_Color
  741. OpExecutionMode %main OriginUpperLeft
  742. OpSource HLSL 500
  743. OpName %main "main"
  744. OpName %cbuff "cbuff"
  745. OpMemberName %cbuff 0 "b"
  746. OpMemberName %cbuff 1 "M"
  747. OpName %_ ""
  748. OpName %g_tTex1df4 "g_tTex1df4"
  749. OpName %g_sSamp "g_sSamp"
  750. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  751. OpMemberDecorate %cbuff 0 Offset 0
  752. OpMemberDecorate %cbuff 1 RowMajor
  753. OpMemberDecorate %cbuff 1 Offset 16
  754. OpMemberDecorate %cbuff 1 MatrixStride 16
  755. OpDecorate %cbuff Block
  756. OpDecorate %_ DescriptorSet 0
  757. OpDecorate %_ Binding 1
  758. OpDecorate %g_tTex1df4 DescriptorSet 0
  759. OpDecorate %g_tTex1df4 Binding 0
  760. OpDecorate %g_sSamp DescriptorSet 0
  761. OpDecorate %g_sSamp Binding 0
  762. OpDecorate %_entryPointOutput_Color Location 0
  763. OpDecorate %72 RelaxedPrecision
  764. OpDecorate %85 RelaxedPrecision
  765. OpDecorate %74 RelaxedPrecision
  766. %void = OpTypeVoid
  767. %3 = OpTypeFunction %void
  768. %float = OpTypeFloat 32
  769. %v4float = OpTypeVector %float 4
  770. %uint = OpTypeInt 32 0
  771. %mat4v4float = OpTypeMatrix %v4float 4
  772. %cbuff = OpTypeStruct %uint %mat4v4float
  773. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  774. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  775. %int = OpTypeInt 32 1
  776. %int_0 = OpConstant %int 0
  777. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  778. %bool = OpTypeBool
  779. %uint_0 = OpConstant %uint 0
  780. %29 = OpTypeImage %float 1D 0 0 0 1 Unknown
  781. %_ptr_UniformConstant_29 = OpTypePointer UniformConstant %29
  782. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_29 UniformConstant
  783. %33 = OpTypeSampler
  784. %_ptr_UniformConstant_33 = OpTypePointer UniformConstant %33
  785. %g_sSamp = OpVariable %_ptr_UniformConstant_33 UniformConstant
  786. %37 = OpTypeSampledImage %29
  787. %float_0_100000001 = OpConstant %float 0.100000001
  788. %float_0 = OpConstant %float 0
  789. %43 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  790. %float_2 = OpConstant %float 2
  791. %_ptr_Output_v4float = OpTypePointer Output %v4float
  792. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  793. )";
  794. const std::string defs_after =
  795. R"(OpCapability Shader
  796. OpCapability Sampled1D
  797. OpCapability Float16
  798. %1 = OpExtInstImport "GLSL.std.450"
  799. OpMemoryModel Logical GLSL450
  800. OpEntryPoint Fragment %main "main" %_entryPointOutput_Color
  801. OpExecutionMode %main OriginUpperLeft
  802. OpSource HLSL 500
  803. OpName %main "main"
  804. OpName %cbuff "cbuff"
  805. OpMemberName %cbuff 0 "b"
  806. OpMemberName %cbuff 1 "M"
  807. OpName %_ ""
  808. OpName %g_tTex1df4 "g_tTex1df4"
  809. OpName %g_sSamp "g_sSamp"
  810. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  811. OpMemberDecorate %cbuff 0 Offset 0
  812. OpMemberDecorate %cbuff 1 RowMajor
  813. OpMemberDecorate %cbuff 1 Offset 16
  814. OpMemberDecorate %cbuff 1 MatrixStride 16
  815. OpDecorate %cbuff Block
  816. OpDecorate %_ DescriptorSet 0
  817. OpDecorate %_ Binding 1
  818. OpDecorate %g_tTex1df4 DescriptorSet 0
  819. OpDecorate %g_tTex1df4 Binding 0
  820. OpDecorate %g_sSamp DescriptorSet 0
  821. OpDecorate %g_sSamp Binding 0
  822. OpDecorate %_entryPointOutput_Color Location 0
  823. %void = OpTypeVoid
  824. %3 = OpTypeFunction %void
  825. %float = OpTypeFloat 32
  826. %v4float = OpTypeVector %float 4
  827. %uint = OpTypeInt 32 0
  828. %mat4v4float = OpTypeMatrix %v4float 4
  829. %cbuff = OpTypeStruct %uint %mat4v4float
  830. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  831. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  832. %int = OpTypeInt 32 1
  833. %int_0 = OpConstant %int 0
  834. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  835. %bool = OpTypeBool
  836. %uint_0 = OpConstant %uint 0
  837. %29 = OpTypeImage %float 1D 0 0 0 1 Unknown
  838. %_ptr_UniformConstant_29 = OpTypePointer UniformConstant %29
  839. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_29 UniformConstant
  840. %33 = OpTypeSampler
  841. %_ptr_UniformConstant_33 = OpTypePointer UniformConstant %33
  842. %g_sSamp = OpVariable %_ptr_UniformConstant_33 UniformConstant
  843. %37 = OpTypeSampledImage %29
  844. %float_0_100000001 = OpConstant %float 0.100000001
  845. %float_0 = OpConstant %float 0
  846. %43 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  847. %float_2 = OpConstant %float 2
  848. %_ptr_Output_v4float = OpTypePointer Output %v4float
  849. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  850. %half = OpTypeFloat 16
  851. %v4half = OpTypeVector %half 4
  852. )";
  853. const std::string func_before =
  854. R"(%main = OpFunction %void None %3
  855. %5 = OpLabel
  856. %63 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  857. %64 = OpLoad %uint %63
  858. %65 = OpINotEqual %bool %64 %uint_0
  859. OpSelectionMerge %66 None
  860. OpBranchConditional %65 %67 %68
  861. %67 = OpLabel
  862. %69 = OpLoad %29 %g_tTex1df4
  863. %70 = OpLoad %33 %g_sSamp
  864. %71 = OpSampledImage %37 %69 %70
  865. %72 = OpImageSampleImplicitLod %v4float %71 %float_0_100000001
  866. OpBranch %66
  867. %68 = OpLabel
  868. OpBranch %66
  869. %66 = OpLabel
  870. %85 = OpPhi %v4float %72 %67 %43 %68
  871. %74 = OpVectorTimesScalar %v4float %85 %float_2
  872. OpStore %_entryPointOutput_Color %74
  873. OpReturn
  874. OpFunctionEnd
  875. )";
  876. const std::string func_after =
  877. R"(%main = OpFunction %void None %3
  878. %5 = OpLabel
  879. %63 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  880. %64 = OpLoad %uint %63
  881. %65 = OpINotEqual %bool %64 %uint_0
  882. OpSelectionMerge %66 None
  883. OpBranchConditional %65 %67 %68
  884. %67 = OpLabel
  885. %69 = OpLoad %29 %g_tTex1df4
  886. %70 = OpLoad %33 %g_sSamp
  887. %71 = OpSampledImage %37 %69 %70
  888. %72 = OpImageSampleImplicitLod %v4float %71 %float_0_100000001
  889. %88 = OpFConvert %v4half %72
  890. OpBranch %66
  891. %68 = OpLabel
  892. %89 = OpFConvert %v4half %43
  893. OpBranch %66
  894. %66 = OpLabel
  895. %85 = OpPhi %v4half %88 %67 %89 %68
  896. %90 = OpFConvert %half %float_2
  897. %74 = OpVectorTimesScalar %v4half %85 %90
  898. %91 = OpFConvert %v4float %74
  899. OpStore %_entryPointOutput_Color %91
  900. OpReturn
  901. OpFunctionEnd
  902. )";
  903. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  904. SinglePassRunAndCheck<ConvertToHalfPass>(defs_before + func_before,
  905. defs_after + func_after, true, true);
  906. }
  907. TEST_F(ConvertToHalfTest, ConvertToHalfWithLoopAndFConvert) {
  908. // The resulting SPIR-V was processed with --relax-float-ops.
  909. //
  910. // The loop causes an FConvert to be generated at the bottom of the loop
  911. // for the Phi. The FConvert is later processed and turned into a (dead)
  912. // copy.
  913. //
  914. // clang-format off
  915. //
  916. // struct PS_OUTPUT
  917. // {
  918. // float4 Color : SV_Target0;
  919. // };
  920. //
  921. // cbuffer cbuff{
  922. // float4 a[10];
  923. // }
  924. //
  925. // PS_OUTPUT main()
  926. // {
  927. // PS_OUTPUT psout;
  928. // float4 t = 0.0;;
  929. //
  930. // for (int i = 0; i<10; ++i)
  931. // t = t + a[i];
  932. //
  933. // float4 t2 = t / 10.0;
  934. // psout.Color = t2;
  935. // return psout;
  936. // }
  937. //
  938. // clang-format on
  939. const std::string defs_before =
  940. R"(OpCapability Shader
  941. %1 = OpExtInstImport "GLSL.std.450"
  942. OpMemoryModel Logical GLSL450
  943. OpEntryPoint Fragment %main "main" %_entryPointOutput_Color
  944. OpExecutionMode %main OriginUpperLeft
  945. OpSource HLSL 500
  946. OpName %main "main"
  947. OpName %cbuff "cbuff"
  948. OpMemberName %cbuff 0 "a"
  949. OpName %_ ""
  950. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  951. OpDecorate %_arr_v4float_uint_10 ArrayStride 16
  952. OpMemberDecorate %cbuff 0 Offset 0
  953. OpDecorate %cbuff Block
  954. OpDecorate %_ DescriptorSet 0
  955. OpDecorate %_ Binding 0
  956. OpDecorate %_entryPointOutput_Color Location 0
  957. OpDecorate %96 RelaxedPrecision
  958. OpDecorate %81 RelaxedPrecision
  959. OpDecorate %75 RelaxedPrecision
  960. OpDecorate %76 RelaxedPrecision
  961. %void = OpTypeVoid
  962. %3 = OpTypeFunction %void
  963. %float = OpTypeFloat 32
  964. %v4float = OpTypeVector %float 4
  965. %float_0 = OpConstant %float 0
  966. %15 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  967. %int = OpTypeInt 32 1
  968. %int_0 = OpConstant %int 0
  969. %int_10 = OpConstant %int 10
  970. %bool = OpTypeBool
  971. %uint = OpTypeInt 32 0
  972. %uint_10 = OpConstant %uint 10
  973. %_arr_v4float_uint_10 = OpTypeArray %v4float %uint_10
  974. %cbuff = OpTypeStruct %_arr_v4float_uint_10
  975. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  976. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  977. %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
  978. %int_1 = OpConstant %int 1
  979. %_ptr_Output_v4float = OpTypePointer Output %v4float
  980. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  981. %float_0_100000001 = OpConstant %float 0.100000001
  982. %94 = OpConstantComposite %v4float %float_0_100000001 %float_0_100000001 %float_0_100000001 %float_0_100000001
  983. )";
  984. const std::string defs_after =
  985. R"(OpCapability Shader
  986. OpCapability Float16
  987. %1 = OpExtInstImport "GLSL.std.450"
  988. OpMemoryModel Logical GLSL450
  989. OpEntryPoint Fragment %main "main" %_entryPointOutput_Color
  990. OpExecutionMode %main OriginUpperLeft
  991. OpSource HLSL 500
  992. OpName %main "main"
  993. OpName %cbuff "cbuff"
  994. OpMemberName %cbuff 0 "a"
  995. OpName %_ ""
  996. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  997. OpDecorate %_arr_v4float_uint_10 ArrayStride 16
  998. OpMemberDecorate %cbuff 0 Offset 0
  999. OpDecorate %cbuff Block
  1000. OpDecorate %_ DescriptorSet 0
  1001. OpDecorate %_ Binding 0
  1002. OpDecorate %_entryPointOutput_Color Location 0
  1003. %void = OpTypeVoid
  1004. %3 = OpTypeFunction %void
  1005. %float = OpTypeFloat 32
  1006. %v4float = OpTypeVector %float 4
  1007. %float_0 = OpConstant %float 0
  1008. %15 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  1009. %int = OpTypeInt 32 1
  1010. %int_0 = OpConstant %int 0
  1011. %int_10 = OpConstant %int 10
  1012. %bool = OpTypeBool
  1013. %uint = OpTypeInt 32 0
  1014. %uint_10 = OpConstant %uint 10
  1015. %_arr_v4float_uint_10 = OpTypeArray %v4float %uint_10
  1016. %cbuff = OpTypeStruct %_arr_v4float_uint_10
  1017. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  1018. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  1019. %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
  1020. %int_1 = OpConstant %int 1
  1021. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1022. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  1023. %float_0_100000001 = OpConstant %float 0.100000001
  1024. %94 = OpConstantComposite %v4float %float_0_100000001 %float_0_100000001 %float_0_100000001 %float_0_100000001
  1025. %half = OpTypeFloat 16
  1026. %v4half = OpTypeVector %half 4
  1027. )";
  1028. const std::string func_before =
  1029. R"(%main = OpFunction %void None %3
  1030. %5 = OpLabel
  1031. OpBranch %65
  1032. %65 = OpLabel
  1033. %96 = OpPhi %v4float %15 %5 %76 %71
  1034. %95 = OpPhi %int %int_0 %5 %78 %71
  1035. %70 = OpSLessThan %bool %95 %int_10
  1036. OpLoopMerge %66 %71 None
  1037. OpBranchConditional %70 %71 %66
  1038. %71 = OpLabel
  1039. %74 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0 %95
  1040. %75 = OpLoad %v4float %74
  1041. %76 = OpFAdd %v4float %96 %75
  1042. %78 = OpIAdd %int %95 %int_1
  1043. OpBranch %65
  1044. %66 = OpLabel
  1045. %81 = OpFMul %v4float %96 %94
  1046. OpStore %_entryPointOutput_Color %81
  1047. OpReturn
  1048. OpFunctionEnd
  1049. )";
  1050. const std::string func_after =
  1051. R"(%main = OpFunction %void None %3
  1052. %5 = OpLabel
  1053. %99 = OpFConvert %v4half %15
  1054. OpBranch %65
  1055. %65 = OpLabel
  1056. %96 = OpPhi %v4half %99 %5 %100 %71
  1057. %95 = OpPhi %int %int_0 %5 %78 %71
  1058. %70 = OpSLessThan %bool %95 %int_10
  1059. OpLoopMerge %66 %71 None
  1060. OpBranchConditional %70 %71 %66
  1061. %71 = OpLabel
  1062. %74 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0 %95
  1063. %75 = OpLoad %v4float %74
  1064. %103 = OpFConvert %v4half %75
  1065. %76 = OpFAdd %v4half %96 %103
  1066. %78 = OpIAdd %int %95 %int_1
  1067. %100 = OpCopyObject %v4half %76
  1068. OpBranch %65
  1069. %66 = OpLabel
  1070. %101 = OpFConvert %v4half %94
  1071. %81 = OpFMul %v4half %96 %101
  1072. %102 = OpFConvert %v4float %81
  1073. OpStore %_entryPointOutput_Color %102
  1074. OpReturn
  1075. OpFunctionEnd
  1076. )";
  1077. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1078. SinglePassRunAndCheck<ConvertToHalfPass>(defs_before + func_before,
  1079. defs_after + func_after, true, true);
  1080. }
  1081. TEST_F(ConvertToHalfTest, ConvertToHalfWithExtracts) {
  1082. // The resulting SPIR-V was processed with --relax-float-ops.
  1083. //
  1084. // The extra converts in the func_after can be DCE'd.
  1085. //
  1086. // clang-format off
  1087. //
  1088. // SamplerState g_sSamp : register(s0);
  1089. // uniform Texture1D <float4> g_tTex1df4 : register(t0);
  1090. //
  1091. // struct PS_INPUT
  1092. // {
  1093. // float Tex0 : TEXCOORD0;
  1094. // };
  1095. //
  1096. // struct PS_OUTPUT
  1097. // {
  1098. // float4 Color : SV_Target0;
  1099. // };
  1100. //
  1101. // cbuffer cbuff{
  1102. // float c;
  1103. // }
  1104. //
  1105. // PS_OUTPUT main(PS_INPUT i)
  1106. // {
  1107. // PS_OUTPUT psout;
  1108. // float4 tx = g_tTex1df4.Sample(g_sSamp, i.Tex0);
  1109. // float4 t = float4(tx.y, tx.z, tx.x, tx.w) * c;
  1110. // psout.Color = t;
  1111. // return psout;
  1112. // }
  1113. //
  1114. // clang-format on
  1115. const std::string defs_before =
  1116. R"(OpCapability Shader
  1117. OpCapability Sampled1D
  1118. %1 = OpExtInstImport "GLSL.std.450"
  1119. OpMemoryModel Logical GLSL450
  1120. OpEntryPoint Fragment %main "main" %i_Tex0 %_entryPointOutput_Color
  1121. OpExecutionMode %main OriginUpperLeft
  1122. OpSource HLSL 500
  1123. OpName %main "main"
  1124. OpName %g_tTex1df4 "g_tTex1df4"
  1125. OpName %g_sSamp "g_sSamp"
  1126. OpName %cbuff "cbuff"
  1127. OpMemberName %cbuff 0 "c"
  1128. OpName %_ ""
  1129. OpName %i_Tex0 "i.Tex0"
  1130. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  1131. OpDecorate %g_tTex1df4 DescriptorSet 0
  1132. OpDecorate %g_tTex1df4 Binding 0
  1133. OpDecorate %g_sSamp DescriptorSet 0
  1134. OpDecorate %g_sSamp Binding 0
  1135. OpMemberDecorate %cbuff 0 Offset 0
  1136. OpDecorate %cbuff Block
  1137. OpDecorate %_ DescriptorSet 0
  1138. OpDecorate %_ Binding 1
  1139. OpDecorate %i_Tex0 Location 0
  1140. OpDecorate %_entryPointOutput_Color Location 0
  1141. OpDecorate %65 RelaxedPrecision
  1142. OpDecorate %82 RelaxedPrecision
  1143. OpDecorate %84 RelaxedPrecision
  1144. OpDecorate %86 RelaxedPrecision
  1145. OpDecorate %88 RelaxedPrecision
  1146. OpDecorate %90 RelaxedPrecision
  1147. OpDecorate %91 RelaxedPrecision
  1148. OpDecorate %93 RelaxedPrecision
  1149. OpDecorate %94 RelaxedPrecision
  1150. %void = OpTypeVoid
  1151. %3 = OpTypeFunction %void
  1152. %float = OpTypeFloat 32
  1153. %v4float = OpTypeVector %float 4
  1154. %17 = OpTypeImage %float 1D 0 0 0 1 Unknown
  1155. %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
  1156. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_17 UniformConstant
  1157. %21 = OpTypeSampler
  1158. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  1159. %g_sSamp = OpVariable %_ptr_UniformConstant_21 UniformConstant
  1160. %25 = OpTypeSampledImage %17
  1161. %int = OpTypeInt 32 1
  1162. %int_0 = OpConstant %int 0
  1163. %cbuff = OpTypeStruct %float
  1164. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  1165. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  1166. %_ptr_Uniform_float = OpTypePointer Uniform %float
  1167. %_ptr_Input_float = OpTypePointer Input %float
  1168. %i_Tex0 = OpVariable %_ptr_Input_float Input
  1169. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1170. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  1171. )";
  1172. const std::string defs_after =
  1173. R"(OpCapability Shader
  1174. OpCapability Sampled1D
  1175. OpCapability Float16
  1176. %1 = OpExtInstImport "GLSL.std.450"
  1177. OpMemoryModel Logical GLSL450
  1178. OpEntryPoint Fragment %main "main" %i_Tex0 %_entryPointOutput_Color
  1179. OpExecutionMode %main OriginUpperLeft
  1180. OpSource HLSL 500
  1181. OpName %main "main"
  1182. OpName %g_tTex1df4 "g_tTex1df4"
  1183. OpName %g_sSamp "g_sSamp"
  1184. OpName %cbuff "cbuff"
  1185. OpMemberName %cbuff 0 "c"
  1186. OpName %_ ""
  1187. OpName %i_Tex0 "i.Tex0"
  1188. OpName %_entryPointOutput_Color "@entryPointOutput.Color"
  1189. OpDecorate %g_tTex1df4 DescriptorSet 0
  1190. OpDecorate %g_tTex1df4 Binding 0
  1191. OpDecorate %g_sSamp DescriptorSet 0
  1192. OpDecorate %g_sSamp Binding 0
  1193. OpMemberDecorate %cbuff 0 Offset 0
  1194. OpDecorate %cbuff Block
  1195. OpDecorate %_ DescriptorSet 0
  1196. OpDecorate %_ Binding 1
  1197. OpDecorate %i_Tex0 Location 0
  1198. OpDecorate %_entryPointOutput_Color Location 0
  1199. %void = OpTypeVoid
  1200. %3 = OpTypeFunction %void
  1201. %float = OpTypeFloat 32
  1202. %v4float = OpTypeVector %float 4
  1203. %17 = OpTypeImage %float 1D 0 0 0 1 Unknown
  1204. %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
  1205. %g_tTex1df4 = OpVariable %_ptr_UniformConstant_17 UniformConstant
  1206. %21 = OpTypeSampler
  1207. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  1208. %g_sSamp = OpVariable %_ptr_UniformConstant_21 UniformConstant
  1209. %25 = OpTypeSampledImage %17
  1210. %int = OpTypeInt 32 1
  1211. %int_0 = OpConstant %int 0
  1212. %cbuff = OpTypeStruct %float
  1213. %_ptr_Uniform_cbuff = OpTypePointer Uniform %cbuff
  1214. %_ = OpVariable %_ptr_Uniform_cbuff Uniform
  1215. %_ptr_Uniform_float = OpTypePointer Uniform %float
  1216. %_ptr_Input_float = OpTypePointer Input %float
  1217. %i_Tex0 = OpVariable %_ptr_Input_float Input
  1218. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1219. %_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
  1220. %half = OpTypeFloat 16
  1221. %v4half = OpTypeVector %half 4
  1222. )";
  1223. const std::string func_before =
  1224. R"(%main = OpFunction %void None %3
  1225. %5 = OpLabel
  1226. %65 = OpLoad %float %i_Tex0
  1227. %77 = OpLoad %17 %g_tTex1df4
  1228. %78 = OpLoad %21 %g_sSamp
  1229. %79 = OpSampledImage %25 %77 %78
  1230. %82 = OpImageSampleImplicitLod %v4float %79 %65
  1231. %84 = OpCompositeExtract %float %82 1
  1232. %86 = OpCompositeExtract %float %82 2
  1233. %88 = OpCompositeExtract %float %82 0
  1234. %90 = OpCompositeExtract %float %82 3
  1235. %91 = OpCompositeConstruct %v4float %84 %86 %88 %90
  1236. %92 = OpAccessChain %_ptr_Uniform_float %_ %int_0
  1237. %93 = OpLoad %float %92
  1238. %94 = OpVectorTimesScalar %v4float %91 %93
  1239. OpStore %_entryPointOutput_Color %94
  1240. OpReturn
  1241. OpFunctionEnd
  1242. )";
  1243. const std::string func_after =
  1244. R"(%main = OpFunction %void None %3
  1245. %5 = OpLabel
  1246. %65 = OpLoad %float %i_Tex0
  1247. %77 = OpLoad %17 %g_tTex1df4
  1248. %78 = OpLoad %21 %g_sSamp
  1249. %79 = OpSampledImage %25 %77 %78
  1250. %82 = OpImageSampleImplicitLod %v4float %79 %65
  1251. %97 = OpFConvert %v4half %82
  1252. %84 = OpCompositeExtract %half %97 1
  1253. %98 = OpFConvert %v4half %82
  1254. %86 = OpCompositeExtract %half %98 2
  1255. %99 = OpFConvert %v4half %82
  1256. %88 = OpCompositeExtract %half %99 0
  1257. %100 = OpFConvert %v4half %82
  1258. %90 = OpCompositeExtract %half %100 3
  1259. %91 = OpCompositeConstruct %v4half %84 %86 %88 %90
  1260. %92 = OpAccessChain %_ptr_Uniform_float %_ %int_0
  1261. %93 = OpLoad %float %92
  1262. %101 = OpFConvert %half %93
  1263. %94 = OpVectorTimesScalar %v4half %91 %101
  1264. %102 = OpFConvert %v4float %94
  1265. OpStore %_entryPointOutput_Color %102
  1266. OpReturn
  1267. OpFunctionEnd
  1268. )";
  1269. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1270. SinglePassRunAndCheck<ConvertToHalfPass>(defs_before + func_before,
  1271. defs_after + func_after, true, true);
  1272. }
  1273. TEST_F(ConvertToHalfTest, ConvertToHalfWithClosure) {
  1274. // Include as many contiguous composite instructions as possible into
  1275. // half-precision computations
  1276. //
  1277. // Compiled with glslang -V -Os
  1278. //
  1279. // clang-format off
  1280. //
  1281. // #version 410 core
  1282. //
  1283. // precision mediump float;
  1284. //
  1285. // layout(location = 1) in vec3 foo;
  1286. // layout(location = 2) in mat2 bar;
  1287. // layout(location = 1) out vec3 res;
  1288. //
  1289. // vec3 func(vec3 tap, mat2 M) {
  1290. // return vec3(M * tap.xy, 1.0);
  1291. // }
  1292. //
  1293. // void main() {
  1294. // res = func(foo, bar);
  1295. // }
  1296. //
  1297. // clang-format on
  1298. const std::string defs =
  1299. R"(OpCapability Shader
  1300. ; CHECK: OpCapability Float16
  1301. %1 = OpExtInstImport "GLSL.std.450"
  1302. OpMemoryModel Logical GLSL450
  1303. OpEntryPoint Fragment %main "main" %res %foo %bar
  1304. OpExecutionMode %main OriginUpperLeft
  1305. OpSource GLSL 410
  1306. OpName %main "main"
  1307. OpName %res "res"
  1308. OpName %foo "foo"
  1309. OpName %bar "bar"
  1310. OpDecorate %res RelaxedPrecision
  1311. ; CHECK-NOT: OpDecorate %res RelaxedPrecision
  1312. OpDecorate %res Location 1
  1313. OpDecorate %foo RelaxedPrecision
  1314. ; CHECK-NOT: OpDecorate %foo RelaxedPrecision
  1315. OpDecorate %foo Location 1
  1316. OpDecorate %bar RelaxedPrecision
  1317. ; CHECK-NOT: OpDecorate %bar RelaxedPrecision
  1318. OpDecorate %bar Location 2
  1319. OpDecorate %34 RelaxedPrecision
  1320. OpDecorate %36 RelaxedPrecision
  1321. OpDecorate %41 RelaxedPrecision
  1322. OpDecorate %42 RelaxedPrecision
  1323. ; CHECK-NOT: OpDecorate %34 RelaxedPrecision
  1324. ; CHECK-NOT: OpDecorate %36 RelaxedPrecision
  1325. ; CHECK-NOT: OpDecorate %41 RelaxedPrecision
  1326. ; CHECK-NOT: OpDecorate %42 RelaxedPrecision
  1327. %void = OpTypeVoid
  1328. %3 = OpTypeFunction %void
  1329. %float = OpTypeFloat 32
  1330. %v3float = OpTypeVector %float 3
  1331. %v2float = OpTypeVector %float 2
  1332. %mat2v2float = OpTypeMatrix %v2float 2
  1333. %float_1 = OpConstant %float 1
  1334. %_ptr_Output_v3float = OpTypePointer Output %v3float
  1335. %res = OpVariable %_ptr_Output_v3float Output
  1336. %_ptr_Input_v3float = OpTypePointer Input %v3float
  1337. %foo = OpVariable %_ptr_Input_v3float Input
  1338. %_ptr_Input_mat2v2float = OpTypePointer Input %mat2v2float
  1339. %bar = OpVariable %_ptr_Input_mat2v2float Input
  1340. )";
  1341. const std::string func =
  1342. R"(%main = OpFunction %void None %3
  1343. %5 = OpLabel
  1344. %34 = OpLoad %v3float %foo
  1345. %36 = OpLoad %mat2v2float %bar
  1346. ; CHECK: %48 = OpFConvert %v3half %34
  1347. ; CHECK: %49 = OpFConvert %v3half %34
  1348. %41 = OpVectorShuffle %v2float %34 %34 0 1
  1349. ; CHECK-NOT: %41 = OpVectorShuffle %v2float %34 %34 0 1
  1350. ; CHECK: %41 = OpVectorShuffle %v2half %48 %49 0 1
  1351. %42 = OpMatrixTimesVector %v2float %36 %41
  1352. ; CHECK-NOT: %42 = OpMatrixTimesVector %v2float %36 %41
  1353. ; CHECK: %55 = OpCompositeExtract %v2float %36 0
  1354. ; CHECK: %56 = OpFConvert %v2half %55
  1355. ; CHECK: %57 = OpCompositeExtract %v2float %36 1
  1356. ; CHECK: %58 = OpFConvert %v2half %57
  1357. ; CHECK: %59 = OpCompositeConstruct %mat2v2half %56 %58
  1358. ; CHECK: %52 = OpCopyObject %mat2v2float %36
  1359. ; CHECK: %42 = OpMatrixTimesVector %v2half %59 %41
  1360. %43 = OpCompositeExtract %float %42 0
  1361. %44 = OpCompositeExtract %float %42 1
  1362. ; CHECK-NOT: %43 = OpCompositeExtract %float %42 0
  1363. ; CHECK-NOT: %44 = OpCompositeExtract %float %42 1
  1364. ; CHECK: %43 = OpCompositeExtract %half %42 0
  1365. ; CHECK: %44 = OpCompositeExtract %half %42 1
  1366. %45 = OpCompositeConstruct %v3float %43 %44 %float_1
  1367. ; CHECK-NOT: %45 = OpCompositeConstruct %v3float %43 %44 %float_1
  1368. ; CHECK: %53 = OpFConvert %float %43
  1369. ; CHECK: %54 = OpFConvert %float %44
  1370. ; CHECK: %45 = OpCompositeConstruct %v3float %53 %54 %float_1
  1371. OpStore %res %45
  1372. OpReturn
  1373. OpFunctionEnd
  1374. )";
  1375. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1376. SinglePassRunAndMatch<ConvertToHalfPass>(defs + func, true);
  1377. }
  1378. TEST_F(ConvertToHalfTest, RemoveRelaxDec) {
  1379. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/4117
  1380. // This test is a case where the relax precision decorations need to be
  1381. // removed, but the body of the function does not change because there are not
  1382. // arithmetic operations. So, there is not need for the Float16 capability.
  1383. const std::string test =
  1384. R"(
  1385. ; CHECK-NOT: OpCapability Float16
  1386. ; GLSL seems to generate this decoration on the load of a texture, which seems odd to me.
  1387. ; This pass does not currently remove it, and I'm not sure what we should do with it, so I will leave it.
  1388. ; CHECK: OpDecorate [[tex:%\w+]] RelaxedPrecision
  1389. ; CHECK-NOT: OpDecorate {{%\w+}} RelaxedPrecision
  1390. ; CHECK: OpLabel
  1391. ; CHECK: [[tex]] = OpLoad {{%\w+}} %sTexture
  1392. ; CHECK: [[coord:%\w+]] = OpLoad %v2float
  1393. ; CHECK: [[retval:%\w+]] = OpImageSampleImplicitLod %v4float {{%\w+}} [[coord]]
  1394. ; CHECK: OpStore %outFragColor [[retval]]
  1395. OpCapability Shader
  1396. %1 = OpExtInstImport "GLSL.std.450"
  1397. OpMemoryModel Logical GLSL450
  1398. OpEntryPoint Fragment %main "main" %outFragColor %v_texcoord
  1399. OpExecutionMode %main OriginUpperLeft
  1400. OpSource ESSL 310
  1401. OpName %main "main"
  1402. OpName %outFragColor "outFragColor"
  1403. OpName %sTexture "sTexture"
  1404. OpName %v_texcoord "v_texcoord"
  1405. OpDecorate %outFragColor RelaxedPrecision
  1406. OpDecorate %outFragColor Location 0
  1407. OpDecorate %sTexture RelaxedPrecision
  1408. OpDecorate %sTexture DescriptorSet 0
  1409. OpDecorate %sTexture Binding 0
  1410. OpDecorate %14 RelaxedPrecision
  1411. OpDecorate %v_texcoord RelaxedPrecision
  1412. OpDecorate %v_texcoord Location 0
  1413. OpDecorate %18 RelaxedPrecision
  1414. OpDecorate %19 RelaxedPrecision
  1415. %void = OpTypeVoid
  1416. %3 = OpTypeFunction %void
  1417. %float = OpTypeFloat 32
  1418. %v4float = OpTypeVector %float 4
  1419. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1420. %outFragColor = OpVariable %_ptr_Output_v4float Output
  1421. %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
  1422. %11 = OpTypeSampledImage %10
  1423. %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
  1424. %sTexture = OpVariable %_ptr_UniformConstant_11 UniformConstant
  1425. %v2float = OpTypeVector %float 2
  1426. %_ptr_Input_v2float = OpTypePointer Input %v2float
  1427. %v_texcoord = OpVariable %_ptr_Input_v2float Input
  1428. %main = OpFunction %void None %3
  1429. %5 = OpLabel
  1430. %14 = OpLoad %11 %sTexture
  1431. %18 = OpLoad %v2float %v_texcoord
  1432. %19 = OpImageSampleImplicitLod %v4float %14 %18
  1433. OpStore %outFragColor %19
  1434. OpReturn
  1435. OpFunctionEnd
  1436. )";
  1437. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1438. auto result = SinglePassRunAndMatch<ConvertToHalfPass>(test, true);
  1439. EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
  1440. }
  1441. TEST_F(ConvertToHalfTest, HandleNonRelaxedPhi) {
  1442. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/4452
  1443. // This test is a case with a non-relaxed phi with a relaxed operand.
  1444. // A convert must be inserted at the end of the block associated with
  1445. // the operand.
  1446. const std::string test =
  1447. R"(
  1448. ; CHECK: [[fcvt:%\w+]] = OpFConvert %v3float {{%\w+}}
  1449. ; CHECK-NEXT: OpSelectionMerge {{%\w+}} None
  1450. ; CHECK: {{%\w+}} = OpPhi %v3float [[fcvt]] {{%\w+}} {{%\w+}} {{%\w+}}
  1451. OpCapability Shader
  1452. %1 = OpExtInstImport "GLSL.std.450"
  1453. OpMemoryModel Logical GLSL450
  1454. OpEntryPoint Fragment %main "main" %output_color
  1455. OpExecutionMode %main OriginUpperLeft
  1456. OpSource GLSL 450
  1457. OpName %main "main"
  1458. OpName %MaterialParams "MaterialParams"
  1459. OpMemberName %MaterialParams 0 "foo"
  1460. OpName %materialParams "materialParams"
  1461. OpName %output_color "output_color"
  1462. OpMemberDecorate %MaterialParams 0 Offset 0
  1463. OpDecorate %MaterialParams Block
  1464. OpDecorate %materialParams DescriptorSet 0
  1465. OpDecorate %materialParams Binding 5
  1466. OpDecorate %output_color Location 0
  1467. OpDecorate %57 RelaxedPrecision
  1468. %void = OpTypeVoid
  1469. %3 = OpTypeFunction %void
  1470. %float = OpTypeFloat 32
  1471. %v3float = OpTypeVector %float 3
  1472. %MaterialParams = OpTypeStruct %float
  1473. %_ptr_Uniform_MaterialParams = OpTypePointer Uniform %MaterialParams
  1474. %materialParams = OpVariable %_ptr_Uniform_MaterialParams Uniform
  1475. %int = OpTypeInt 32 1
  1476. %int_0 = OpConstant %int 0
  1477. %_ptr_Uniform_float = OpTypePointer Uniform %float
  1478. %float_0 = OpConstant %float 0
  1479. %bool = OpTypeBool
  1480. %v4float = OpTypeVector %float 4
  1481. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1482. %output_color = OpVariable %_ptr_Output_v4float Output
  1483. %uint = OpTypeInt 32 0
  1484. %uint_0 = OpConstant %uint 0
  1485. %_ptr_Output_float = OpTypePointer Output %float
  1486. %uint_1 = OpConstant %uint 1
  1487. %uint_2 = OpConstant %uint 2
  1488. %float_0_5 = OpConstant %float 0.5
  1489. %61 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
  1490. %main = OpFunction %void None %3
  1491. %5 = OpLabel
  1492. %55 = OpAccessChain %_ptr_Uniform_float %materialParams %int_0
  1493. %56 = OpLoad %float %55
  1494. %57 = OpCompositeConstruct %v3float %56 %56 %56
  1495. %31 = OpFOrdGreaterThan %bool %56 %float_0
  1496. OpSelectionMerge %33 None
  1497. OpBranchConditional %31 %32 %33
  1498. %32 = OpLabel
  1499. %37 = OpFMul %v3float %57 %61
  1500. OpBranch %33
  1501. %33 = OpLabel
  1502. %58 = OpPhi %v3float %57 %5 %37 %32
  1503. %45 = OpAccessChain %_ptr_Output_float %output_color %uint_0
  1504. %46 = OpCompositeExtract %float %58 0
  1505. OpStore %45 %46
  1506. %48 = OpAccessChain %_ptr_Output_float %output_color %uint_1
  1507. %49 = OpCompositeExtract %float %58 1
  1508. OpStore %48 %49
  1509. %51 = OpAccessChain %_ptr_Output_float %output_color %uint_2
  1510. %52 = OpCompositeExtract %float %58 2
  1511. OpStore %51 %52
  1512. OpReturn
  1513. OpFunctionEnd
  1514. )";
  1515. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1516. auto result = SinglePassRunAndMatch<ConvertToHalfPass>(test, true);
  1517. EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
  1518. }
  1519. TEST_F(ConvertToHalfTest, DoNotReplaceStructMember) {
  1520. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/4814
  1521. // This test is a case with a non-relaxed phi with a relaxed operand.
  1522. // A convert must be inserted at the end of the block associated with
  1523. // the operand.
  1524. const std::string test =
  1525. R"(OpCapability Shader
  1526. OpMemoryModel Logical GLSL450
  1527. OpEntryPoint Fragment %PSMain "PSMain" %out_var_SV_TARGET %MyConstants
  1528. OpExecutionMode %PSMain OriginUpperLeft
  1529. OpSource HLSL 600
  1530. OpName %type_ConstantBuffer_myStruct "type.ConstantBuffer.myStruct"
  1531. OpMemberName %type_ConstantBuffer_myStruct 0 "f"
  1532. OpName %MyConstants "MyConstants"
  1533. OpName %out_var_SV_TARGET "out.var.SV_TARGET"
  1534. OpName %PSMain "PSMain"
  1535. OpDecorate %out_var_SV_TARGET Location 0
  1536. OpDecorate %MyConstants DescriptorSet 1
  1537. OpDecorate %MyConstants Binding 2
  1538. OpMemberDecorate %type_ConstantBuffer_myStruct 0 Offset 0
  1539. OpDecorate %type_ConstantBuffer_myStruct Block
  1540. %float = OpTypeFloat 32
  1541. %type_ConstantBuffer_myStruct = OpTypeStruct %float
  1542. %_ptr_Uniform_type_ConstantBuffer_myStruct = OpTypePointer Uniform %type_ConstantBuffer_myStruct
  1543. %_ptr_Output_float = OpTypePointer Output %float
  1544. %void = OpTypeVoid
  1545. %9 = OpTypeFunction %void
  1546. %MyConstants = OpVariable %_ptr_Uniform_type_ConstantBuffer_myStruct Uniform
  1547. %out_var_SV_TARGET = OpVariable %_ptr_Output_float Output
  1548. %PSMain = OpFunction %void None %9
  1549. %10 = OpLabel
  1550. %11 = OpLoad %type_ConstantBuffer_myStruct %MyConstants
  1551. %12 = OpCompositeExtract %float %11 0
  1552. OpStore %out_var_SV_TARGET %12
  1553. OpReturn
  1554. OpFunctionEnd
  1555. )";
  1556. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1557. SinglePassRunAndCheck<ConvertToHalfPass>(test, test, true);
  1558. }
  1559. TEST_F(ConvertToHalfTest, PreserveImageOperandPrecision) {
  1560. // Ensure that a non-relaxed texture coordinate does not get relaxed nor
  1561. // converted to half precision if the image instruction is marked relaxed.
  1562. // Also ensure that a relaxed local variable does get converted to half
  1563. // precision before being passed to an image opeartor.
  1564. // #version 310 es
  1565. //
  1566. // precision mediump float;
  1567. //
  1568. // layout(location = 10) in highp vec4 vertex_uv01;
  1569. // layout(binding = 0, set = 3) uniform sampler2D materialParams_baseColorMap;
  1570. //
  1571. // layout(location = 0) out vec4 fragColor;
  1572. //
  1573. // void main() {
  1574. // vec4 uv = vec4(2.0);
  1575. // fragColor = texture(materialParams_baseColorMap, uv.xy);
  1576. // fragColor = texture(materialParams_baseColorMap, vertex_uv01.xy);
  1577. // }
  1578. const std::string test = R"(
  1579. OpCapability Shader
  1580. OpCapability Float16
  1581. %1 = OpExtInstImport "GLSL.std.450"
  1582. OpMemoryModel Logical GLSL450
  1583. OpEntryPoint Fragment %4 "main" %13 %25
  1584. OpExecutionMode %4 OriginUpperLeft
  1585. OpSource ESSL 310
  1586. OpDecorate %9 RelaxedPrecision
  1587. ;CHECK: OpDecorate [[uv:%\w+]] RelaxedPrecision
  1588. OpDecorate %13 Location 0
  1589. OpDecorate %17 DescriptorSet 3
  1590. OpDecorate %17 Binding 0
  1591. OpDecorate %18 RelaxedPrecision
  1592. OpDecorate %23 RelaxedPrecision
  1593. OpDecorate %25 Location 10
  1594. %2 = OpTypeVoid
  1595. %3 = OpTypeFunction %2
  1596. %6 = OpTypeFloat 32
  1597. ;CHECK: [[float32_t:%\w+]] = OpTypeFloat 32
  1598. %7 = OpTypeVector %6 4
  1599. ;CHECK: [[vec4_t:%\w+]] = OpTypeVector [[float32_t]] 4
  1600. %8 = OpTypePointer Function %7
  1601. %10 = OpConstant %6 2
  1602. %11 = OpConstantComposite %7 %10 %10 %10 %10
  1603. %12 = OpTypePointer Output %7
  1604. ;CHECK: [[output_ptr_t:%\w+]] = OpTypePointer Output [[vec4_t]]
  1605. %13 = OpVariable %12 Output
  1606. ;CHECK: [[output:%\w+]] = OpVariable [[output_ptr_t]] Output
  1607. %14 = OpTypeImage %6 2D 0 0 0 1 Unknown
  1608. %15 = OpTypeSampledImage %14
  1609. %16 = OpTypePointer UniformConstant %15
  1610. %17 = OpVariable %16 UniformConstant
  1611. %19 = OpTypeVector %6 2
  1612. ;CHECK: [[vec2_t:%\w+]] = OpTypeVector [[float32_t]] 2
  1613. %24 = OpTypePointer Input %7
  1614. ;CHECK: [[input_ptr_t:%\w+]] = OpTypePointer Input [[vec4_t]]
  1615. %25 = OpVariable %24 Input
  1616. %29 = OpTypeFloat 16
  1617. ;CHECK: [[float16_t:%\w+]] = OpTypeFloat 16
  1618. %30 = OpTypeVector %29 4
  1619. %33 = OpTypeVector %29 2
  1620. ;CHECK: [[vec2_16b_t:%\w+]] = OpTypeVector [[float16_t]] 2
  1621. %4 = OpFunction %2 None %3
  1622. %5 = OpLabel
  1623. ; The only Function storage variable is marked as relaxed
  1624. %9 = OpVariable %8 Function
  1625. ;CHECK: [[uv]] = OpVariable {{%\w+}} Function
  1626. OpStore %9 %11
  1627. %18 = OpLoad %15 %17
  1628. %20 = OpLoad %7 %9
  1629. %31 = OpFConvert %30 %20
  1630. %32 = OpFConvert %30 %20
  1631. ; The first sample op should get a 16b coordinate
  1632. %21 = OpVectorShuffle %33 %31 %32 0 1
  1633. ;CHECK: [[uv_16b:%\w+]] = OpVectorShuffle [[vec2_16b_t]]
  1634. %22 = OpImageSampleImplicitLod %7 %18 %21
  1635. ;CHECK: OpImageSampleImplicitLod [[vec4_t]] {{%\w+}} [[uv_16b]]
  1636. OpStore %13 %22
  1637. %23 = OpLoad %15 %17
  1638. %26 = OpLoad %7 %25
  1639. ; The second sample op should get a 32b coordinate
  1640. %27 = OpVectorShuffle %19 %26 %26 0 1
  1641. ;CHECK: [[uv_32b:%\w+]] = OpVectorShuffle [[vec2_t]]
  1642. %28 = OpImageSampleImplicitLod %7 %23 %27
  1643. ;CHECK: OpImageSampleImplicitLod [[vec4_t]] {{%\w+}} [[uv_32b]]
  1644. OpStore %13 %28
  1645. OpReturn
  1646. OpFunctionEnd
  1647. )";
  1648. SinglePassRunAndMatch<ConvertToHalfPass>(test, true);
  1649. }
  1650. TEST_F(ConvertToHalfTest, DontRelaxDecoratedOpCompositeExtract) {
  1651. // This test checks that a OpCompositeExtract with a Struct operand won't be
  1652. // relaxed, even if it is explicitly decorated with RelaxedPrecision.
  1653. const std::string test =
  1654. R"(OpCapability Shader
  1655. OpMemoryModel Logical GLSL450
  1656. OpEntryPoint Fragment %1 "main"
  1657. OpExecutionMode %1 OriginUpperLeft
  1658. OpDecorate %9 RelaxedPrecision
  1659. %void = OpTypeVoid
  1660. %3 = OpTypeFunction %void
  1661. %float = OpTypeFloat 32
  1662. %v4float = OpTypeVector %float 4
  1663. %_struct_6 = OpTypeStruct %v4float
  1664. %7 = OpUndef %_struct_6
  1665. %1 = OpFunction %void None %3
  1666. %8 = OpLabel
  1667. %9 = OpCompositeExtract %float %7 0 3
  1668. OpReturn
  1669. OpFunctionEnd
  1670. )";
  1671. const std::string expected =
  1672. R"(OpCapability Shader
  1673. OpMemoryModel Logical GLSL450
  1674. OpEntryPoint Fragment %1 "main"
  1675. OpExecutionMode %1 OriginUpperLeft
  1676. %void = OpTypeVoid
  1677. %3 = OpTypeFunction %void
  1678. %float = OpTypeFloat 32
  1679. %v4float = OpTypeVector %float 4
  1680. %_struct_6 = OpTypeStruct %v4float
  1681. %7 = OpUndef %_struct_6
  1682. %1 = OpFunction %void None %3
  1683. %8 = OpLabel
  1684. %9 = OpCompositeExtract %float %7 0 3
  1685. OpReturn
  1686. OpFunctionEnd
  1687. )";
  1688. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1689. SinglePassRunAndCheck<ConvertToHalfPass>(test, expected, true);
  1690. }
  1691. TEST_F(ConvertToHalfTest, DontRelaxOpCompositeExtract) {
  1692. // This test checks that a OpCompositeExtract with a Struct operand won't be
  1693. // relaxed, even if its result has no uses.
  1694. const std::string test =
  1695. R"(OpCapability Shader
  1696. OpMemoryModel Logical GLSL450
  1697. OpEntryPoint Fragment %1 "main"
  1698. OpExecutionMode %1 OriginUpperLeft
  1699. %void = OpTypeVoid
  1700. %3 = OpTypeFunction %void
  1701. %float = OpTypeFloat 32
  1702. %v4float = OpTypeVector %float 4
  1703. %_struct_6 = OpTypeStruct %v4float
  1704. %7 = OpUndef %_struct_6
  1705. %1 = OpFunction %void None %3
  1706. %8 = OpLabel
  1707. %9 = OpCompositeExtract %float %7 0 3
  1708. OpReturn
  1709. OpFunctionEnd
  1710. )";
  1711. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1712. SinglePassRunAndCheck<ConvertToHalfPass>(test, test, true);
  1713. }
  1714. } // namespace
  1715. } // namespace opt
  1716. } // namespace spvtools