val_memory_test.cpp 132 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186
  1. // Copyright (c) 2018 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Validation tests for memory/storage
  15. #include <string>
  16. #include <vector>
  17. #include "gmock/gmock.h"
  18. #include "test/unit_spirv.h"
  19. #include "test/val/val_code_generator.h"
  20. #include "test/val/val_fixtures.h"
  21. // For pretty-printing tuples with spv_target_env.
  22. std::ostream& operator<<(std::ostream& stream, spv_target_env target)
  23. {
  24. switch (target) {
  25. case SPV_ENV_UNIVERSAL_1_3: return stream << "SPV_ENV_UNIVERSAL_1_3";
  26. case SPV_ENV_UNIVERSAL_1_4: return stream << "SPV_ENV_UNIVERSAL_1_4";
  27. default: return stream << (unsigned)target;
  28. }
  29. }
  30. namespace spvtools {
  31. namespace val {
  32. namespace {
  33. using ::testing::Combine;
  34. using ::testing::Eq;
  35. using ::testing::HasSubstr;
  36. using ::testing::Values;
  37. using ValidateMemory = spvtest::ValidateBase<bool>;
  38. TEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceBad) {
  39. std::string spirv = R"(
  40. OpCapability Shader
  41. OpMemoryModel Logical GLSL450
  42. OpEntryPoint Fragment %func "func"
  43. OpExecutionMode %func OriginUpperLeft
  44. %float = OpTypeFloat 32
  45. %float_ptr = OpTypePointer UniformConstant %float
  46. %2 = OpVariable %float_ptr UniformConstant
  47. %void = OpTypeVoid
  48. %functy = OpTypeFunction %void
  49. %func = OpFunction %void None %functy
  50. %1 = OpLabel
  51. OpReturn
  52. OpFunctionEnd
  53. )";
  54. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  55. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  56. EXPECT_THAT(
  57. getDiagnosticString(),
  58. HasSubstr("From Vulkan spec, section 14.5.2:\n"
  59. "Variables identified with the UniformConstant storage class "
  60. "are used only as handles to refer to opaque resources. Such "
  61. "variables must be typed as OpTypeImage, OpTypeSampler, "
  62. "OpTypeSampledImage, OpTypeAccelerationStructureNV, "
  63. "OpTypeAccelerationStructureKHR, OpTypeRayQueryKHR, "
  64. "or an array of one of these types."));
  65. }
  66. TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceGood) {
  67. std::string spirv = R"(
  68. OpCapability Shader
  69. OpMemoryModel Logical GLSL450
  70. OpEntryPoint Fragment %func "func"
  71. OpExecutionMode %func OriginUpperLeft
  72. OpDecorate %2 DescriptorSet 0
  73. OpDecorate %2 Binding 0
  74. %sampler = OpTypeSampler
  75. %sampler_ptr = OpTypePointer UniformConstant %sampler
  76. %2 = OpVariable %sampler_ptr UniformConstant
  77. %void = OpTypeVoid
  78. %functy = OpTypeFunction %void
  79. %func = OpFunction %void None %functy
  80. %1 = OpLabel
  81. OpReturn
  82. OpFunctionEnd
  83. )";
  84. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  85. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  86. }
  87. TEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceArrayBad) {
  88. std::string spirv = R"(
  89. OpCapability Shader
  90. OpMemoryModel Logical GLSL450
  91. OpEntryPoint Fragment %func "func"
  92. OpExecutionMode %func OriginUpperLeft
  93. %float = OpTypeFloat 32
  94. %uint = OpTypeInt 32 0
  95. %array_size = OpConstant %uint 5
  96. %array = OpTypeArray %float %array_size
  97. %array_ptr = OpTypePointer UniformConstant %array
  98. %2 = OpVariable %array_ptr UniformConstant
  99. %void = OpTypeVoid
  100. %functy = OpTypeFunction %void
  101. %func = OpFunction %void None %functy
  102. %1 = OpLabel
  103. OpReturn
  104. OpFunctionEnd
  105. )";
  106. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  107. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  108. EXPECT_THAT(
  109. getDiagnosticString(),
  110. HasSubstr("From Vulkan spec, section 14.5.2:\n"
  111. "Variables identified with the UniformConstant storage class "
  112. "are used only as handles to refer to opaque resources. Such "
  113. "variables must be typed as OpTypeImage, OpTypeSampler, "
  114. "OpTypeSampledImage, OpTypeAccelerationStructureNV, "
  115. "OpTypeAccelerationStructureKHR, OpTypeRayQueryKHR, "
  116. "or an array of one of these types."));
  117. }
  118. TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceArrayGood) {
  119. std::string spirv = R"(
  120. OpCapability Shader
  121. OpMemoryModel Logical GLSL450
  122. OpEntryPoint Fragment %func "func"
  123. OpExecutionMode %func OriginUpperLeft
  124. OpDecorate %2 DescriptorSet 0
  125. OpDecorate %2 Binding 0
  126. %sampler = OpTypeSampler
  127. %uint = OpTypeInt 32 0
  128. %array_size = OpConstant %uint 5
  129. %array = OpTypeArray %sampler %array_size
  130. %array_ptr = OpTypePointer UniformConstant %array
  131. %2 = OpVariable %array_ptr UniformConstant
  132. %void = OpTypeVoid
  133. %functy = OpTypeFunction %void
  134. %func = OpFunction %void None %functy
  135. %1 = OpLabel
  136. OpReturn
  137. OpFunctionEnd
  138. )";
  139. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  140. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  141. }
  142. TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceRuntimeArrayGood) {
  143. std::string spirv = R"(
  144. OpCapability RuntimeDescriptorArrayEXT
  145. OpCapability Shader
  146. OpExtension "SPV_EXT_descriptor_indexing"
  147. OpMemoryModel Logical GLSL450
  148. OpEntryPoint Fragment %func "func"
  149. OpExecutionMode %func OriginUpperLeft
  150. OpDecorate %2 DescriptorSet 0
  151. OpDecorate %2 Binding 0
  152. %sampler = OpTypeSampler
  153. %uint = OpTypeInt 32 0
  154. %array = OpTypeRuntimeArray %sampler
  155. %array_ptr = OpTypePointer UniformConstant %array
  156. %2 = OpVariable %array_ptr UniformConstant
  157. %void = OpTypeVoid
  158. %functy = OpTypeFunction %void
  159. %func = OpFunction %void None %functy
  160. %1 = OpLabel
  161. OpReturn
  162. OpFunctionEnd
  163. )";
  164. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  165. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  166. }
  167. TEST_F(ValidateMemory, VulkanUniformOnIntBad) {
  168. char src[] = R"(
  169. OpCapability Shader
  170. OpMemoryModel Logical GLSL450
  171. OpEntryPoint GLCompute %kernel "main"
  172. OpExecutionMode %kernel LocalSize 1 1 1
  173. OpDecorate %var DescriptorSet 0
  174. OpDecorate %var Binding 0
  175. %voidty = OpTypeVoid
  176. %kernelty = OpTypeFunction %voidty
  177. %intty = OpTypeInt 32 0
  178. %varty = OpTypePointer Uniform %intty
  179. %value = OpConstant %intty 42
  180. %var = OpVariable %varty Uniform
  181. %kernel = OpFunction %voidty None %kernelty
  182. %label = OpLabel
  183. OpStore %var %value
  184. OpReturn
  185. OpFunctionEnd
  186. )";
  187. CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
  188. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  189. EXPECT_THAT(
  190. getDiagnosticString(),
  191. HasSubstr("From Vulkan spec, section 14.5.2:\n"
  192. "Variables identified with the Uniform storage class are used "
  193. "to access transparent buffer backed resources. Such variables "
  194. "must be typed as OpTypeStruct, or an array of this type"));
  195. }
  196. // #version 440
  197. // #extension GL_EXT_nonuniform_qualifier : enable
  198. // layout(binding = 1) uniform sampler2D s2d[][2];
  199. // layout(location = 0) in nonuniformEXT int i;
  200. // void main()
  201. // {
  202. // vec4 v = texture(s2d[i][i], vec2(0.3));
  203. // }
  204. TEST_F(ValidateMemory, VulkanUniformOnRuntimeArrayOfArrayBad) {
  205. char src[] = R"(
  206. OpCapability Shader
  207. OpCapability ShaderNonUniformEXT
  208. OpCapability RuntimeDescriptorArrayEXT
  209. OpCapability SampledImageArrayNonUniformIndexingEXT
  210. OpExtension "SPV_EXT_descriptor_indexing"
  211. %1 = OpExtInstImport "GLSL.std.450"
  212. OpMemoryModel Logical GLSL450
  213. OpEntryPoint Vertex %main "main" %i
  214. OpSource GLSL 440
  215. OpSourceExtension "GL_EXT_nonuniform_qualifier"
  216. OpName %main "main"
  217. OpName %v "v"
  218. OpName %s2d "s2d"
  219. OpName %i "i"
  220. OpDecorate %s2d DescriptorSet 0
  221. OpDecorate %s2d Binding 1
  222. OpDecorate %i Location 0
  223. OpDecorate %i NonUniformEXT
  224. OpDecorate %21 NonUniformEXT
  225. OpDecorate %22 NonUniformEXT
  226. OpDecorate %25 NonUniformEXT
  227. %void = OpTypeVoid
  228. %3 = OpTypeFunction %void
  229. %float = OpTypeFloat 32
  230. %v4float = OpTypeVector %float 4
  231. %_ptr_Function_v4float = OpTypePointer Function %v4float
  232. %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
  233. %11 = OpTypeSampledImage %10
  234. %uint = OpTypeInt 32 0
  235. %uint_2 = OpConstant %uint 2
  236. %_arr_11_uint_2 = OpTypeArray %11 %uint_2
  237. %_runtimearr__arr_11_uint_2 = OpTypeRuntimeArray %_arr_11_uint_2
  238. %_ptr_Uniform__runtimearr__arr_11_uint_2 = OpTypePointer Uniform %_runtimearr__arr_11_uint_2
  239. %s2d = OpVariable %_ptr_Uniform__runtimearr__arr_11_uint_2 Uniform
  240. %int = OpTypeInt 32 1
  241. %_ptr_Input_int = OpTypePointer Input %int
  242. %i = OpVariable %_ptr_Input_int Input
  243. %_ptr_Uniform_11 = OpTypePointer Uniform %11
  244. %v2float = OpTypeVector %float 2
  245. %float_0_300000012 = OpConstant %float 0.300000012
  246. %28 = OpConstantComposite %v2float %float_0_300000012 %float_0_300000012
  247. %float_0 = OpConstant %float 0
  248. %main = OpFunction %void None %3
  249. %5 = OpLabel
  250. %v = OpVariable %_ptr_Function_v4float Function
  251. %21 = OpLoad %int %i
  252. %22 = OpLoad %int %i
  253. %24 = OpAccessChain %_ptr_Uniform_11 %s2d %21 %22
  254. %25 = OpLoad %11 %24
  255. %30 = OpImageSampleExplicitLod %v4float %25 %28 Lod %float_0
  256. OpStore %v %30
  257. OpReturn
  258. OpFunctionEnd
  259. )";
  260. CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
  261. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  262. EXPECT_THAT(
  263. getDiagnosticString(),
  264. HasSubstr("From Vulkan spec, section 14.5.2:\n"
  265. "Variables identified with the Uniform storage class are used "
  266. "to access transparent buffer backed resources. Such variables "
  267. "must be typed as OpTypeStruct, or an array of this type"));
  268. }
  269. // #version 440
  270. // layout (set=1, binding=1) uniform sampler2D variableName[2][2];
  271. // void main() {
  272. // }
  273. TEST_F(ValidateMemory, VulkanUniformOnArrayOfArrayBad) {
  274. char src[] = R"(
  275. OpCapability Shader
  276. %1 = OpExtInstImport "GLSL.std.450"
  277. OpMemoryModel Logical GLSL450
  278. OpEntryPoint Vertex %main "main"
  279. OpSource GLSL 440
  280. OpName %main "main"
  281. OpName %variableName "variableName"
  282. OpDecorate %variableName DescriptorSet 1
  283. OpDecorate %variableName Binding 1
  284. %void = OpTypeVoid
  285. %3 = OpTypeFunction %void
  286. %float = OpTypeFloat 32
  287. %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
  288. %8 = OpTypeSampledImage %7
  289. %uint = OpTypeInt 32 0
  290. %uint_2 = OpConstant %uint 2
  291. %_arr_8_uint_2 = OpTypeArray %8 %uint_2
  292. %_arr__arr_8_uint_2_uint_2 = OpTypeArray %_arr_8_uint_2 %uint_2
  293. %_ptr_Uniform__arr__arr_8_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_8_uint_2_uint_2
  294. %variableName = OpVariable %_ptr_Uniform__arr__arr_8_uint_2_uint_2 Uniform
  295. %main = OpFunction %void None %3
  296. %5 = OpLabel
  297. OpReturn
  298. OpFunctionEnd
  299. )";
  300. CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
  301. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  302. EXPECT_THAT(
  303. getDiagnosticString(),
  304. HasSubstr("From Vulkan spec, section 14.5.2:\n"
  305. "Variables identified with the Uniform storage class are used "
  306. "to access transparent buffer backed resources. Such variables "
  307. "must be typed as OpTypeStruct, or an array of this type"));
  308. }
  309. TEST_F(ValidateMemory, MismatchingStorageClassesBad) {
  310. std::string spirv = R"(
  311. OpCapability Shader
  312. OpMemoryModel Logical GLSL450
  313. OpEntryPoint Fragment %func "func"
  314. OpExecutionMode %func OriginUpperLeft
  315. %float = OpTypeFloat 32
  316. %float_ptr = OpTypePointer Uniform %float
  317. %void = OpTypeVoid
  318. %functy = OpTypeFunction %void
  319. %func = OpFunction %void None %functy
  320. %1 = OpLabel
  321. %2 = OpVariable %float_ptr Function
  322. OpReturn
  323. OpFunctionEnd
  324. )";
  325. CompileSuccessfully(spirv.c_str());
  326. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  327. EXPECT_THAT(
  328. getDiagnosticString(),
  329. HasSubstr(
  330. "From SPIR-V spec, section 3.32.8 on OpVariable:\n"
  331. "Its Storage Class operand must be the same as the Storage Class "
  332. "operand of the result type."));
  333. }
  334. TEST_F(ValidateMemory, MatchingStorageClassesGood) {
  335. std::string spirv = R"(
  336. OpCapability Shader
  337. OpMemoryModel Logical GLSL450
  338. OpEntryPoint Fragment %func "func"
  339. OpExecutionMode %func OriginUpperLeft
  340. %float = OpTypeFloat 32
  341. %float_ptr = OpTypePointer Function %float
  342. %void = OpTypeVoid
  343. %functy = OpTypeFunction %void
  344. %func = OpFunction %void None %functy
  345. %1 = OpLabel
  346. %2 = OpVariable %float_ptr Function
  347. OpReturn
  348. OpFunctionEnd
  349. )";
  350. CompileSuccessfully(spirv.c_str());
  351. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  352. }
  353. TEST_F(ValidateMemory, VulkanInitializerWithOutputStorageClassesGood) {
  354. std::string spirv = R"(
  355. OpCapability Shader
  356. OpMemoryModel Logical GLSL450
  357. OpEntryPoint Fragment %func "func"
  358. OpExecutionMode %func OriginUpperLeft
  359. %float = OpTypeFloat 32
  360. %float_ptr = OpTypePointer Output %float
  361. %init_val = OpConstant %float 1.0
  362. %1 = OpVariable %float_ptr Output %init_val
  363. %void = OpTypeVoid
  364. %functy = OpTypeFunction %void
  365. %func = OpFunction %void None %functy
  366. %2 = OpLabel
  367. OpReturn
  368. OpFunctionEnd
  369. )";
  370. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  371. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  372. }
  373. TEST_F(ValidateMemory, VulkanInitializerWithFunctionStorageClassesGood) {
  374. std::string spirv = R"(
  375. OpCapability Shader
  376. OpMemoryModel Logical GLSL450
  377. OpEntryPoint Fragment %func "func"
  378. OpExecutionMode %func OriginUpperLeft
  379. %float = OpTypeFloat 32
  380. %float_ptr = OpTypePointer Function %float
  381. %init_val = OpConstant %float 1.0
  382. %void = OpTypeVoid
  383. %functy = OpTypeFunction %void
  384. %func = OpFunction %void None %functy
  385. %1 = OpLabel
  386. %2 = OpVariable %float_ptr Function %init_val
  387. OpReturn
  388. OpFunctionEnd
  389. )";
  390. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  391. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  392. }
  393. TEST_F(ValidateMemory, VulkanInitializerWithPrivateStorageClassesGood) {
  394. std::string spirv = R"(
  395. OpCapability Shader
  396. OpMemoryModel Logical GLSL450
  397. OpEntryPoint Fragment %func "func"
  398. OpExecutionMode %func OriginUpperLeft
  399. %float = OpTypeFloat 32
  400. %float_ptr = OpTypePointer Private %float
  401. %init_val = OpConstant %float 1.0
  402. %1 = OpVariable %float_ptr Private %init_val
  403. %void = OpTypeVoid
  404. %functy = OpTypeFunction %void
  405. %func = OpFunction %void None %functy
  406. %2 = OpLabel
  407. OpReturn
  408. OpFunctionEnd
  409. )";
  410. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  411. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  412. }
  413. TEST_F(ValidateMemory, VulkanInitializerWithDisallowedStorageClassesBad) {
  414. std::string spirv = R"(
  415. OpCapability Shader
  416. OpMemoryModel Logical GLSL450
  417. OpEntryPoint Fragment %func "func"
  418. OpExecutionMode %func OriginUpperLeft
  419. %float = OpTypeFloat 32
  420. %float_ptr = OpTypePointer Input %float
  421. %init_val = OpConstant %float 1.0
  422. %1 = OpVariable %float_ptr Input %init_val
  423. %void = OpTypeVoid
  424. %functy = OpTypeFunction %void
  425. %func = OpFunction %void None %functy
  426. %2 = OpLabel
  427. OpReturn
  428. OpFunctionEnd
  429. )";
  430. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  431. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  432. EXPECT_THAT(getDiagnosticString(),
  433. AnyVUID("VUID-StandaloneSpirv-OpVariable-04651"));
  434. EXPECT_THAT(
  435. getDiagnosticString(),
  436. HasSubstr("OpVariable, <id> '5[%5]', has a disallowed initializer & "
  437. "storage class combination.\nFrom Vulkan spec:\nVariable "
  438. "declarations that include initializers must have one of the "
  439. "following storage classes: Output, Private, Function or "
  440. "Workgroup\n %5 "
  441. "= OpVariable %_ptr_Input_float Input %float_1\n"));
  442. }
  443. TEST_F(ValidateMemory, ArrayLenCorrectResultType) {
  444. std::string spirv = R"(
  445. OpCapability Shader
  446. OpMemoryModel Logical GLSL450
  447. OpEntryPoint Fragment %1 "main"
  448. OpExecutionMode %1 OriginUpperLeft
  449. %void = OpTypeVoid
  450. %3 = OpTypeFunction %void
  451. %float = OpTypeFloat 32
  452. %uint = OpTypeInt 32 0
  453. %_runtimearr_float = OpTypeRuntimeArray %float
  454. %_struct_7 = OpTypeStruct %_runtimearr_float
  455. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  456. %1 = OpFunction %void None %3
  457. %9 = OpLabel
  458. %10 = OpVariable %_ptr_Function__struct_7 Function
  459. %11 = OpArrayLength %uint %10 0
  460. OpReturn
  461. OpFunctionEnd
  462. )";
  463. CompileSuccessfully(spirv.c_str());
  464. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  465. }
  466. TEST_F(ValidateMemory, ArrayLenIndexCorrectWith2Members) {
  467. std::string spirv = R"(
  468. OpCapability Shader
  469. OpMemoryModel Logical GLSL450
  470. OpEntryPoint Fragment %1 "main"
  471. OpExecutionMode %1 OriginUpperLeft
  472. %void = OpTypeVoid
  473. %3 = OpTypeFunction %void
  474. %float = OpTypeFloat 32
  475. %uint = OpTypeInt 32 0
  476. %_runtimearr_float = OpTypeRuntimeArray %float
  477. %_struct_7 = OpTypeStruct %float %_runtimearr_float
  478. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  479. %1 = OpFunction %void None %3
  480. %9 = OpLabel
  481. %10 = OpVariable %_ptr_Function__struct_7 Function
  482. %11 = OpArrayLength %uint %10 1
  483. OpReturn
  484. OpFunctionEnd
  485. )";
  486. CompileSuccessfully(spirv.c_str());
  487. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  488. }
  489. TEST_F(ValidateMemory, ArrayLenResultNotIntType) {
  490. std::string spirv = R"(
  491. OpCapability Shader
  492. OpMemoryModel Logical GLSL450
  493. OpEntryPoint Fragment %1 "main"
  494. OpExecutionMode %1 OriginUpperLeft
  495. %void = OpTypeVoid
  496. %3 = OpTypeFunction %void
  497. %float = OpTypeFloat 32
  498. %_runtimearr_float = OpTypeRuntimeArray %float
  499. %_struct_6 = OpTypeStruct %_runtimearr_float
  500. %_ptr_Function__struct_6 = OpTypePointer Function %_struct_6
  501. %1 = OpFunction %void None %3
  502. %8 = OpLabel
  503. %9 = OpVariable %_ptr_Function__struct_6 Function
  504. %10 = OpArrayLength %float %9 0
  505. OpReturn
  506. OpFunctionEnd
  507. )";
  508. CompileSuccessfully(spirv.c_str());
  509. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  510. EXPECT_THAT(
  511. getDiagnosticString(),
  512. HasSubstr(
  513. "The Result Type of OpArrayLength <id> '10[%10]' must be OpTypeInt "
  514. "with width 32 and signedness 0.\n %10 = OpArrayLength %float %9 "
  515. "0\n"));
  516. }
  517. TEST_F(ValidateMemory, ArrayLenResultNot32bits) {
  518. std::string spirv = R"(
  519. OpCapability Shader
  520. OpCapability Int16
  521. OpMemoryModel Logical GLSL450
  522. OpEntryPoint Fragment %1 "main"
  523. OpExecutionMode %1 OriginUpperLeft
  524. %void = OpTypeVoid
  525. %3 = OpTypeFunction %void
  526. %float = OpTypeFloat 32
  527. %ushort = OpTypeInt 16 0
  528. %_runtimearr_float = OpTypeRuntimeArray %float
  529. %_struct_7 = OpTypeStruct %_runtimearr_float
  530. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  531. %1 = OpFunction %void None %3
  532. %9 = OpLabel
  533. %10 = OpVariable %_ptr_Function__struct_7 Function
  534. %11 = OpArrayLength %ushort %10 0
  535. OpReturn
  536. OpFunctionEnd
  537. )";
  538. CompileSuccessfully(spirv.c_str());
  539. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  540. EXPECT_THAT(
  541. getDiagnosticString(),
  542. HasSubstr(
  543. "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
  544. "with width 32 and signedness 0.\n %11 = OpArrayLength %ushort %10 "
  545. "0\n"));
  546. }
  547. TEST_F(ValidateMemory, ArrayLenResultSigned) {
  548. std::string spirv = R"(
  549. OpCapability Shader
  550. OpMemoryModel Logical GLSL450
  551. OpEntryPoint Fragment %1 "main"
  552. OpExecutionMode %1 OriginUpperLeft
  553. %void = OpTypeVoid
  554. %3 = OpTypeFunction %void
  555. %float = OpTypeFloat 32
  556. %int = OpTypeInt 32 1
  557. %_runtimearr_float = OpTypeRuntimeArray %float
  558. %_struct_7 = OpTypeStruct %_runtimearr_float
  559. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  560. %1 = OpFunction %void None %3
  561. %9 = OpLabel
  562. %10 = OpVariable %_ptr_Function__struct_7 Function
  563. %11 = OpArrayLength %int %10 0
  564. OpReturn
  565. OpFunctionEnd
  566. )";
  567. CompileSuccessfully(spirv.c_str());
  568. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  569. EXPECT_THAT(
  570. getDiagnosticString(),
  571. HasSubstr(
  572. "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
  573. "with width 32 and signedness 0.\n %11 = OpArrayLength %int %10 "
  574. "0\n"));
  575. }
  576. TEST_F(ValidateMemory, ArrayLenInputNotStruct) {
  577. std::string spirv = R"(
  578. OpCapability Shader
  579. OpMemoryModel Logical GLSL450
  580. OpEntryPoint Fragment %1 "main"
  581. OpExecutionMode %1 OriginUpperLeft
  582. %void = OpTypeVoid
  583. %3 = OpTypeFunction %void
  584. %float = OpTypeFloat 32
  585. %uint = OpTypeInt 32 0
  586. %_runtimearr_float = OpTypeRuntimeArray %float
  587. %_struct_7 = OpTypeStruct %_runtimearr_float
  588. %_ptr_Function_float = OpTypePointer Function %float
  589. %1 = OpFunction %void None %3
  590. %9 = OpLabel
  591. %10 = OpVariable %_ptr_Function_float Function
  592. %11 = OpArrayLength %uint %10 0
  593. OpReturn
  594. OpFunctionEnd
  595. )";
  596. CompileSuccessfully(spirv.c_str());
  597. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  598. EXPECT_THAT(getDiagnosticString(),
  599. HasSubstr("The Struture's type in OpArrayLength <id> '11[%11]' "
  600. "must be a pointer to an OpTypeStruct."));
  601. }
  602. TEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA) {
  603. std::string spirv = R"(
  604. OpCapability Shader
  605. OpMemoryModel Logical GLSL450
  606. OpEntryPoint Fragment %1 "main"
  607. OpExecutionMode %1 OriginUpperLeft
  608. %void = OpTypeVoid
  609. %3 = OpTypeFunction %void
  610. %float = OpTypeFloat 32
  611. %uint = OpTypeInt 32 0
  612. %_runtimearr_float = OpTypeRuntimeArray %float
  613. %_struct_7 = OpTypeStruct %float
  614. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  615. %1 = OpFunction %void None %3
  616. %9 = OpLabel
  617. %10 = OpVariable %_ptr_Function__struct_7 Function
  618. %11 = OpArrayLength %uint %10 0
  619. OpReturn
  620. OpFunctionEnd
  621. )";
  622. CompileSuccessfully(spirv.c_str());
  623. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  624. EXPECT_THAT(
  625. getDiagnosticString(),
  626. HasSubstr("The Struture's last member in OpArrayLength <id> '11[%11]' "
  627. "must be an OpTypeRuntimeArray.\n %11 = OpArrayLength %uint "
  628. "%10 0\n"));
  629. }
  630. TEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA2) {
  631. std::string spirv = R"(
  632. OpCapability Shader
  633. OpMemoryModel Logical GLSL450
  634. OpEntryPoint Fragment %1 "main"
  635. OpExecutionMode %1 OriginUpperLeft
  636. %void = OpTypeVoid
  637. %3 = OpTypeFunction %void
  638. %float = OpTypeFloat 32
  639. %uint = OpTypeInt 32 0
  640. %_runtimearr_float = OpTypeRuntimeArray %float
  641. %_struct_7 = OpTypeStruct %_runtimearr_float %float
  642. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  643. %1 = OpFunction %void None %3
  644. %9 = OpLabel
  645. %10 = OpVariable %_ptr_Function__struct_7 Function
  646. %11 = OpArrayLength %uint %10 1
  647. OpReturn
  648. OpFunctionEnd
  649. )";
  650. CompileSuccessfully(spirv.c_str());
  651. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  652. EXPECT_THAT(
  653. getDiagnosticString(),
  654. HasSubstr("The Struture's last member in OpArrayLength <id> '11[%11]' "
  655. "must be an OpTypeRuntimeArray.\n %11 = OpArrayLength %uint "
  656. "%10 1\n"));
  657. }
  658. TEST_F(ValidateMemory, ArrayLenIndexNotLastMember) {
  659. std::string spirv = R"(
  660. OpCapability Shader
  661. OpMemoryModel Logical GLSL450
  662. OpEntryPoint Fragment %1 "main"
  663. OpExecutionMode %1 OriginUpperLeft
  664. %void = OpTypeVoid
  665. %3 = OpTypeFunction %void
  666. %float = OpTypeFloat 32
  667. %uint = OpTypeInt 32 0
  668. %_runtimearr_float = OpTypeRuntimeArray %float
  669. %_struct_7 = OpTypeStruct %float %_runtimearr_float
  670. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  671. %1 = OpFunction %void None %3
  672. %9 = OpLabel
  673. %10 = OpVariable %_ptr_Function__struct_7 Function
  674. %11 = OpArrayLength %uint %10 0
  675. OpReturn
  676. OpFunctionEnd
  677. )";
  678. CompileSuccessfully(spirv.c_str());
  679. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  680. EXPECT_THAT(
  681. getDiagnosticString(),
  682. HasSubstr(
  683. "The array member in OpArrayLength <id> '11[%11]' must be an the "
  684. "last member of the struct.\n %11 = OpArrayLength %uint %10 0\n"));
  685. }
  686. TEST_F(ValidateMemory, ArrayLenIndexNotPointerToStruct) {
  687. std::string spirv = R"(
  688. OpCapability Shader
  689. OpMemoryModel Logical GLSL450
  690. OpEntryPoint Fragment %1 "main"
  691. OpExecutionMode %1 OriginUpperLeft
  692. %void = OpTypeVoid
  693. %3 = OpTypeFunction %void
  694. %float = OpTypeFloat 32
  695. %uint = OpTypeInt 32 0
  696. %_runtimearr_float = OpTypeRuntimeArray %float
  697. %_struct_7 = OpTypeStruct %float %_runtimearr_float
  698. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  699. %1 = OpFunction %void None %3
  700. %9 = OpLabel
  701. %10 = OpVariable %_ptr_Function__struct_7 Function
  702. %11 = OpLoad %_struct_7 %10
  703. %12 = OpArrayLength %uint %11 0
  704. OpReturn
  705. OpFunctionEnd
  706. )";
  707. CompileSuccessfully(spirv.c_str());
  708. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  709. EXPECT_THAT(
  710. getDiagnosticString(),
  711. HasSubstr(
  712. "The Struture's type in OpArrayLength <id> '12[%12]' must be a "
  713. "pointer to an OpTypeStruct.\n %12 = OpArrayLength %uint %11 0\n"));
  714. }
  715. TEST_F(ValidateMemory, ArrayLenPointerIsAType) {
  716. std::string spirv = R"(
  717. OpCapability Shader
  718. OpMemoryModel Logical GLSL450
  719. OpEntryPoint Fragment %1 "main"
  720. OpExecutionMode %1 OriginUpperLeft
  721. %void = OpTypeVoid
  722. %3 = OpTypeFunction %void
  723. %float = OpTypeFloat 32
  724. %uint = OpTypeInt 32 0
  725. %1 = OpFunction %void None %3
  726. %9 = OpLabel
  727. %12 = OpArrayLength %uint %float 0
  728. OpReturn
  729. OpFunctionEnd
  730. )";
  731. CompileSuccessfully(spirv.c_str());
  732. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  733. EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 4[%float] cannot be a "
  734. "type"));
  735. }
  736. TEST_F(ValidateMemory, PushConstantNotStructGood) {
  737. std::string spirv = R"(
  738. OpCapability Shader
  739. OpMemoryModel Logical GLSL450
  740. OpEntryPoint Fragment %1 "main"
  741. OpExecutionMode %1 OriginUpperLeft
  742. %void = OpTypeVoid
  743. %voidfn = OpTypeFunction %void
  744. %float = OpTypeFloat 32
  745. %ptr = OpTypePointer PushConstant %float
  746. %pc = OpVariable %ptr PushConstant
  747. %1 = OpFunction %void None %voidfn
  748. %label = OpLabel
  749. OpReturn
  750. OpFunctionEnd
  751. )";
  752. CompileSuccessfully(spirv);
  753. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  754. }
  755. TEST_F(ValidateMemory, VulkanPushConstantNotStructBad) {
  756. std::string spirv = R"(
  757. OpCapability Shader
  758. OpMemoryModel Logical GLSL450
  759. OpEntryPoint Fragment %1 "main"
  760. OpExecutionMode %1 OriginUpperLeft
  761. %void = OpTypeVoid
  762. %voidfn = OpTypeFunction %void
  763. %float = OpTypeFloat 32
  764. %ptr = OpTypePointer PushConstant %float
  765. %pc = OpVariable %ptr PushConstant
  766. %1 = OpFunction %void None %voidfn
  767. %label = OpLabel
  768. OpReturn
  769. OpFunctionEnd
  770. )";
  771. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  772. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  773. EXPECT_THAT(getDiagnosticString(),
  774. HasSubstr("PushConstant OpVariable <id> '6[%6]' has illegal "
  775. "type.\nFrom Vulkan spec, section 14.5.1:\n"
  776. "Such variables must be typed as OpTypeStruct, "
  777. "or an array of this type"));
  778. }
  779. TEST_F(ValidateMemory, VulkanPushConstant) {
  780. std::string spirv = R"(
  781. OpCapability Shader
  782. OpMemoryModel Logical GLSL450
  783. OpEntryPoint Fragment %1 "main"
  784. OpExecutionMode %1 OriginUpperLeft
  785. OpDecorate %struct Block
  786. OpMemberDecorate %struct 0 Offset 0
  787. %void = OpTypeVoid
  788. %voidfn = OpTypeFunction %void
  789. %float = OpTypeFloat 32
  790. %struct = OpTypeStruct %float
  791. %ptr = OpTypePointer PushConstant %struct
  792. %pc = OpVariable %ptr PushConstant
  793. %1 = OpFunction %void None %voidfn
  794. %label = OpLabel
  795. OpReturn
  796. OpFunctionEnd
  797. )";
  798. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  799. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  800. }
  801. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad1) {
  802. const std::string spirv = R"(
  803. OpCapability Shader
  804. OpCapability VulkanMemoryModelKHR
  805. OpCapability Linkage
  806. OpExtension "SPV_KHR_vulkan_memory_model"
  807. OpMemoryModel Logical VulkanKHR
  808. %void = OpTypeVoid
  809. %int = OpTypeInt 32 0
  810. %device = OpConstant %int 1
  811. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  812. %var = OpVariable %int_ptr_ssbo StorageBuffer
  813. %voidfn = OpTypeFunction %void
  814. %func = OpFunction %void None %voidfn
  815. %entry = OpLabel
  816. %load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
  817. OpReturn
  818. OpFunctionEnd
  819. )";
  820. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  821. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  822. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  823. EXPECT_THAT(
  824. getDiagnosticString(),
  825. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  826. "VulkanMemoryModelDeviceScopeKHR capability"));
  827. }
  828. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad2) {
  829. const std::string spirv = R"(
  830. OpCapability Shader
  831. OpCapability VulkanMemoryModelKHR
  832. OpCapability Linkage
  833. OpExtension "SPV_KHR_vulkan_memory_model"
  834. OpMemoryModel Logical VulkanKHR
  835. %void = OpTypeVoid
  836. %int = OpTypeInt 32 0
  837. %device = OpConstant %int 1
  838. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  839. %var = OpVariable %int_ptr_ssbo StorageBuffer
  840. %voidfn = OpTypeFunction %void
  841. %func = OpFunction %void None %voidfn
  842. %entry = OpLabel
  843. %load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
  844. OpReturn
  845. OpFunctionEnd
  846. )";
  847. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  848. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  849. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  850. EXPECT_THAT(
  851. getDiagnosticString(),
  852. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  853. "VulkanMemoryModelDeviceScopeKHR capability"));
  854. }
  855. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood1) {
  856. const std::string spirv = R"(
  857. OpCapability Shader
  858. OpCapability VulkanMemoryModelKHR
  859. OpCapability VulkanMemoryModelDeviceScopeKHR
  860. OpCapability Linkage
  861. OpExtension "SPV_KHR_vulkan_memory_model"
  862. OpMemoryModel Logical VulkanKHR
  863. %void = OpTypeVoid
  864. %int = OpTypeInt 32 0
  865. %device = OpConstant %int 1
  866. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  867. %var = OpVariable %int_ptr_ssbo StorageBuffer
  868. %voidfn = OpTypeFunction %void
  869. %func = OpFunction %void None %voidfn
  870. %entry = OpLabel
  871. %load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
  872. OpReturn
  873. OpFunctionEnd
  874. )";
  875. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  876. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  877. }
  878. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood2) {
  879. const std::string spirv = R"(
  880. OpCapability Shader
  881. OpCapability VulkanMemoryModelKHR
  882. OpCapability VulkanMemoryModelDeviceScopeKHR
  883. OpCapability Linkage
  884. OpExtension "SPV_KHR_vulkan_memory_model"
  885. OpMemoryModel Logical VulkanKHR
  886. %void = OpTypeVoid
  887. %int = OpTypeInt 32 0
  888. %device = OpConstant %int 1
  889. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  890. %var = OpVariable %int_ptr_ssbo StorageBuffer
  891. %voidfn = OpTypeFunction %void
  892. %func = OpFunction %void None %voidfn
  893. %entry = OpLabel
  894. %load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
  895. OpReturn
  896. OpFunctionEnd
  897. )";
  898. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  899. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  900. }
  901. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad1) {
  902. const std::string spirv = R"(
  903. OpCapability Shader
  904. OpCapability VulkanMemoryModelKHR
  905. OpCapability Linkage
  906. OpExtension "SPV_KHR_vulkan_memory_model"
  907. OpMemoryModel Logical VulkanKHR
  908. %void = OpTypeVoid
  909. %int = OpTypeInt 32 0
  910. %device = OpConstant %int 1
  911. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  912. %var = OpVariable %int_ptr_ssbo StorageBuffer
  913. %voidfn = OpTypeFunction %void
  914. %func = OpFunction %void None %voidfn
  915. %entry = OpLabel
  916. OpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
  917. OpReturn
  918. OpFunctionEnd
  919. )";
  920. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  921. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  922. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  923. EXPECT_THAT(
  924. getDiagnosticString(),
  925. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  926. "VulkanMemoryModelDeviceScopeKHR capability"));
  927. }
  928. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad2) {
  929. const std::string spirv = R"(
  930. OpCapability Shader
  931. OpCapability VulkanMemoryModelKHR
  932. OpCapability Linkage
  933. OpExtension "SPV_KHR_vulkan_memory_model"
  934. OpMemoryModel Logical VulkanKHR
  935. %void = OpTypeVoid
  936. %int = OpTypeInt 32 0
  937. %device = OpConstant %int 1
  938. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  939. %var = OpVariable %int_ptr_ssbo StorageBuffer
  940. %voidfn = OpTypeFunction %void
  941. %func = OpFunction %void None %voidfn
  942. %entry = OpLabel
  943. OpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
  944. OpReturn
  945. OpFunctionEnd
  946. )";
  947. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  948. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  949. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  950. EXPECT_THAT(
  951. getDiagnosticString(),
  952. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  953. "VulkanMemoryModelDeviceScopeKHR capability"));
  954. }
  955. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood1) {
  956. const std::string spirv = R"(
  957. OpCapability Shader
  958. OpCapability VulkanMemoryModelKHR
  959. OpCapability VulkanMemoryModelDeviceScopeKHR
  960. OpCapability Linkage
  961. OpExtension "SPV_KHR_vulkan_memory_model"
  962. OpMemoryModel Logical VulkanKHR
  963. %void = OpTypeVoid
  964. %int = OpTypeInt 32 0
  965. %device = OpConstant %int 1
  966. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  967. %var = OpVariable %int_ptr_ssbo StorageBuffer
  968. %voidfn = OpTypeFunction %void
  969. %func = OpFunction %void None %voidfn
  970. %entry = OpLabel
  971. OpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
  972. OpReturn
  973. OpFunctionEnd
  974. )";
  975. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  976. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  977. }
  978. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood2) {
  979. const std::string spirv = R"(
  980. OpCapability Shader
  981. OpCapability VulkanMemoryModelKHR
  982. OpCapability VulkanMemoryModelDeviceScopeKHR
  983. OpCapability Linkage
  984. OpExtension "SPV_KHR_vulkan_memory_model"
  985. OpMemoryModel Logical VulkanKHR
  986. %void = OpTypeVoid
  987. %int = OpTypeInt 32 0
  988. %device = OpConstant %int 1
  989. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  990. %var = OpVariable %int_ptr_ssbo StorageBuffer
  991. %voidfn = OpTypeFunction %void
  992. %func = OpFunction %void None %voidfn
  993. %entry = OpLabel
  994. OpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
  995. OpReturn
  996. OpFunctionEnd
  997. )";
  998. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  999. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1000. }
  1001. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad1) {
  1002. const std::string spirv = R"(
  1003. OpCapability Shader
  1004. OpCapability VulkanMemoryModelKHR
  1005. OpCapability Linkage
  1006. OpExtension "SPV_KHR_vulkan_memory_model"
  1007. OpMemoryModel Logical VulkanKHR
  1008. %void = OpTypeVoid
  1009. %int = OpTypeInt 32 0
  1010. %device = OpConstant %int 1
  1011. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1012. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1013. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1014. %voidfn = OpTypeFunction %void
  1015. %func = OpFunction %void None %voidfn
  1016. %entry = OpLabel
  1017. OpCopyMemory %var1 %var2 MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1018. OpReturn
  1019. OpFunctionEnd
  1020. )";
  1021. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1022. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1023. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1024. EXPECT_THAT(
  1025. getDiagnosticString(),
  1026. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1027. "VulkanMemoryModelDeviceScopeKHR capability"));
  1028. }
  1029. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad2) {
  1030. const std::string spirv = R"(
  1031. OpCapability Shader
  1032. OpCapability VulkanMemoryModelKHR
  1033. OpCapability Linkage
  1034. OpExtension "SPV_KHR_vulkan_memory_model"
  1035. OpMemoryModel Logical VulkanKHR
  1036. %void = OpTypeVoid
  1037. %int = OpTypeInt 32 0
  1038. %device = OpConstant %int 1
  1039. %workgroup = OpConstant %int 1
  1040. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1041. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1042. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1043. %voidfn = OpTypeFunction %void
  1044. %func = OpFunction %void None %voidfn
  1045. %entry = OpLabel
  1046. OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
  1047. OpReturn
  1048. OpFunctionEnd
  1049. )";
  1050. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1051. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1052. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1053. EXPECT_THAT(
  1054. getDiagnosticString(),
  1055. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1056. "VulkanMemoryModelDeviceScopeKHR capability"));
  1057. }
  1058. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad3) {
  1059. const std::string spirv = R"(
  1060. OpCapability Shader
  1061. OpCapability VulkanMemoryModelKHR
  1062. OpCapability Linkage
  1063. OpExtension "SPV_KHR_vulkan_memory_model"
  1064. OpMemoryModel Logical VulkanKHR
  1065. %void = OpTypeVoid
  1066. %int = OpTypeInt 32 0
  1067. %device = OpConstant %int 1
  1068. %workgroup = OpConstant %int 1
  1069. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1070. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1071. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1072. %voidfn = OpTypeFunction %void
  1073. %func = OpFunction %void None %voidfn
  1074. %entry = OpLabel
  1075. OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
  1076. OpReturn
  1077. OpFunctionEnd
  1078. )";
  1079. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1080. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1081. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1082. EXPECT_THAT(
  1083. getDiagnosticString(),
  1084. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1085. "VulkanMemoryModelDeviceScopeKHR capability"));
  1086. }
  1087. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood2) {
  1088. const std::string spirv = R"(
  1089. OpCapability Shader
  1090. OpCapability VulkanMemoryModelKHR
  1091. OpCapability VulkanMemoryModelDeviceScopeKHR
  1092. OpCapability Linkage
  1093. OpExtension "SPV_KHR_vulkan_memory_model"
  1094. OpMemoryModel Logical VulkanKHR
  1095. %void = OpTypeVoid
  1096. %int = OpTypeInt 32 0
  1097. %device = OpConstant %int 1
  1098. %workgroup = OpConstant %int 2
  1099. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1100. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1101. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1102. %voidfn = OpTypeFunction %void
  1103. %func = OpFunction %void None %voidfn
  1104. %entry = OpLabel
  1105. OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
  1106. OpReturn
  1107. OpFunctionEnd
  1108. )";
  1109. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1110. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1111. }
  1112. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood3) {
  1113. const std::string spirv = R"(
  1114. OpCapability Shader
  1115. OpCapability VulkanMemoryModelKHR
  1116. OpCapability VulkanMemoryModelDeviceScopeKHR
  1117. OpCapability Linkage
  1118. OpExtension "SPV_KHR_vulkan_memory_model"
  1119. OpMemoryModel Logical VulkanKHR
  1120. %void = OpTypeVoid
  1121. %int = OpTypeInt 32 0
  1122. %device = OpConstant %int 1
  1123. %workgroup = OpConstant %int 2
  1124. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1125. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1126. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1127. %voidfn = OpTypeFunction %void
  1128. %func = OpFunction %void None %voidfn
  1129. %entry = OpLabel
  1130. OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
  1131. OpReturn
  1132. OpFunctionEnd
  1133. )";
  1134. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1135. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1136. }
  1137. TEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessAvVisBadBinaryV13) {
  1138. const std::string spirv = R"(
  1139. OpCapability Shader
  1140. OpCapability VulkanMemoryModelKHR
  1141. OpCapability VulkanMemoryModelDeviceScopeKHR
  1142. OpCapability Linkage
  1143. OpExtension "SPV_KHR_vulkan_memory_model"
  1144. OpMemoryModel Logical VulkanKHR
  1145. %void = OpTypeVoid
  1146. %int = OpTypeInt 32 0
  1147. %device = OpConstant %int 1
  1148. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1149. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1150. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1151. %voidfn = OpTypeFunction %void
  1152. %func = OpFunction %void None %voidfn
  1153. %entry = OpLabel
  1154. OpCopyMemory %var1 %var2
  1155. MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1156. MakePointerVisibleKHR|NonPrivatePointerKHR %device
  1157. OpReturn
  1158. OpFunctionEnd
  1159. )";
  1160. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1161. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1162. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1163. EXPECT_THAT(
  1164. getDiagnosticString(),
  1165. HasSubstr(
  1166. "with two memory access operands requires SPIR-V 1.4 or later"));
  1167. }
  1168. TEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessAvVisGood) {
  1169. const std::string spirv = R"(
  1170. OpCapability Shader
  1171. OpCapability VulkanMemoryModelKHR
  1172. OpCapability VulkanMemoryModelDeviceScopeKHR
  1173. OpCapability Linkage
  1174. OpExtension "SPV_KHR_vulkan_memory_model"
  1175. OpMemoryModel Logical VulkanKHR
  1176. %void = OpTypeVoid
  1177. %int = OpTypeInt 32 0
  1178. %device = OpConstant %int 1
  1179. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1180. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1181. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1182. %voidfn = OpTypeFunction %void
  1183. %func = OpFunction %void None %voidfn
  1184. %entry = OpLabel
  1185. OpCopyMemory %var1 %var2
  1186. MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1187. MakePointerVisibleKHR|NonPrivatePointerKHR %device
  1188. OpReturn
  1189. OpFunctionEnd
  1190. )";
  1191. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  1192. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1193. EXPECT_THAT(getDiagnosticString(), Eq(""));
  1194. }
  1195. TEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessFirstWithAvBad) {
  1196. const std::string spirv = R"(
  1197. OpCapability Shader
  1198. OpCapability VulkanMemoryModelKHR
  1199. OpCapability VulkanMemoryModelDeviceScopeKHR
  1200. OpCapability Linkage
  1201. OpExtension "SPV_KHR_vulkan_memory_model"
  1202. OpMemoryModel Logical VulkanKHR
  1203. %void = OpTypeVoid
  1204. %int = OpTypeInt 32 0
  1205. %device = OpConstant %int 1
  1206. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1207. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1208. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1209. %voidfn = OpTypeFunction %void
  1210. %func = OpFunction %void None %voidfn
  1211. %entry = OpLabel
  1212. OpCopyMemory %var1 %var2
  1213. MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1214. MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1215. OpReturn
  1216. OpFunctionEnd
  1217. )";
  1218. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  1219. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1220. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1221. EXPECT_THAT(
  1222. getDiagnosticString(),
  1223. HasSubstr(
  1224. "Source memory access must not include MakePointerAvailableKHR\n"
  1225. " OpCopyMemory %5 %6 MakePointerAvailable|NonPrivatePointer"
  1226. " %uint_1 MakePointerAvailable|NonPrivatePointer %uint_1"));
  1227. }
  1228. TEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessSecondWithVisBad) {
  1229. const std::string spirv = R"(
  1230. OpCapability Shader
  1231. OpCapability VulkanMemoryModelKHR
  1232. OpCapability VulkanMemoryModelDeviceScopeKHR
  1233. OpCapability Linkage
  1234. OpExtension "SPV_KHR_vulkan_memory_model"
  1235. OpMemoryModel Logical VulkanKHR
  1236. %void = OpTypeVoid
  1237. %int = OpTypeInt 32 0
  1238. %device = OpConstant %int 1
  1239. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1240. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1241. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1242. %voidfn = OpTypeFunction %void
  1243. %func = OpFunction %void None %voidfn
  1244. %entry = OpLabel
  1245. OpCopyMemory %var1 %var2
  1246. MakePointerVisibleKHR|NonPrivatePointerKHR %device
  1247. MakePointerVisibleKHR|NonPrivatePointerKHR %device
  1248. OpReturn
  1249. OpFunctionEnd
  1250. )";
  1251. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  1252. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1253. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1254. EXPECT_THAT(
  1255. getDiagnosticString(),
  1256. HasSubstr("Target memory access must not include MakePointerVisibleKHR\n"
  1257. " OpCopyMemory %5 %6 MakePointerVisible|NonPrivatePointer"
  1258. " %uint_1 MakePointerVisible|NonPrivatePointer %uint_1"));
  1259. }
  1260. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad1) {
  1261. const std::string spirv = R"(
  1262. OpCapability Shader
  1263. OpCapability VulkanMemoryModelKHR
  1264. OpCapability Linkage
  1265. OpCapability Addresses
  1266. OpExtension "SPV_KHR_vulkan_memory_model"
  1267. OpMemoryModel Logical VulkanKHR
  1268. %void = OpTypeVoid
  1269. %int = OpTypeInt 32 0
  1270. %device = OpConstant %int 1
  1271. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1272. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1273. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1274. %voidfn = OpTypeFunction %void
  1275. %func = OpFunction %void None %voidfn
  1276. %entry = OpLabel
  1277. OpCopyMemorySized %var1 %var2 %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1278. OpReturn
  1279. OpFunctionEnd
  1280. )";
  1281. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1282. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1283. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1284. EXPECT_THAT(
  1285. getDiagnosticString(),
  1286. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1287. "VulkanMemoryModelDeviceScopeKHR capability"));
  1288. }
  1289. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad2) {
  1290. const std::string spirv = R"(
  1291. OpCapability Shader
  1292. OpCapability VulkanMemoryModelKHR
  1293. OpCapability Linkage
  1294. OpCapability Addresses
  1295. OpExtension "SPV_KHR_vulkan_memory_model"
  1296. OpMemoryModel Logical VulkanKHR
  1297. %void = OpTypeVoid
  1298. %int = OpTypeInt 32 0
  1299. %device = OpConstant %int 1
  1300. %workgroup = OpConstant %int 1
  1301. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1302. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1303. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1304. %voidfn = OpTypeFunction %void
  1305. %func = OpFunction %void None %voidfn
  1306. %entry = OpLabel
  1307. OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
  1308. OpReturn
  1309. OpFunctionEnd
  1310. )";
  1311. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1312. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1313. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1314. EXPECT_THAT(
  1315. getDiagnosticString(),
  1316. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1317. "VulkanMemoryModelDeviceScopeKHR capability"));
  1318. }
  1319. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad3) {
  1320. const std::string spirv = R"(
  1321. OpCapability Shader
  1322. OpCapability VulkanMemoryModelKHR
  1323. OpCapability Linkage
  1324. OpCapability Addresses
  1325. OpExtension "SPV_KHR_vulkan_memory_model"
  1326. OpMemoryModel Logical VulkanKHR
  1327. %void = OpTypeVoid
  1328. %int = OpTypeInt 32 0
  1329. %device = OpConstant %int 1
  1330. %workgroup = OpConstant %int 1
  1331. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1332. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1333. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1334. %voidfn = OpTypeFunction %void
  1335. %func = OpFunction %void None %voidfn
  1336. %entry = OpLabel
  1337. OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
  1338. OpReturn
  1339. OpFunctionEnd
  1340. )";
  1341. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1342. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1343. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1344. EXPECT_THAT(
  1345. getDiagnosticString(),
  1346. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1347. "VulkanMemoryModelDeviceScopeKHR capability"));
  1348. }
  1349. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood1) {
  1350. const std::string spirv = R"(
  1351. OpCapability Shader
  1352. OpCapability VulkanMemoryModelKHR
  1353. OpCapability VulkanMemoryModelDeviceScopeKHR
  1354. OpCapability Linkage
  1355. OpCapability Addresses
  1356. OpExtension "SPV_KHR_vulkan_memory_model"
  1357. OpMemoryModel Logical VulkanKHR
  1358. %void = OpTypeVoid
  1359. %int = OpTypeInt 32 0
  1360. %device = OpConstant %int 1
  1361. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1362. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1363. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1364. %voidfn = OpTypeFunction %void
  1365. %func = OpFunction %void None %voidfn
  1366. %entry = OpLabel
  1367. OpCopyMemorySized %var1 %var2 %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1368. OpReturn
  1369. OpFunctionEnd
  1370. )";
  1371. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1372. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1373. }
  1374. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood2) {
  1375. const std::string spirv = R"(
  1376. OpCapability Shader
  1377. OpCapability VulkanMemoryModelKHR
  1378. OpCapability VulkanMemoryModelDeviceScopeKHR
  1379. OpCapability Linkage
  1380. OpCapability Addresses
  1381. OpExtension "SPV_KHR_vulkan_memory_model"
  1382. OpMemoryModel Logical VulkanKHR
  1383. %void = OpTypeVoid
  1384. %int = OpTypeInt 32 0
  1385. %device = OpConstant %int 1
  1386. %workgroup = OpConstant %int 2
  1387. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1388. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1389. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1390. %voidfn = OpTypeFunction %void
  1391. %func = OpFunction %void None %voidfn
  1392. %entry = OpLabel
  1393. OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
  1394. OpReturn
  1395. OpFunctionEnd
  1396. )";
  1397. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1398. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1399. }
  1400. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood3) {
  1401. const std::string spirv = R"(
  1402. OpCapability Shader
  1403. OpCapability VulkanMemoryModelKHR
  1404. OpCapability VulkanMemoryModelDeviceScopeKHR
  1405. OpCapability Linkage
  1406. OpCapability Addresses
  1407. OpExtension "SPV_KHR_vulkan_memory_model"
  1408. OpMemoryModel Logical VulkanKHR
  1409. %void = OpTypeVoid
  1410. %int = OpTypeInt 32 0
  1411. %device = OpConstant %int 1
  1412. %workgroup = OpConstant %int 2
  1413. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1414. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1415. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1416. %voidfn = OpTypeFunction %void
  1417. %func = OpFunction %void None %voidfn
  1418. %entry = OpLabel
  1419. OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
  1420. OpReturn
  1421. OpFunctionEnd
  1422. )";
  1423. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1424. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1425. }
  1426. TEST_F(ValidateMemory, ArrayLengthStructIsLabel) {
  1427. const std::string spirv = R"(
  1428. OpCapability Tessellation
  1429. OpMemoryModel Logical GLSL450
  1430. OpName %20 "incorrect"
  1431. %void = OpTypeVoid
  1432. %3 = OpTypeFunction %void
  1433. %float = OpTypeFloat 32
  1434. %v4float = OpTypeVector %float 4
  1435. %uint = OpTypeInt 32 0
  1436. %4 = OpFunction %void None %3
  1437. %20 = OpLabel
  1438. %24 = OpArrayLength %uint %20 0
  1439. %25 = OpLoad %v4float %24
  1440. OpReturnValue %25
  1441. OpFunctionEnd
  1442. )";
  1443. CompileSuccessfully(spirv);
  1444. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1445. EXPECT_THAT(getDiagnosticString(),
  1446. HasSubstr("Operand 1[%incorrect] requires a type"));
  1447. }
  1448. TEST_F(ValidateMemory, PSBLoadAlignedSuccess) {
  1449. const std::string body = R"(
  1450. OpCapability PhysicalStorageBufferAddressesEXT
  1451. OpCapability Int64
  1452. OpCapability Shader
  1453. OpExtension "SPV_EXT_physical_storage_buffer"
  1454. OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
  1455. OpEntryPoint Fragment %main "main"
  1456. OpExecutionMode %main OriginUpperLeft
  1457. OpDecorate %val1 AliasedPointerEXT
  1458. %uint64 = OpTypeInt 64 0
  1459. %ptr = OpTypePointer PhysicalStorageBufferEXT %uint64
  1460. %pptr_f = OpTypePointer Function %ptr
  1461. %void = OpTypeVoid
  1462. %voidfn = OpTypeFunction %void
  1463. %main = OpFunction %void None %voidfn
  1464. %entry = OpLabel
  1465. %val1 = OpVariable %pptr_f Function
  1466. %val2 = OpLoad %ptr %val1
  1467. %val3 = OpLoad %uint64 %val2 Aligned 8
  1468. OpReturn
  1469. OpFunctionEnd
  1470. )";
  1471. CompileSuccessfully(body.c_str());
  1472. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1473. }
  1474. TEST_F(ValidateMemory, PSBLoadAlignedMissing) {
  1475. const std::string body = R"(
  1476. OpCapability PhysicalStorageBufferAddressesEXT
  1477. OpCapability Int64
  1478. OpCapability Shader
  1479. OpExtension "SPV_EXT_physical_storage_buffer"
  1480. OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
  1481. OpEntryPoint Fragment %main "main"
  1482. OpExecutionMode %main OriginUpperLeft
  1483. OpDecorate %val1 AliasedPointerEXT
  1484. %uint64 = OpTypeInt 64 0
  1485. %ptr = OpTypePointer PhysicalStorageBufferEXT %uint64
  1486. %pptr_f = OpTypePointer Function %ptr
  1487. %void = OpTypeVoid
  1488. %voidfn = OpTypeFunction %void
  1489. %main = OpFunction %void None %voidfn
  1490. %entry = OpLabel
  1491. %val1 = OpVariable %pptr_f Function
  1492. %val2 = OpLoad %ptr %val1
  1493. %val3 = OpLoad %uint64 %val2
  1494. OpReturn
  1495. OpFunctionEnd
  1496. )";
  1497. CompileSuccessfully(body.c_str());
  1498. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1499. EXPECT_THAT(
  1500. getDiagnosticString(),
  1501. HasSubstr(
  1502. "Memory accesses with PhysicalStorageBufferEXT must use Aligned"));
  1503. }
  1504. TEST_F(ValidateMemory, PSBStoreAlignedSuccess) {
  1505. const std::string body = R"(
  1506. OpCapability PhysicalStorageBufferAddressesEXT
  1507. OpCapability Int64
  1508. OpCapability Shader
  1509. OpExtension "SPV_EXT_physical_storage_buffer"
  1510. OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
  1511. OpEntryPoint Fragment %main "main"
  1512. OpExecutionMode %main OriginUpperLeft
  1513. OpDecorate %val1 AliasedPointerEXT
  1514. %uint64 = OpTypeInt 64 0
  1515. %u64_1 = OpConstant %uint64 1
  1516. %ptr = OpTypePointer PhysicalStorageBufferEXT %uint64
  1517. %pptr_f = OpTypePointer Function %ptr
  1518. %void = OpTypeVoid
  1519. %voidfn = OpTypeFunction %void
  1520. %main = OpFunction %void None %voidfn
  1521. %entry = OpLabel
  1522. %val1 = OpVariable %pptr_f Function
  1523. %val2 = OpLoad %ptr %val1
  1524. OpStore %val2 %u64_1 Aligned 8
  1525. OpReturn
  1526. OpFunctionEnd
  1527. )";
  1528. CompileSuccessfully(body.c_str());
  1529. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1530. }
  1531. TEST_F(ValidateMemory, PSBStoreAlignedMissing) {
  1532. const std::string body = R"(
  1533. OpCapability PhysicalStorageBufferAddressesEXT
  1534. OpCapability Int64
  1535. OpCapability Shader
  1536. OpExtension "SPV_EXT_physical_storage_buffer"
  1537. OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
  1538. OpEntryPoint Fragment %main "main"
  1539. OpExecutionMode %main OriginUpperLeft
  1540. OpDecorate %val1 AliasedPointerEXT
  1541. %uint64 = OpTypeInt 64 0
  1542. %u64_1 = OpConstant %uint64 1
  1543. %ptr = OpTypePointer PhysicalStorageBufferEXT %uint64
  1544. %pptr_f = OpTypePointer Function %ptr
  1545. %void = OpTypeVoid
  1546. %voidfn = OpTypeFunction %void
  1547. %main = OpFunction %void None %voidfn
  1548. %entry = OpLabel
  1549. %val1 = OpVariable %pptr_f Function
  1550. %val2 = OpLoad %ptr %val1
  1551. OpStore %val2 %u64_1 None
  1552. OpReturn
  1553. OpFunctionEnd
  1554. )";
  1555. CompileSuccessfully(body.c_str());
  1556. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1557. EXPECT_THAT(
  1558. getDiagnosticString(),
  1559. HasSubstr(
  1560. "Memory accesses with PhysicalStorageBufferEXT must use Aligned"));
  1561. }
  1562. TEST_F(ValidateMemory, PSBVariable) {
  1563. const std::string body = R"(
  1564. OpCapability PhysicalStorageBufferAddressesEXT
  1565. OpCapability Int64
  1566. OpCapability Shader
  1567. OpExtension "SPV_EXT_physical_storage_buffer"
  1568. OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
  1569. OpEntryPoint Fragment %main "main"
  1570. OpExecutionMode %main OriginUpperLeft
  1571. OpDecorate %val1 AliasedPointerEXT
  1572. %uint64 = OpTypeInt 64 0
  1573. %ptr = OpTypePointer PhysicalStorageBufferEXT %uint64
  1574. %val1 = OpVariable %ptr PhysicalStorageBufferEXT
  1575. %void = OpTypeVoid
  1576. %voidfn = OpTypeFunction %void
  1577. %main = OpFunction %void None %voidfn
  1578. %entry = OpLabel
  1579. OpReturn
  1580. OpFunctionEnd
  1581. )";
  1582. CompileSuccessfully(body);
  1583. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1584. EXPECT_THAT(
  1585. getDiagnosticString(),
  1586. HasSubstr("PhysicalStorageBufferEXT must not be used with OpVariable"));
  1587. }
  1588. std::string GenCoopMatLoadStoreShader(const std::string& storeMemoryAccess,
  1589. const std::string& loadMemoryAccess) {
  1590. std::string s = R"(
  1591. OpCapability Shader
  1592. OpCapability GroupNonUniform
  1593. OpCapability VulkanMemoryModelKHR
  1594. OpCapability CooperativeMatrixNV
  1595. OpExtension "SPV_KHR_vulkan_memory_model"
  1596. OpExtension "SPV_NV_cooperative_matrix"
  1597. %1 = OpExtInstImport "GLSL.std.450"
  1598. OpMemoryModel Logical VulkanKHR
  1599. OpEntryPoint GLCompute %4 "main" %11 %21
  1600. OpExecutionMode %4 LocalSize 1 1 1
  1601. OpDecorate %11 BuiltIn SubgroupId
  1602. OpDecorate %21 BuiltIn WorkgroupId
  1603. OpDecorate %74 ArrayStride 4
  1604. OpMemberDecorate %75 0 Offset 0
  1605. OpDecorate %75 Block
  1606. OpDecorate %77 DescriptorSet 0
  1607. OpDecorate %77 Binding 0
  1608. OpDecorate %92 ArrayStride 4
  1609. OpMemberDecorate %93 0 Offset 0
  1610. OpDecorate %93 Block
  1611. OpDecorate %95 DescriptorSet 0
  1612. OpDecorate %95 Binding 1
  1613. OpDecorate %102 ArrayStride 4
  1614. OpMemberDecorate %103 0 Offset 0
  1615. OpDecorate %103 Block
  1616. OpDecorate %105 DescriptorSet 0
  1617. OpDecorate %105 Binding 2
  1618. OpDecorate %117 ArrayStride 4
  1619. OpMemberDecorate %118 0 Offset 0
  1620. OpDecorate %118 Block
  1621. OpDecorate %120 DescriptorSet 0
  1622. OpDecorate %120 Binding 3
  1623. OpDecorate %123 SpecId 2
  1624. OpDecorate %124 SpecId 3
  1625. OpDecorate %125 SpecId 4
  1626. OpDecorate %126 SpecId 5
  1627. OpDecorate %127 SpecId 0
  1628. OpDecorate %128 SpecId 1
  1629. OpDecorate %129 BuiltIn WorkgroupSize
  1630. %2 = OpTypeVoid
  1631. %3 = OpTypeFunction %2
  1632. %6 = OpTypeInt 32 0
  1633. %7 = OpTypeVector %6 2
  1634. %8 = OpTypePointer Function %7
  1635. %10 = OpTypePointer Input %6
  1636. %11 = OpVariable %10 Input
  1637. %13 = OpConstant %6 2
  1638. %19 = OpTypeVector %6 3
  1639. %20 = OpTypePointer Input %19
  1640. %21 = OpVariable %20 Input
  1641. %27 = OpConstantComposite %7 %13 %13
  1642. %31 = OpTypePointer Function %6
  1643. %33 = OpConstant %6 1024
  1644. %34 = OpConstant %6 1
  1645. %38 = OpConstant %6 8
  1646. %39 = OpConstant %6 0
  1647. %68 = OpTypeFloat 32
  1648. %69 = OpConstant %6 16
  1649. %70 = OpConstant %6 3
  1650. %71 = OpTypeCooperativeMatrixNV %68 %70 %69 %38
  1651. %72 = OpTypePointer Function %71
  1652. %74 = OpTypeRuntimeArray %68
  1653. %75 = OpTypeStruct %74
  1654. %76 = OpTypePointer StorageBuffer %75
  1655. %77 = OpVariable %76 StorageBuffer
  1656. %78 = OpTypeInt 32 1
  1657. %79 = OpConstant %78 0
  1658. %81 = OpConstant %6 5
  1659. %82 = OpTypePointer StorageBuffer %68
  1660. %84 = OpConstant %6 64
  1661. %85 = OpTypeBool
  1662. %86 = OpConstantFalse %85
  1663. %88 = OpTypePointer Private %71
  1664. %89 = OpVariable %88 Private
  1665. %92 = OpTypeRuntimeArray %68
  1666. %93 = OpTypeStruct %92
  1667. %94 = OpTypePointer StorageBuffer %93
  1668. %95 = OpVariable %94 StorageBuffer
  1669. %99 = OpVariable %88 Private
  1670. %102 = OpTypeRuntimeArray %68
  1671. %103 = OpTypeStruct %102
  1672. %104 = OpTypePointer StorageBuffer %103
  1673. %105 = OpVariable %104 StorageBuffer
  1674. %109 = OpVariable %88 Private
  1675. %111 = OpVariable %88 Private
  1676. %112 = OpSpecConstantOp %6 CooperativeMatrixLengthNV %71
  1677. %113 = OpSpecConstantOp %78 IAdd %112 %79
  1678. %117 = OpTypeRuntimeArray %68
  1679. %118 = OpTypeStruct %117
  1680. %119 = OpTypePointer StorageBuffer %118
  1681. %120 = OpVariable %119 StorageBuffer
  1682. %123 = OpSpecConstant %78 1
  1683. %124 = OpSpecConstant %78 1
  1684. %125 = OpSpecConstant %78 1
  1685. %126 = OpSpecConstant %78 1
  1686. %127 = OpSpecConstant %6 1
  1687. %128 = OpSpecConstant %6 1
  1688. %129 = OpSpecConstantComposite %19 %127 %128 %34
  1689. %4 = OpFunction %2 None %3
  1690. %5 = OpLabel
  1691. %9 = OpVariable %8 Function
  1692. %18 = OpVariable %8 Function
  1693. %32 = OpVariable %31 Function
  1694. %44 = OpVariable %31 Function
  1695. %52 = OpVariable %31 Function
  1696. %60 = OpVariable %31 Function
  1697. %73 = OpVariable %72 Function
  1698. %91 = OpVariable %72 Function
  1699. %101 = OpVariable %72 Function
  1700. %12 = OpLoad %6 %11
  1701. %14 = OpUMod %6 %12 %13
  1702. %15 = OpLoad %6 %11
  1703. %16 = OpUDiv %6 %15 %13
  1704. %17 = OpCompositeConstruct %7 %14 %16
  1705. OpStore %9 %17
  1706. %22 = OpLoad %19 %21
  1707. %23 = OpVectorShuffle %7 %22 %22 0 1
  1708. %24 = OpCompositeExtract %6 %23 0
  1709. %25 = OpCompositeExtract %6 %23 1
  1710. %26 = OpCompositeConstruct %7 %24 %25
  1711. %28 = OpIMul %7 %26 %27
  1712. %29 = OpLoad %7 %9
  1713. %30 = OpIAdd %7 %28 %29
  1714. OpStore %18 %30
  1715. %35 = OpAccessChain %31 %18 %34
  1716. %36 = OpLoad %6 %35
  1717. %37 = OpIMul %6 %33 %36
  1718. %40 = OpAccessChain %31 %18 %39
  1719. %41 = OpLoad %6 %40
  1720. %42 = OpIMul %6 %38 %41
  1721. %43 = OpIAdd %6 %37 %42
  1722. OpStore %32 %43
  1723. %45 = OpAccessChain %31 %18 %34
  1724. %46 = OpLoad %6 %45
  1725. %47 = OpIMul %6 %33 %46
  1726. %48 = OpAccessChain %31 %18 %39
  1727. %49 = OpLoad %6 %48
  1728. %50 = OpIMul %6 %38 %49
  1729. %51 = OpIAdd %6 %47 %50
  1730. OpStore %44 %51
  1731. %53 = OpAccessChain %31 %18 %34
  1732. %54 = OpLoad %6 %53
  1733. %55 = OpIMul %6 %33 %54
  1734. %56 = OpAccessChain %31 %18 %39
  1735. %57 = OpLoad %6 %56
  1736. %58 = OpIMul %6 %38 %57
  1737. %59 = OpIAdd %6 %55 %58
  1738. OpStore %52 %59
  1739. %61 = OpAccessChain %31 %18 %34
  1740. %62 = OpLoad %6 %61
  1741. %63 = OpIMul %6 %33 %62
  1742. %64 = OpAccessChain %31 %18 %39
  1743. %65 = OpLoad %6 %64
  1744. %66 = OpIMul %6 %38 %65
  1745. %67 = OpIAdd %6 %63 %66
  1746. OpStore %60 %67
  1747. %80 = OpLoad %6 %32
  1748. %83 = OpAccessChain %82 %77 %79 %80
  1749. %87 = OpCooperativeMatrixLoadNV %71 %83 %84 %86 )" +
  1750. loadMemoryAccess + R"( %81
  1751. OpStore %73 %87
  1752. %90 = OpLoad %71 %73
  1753. OpStore %89 %90
  1754. %96 = OpLoad %6 %44
  1755. %97 = OpAccessChain %82 %95 %79 %96
  1756. %98 = OpCooperativeMatrixLoadNV %71 %97 %84 %86 MakePointerVisibleKHR|NonPrivatePointerKHR %81
  1757. OpStore %91 %98
  1758. %100 = OpLoad %71 %91
  1759. OpStore %99 %100
  1760. %106 = OpLoad %6 %52
  1761. %107 = OpAccessChain %82 %105 %79 %106
  1762. %108 = OpCooperativeMatrixLoadNV %71 %107 %84 %86 MakePointerVisibleKHR|NonPrivatePointerKHR %81
  1763. OpStore %101 %108
  1764. %110 = OpLoad %71 %101
  1765. OpStore %109 %110
  1766. %114 = OpConvertSToF %68 %113
  1767. %115 = OpCompositeConstruct %71 %114
  1768. OpStore %111 %115
  1769. %116 = OpLoad %71 %111
  1770. %121 = OpLoad %6 %60
  1771. %122 = OpAccessChain %82 %120 %79 %121
  1772. OpCooperativeMatrixStoreNV %122 %116 %84 %86 )" + storeMemoryAccess + R"( %81
  1773. OpReturn
  1774. OpFunctionEnd
  1775. )";
  1776. return s;
  1777. }
  1778. TEST_F(ValidateMemory, CoopMatLoadStoreSuccess) {
  1779. std::string spirv =
  1780. GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
  1781. "MakePointerVisibleKHR|NonPrivatePointerKHR");
  1782. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  1783. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  1784. }
  1785. TEST_F(ValidateMemory, CoopMatStoreMemoryAccessFail) {
  1786. std::string spirv =
  1787. GenCoopMatLoadStoreShader("MakePointerVisibleKHR|NonPrivatePointerKHR",
  1788. "MakePointerVisibleKHR|NonPrivatePointerKHR");
  1789. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  1790. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  1791. EXPECT_THAT(getDiagnosticString(),
  1792. HasSubstr("MakePointerVisibleKHR cannot be used with OpStore"));
  1793. }
  1794. TEST_F(ValidateMemory, CoopMatLoadMemoryAccessFail) {
  1795. std::string spirv =
  1796. GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
  1797. "MakePointerAvailableKHR|NonPrivatePointerKHR");
  1798. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  1799. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  1800. EXPECT_THAT(getDiagnosticString(),
  1801. HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad"));
  1802. }
  1803. TEST_F(ValidateMemory, CoopMatInvalidStorageClassFail) {
  1804. const std::string body =
  1805. R"(
  1806. OpCapability Shader
  1807. OpCapability Float16
  1808. OpCapability CooperativeMatrixNV
  1809. OpExtension "SPV_NV_cooperative_matrix"
  1810. OpMemoryModel Logical GLSL450
  1811. OpEntryPoint GLCompute %main "main"
  1812. %void = OpTypeVoid
  1813. %func = OpTypeFunction %void
  1814. %f16 = OpTypeFloat 16
  1815. %u32 = OpTypeInt 32 0
  1816. %u32_8 = OpConstant %u32 8
  1817. %subgroup = OpConstant %u32 3
  1818. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  1819. %str = OpTypeStruct %f16mat
  1820. %str_ptr = OpTypePointer Workgroup %str
  1821. %sh = OpVariable %str_ptr Workgroup
  1822. %main = OpFunction %void None %func
  1823. %main_entry = OpLabel
  1824. OpReturn
  1825. OpFunctionEnd)";
  1826. CompileSuccessfully(body.c_str());
  1827. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1828. EXPECT_THAT(
  1829. getDiagnosticString(),
  1830. HasSubstr(
  1831. "Cooperative matrix types (or types containing them) can only be "
  1832. "allocated in Function or Private storage classes or as function "
  1833. "parameters"));
  1834. }
  1835. TEST_F(ValidateMemory, CoopMatMatrixLengthResultTypeBad) {
  1836. const std::string body =
  1837. R"(
  1838. OpCapability Shader
  1839. OpCapability Float16
  1840. OpCapability CooperativeMatrixNV
  1841. OpExtension "SPV_NV_cooperative_matrix"
  1842. OpMemoryModel Logical GLSL450
  1843. OpEntryPoint GLCompute %main "main"
  1844. %void = OpTypeVoid
  1845. %func = OpTypeFunction %void
  1846. %f16 = OpTypeFloat 16
  1847. %u32 = OpTypeInt 32 0
  1848. %i32 = OpTypeInt 32 1
  1849. %u32_8 = OpConstant %u32 8
  1850. %subgroup = OpConstant %u32 3
  1851. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  1852. %main = OpFunction %void None %func
  1853. %main_entry = OpLabel
  1854. %1 = OpCooperativeMatrixLengthNV %i32 %f16mat
  1855. OpReturn
  1856. OpFunctionEnd)";
  1857. CompileSuccessfully(body.c_str());
  1858. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1859. EXPECT_THAT(
  1860. getDiagnosticString(),
  1861. HasSubstr("The Result Type of OpCooperativeMatrixLengthNV <id> "
  1862. "'11[%11]' must be OpTypeInt with width 32 and signedness 0"));
  1863. }
  1864. TEST_F(ValidateMemory, CoopMatMatrixLengthOperandTypeBad) {
  1865. const std::string body =
  1866. R"(
  1867. OpCapability Shader
  1868. OpCapability Float16
  1869. OpCapability CooperativeMatrixNV
  1870. OpExtension "SPV_NV_cooperative_matrix"
  1871. OpMemoryModel Logical GLSL450
  1872. OpEntryPoint GLCompute %main "main"
  1873. %void = OpTypeVoid
  1874. %func = OpTypeFunction %void
  1875. %f16 = OpTypeFloat 16
  1876. %u32 = OpTypeInt 32 0
  1877. %i32 = OpTypeInt 32 1
  1878. %u32_8 = OpConstant %u32 8
  1879. %subgroup = OpConstant %u32 3
  1880. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  1881. %main = OpFunction %void None %func
  1882. %main_entry = OpLabel
  1883. %1 = OpCooperativeMatrixLengthNV %u32 %u32
  1884. OpReturn
  1885. OpFunctionEnd)";
  1886. CompileSuccessfully(body.c_str());
  1887. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1888. EXPECT_THAT(
  1889. getDiagnosticString(),
  1890. HasSubstr("The type in OpCooperativeMatrixLengthNV <id> '5[%uint]' "
  1891. "must be OpTypeCooperativeMatrixNV"));
  1892. }
  1893. TEST_F(ValidateMemory, CoopMatMatrixLengthGood) {
  1894. const std::string body =
  1895. R"(
  1896. OpCapability Shader
  1897. OpCapability Float16
  1898. OpCapability CooperativeMatrixNV
  1899. OpExtension "SPV_NV_cooperative_matrix"
  1900. OpMemoryModel Logical GLSL450
  1901. OpEntryPoint GLCompute %main "main"
  1902. %void = OpTypeVoid
  1903. %func = OpTypeFunction %void
  1904. %f16 = OpTypeFloat 16
  1905. %u32 = OpTypeInt 32 0
  1906. %i32 = OpTypeInt 32 1
  1907. %u32_8 = OpConstant %u32 8
  1908. %subgroup = OpConstant %u32 3
  1909. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  1910. %main = OpFunction %void None %func
  1911. %main_entry = OpLabel
  1912. %1 = OpCooperativeMatrixLengthNV %u32 %f16mat
  1913. OpReturn
  1914. OpFunctionEnd)";
  1915. CompileSuccessfully(body.c_str());
  1916. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1917. }
  1918. TEST_F(ValidateMemory, VulkanRTAOutsideOfStructBad) {
  1919. std::string spirv = R"(
  1920. OpCapability Shader
  1921. OpMemoryModel Logical GLSL450
  1922. OpEntryPoint Fragment %func "func"
  1923. OpExecutionMode %func OriginUpperLeft
  1924. %sampler_t = OpTypeSampler
  1925. %array_t = OpTypeRuntimeArray %sampler_t
  1926. %array_ptr = OpTypePointer UniformConstant %array_t
  1927. %2 = OpVariable %array_ptr UniformConstant
  1928. %void = OpTypeVoid
  1929. %func_t = OpTypeFunction %void
  1930. %func = OpFunction %void None %func_t
  1931. %1 = OpLabel
  1932. OpReturn
  1933. OpFunctionEnd
  1934. )";
  1935. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  1936. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  1937. EXPECT_THAT(
  1938. getDiagnosticString(),
  1939. HasSubstr(
  1940. "OpVariable, <id> '5[%5]', is attempting to create memory for an "
  1941. "illegal type, OpTypeRuntimeArray.\nFor Vulkan OpTypeRuntimeArray "
  1942. "can only appear as the final member of an OpTypeStruct, thus cannot "
  1943. "be instantiated via OpVariable\n %5 = OpVariable "
  1944. "%_ptr_UniformConstant__runtimearr_2 UniformConstant\n"));
  1945. }
  1946. TEST_F(ValidateMemory, VulkanRTAOutsideOfStructWithRuntimeDescriptorArrayGood) {
  1947. std::string spirv = R"(
  1948. OpCapability Shader
  1949. OpCapability RuntimeDescriptorArrayEXT
  1950. OpExtension "SPV_EXT_descriptor_indexing"
  1951. OpMemoryModel Logical GLSL450
  1952. OpEntryPoint Fragment %func "func"
  1953. OpExecutionMode %func OriginUpperLeft
  1954. OpDecorate %struct Block
  1955. OpMemberDecorate %struct 0 Offset 0
  1956. %sampler_t = OpTypeSampler
  1957. %uint = OpTypeInt 32 0
  1958. %array_t = OpTypeRuntimeArray %sampler_t
  1959. %struct = OpTypeStruct %uint
  1960. %sb_array_t = OpTypeRuntimeArray %struct
  1961. %array_sb_ptr = OpTypePointer StorageBuffer %sb_array_t
  1962. %2 = OpVariable %array_sb_ptr StorageBuffer
  1963. %array_uc_ptr = OpTypePointer UniformConstant %array_t
  1964. %3 = OpVariable %array_uc_ptr UniformConstant
  1965. %void = OpTypeVoid
  1966. %func_t = OpTypeFunction %void
  1967. %func = OpFunction %void None %func_t
  1968. %1 = OpLabel
  1969. OpReturn
  1970. OpFunctionEnd
  1971. )";
  1972. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  1973. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  1974. }
  1975. TEST_F(
  1976. ValidateMemory,
  1977. VulkanRTAOutsideOfStructWithRuntimeDescriptorArrayAndWrongStorageClassBad) {
  1978. std::string spirv = R"(
  1979. OpCapability Shader
  1980. OpCapability RuntimeDescriptorArrayEXT
  1981. OpExtension "SPV_EXT_descriptor_indexing"
  1982. OpMemoryModel Logical GLSL450
  1983. OpEntryPoint Fragment %func "func"
  1984. OpExecutionMode %func OriginUpperLeft
  1985. %uint_t = OpTypeInt 32 0
  1986. %array_t = OpTypeRuntimeArray %uint_t
  1987. %array_ptr = OpTypePointer Workgroup %array_t
  1988. %2 = OpVariable %array_ptr Workgroup
  1989. %void = OpTypeVoid
  1990. %func_t = OpTypeFunction %void
  1991. %func = OpFunction %void None %func_t
  1992. %1 = OpLabel
  1993. OpReturn
  1994. OpFunctionEnd
  1995. )";
  1996. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  1997. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  1998. EXPECT_THAT(
  1999. getDiagnosticString(),
  2000. HasSubstr("For Vulkan with RuntimeDescriptorArrayEXT, a variable "
  2001. "containing OpTypeRuntimeArray must have storage class of "
  2002. "StorageBuffer, Uniform, or UniformConstant.\n %5 = "
  2003. "OpVariable %_ptr_Workgroup__runtimearr_uint Workgroup\n"));
  2004. }
  2005. TEST_F(ValidateMemory, VulkanRTAInsideStorageBufferStructGood) {
  2006. std::string spirv = R"(
  2007. OpCapability Shader
  2008. OpMemoryModel Logical GLSL450
  2009. OpEntryPoint Fragment %func "func"
  2010. OpExecutionMode %func OriginUpperLeft
  2011. OpDecorate %array_t ArrayStride 4
  2012. OpMemberDecorate %struct_t 0 Offset 0
  2013. OpDecorate %struct_t Block
  2014. %uint_t = OpTypeInt 32 0
  2015. %array_t = OpTypeRuntimeArray %uint_t
  2016. %struct_t = OpTypeStruct %array_t
  2017. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  2018. %2 = OpVariable %struct_ptr StorageBuffer
  2019. %void = OpTypeVoid
  2020. %func_t = OpTypeFunction %void
  2021. %func = OpFunction %void None %func_t
  2022. %1 = OpLabel
  2023. OpReturn
  2024. OpFunctionEnd
  2025. )";
  2026. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2027. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2028. }
  2029. TEST_F(ValidateMemory, VulkanRTAInsideWrongStorageClassStructBad) {
  2030. std::string spirv = R"(
  2031. OpCapability Shader
  2032. OpMemoryModel Logical GLSL450
  2033. OpEntryPoint Fragment %func "func"
  2034. OpExecutionMode %func OriginUpperLeft
  2035. %uint_t = OpTypeInt 32 0
  2036. %array_t = OpTypeRuntimeArray %uint_t
  2037. %struct_t = OpTypeStruct %array_t
  2038. %struct_ptr = OpTypePointer Workgroup %struct_t
  2039. %2 = OpVariable %struct_ptr Workgroup
  2040. %void = OpTypeVoid
  2041. %func_t = OpTypeFunction %void
  2042. %func = OpFunction %void None %func_t
  2043. %1 = OpLabel
  2044. OpReturn
  2045. OpFunctionEnd
  2046. )";
  2047. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2048. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2049. EXPECT_THAT(
  2050. getDiagnosticString(),
  2051. HasSubstr(
  2052. "For Vulkan, OpTypeStruct variables containing OpTypeRuntimeArray "
  2053. "must have storage class of StorageBuffer or Uniform.\n %6 = "
  2054. "OpVariable %_ptr_Workgroup__struct_4 Workgroup\n"));
  2055. }
  2056. TEST_F(ValidateMemory, VulkanRTAInsideStorageBufferStructWithoutBlockBad) {
  2057. std::string spirv = R"(
  2058. OpCapability Shader
  2059. OpMemoryModel Logical GLSL450
  2060. OpEntryPoint Fragment %func "func"
  2061. OpExecutionMode %func OriginUpperLeft
  2062. %uint_t = OpTypeInt 32 0
  2063. %array_t = OpTypeRuntimeArray %uint_t
  2064. %struct_t = OpTypeStruct %array_t
  2065. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  2066. %2 = OpVariable %struct_ptr StorageBuffer
  2067. %void = OpTypeVoid
  2068. %func_t = OpTypeFunction %void
  2069. %func = OpFunction %void None %func_t
  2070. %1 = OpLabel
  2071. OpReturn
  2072. OpFunctionEnd
  2073. )";
  2074. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2075. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2076. EXPECT_THAT(getDiagnosticString(),
  2077. HasSubstr("For Vulkan, an OpTypeStruct variable containing an "
  2078. "OpTypeRuntimeArray must be decorated with Block if it "
  2079. "has storage class StorageBuffer.\n %6 = OpVariable "
  2080. "%_ptr_StorageBuffer__struct_4 StorageBuffer\n"));
  2081. }
  2082. TEST_F(ValidateMemory, VulkanRTAInsideUniformStructGood) {
  2083. std::string spirv = R"(
  2084. OpCapability Shader
  2085. OpMemoryModel Logical GLSL450
  2086. OpEntryPoint Fragment %func "func"
  2087. OpExecutionMode %func OriginUpperLeft
  2088. OpDecorate %array_t ArrayStride 4
  2089. OpMemberDecorate %struct_t 0 Offset 0
  2090. OpDecorate %struct_t BufferBlock
  2091. %uint_t = OpTypeInt 32 0
  2092. %array_t = OpTypeRuntimeArray %uint_t
  2093. %struct_t = OpTypeStruct %array_t
  2094. %struct_ptr = OpTypePointer Uniform %struct_t
  2095. %2 = OpVariable %struct_ptr Uniform
  2096. %void = OpTypeVoid
  2097. %func_t = OpTypeFunction %void
  2098. %func = OpFunction %void None %func_t
  2099. %1 = OpLabel
  2100. OpReturn
  2101. OpFunctionEnd
  2102. )";
  2103. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2104. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2105. }
  2106. TEST_F(ValidateMemory, VulkanRTAInsideUniformStructWithoutBufferBlockBad) {
  2107. std::string spirv = R"(
  2108. OpCapability Shader
  2109. OpMemoryModel Logical GLSL450
  2110. OpEntryPoint Fragment %func "func"
  2111. OpExecutionMode %func OriginUpperLeft
  2112. %uint_t = OpTypeInt 32 0
  2113. %array_t = OpTypeRuntimeArray %uint_t
  2114. %struct_t = OpTypeStruct %array_t
  2115. %struct_ptr = OpTypePointer Uniform %struct_t
  2116. %2 = OpVariable %struct_ptr Uniform
  2117. %void = OpTypeVoid
  2118. %func_t = OpTypeFunction %void
  2119. %func = OpFunction %void None %func_t
  2120. %1 = OpLabel
  2121. OpReturn
  2122. OpFunctionEnd
  2123. )";
  2124. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2125. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2126. EXPECT_THAT(getDiagnosticString(),
  2127. HasSubstr("For Vulkan, an OpTypeStruct variable containing an "
  2128. "OpTypeRuntimeArray must be decorated with BufferBlock "
  2129. "if it has storage class Uniform.\n %6 = OpVariable "
  2130. "%_ptr_Uniform__struct_4 Uniform\n"));
  2131. }
  2132. TEST_F(ValidateMemory, VulkanRTAInsideRTABad) {
  2133. std::string spirv = R"(
  2134. OpCapability Shader
  2135. OpMemoryModel Logical GLSL450
  2136. OpEntryPoint Fragment %func "func"
  2137. OpExecutionMode %func OriginUpperLeft
  2138. %sampler_t = OpTypeSampler
  2139. %inner_array_t = OpTypeRuntimeArray %sampler_t
  2140. %array_t = OpTypeRuntimeArray %inner_array_t
  2141. %array_ptr = OpTypePointer UniformConstant %array_t
  2142. %2 = OpVariable %array_ptr UniformConstant
  2143. %void = OpTypeVoid
  2144. %func_t = OpTypeFunction %void
  2145. %func = OpFunction %void None %func_t
  2146. %1 = OpLabel
  2147. OpReturn
  2148. OpFunctionEnd
  2149. )";
  2150. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2151. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2152. EXPECT_THAT(
  2153. getDiagnosticString(),
  2154. HasSubstr(
  2155. "OpTypeRuntimeArray Element Type <id> '3[%_runtimearr_2]' is not "
  2156. "valid in Vulkan environments.\n %_runtimearr__runtimearr_2 = "
  2157. "OpTypeRuntimeArray %_runtimearr_2\n"));
  2158. }
  2159. TEST_F(ValidateMemory, VulkanRTAInsideRTAWithRuntimeDescriptorArrayBad) {
  2160. std::string spirv = R"(
  2161. OpCapability RuntimeDescriptorArrayEXT
  2162. OpCapability Shader
  2163. OpExtension "SPV_EXT_descriptor_indexing"
  2164. OpMemoryModel Logical GLSL450
  2165. OpEntryPoint Fragment %func "func"
  2166. OpExecutionMode %func OriginUpperLeft
  2167. OpDecorate %array_t Block
  2168. %uint_t = OpTypeInt 32 0
  2169. %inner_array_t = OpTypeRuntimeArray %uint_t
  2170. %array_t = OpTypeRuntimeArray %inner_array_t
  2171. %array_ptr = OpTypePointer StorageBuffer %array_t
  2172. %2 = OpVariable %array_ptr StorageBuffer
  2173. %void = OpTypeVoid
  2174. %func_t = OpTypeFunction %void
  2175. %func = OpFunction %void None %func_t
  2176. %1 = OpLabel
  2177. OpReturn
  2178. OpFunctionEnd
  2179. )";
  2180. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2181. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2182. EXPECT_THAT(
  2183. getDiagnosticString(),
  2184. HasSubstr(
  2185. "OpTypeRuntimeArray Element Type <id> '4[%_runtimearr_uint]' is not "
  2186. "valid in Vulkan environments.\n %_runtimearr__runtimearr_uint = "
  2187. "OpTypeRuntimeArray %_runtimearr_uint\n"));
  2188. }
  2189. TEST_F(ValidateMemory,
  2190. VulkanUniformStructInsideRTAWithRuntimeDescriptorArrayGood) {
  2191. std::string spirv = R"(
  2192. OpCapability RuntimeDescriptorArrayEXT
  2193. OpCapability Shader
  2194. OpExtension "SPV_EXT_descriptor_indexing"
  2195. OpMemoryModel Logical GLSL450
  2196. OpEntryPoint Fragment %func "func"
  2197. OpExecutionMode %func OriginUpperLeft
  2198. OpDecorate %array_t ArrayStride 4
  2199. OpMemberDecorate %struct_t 0 Offset 0
  2200. OpDecorate %struct_t Block
  2201. %uint_t = OpTypeInt 32 0
  2202. %struct_t = OpTypeStruct %uint_t
  2203. %array_t = OpTypeRuntimeArray %struct_t
  2204. %array_ptr = OpTypePointer Uniform %array_t
  2205. %2 = OpVariable %array_ptr Uniform
  2206. %void = OpTypeVoid
  2207. %func_t = OpTypeFunction %void
  2208. %func = OpFunction %void None %func_t
  2209. %1 = OpLabel
  2210. OpReturn
  2211. OpFunctionEnd
  2212. )";
  2213. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2214. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2215. }
  2216. TEST_F(ValidateMemory, VulkanRTAInsideRTAInsideStructBad) {
  2217. std::string spirv = R"(
  2218. OpCapability Shader
  2219. OpMemoryModel Logical GLSL450
  2220. OpEntryPoint Fragment %func "func"
  2221. OpExecutionMode %func OriginUpperLeft
  2222. OpDecorate %array_t ArrayStride 4
  2223. OpMemberDecorate %struct_t 0 Offset 0
  2224. OpDecorate %struct_t Block
  2225. %uint_t = OpTypeInt 32 0
  2226. %inner_array_t = OpTypeRuntimeArray %uint_t
  2227. %array_t = OpTypeRuntimeArray %inner_array_t
  2228. %struct_t = OpTypeStruct %array_t
  2229. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  2230. %2 = OpVariable %struct_ptr StorageBuffer
  2231. %void = OpTypeVoid
  2232. %func_t = OpTypeFunction %void
  2233. %func = OpFunction %void None %func_t
  2234. %1 = OpLabel
  2235. OpReturn
  2236. OpFunctionEnd
  2237. )";
  2238. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2239. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2240. EXPECT_THAT(
  2241. getDiagnosticString(),
  2242. HasSubstr(
  2243. "OpTypeRuntimeArray Element Type <id> '5[%_runtimearr_uint]' is not "
  2244. "valid in Vulkan environments.\n %_runtimearr__runtimearr_uint = "
  2245. "OpTypeRuntimeArray %_runtimearr_uint\n"));
  2246. }
  2247. TEST_F(ValidateMemory,
  2248. VulkanRTAInsideRTAInsideStructWithRuntimeDescriptorArrayBad) {
  2249. std::string spirv = R"(
  2250. OpCapability RuntimeDescriptorArrayEXT
  2251. OpCapability Shader
  2252. OpExtension "SPV_EXT_descriptor_indexing"
  2253. OpMemoryModel Logical GLSL450
  2254. OpEntryPoint Fragment %func "func"
  2255. OpExecutionMode %func OriginUpperLeft
  2256. OpDecorate %array_t ArrayStride 4
  2257. OpMemberDecorate %struct_t 0 Offset 0
  2258. OpDecorate %struct_t Block
  2259. %uint_t = OpTypeInt 32 0
  2260. %inner_array_t = OpTypeRuntimeArray %uint_t
  2261. %array_t = OpTypeRuntimeArray %inner_array_t
  2262. %struct_t = OpTypeStruct %array_t
  2263. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  2264. %2 = OpVariable %struct_ptr StorageBuffer
  2265. %void = OpTypeVoid
  2266. %func_t = OpTypeFunction %void
  2267. %func = OpFunction %void None %func_t
  2268. %1 = OpLabel
  2269. OpReturn
  2270. OpFunctionEnd
  2271. )";
  2272. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2273. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2274. EXPECT_THAT(
  2275. getDiagnosticString(),
  2276. HasSubstr(
  2277. "OpTypeRuntimeArray Element Type <id> '5[%_runtimearr_uint]' is not "
  2278. "valid in Vulkan environments.\n %_runtimearr__runtimearr_uint = "
  2279. "OpTypeRuntimeArray %_runtimearr_uint\n"));
  2280. }
  2281. TEST_F(ValidateMemory, VulkanRTAInsideArrayBad) {
  2282. std::string spirv = R"(
  2283. OpCapability Shader
  2284. OpMemoryModel Logical GLSL450
  2285. OpEntryPoint Fragment %func "func"
  2286. OpExecutionMode %func OriginUpperLeft
  2287. %uint_t = OpTypeInt 32 0
  2288. %dim = OpConstant %uint_t 1
  2289. %sampler_t = OpTypeSampler
  2290. %inner_array_t = OpTypeRuntimeArray %sampler_t
  2291. %array_t = OpTypeArray %inner_array_t %dim
  2292. %array_ptr = OpTypePointer UniformConstant %array_t
  2293. %2 = OpVariable %array_ptr UniformConstant
  2294. %void = OpTypeVoid
  2295. %func_t = OpTypeFunction %void
  2296. %func = OpFunction %void None %func_t
  2297. %1 = OpLabel
  2298. OpReturn
  2299. OpFunctionEnd
  2300. )";
  2301. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2302. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2303. EXPECT_THAT(
  2304. getDiagnosticString(),
  2305. HasSubstr("OpTypeArray Element Type <id> '5[%_runtimearr_4]' is not "
  2306. "valid in Vulkan environments.\n %_arr__runtimearr_4_uint_1 = "
  2307. "OpTypeArray %_runtimearr_4 %uint_1\n"));
  2308. }
  2309. TEST_F(ValidateMemory, VulkanRTAInsideArrayWithRuntimeDescriptorArrayBad) {
  2310. std::string spirv = R"(
  2311. OpCapability RuntimeDescriptorArrayEXT
  2312. OpCapability Shader
  2313. OpExtension "SPV_EXT_descriptor_indexing"
  2314. OpMemoryModel Logical GLSL450
  2315. OpEntryPoint Fragment %func "func"
  2316. OpExecutionMode %func OriginUpperLeft
  2317. OpDecorate %array_t Block
  2318. %uint_t = OpTypeInt 32 0
  2319. %dim = OpConstant %uint_t 1
  2320. %sampler_t = OpTypeSampler
  2321. %inner_array_t = OpTypeRuntimeArray %uint_t
  2322. %array_t = OpTypeRuntimeArray %inner_array_t
  2323. %array_ptr = OpTypePointer StorageBuffer %array_t
  2324. %2 = OpVariable %array_ptr StorageBuffer
  2325. %void = OpTypeVoid
  2326. %func_t = OpTypeFunction %void
  2327. %func = OpFunction %void None %func_t
  2328. %1 = OpLabel
  2329. OpReturn
  2330. OpFunctionEnd
  2331. )";
  2332. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2333. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2334. EXPECT_THAT(
  2335. getDiagnosticString(),
  2336. HasSubstr(
  2337. "OpTypeRuntimeArray Element Type <id> '6[%_runtimearr_uint]' is not "
  2338. "valid in Vulkan environments.\n %_runtimearr__runtimearr_uint = "
  2339. "OpTypeRuntimeArray %_runtimearr_uint\n"));
  2340. }
  2341. TEST_F(ValidateMemory, VulkanRTAInsideArrayInsideStructBad) {
  2342. std::string spirv = R"(
  2343. OpCapability Shader
  2344. OpMemoryModel Logical GLSL450
  2345. OpEntryPoint Fragment %func "func"
  2346. OpExecutionMode %func OriginUpperLeft
  2347. OpDecorate %array_t ArrayStride 4
  2348. OpMemberDecorate %struct_t 0 Offset 0
  2349. OpDecorate %struct_t Block
  2350. %uint_t = OpTypeInt 32 0
  2351. %dim = OpConstant %uint_t 1
  2352. %inner_array_t = OpTypeRuntimeArray %uint_t
  2353. %array_t = OpTypeArray %inner_array_t %dim
  2354. %struct_t = OpTypeStruct %array_t
  2355. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  2356. %2 = OpVariable %struct_ptr StorageBuffer
  2357. %void = OpTypeVoid
  2358. %func_t = OpTypeFunction %void
  2359. %func = OpFunction %void None %func_t
  2360. %1 = OpLabel
  2361. OpReturn
  2362. OpFunctionEnd
  2363. )";
  2364. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2365. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2366. EXPECT_THAT(
  2367. getDiagnosticString(),
  2368. HasSubstr(
  2369. "OpTypeArray Element Type <id> '6[%_runtimearr_uint]' is not "
  2370. "valid in Vulkan environments.\n %_arr__runtimearr_uint_uint_1 "
  2371. "= OpTypeArray %_runtimearr_uint %uint_1\n"));
  2372. }
  2373. TEST_F(ValidateMemory,
  2374. VulkanRTAInsideArrayInsideStructWithRuntimeDescriptorArrayBad) {
  2375. std::string spirv = R"(
  2376. OpCapability RuntimeDescriptorArrayEXT
  2377. OpCapability Shader
  2378. OpExtension "SPV_EXT_descriptor_indexing"
  2379. OpMemoryModel Logical GLSL450
  2380. OpEntryPoint Fragment %func "func"
  2381. OpExecutionMode %func OriginUpperLeft
  2382. OpDecorate %array_t ArrayStride 4
  2383. OpMemberDecorate %struct_t 0 Offset 0
  2384. OpDecorate %struct_t Block
  2385. %uint_t = OpTypeInt 32 0
  2386. %dim = OpConstant %uint_t 1
  2387. %inner_array_t = OpTypeRuntimeArray %uint_t
  2388. %array_t = OpTypeArray %inner_array_t %dim
  2389. %struct_t = OpTypeStruct %array_t
  2390. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  2391. %2 = OpVariable %struct_ptr StorageBuffer
  2392. %void = OpTypeVoid
  2393. %func_t = OpTypeFunction %void
  2394. %func = OpFunction %void None %func_t
  2395. %1 = OpLabel
  2396. OpReturn
  2397. OpFunctionEnd
  2398. )";
  2399. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2400. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2401. EXPECT_THAT(
  2402. getDiagnosticString(),
  2403. HasSubstr(
  2404. "OpTypeArray Element Type <id> '6[%_runtimearr_uint]' is not "
  2405. "valid in Vulkan environments.\n %_arr__runtimearr_uint_uint_1 "
  2406. "= OpTypeArray %_runtimearr_uint %uint_1\n"));
  2407. }
  2408. TEST_F(ValidateMemory, VulkanRTAStructInsideRTAWithRuntimeDescriptorArrayGood) {
  2409. std::string spirv = R"(
  2410. OpCapability RuntimeDescriptorArrayEXT
  2411. OpCapability Shader
  2412. OpExtension "SPV_EXT_descriptor_indexing"
  2413. OpMemoryModel Logical GLSL450
  2414. OpEntryPoint Fragment %func "func"
  2415. OpExecutionMode %func OriginUpperLeft
  2416. OpDecorate %inner_array_t ArrayStride 4
  2417. OpDecorate %array_t ArrayStride 4
  2418. OpMemberDecorate %struct_t 0 Offset 0
  2419. OpDecorate %struct_t Block
  2420. %uint_t = OpTypeInt 32 0
  2421. %inner_array_t = OpTypeRuntimeArray %uint_t
  2422. %struct_t = OpTypeStruct %inner_array_t
  2423. %array_t = OpTypeRuntimeArray %struct_t
  2424. %array_ptr = OpTypePointer StorageBuffer %array_t
  2425. %2 = OpVariable %array_ptr StorageBuffer
  2426. %void = OpTypeVoid
  2427. %func_t = OpTypeFunction %void
  2428. %func = OpFunction %void None %func_t
  2429. %1 = OpLabel
  2430. OpReturn
  2431. OpFunctionEnd
  2432. )";
  2433. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2434. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2435. }
  2436. TEST_F(ValidateMemory, VulkanRTAStructInsideArrayGood) {
  2437. std::string spirv = R"(
  2438. OpCapability RuntimeDescriptorArrayEXT
  2439. OpCapability Shader
  2440. OpExtension "SPV_EXT_descriptor_indexing"
  2441. OpMemoryModel Logical GLSL450
  2442. OpEntryPoint Fragment %func "func"
  2443. OpExecutionMode %func OriginUpperLeft
  2444. OpDecorate %inner_array_t ArrayStride 4
  2445. OpDecorate %array_t ArrayStride 4
  2446. OpMemberDecorate %struct_t 0 Offset 0
  2447. OpDecorate %struct_t Block
  2448. %uint_t = OpTypeInt 32 0
  2449. %inner_array_t = OpTypeRuntimeArray %uint_t
  2450. %struct_t = OpTypeStruct %inner_array_t
  2451. %array_size = OpConstant %uint_t 5
  2452. %array_t = OpTypeArray %struct_t %array_size
  2453. %array_ptr = OpTypePointer StorageBuffer %array_t
  2454. %2 = OpVariable %array_ptr StorageBuffer
  2455. %void = OpTypeVoid
  2456. %func_t = OpTypeFunction %void
  2457. %func = OpFunction %void None %func_t
  2458. %1 = OpLabel
  2459. OpReturn
  2460. OpFunctionEnd
  2461. )";
  2462. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2463. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2464. }
  2465. TEST_F(ValidateMemory, CopyMemoryNoAccessGood) {
  2466. const std::string spirv = R"(
  2467. OpCapability Shader
  2468. OpCapability Linkage
  2469. OpMemoryModel Logical GLSL450
  2470. %void = OpTypeVoid
  2471. %int = OpTypeInt 32 0
  2472. %int_ptr_priv = OpTypePointer Private %int
  2473. %var1 = OpVariable %int_ptr_priv Private
  2474. %var2 = OpVariable %int_ptr_priv Private
  2475. %voidfn = OpTypeFunction %void
  2476. %func = OpFunction %void None %voidfn
  2477. %entry = OpLabel
  2478. OpCopyMemory %var1 %var2
  2479. OpReturn
  2480. OpFunctionEnd
  2481. )";
  2482. CompileSuccessfully(spirv);
  2483. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2484. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2485. }
  2486. TEST_F(ValidateMemory, CopyMemorySimpleMixedAccessGood) {
  2487. // Test one memory access operand using features that don't require the
  2488. // Vulkan memory model.
  2489. const std::string spirv = R"(
  2490. OpCapability Shader
  2491. OpCapability Linkage
  2492. OpMemoryModel Logical GLSL450
  2493. %void = OpTypeVoid
  2494. %int = OpTypeInt 32 0
  2495. %int_ptr_priv = OpTypePointer Private %int
  2496. %var1 = OpVariable %int_ptr_priv Private
  2497. %var2 = OpVariable %int_ptr_priv Private
  2498. %voidfn = OpTypeFunction %void
  2499. %func = OpFunction %void None %voidfn
  2500. %entry = OpLabel
  2501. OpCopyMemory %var1 %var2 Volatile|Aligned|Nontemporal 4
  2502. OpReturn
  2503. OpFunctionEnd
  2504. )";
  2505. CompileSuccessfully(spirv);
  2506. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2507. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2508. }
  2509. TEST_F(ValidateMemory, CopyMemorySimpleTwoMixedAccessV13Bad) {
  2510. // Two memory access operands is invalid up to SPIR-V 1.3
  2511. const std::string spirv = R"(
  2512. OpCapability Shader
  2513. OpCapability Linkage
  2514. OpMemoryModel Logical GLSL450
  2515. %void = OpTypeVoid
  2516. %int = OpTypeInt 32 0
  2517. %int_ptr_priv = OpTypePointer Private %int
  2518. %var1 = OpVariable %int_ptr_priv Private
  2519. %var2 = OpVariable %int_ptr_priv Private
  2520. %voidfn = OpTypeFunction %void
  2521. %func = OpFunction %void None %voidfn
  2522. %entry = OpLabel
  2523. OpCopyMemory %var1 %var2 Volatile Volatile
  2524. OpReturn
  2525. OpFunctionEnd
  2526. )";
  2527. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  2528. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  2529. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2530. EXPECT_THAT(getDiagnosticString(),
  2531. HasSubstr("CopyMemory with two memory access operands requires "
  2532. "SPIR-V 1.4 or later"));
  2533. }
  2534. TEST_F(ValidateMemory, CopyMemorySimpleTwoMixedAccessV14Good) {
  2535. // Two memory access operands is valid in SPIR-V 1.4
  2536. const std::string spirv = R"(
  2537. OpCapability Shader
  2538. OpCapability Linkage
  2539. OpMemoryModel Logical GLSL450
  2540. %void = OpTypeVoid
  2541. %int = OpTypeInt 32 0
  2542. %int_ptr_priv = OpTypePointer Private %int
  2543. %var1 = OpVariable %int_ptr_priv Private
  2544. %var2 = OpVariable %int_ptr_priv Private
  2545. %voidfn = OpTypeFunction %void
  2546. %func = OpFunction %void None %voidfn
  2547. %entry = OpLabel
  2548. OpCopyMemory %var1 %var2 Volatile Volatile
  2549. OpReturn
  2550. OpFunctionEnd
  2551. )";
  2552. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2553. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2554. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2555. }
  2556. TEST_F(ValidateMemory, CopyMemorySizedNoAccessGood) {
  2557. const std::string spirv = R"(
  2558. OpCapability Shader
  2559. OpCapability Linkage
  2560. OpCapability Addresses
  2561. OpMemoryModel Logical GLSL450
  2562. %void = OpTypeVoid
  2563. %int = OpTypeInt 32 0
  2564. %int_16 = OpConstant %int 16
  2565. %int_ptr_priv = OpTypePointer Private %int
  2566. %var1 = OpVariable %int_ptr_priv Private
  2567. %var2 = OpVariable %int_ptr_priv Private
  2568. %voidfn = OpTypeFunction %void
  2569. %func = OpFunction %void None %voidfn
  2570. %entry = OpLabel
  2571. OpCopyMemorySized %var1 %var2 %int_16
  2572. OpReturn
  2573. OpFunctionEnd
  2574. )";
  2575. CompileSuccessfully(spirv);
  2576. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2577. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2578. }
  2579. TEST_F(ValidateMemory, CopyMemorySizedSimpleMixedAccessGood) {
  2580. // Test one memory access operand using features that don't require the
  2581. // Vulkan memory model.
  2582. const std::string spirv = R"(
  2583. OpCapability Shader
  2584. OpCapability Linkage
  2585. OpCapability Addresses
  2586. OpMemoryModel Logical GLSL450
  2587. %void = OpTypeVoid
  2588. %int = OpTypeInt 32 0
  2589. %int_16 = OpConstant %int 16
  2590. %int_ptr_priv = OpTypePointer Private %int
  2591. %var1 = OpVariable %int_ptr_priv Private
  2592. %var2 = OpVariable %int_ptr_priv Private
  2593. %voidfn = OpTypeFunction %void
  2594. %func = OpFunction %void None %voidfn
  2595. %entry = OpLabel
  2596. OpCopyMemorySized %var1 %var2 %int_16 Volatile|Aligned|Nontemporal 4
  2597. OpReturn
  2598. OpFunctionEnd
  2599. )";
  2600. CompileSuccessfully(spirv);
  2601. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2602. }
  2603. TEST_F(ValidateMemory, CopyMemorySizedSimpleTwoMixedAccessV13Bad) {
  2604. // Two memory access operands is invalid up to SPIR-V 1.3
  2605. const std::string spirv = R"(
  2606. OpCapability Shader
  2607. OpCapability Linkage
  2608. OpCapability Addresses
  2609. OpMemoryModel Logical GLSL450
  2610. %void = OpTypeVoid
  2611. %int = OpTypeInt 32 0
  2612. %int_16 = OpConstant %int 16
  2613. %int_ptr_priv = OpTypePointer Private %int
  2614. %var1 = OpVariable %int_ptr_priv Private
  2615. %var2 = OpVariable %int_ptr_priv Private
  2616. %voidfn = OpTypeFunction %void
  2617. %func = OpFunction %void None %voidfn
  2618. %entry = OpLabel
  2619. OpCopyMemorySized %var1 %var2 %int_16 Volatile Volatile
  2620. OpReturn
  2621. OpFunctionEnd
  2622. )";
  2623. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  2624. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  2625. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2626. EXPECT_THAT(
  2627. getDiagnosticString(),
  2628. HasSubstr("CopyMemorySized with two memory access operands requires "
  2629. "SPIR-V 1.4 or later"));
  2630. }
  2631. TEST_F(ValidateMemory, CopyMemorySizedSimpleTwoMixedAccessV14Good) {
  2632. // Two memory access operands is valid in SPIR-V 1.4
  2633. const std::string spirv = R"(
  2634. OpCapability Shader
  2635. OpCapability Linkage
  2636. OpCapability Addresses
  2637. OpMemoryModel Logical GLSL450
  2638. %void = OpTypeVoid
  2639. %int = OpTypeInt 32 0
  2640. %int_16 = OpConstant %int 16
  2641. %int_ptr_priv = OpTypePointer Private %int
  2642. %var1 = OpVariable %int_ptr_priv Private
  2643. %var2 = OpVariable %int_ptr_priv Private
  2644. %voidfn = OpTypeFunction %void
  2645. %func = OpFunction %void None %voidfn
  2646. %entry = OpLabel
  2647. OpCopyMemorySized %var1 %var2 %int_16 Volatile Volatile
  2648. OpReturn
  2649. OpFunctionEnd
  2650. )";
  2651. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2652. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2653. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2654. }
  2655. using ValidatePointerComparisons = spvtest::ValidateBase<std::string>;
  2656. TEST_P(ValidatePointerComparisons, Good) {
  2657. const std::string operation = GetParam();
  2658. std::string spirv = R"(
  2659. OpCapability Shader
  2660. OpCapability Linkage
  2661. OpCapability VariablePointersStorageBuffer
  2662. OpMemoryModel Logical GLSL450
  2663. %void = OpTypeVoid
  2664. %bool = OpTypeBool
  2665. %int = OpTypeInt 32 0
  2666. %ptr_int = OpTypePointer StorageBuffer %int
  2667. %var = OpVariable %ptr_int StorageBuffer
  2668. %func_ty = OpTypeFunction %void
  2669. %func = OpFunction %void None %func_ty
  2670. %1 = OpLabel
  2671. %equal = )" + operation;
  2672. if (operation == "OpPtrDiff") {
  2673. spirv += " %int ";
  2674. } else {
  2675. spirv += " %bool ";
  2676. }
  2677. spirv += R"(%var %var
  2678. OpReturn
  2679. OpFunctionEnd
  2680. )";
  2681. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2682. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2683. }
  2684. TEST_P(ValidatePointerComparisons, GoodWorkgroup) {
  2685. const std::string operation = GetParam();
  2686. std::string spirv = R"(
  2687. OpCapability Shader
  2688. OpCapability Linkage
  2689. OpCapability VariablePointers
  2690. OpMemoryModel Logical GLSL450
  2691. %void = OpTypeVoid
  2692. %bool = OpTypeBool
  2693. %int = OpTypeInt 32 0
  2694. %ptr_int = OpTypePointer Workgroup %int
  2695. %var = OpVariable %ptr_int Workgroup
  2696. %func_ty = OpTypeFunction %void
  2697. %func = OpFunction %void None %func_ty
  2698. %1 = OpLabel
  2699. %equal = )" + operation;
  2700. if (operation == "OpPtrDiff") {
  2701. spirv += " %int ";
  2702. } else {
  2703. spirv += " %bool ";
  2704. }
  2705. spirv += R"(%var %var
  2706. OpReturn
  2707. OpFunctionEnd
  2708. )";
  2709. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2710. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2711. }
  2712. TEST_P(ValidatePointerComparisons, BadResultType) {
  2713. const std::string operation = GetParam();
  2714. std::string spirv = R"(
  2715. OpCapability Shader
  2716. OpCapability Linkage
  2717. OpCapability VariablePointersStorageBuffer
  2718. OpMemoryModel Logical GLSL450
  2719. %void = OpTypeVoid
  2720. %bool = OpTypeBool
  2721. %int = OpTypeInt 32 0
  2722. %ptr_int = OpTypePointer StorageBuffer %int
  2723. %var = OpVariable %ptr_int StorageBuffer
  2724. %func_ty = OpTypeFunction %void
  2725. %func = OpFunction %void None %func_ty
  2726. %1 = OpLabel
  2727. %equal = )" + operation;
  2728. if (operation == "OpPtrDiff") {
  2729. spirv += " %bool ";
  2730. } else {
  2731. spirv += " %int ";
  2732. }
  2733. spirv += R"(%var %var
  2734. OpReturn
  2735. OpFunctionEnd
  2736. )";
  2737. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2738. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2739. if (operation == "OpPtrDiff") {
  2740. EXPECT_THAT(getDiagnosticString(),
  2741. HasSubstr("Result Type must be an integer scalar"));
  2742. } else {
  2743. EXPECT_THAT(getDiagnosticString(),
  2744. HasSubstr("Result Type must be OpTypeBool"));
  2745. }
  2746. }
  2747. TEST_P(ValidatePointerComparisons, BadCapabilities) {
  2748. const std::string operation = GetParam();
  2749. std::string spirv = R"(
  2750. OpCapability Shader
  2751. OpCapability Linkage
  2752. OpMemoryModel Logical GLSL450
  2753. %void = OpTypeVoid
  2754. %bool = OpTypeBool
  2755. %int = OpTypeInt 32 0
  2756. %ptr_int = OpTypePointer StorageBuffer %int
  2757. %var = OpVariable %ptr_int StorageBuffer
  2758. %func_ty = OpTypeFunction %void
  2759. %func = OpFunction %void None %func_ty
  2760. %1 = OpLabel
  2761. %equal = )" + operation;
  2762. if (operation == "OpPtrDiff") {
  2763. spirv += " %int ";
  2764. } else {
  2765. spirv += " %bool ";
  2766. }
  2767. spirv += R"(%var %var
  2768. OpReturn
  2769. OpFunctionEnd
  2770. )";
  2771. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2772. if (operation == "OpPtrDiff") {
  2773. // Gets caught by the grammar.
  2774. EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
  2775. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2776. } else {
  2777. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2778. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2779. EXPECT_THAT(getDiagnosticString(),
  2780. HasSubstr("Instruction cannot be used without a variable "
  2781. "pointers capability"));
  2782. }
  2783. }
  2784. TEST_P(ValidatePointerComparisons, BadOperandType) {
  2785. const std::string operation = GetParam();
  2786. std::string spirv = R"(
  2787. OpCapability Shader
  2788. OpCapability Linkage
  2789. OpCapability VariablePointersStorageBuffer
  2790. OpMemoryModel Logical GLSL450
  2791. %void = OpTypeVoid
  2792. %bool = OpTypeBool
  2793. %int = OpTypeInt 32 0
  2794. %ptr_int = OpTypePointer StorageBuffer %int
  2795. %var = OpVariable %ptr_int StorageBuffer
  2796. %func_ty = OpTypeFunction %void
  2797. %func = OpFunction %void None %func_ty
  2798. %1 = OpLabel
  2799. %ld = OpLoad %int %var
  2800. %equal = )" + operation;
  2801. if (operation == "OpPtrDiff") {
  2802. spirv += " %int ";
  2803. } else {
  2804. spirv += " %bool ";
  2805. }
  2806. spirv += R"(%ld %ld
  2807. OpReturn
  2808. OpFunctionEnd
  2809. )";
  2810. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2811. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2812. EXPECT_THAT(getDiagnosticString(),
  2813. HasSubstr("Operand type must be a pointer"));
  2814. }
  2815. TEST_P(ValidatePointerComparisons, BadStorageClassWorkgroup) {
  2816. const std::string operation = GetParam();
  2817. std::string spirv = R"(
  2818. OpCapability Shader
  2819. OpCapability Linkage
  2820. OpCapability VariablePointersStorageBuffer
  2821. OpMemoryModel Logical GLSL450
  2822. %void = OpTypeVoid
  2823. %bool = OpTypeBool
  2824. %int = OpTypeInt 32 0
  2825. %ptr_int = OpTypePointer Workgroup %int
  2826. %var = OpVariable %ptr_int Workgroup
  2827. %func_ty = OpTypeFunction %void
  2828. %func = OpFunction %void None %func_ty
  2829. %1 = OpLabel
  2830. %equal = )" + operation;
  2831. if (operation == "OpPtrDiff") {
  2832. spirv += " %int ";
  2833. } else {
  2834. spirv += " %bool ";
  2835. }
  2836. spirv += R"(%var %var
  2837. OpReturn
  2838. OpFunctionEnd
  2839. )";
  2840. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2841. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2842. EXPECT_THAT(getDiagnosticString(),
  2843. HasSubstr("Workgroup storage class pointer requires "
  2844. "VariablePointers capability to be specified"));
  2845. }
  2846. TEST_P(ValidatePointerComparisons, BadStorageClass) {
  2847. const std::string operation = GetParam();
  2848. std::string spirv = R"(
  2849. OpCapability Shader
  2850. OpCapability Linkage
  2851. OpCapability VariablePointersStorageBuffer
  2852. OpMemoryModel Logical GLSL450
  2853. %void = OpTypeVoid
  2854. %bool = OpTypeBool
  2855. %int = OpTypeInt 32 0
  2856. %ptr_int = OpTypePointer Private %int
  2857. %var = OpVariable %ptr_int Private
  2858. %func_ty = OpTypeFunction %void
  2859. %func = OpFunction %void None %func_ty
  2860. %1 = OpLabel
  2861. %equal = )" + operation;
  2862. if (operation == "OpPtrDiff") {
  2863. spirv += " %int ";
  2864. } else {
  2865. spirv += " %bool ";
  2866. }
  2867. spirv += R"(%var %var
  2868. OpReturn
  2869. OpFunctionEnd
  2870. )";
  2871. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2872. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2873. EXPECT_THAT(getDiagnosticString(),
  2874. HasSubstr("Invalid pointer storage class"));
  2875. }
  2876. TEST_P(ValidatePointerComparisons, BadDiffOperandTypes) {
  2877. const std::string operation = GetParam();
  2878. std::string spirv = R"(
  2879. OpCapability Shader
  2880. OpCapability Linkage
  2881. OpCapability VariablePointersStorageBuffer
  2882. OpMemoryModel Logical GLSL450
  2883. %void = OpTypeVoid
  2884. %bool = OpTypeBool
  2885. %int = OpTypeInt 32 0
  2886. %ptr_int = OpTypePointer Private %int
  2887. %var = OpVariable %ptr_int Private
  2888. %func_ty = OpTypeFunction %void
  2889. %func = OpFunction %void None %func_ty
  2890. %1 = OpLabel
  2891. %ld = OpLoad %int %var
  2892. %equal = )" + operation;
  2893. if (operation == "OpPtrDiff") {
  2894. spirv += " %int ";
  2895. } else {
  2896. spirv += " %bool ";
  2897. }
  2898. spirv += R"(%var %ld
  2899. OpReturn
  2900. OpFunctionEnd
  2901. )";
  2902. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  2903. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  2904. EXPECT_THAT(getDiagnosticString(),
  2905. HasSubstr("The types of Operand 1 and Operand 2 must match"));
  2906. }
  2907. INSTANTIATE_TEST_SUITE_P(PointerComparisons, ValidatePointerComparisons,
  2908. Values("OpPtrEqual", "OpPtrNotEqual", "OpPtrDiff"));
  2909. TEST_F(ValidateMemory, VariableInitializerWrongType) {
  2910. const std::string spirv = R"(
  2911. OpCapability Shader
  2912. OpCapability Linkage
  2913. OpCapability VariablePointersStorageBuffer
  2914. OpMemoryModel Logical GLSL450
  2915. %void = OpTypeVoid
  2916. %int = OpTypeInt 32 0
  2917. %float = OpTypeFloat 32
  2918. %ptr_wg_int = OpTypePointer Workgroup %int
  2919. %ptr_wg_float = OpTypePointer Workgroup %int
  2920. %wg_var = OpVariable %ptr_wg_int Workgroup
  2921. %ptr_private_wg_float = OpTypePointer Private %ptr_wg_float
  2922. %priv_var = OpVariable %ptr_private_wg_float Private %wg_var
  2923. )";
  2924. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  2925. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2926. EXPECT_THAT(getDiagnosticString(),
  2927. HasSubstr("Initializer type must match the type pointed to by "
  2928. "the Result Type"));
  2929. }
  2930. TEST_F(ValidateMemory, StoreToUniformBlock) {
  2931. const std::string spirv = R"(
  2932. OpCapability Shader
  2933. OpMemoryModel Logical GLSL450
  2934. OpEntryPoint GLCompute %main "main"
  2935. OpExecutionMode %main LocalSize 1 1 1
  2936. OpDecorate %struct Block
  2937. OpMemberDecorate %struct 0 Offset 0
  2938. OpDecorate %var DescriptorSet 0
  2939. OpDecorate %var Binding 0
  2940. %void = OpTypeVoid
  2941. %int = OpTypeInt 32 0
  2942. %int_0 = OpConstant %int 0
  2943. %int4 = OpTypeVector %int 4
  2944. %struct = OpTypeStruct %int4
  2945. %ptr_uniform_struct = OpTypePointer Uniform %struct
  2946. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  2947. %ptr_uniform_int = OpTypePointer Uniform %int
  2948. %var = OpVariable %ptr_uniform_struct Uniform
  2949. %void_fn = OpTypeFunction %void
  2950. %main = OpFunction %void None %void_fn
  2951. %entry = OpLabel
  2952. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
  2953. %gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
  2954. OpStore %gep2 %int_0
  2955. OpReturn
  2956. OpFunctionEnd
  2957. )";
  2958. CompileSuccessfully(spirv);
  2959. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2960. }
  2961. TEST_F(ValidateMemory, StoreToUniformBlockVulkan) {
  2962. const std::string spirv = R"(
  2963. OpCapability Shader
  2964. OpMemoryModel Logical GLSL450
  2965. OpEntryPoint GLCompute %main "main"
  2966. OpExecutionMode %main LocalSize 1 1 1
  2967. OpDecorate %struct Block
  2968. OpMemberDecorate %struct 0 Offset 0
  2969. OpDecorate %var DescriptorSet 0
  2970. OpDecorate %var Binding 0
  2971. %void = OpTypeVoid
  2972. %int = OpTypeInt 32 0
  2973. %int_0 = OpConstant %int 0
  2974. %int4 = OpTypeVector %int 4
  2975. %struct = OpTypeStruct %int4
  2976. %ptr_uniform_struct = OpTypePointer Uniform %struct
  2977. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  2978. %ptr_uniform_int = OpTypePointer Uniform %int
  2979. %var = OpVariable %ptr_uniform_struct Uniform
  2980. %void_fn = OpTypeFunction %void
  2981. %main = OpFunction %void None %void_fn
  2982. %entry = OpLabel
  2983. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
  2984. %gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
  2985. OpStore %gep2 %int_0
  2986. OpReturn
  2987. OpFunctionEnd
  2988. )";
  2989. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  2990. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2991. EXPECT_THAT(
  2992. getDiagnosticString(),
  2993. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  2994. }
  2995. // This test requires that the struct is not id 2.
  2996. TEST_F(ValidateMemory, StoreToUniformBlockVulkan2) {
  2997. const std::string spirv = R"(
  2998. OpCapability Shader
  2999. OpMemoryModel Logical GLSL450
  3000. OpEntryPoint GLCompute %main "main" %gid_var
  3001. OpExecutionMode %main LocalSize 1 1 1
  3002. OpDecorate %3 Block
  3003. OpMemberDecorate %3 0 Offset 0
  3004. OpDecorate %var DescriptorSet 0
  3005. OpDecorate %var Binding 0
  3006. OpDecorate %gid_var BuiltIn GlobalInvocationId
  3007. %void = OpTypeVoid
  3008. %int = OpTypeInt 32 0
  3009. %int_0 = OpConstant %int 0
  3010. %int3 = OpTypeVector %int 3
  3011. %int4 = OpTypeVector %int 4
  3012. %3 = OpTypeStruct %int4
  3013. %ptr_uniform_struct = OpTypePointer Uniform %3
  3014. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  3015. %ptr_uniform_int = OpTypePointer Uniform %int
  3016. %var = OpVariable %ptr_uniform_struct Uniform
  3017. %ptr_input_int3 = OpTypePointer Input %int3
  3018. %gid_var = OpVariable %ptr_input_int3 Input
  3019. %void_fn = OpTypeFunction %void
  3020. %main = OpFunction %void None %void_fn
  3021. %entry = OpLabel
  3022. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
  3023. %gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
  3024. OpStore %gep2 %int_0
  3025. OpReturn
  3026. OpFunctionEnd
  3027. )";
  3028. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3029. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3030. EXPECT_THAT(
  3031. getDiagnosticString(),
  3032. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  3033. }
  3034. TEST_F(ValidateMemory, StoreToUniformBufferBlockVulkan) {
  3035. const std::string spirv = R"(
  3036. OpCapability Shader
  3037. OpMemoryModel Logical GLSL450
  3038. OpEntryPoint GLCompute %main "main"
  3039. OpExecutionMode %main LocalSize 1 1 1
  3040. OpDecorate %struct BufferBlock
  3041. OpMemberDecorate %struct 0 Offset 0
  3042. OpDecorate %var DescriptorSet 0
  3043. OpDecorate %var Binding 0
  3044. %void = OpTypeVoid
  3045. %int = OpTypeInt 32 0
  3046. %int_0 = OpConstant %int 0
  3047. %int4 = OpTypeVector %int 4
  3048. %struct = OpTypeStruct %int4
  3049. %ptr_uniform_struct = OpTypePointer Uniform %struct
  3050. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  3051. %ptr_uniform_int = OpTypePointer Uniform %int
  3052. %var = OpVariable %ptr_uniform_struct Uniform
  3053. %void_fn = OpTypeFunction %void
  3054. %main = OpFunction %void None %void_fn
  3055. %entry = OpLabel
  3056. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
  3057. %gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
  3058. OpStore %gep2 %int_0
  3059. OpReturn
  3060. OpFunctionEnd
  3061. )";
  3062. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3063. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3064. }
  3065. TEST_F(ValidateMemory, StoreToUniformBlockVulkanArray) {
  3066. const std::string spirv = R"(
  3067. OpCapability Shader
  3068. OpMemoryModel Logical GLSL450
  3069. OpEntryPoint GLCompute %main "main"
  3070. OpExecutionMode %main LocalSize 1 1 1
  3071. OpDecorate %struct Block
  3072. OpMemberDecorate %struct 0 Offset 0
  3073. OpDecorate %var DescriptorSet 0
  3074. OpDecorate %var Binding 0
  3075. %void = OpTypeVoid
  3076. %int = OpTypeInt 32 0
  3077. %int_0 = OpConstant %int 0
  3078. %int_1 = OpConstant %int 1
  3079. %int4 = OpTypeVector %int 4
  3080. %struct = OpTypeStruct %int4
  3081. %array_struct = OpTypeArray %struct %int_1
  3082. %ptr_uniform_array = OpTypePointer Uniform %array_struct
  3083. %ptr_uniform_struct = OpTypePointer Uniform %struct
  3084. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  3085. %ptr_uniform_int = OpTypePointer Uniform %int
  3086. %var = OpVariable %ptr_uniform_array Uniform
  3087. %void_fn = OpTypeFunction %void
  3088. %main = OpFunction %void None %void_fn
  3089. %entry = OpLabel
  3090. %gep1 = OpAccessChain %ptr_uniform_int %var %int_0 %int_0 %int_0
  3091. %gep2 = OpCopyObject %ptr_uniform_int %gep1
  3092. OpStore %gep2 %int_0
  3093. OpReturn
  3094. OpFunctionEnd
  3095. )";
  3096. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3097. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3098. EXPECT_THAT(
  3099. getDiagnosticString(),
  3100. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  3101. }
  3102. // This test requires that the struct is not id 2.
  3103. TEST_F(ValidateMemory, StoreToUniformBlockVulkanArray2) {
  3104. const std::string spirv = R"(
  3105. OpCapability Shader
  3106. OpMemoryModel Logical GLSL450
  3107. OpEntryPoint GLCompute %main "main" %gid_var
  3108. OpExecutionMode %main LocalSize 1 1 1
  3109. OpDecorate %struct Block
  3110. OpMemberDecorate %struct 0 Offset 0
  3111. OpDecorate %var DescriptorSet 0
  3112. OpDecorate %var Binding 0
  3113. OpDecorate %gid_var BuiltIn GlobalInvocationId
  3114. %void = OpTypeVoid
  3115. %int = OpTypeInt 32 0
  3116. %int_0 = OpConstant %int 0
  3117. %int_1 = OpConstant %int 1
  3118. %int3 = OpTypeVector %int 3
  3119. %int4 = OpTypeVector %int 4
  3120. %struct = OpTypeStruct %int4
  3121. %array_struct = OpTypeArray %struct %int_1
  3122. %ptr_uniform_array = OpTypePointer Uniform %array_struct
  3123. %ptr_uniform_struct = OpTypePointer Uniform %struct
  3124. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  3125. %ptr_uniform_int = OpTypePointer Uniform %int
  3126. %var = OpVariable %ptr_uniform_array Uniform
  3127. %ptr_input_int3 = OpTypePointer Input %int3
  3128. %gid_var = OpVariable %ptr_input_int3 Input
  3129. %void_fn = OpTypeFunction %void
  3130. %main = OpFunction %void None %void_fn
  3131. %entry = OpLabel
  3132. %gep1 = OpAccessChain %ptr_uniform_int %var %int_0 %int_0 %int_0
  3133. %gep2 = OpCopyObject %ptr_uniform_int %gep1
  3134. OpStore %gep2 %int_0
  3135. OpReturn
  3136. OpFunctionEnd
  3137. )";
  3138. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3139. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3140. EXPECT_THAT(
  3141. getDiagnosticString(),
  3142. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  3143. }
  3144. TEST_F(ValidateMemory, StoreToUniformBlockVulkanRuntimeArray) {
  3145. const std::string spirv = R"(
  3146. OpCapability Shader
  3147. OpCapability RuntimeDescriptorArrayEXT
  3148. OpExtension "SPV_EXT_descriptor_indexing"
  3149. OpMemoryModel Logical GLSL450
  3150. OpEntryPoint GLCompute %main "main"
  3151. OpExecutionMode %main LocalSize 1 1 1
  3152. OpDecorate %struct Block
  3153. OpMemberDecorate %struct 0 Offset 0
  3154. OpDecorate %var DescriptorSet 0
  3155. OpDecorate %var Binding 0
  3156. %void = OpTypeVoid
  3157. %int = OpTypeInt 32 0
  3158. %int_0 = OpConstant %int 0
  3159. %int4 = OpTypeVector %int 4
  3160. %struct = OpTypeStruct %int4
  3161. %array_struct = OpTypeRuntimeArray %struct
  3162. %ptr_uniform_array = OpTypePointer Uniform %array_struct
  3163. %ptr_uniform_struct = OpTypePointer Uniform %struct
  3164. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  3165. %ptr_uniform_int = OpTypePointer Uniform %int
  3166. %var = OpVariable %ptr_uniform_array Uniform
  3167. %void_fn = OpTypeFunction %void
  3168. %main = OpFunction %void None %void_fn
  3169. %entry = OpLabel
  3170. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0 %int_0
  3171. %gep2 = OpInBoundsAccessChain %ptr_uniform_int %gep1 %int_0
  3172. OpStore %gep2 %int_0
  3173. OpReturn
  3174. OpFunctionEnd
  3175. )";
  3176. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3177. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3178. EXPECT_THAT(
  3179. getDiagnosticString(),
  3180. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  3181. }
  3182. using ValidateSizedVariable =
  3183. spvtest::ValidateBase<std::tuple<std::string, std::string,
  3184. std::string, spv_target_env>>;
  3185. CodeGenerator GetSizedVariableCodeGenerator(bool is_8bit, bool buffer_block) {
  3186. CodeGenerator generator;
  3187. generator.capabilities_ = "OpCapability Shader\nOpCapability Linkage\n";
  3188. generator.extensions_ =
  3189. "OpExtension \"SPV_KHR_16bit_storage\"\nOpExtension "
  3190. "\"SPV_KHR_8bit_storage\"\n";
  3191. generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
  3192. if (is_8bit) {
  3193. generator.before_types_ = "OpMemberDecorate %char_buffer_block 0 Offset 0\n";
  3194. if (buffer_block)
  3195. generator.before_types_ += "OpDecorate %char_buffer_block BufferBlock\n";
  3196. generator.types_ = R"(%void = OpTypeVoid
  3197. %char = OpTypeInt 8 0
  3198. %char4 = OpTypeVector %char 4
  3199. %char_buffer_block = OpTypeStruct %char
  3200. )";
  3201. } else {
  3202. generator.before_types_ =
  3203. "OpMemberDecorate %half_buffer_block 0 Offset 0\n"
  3204. "OpMemberDecorate %short_buffer_block 0 Offset 0\n";
  3205. if (buffer_block) {
  3206. generator.before_types_ +=
  3207. "OpDecorate %half_buffer_block BufferBlock\n"
  3208. "OpDecorate %short_buffer_block BufferBlock\n";
  3209. }
  3210. generator.types_ = R"(%void = OpTypeVoid
  3211. %short = OpTypeInt 16 0
  3212. %half = OpTypeFloat 16
  3213. %short4 = OpTypeVector %short 4
  3214. %half4 = OpTypeVector %half 4
  3215. %mat4x4 = OpTypeMatrix %half4 4
  3216. %short_buffer_block = OpTypeStruct %short
  3217. %half_buffer_block = OpTypeStruct %half
  3218. )";
  3219. }
  3220. generator.after_types_ = R"(%void_fn = OpTypeFunction %void
  3221. %func = OpFunction %void None %void_fn
  3222. %entry = OpLabel
  3223. )";
  3224. generator.add_at_the_end_ = "OpReturn\nOpFunctionEnd\n";
  3225. return generator;
  3226. }
  3227. TEST_P(ValidateSizedVariable, Capability) {
  3228. const std::string storage_class = std::get<0>(GetParam());
  3229. const std::string capability = std::get<1>(GetParam());
  3230. const std::string var_type = std::get<2>(GetParam());
  3231. const spv_target_env target = std::get<3>(GetParam());
  3232. ASSERT_TRUE(target == SPV_ENV_UNIVERSAL_1_3 ||
  3233. target == SPV_ENV_UNIVERSAL_1_4);
  3234. bool type_8bit = false;
  3235. if (var_type == "%char" || var_type == "%char4" ||
  3236. var_type == "%char_buffer_block") {
  3237. type_8bit = true;
  3238. }
  3239. const bool buffer_block = var_type.find("buffer_block") != std::string::npos;
  3240. auto generator = GetSizedVariableCodeGenerator(type_8bit, buffer_block);
  3241. if (capability == "WorkgroupMemoryExplicitLayout8BitAccessKHR" ||
  3242. capability == "WorkgroupMemoryExplicitLayout16BitAccessKHR") {
  3243. generator.extensions_ +=
  3244. "OpExtension \"SPV_KHR_workgroup_memory_explicit_layout\"\n";
  3245. }
  3246. generator.types_ += "%ptr_type = OpTypePointer " + storage_class + " " +
  3247. var_type + "\n%var = OpVariable %ptr_type " +
  3248. storage_class + "\n";
  3249. generator.capabilities_ += "OpCapability " + capability + "\n";
  3250. bool capability_ok = false;
  3251. bool storage_class_ok = false;
  3252. if (storage_class == "Input" || storage_class == "Output") {
  3253. if (!type_8bit) {
  3254. capability_ok = capability == "StorageInputOutput16";
  3255. storage_class_ok = true;
  3256. }
  3257. } else if (storage_class == "StorageBuffer") {
  3258. if (type_8bit) {
  3259. capability_ok = capability == "StorageBuffer8BitAccess" ||
  3260. capability == "UniformAndStorageBuffer8BitAccess";
  3261. } else {
  3262. capability_ok = capability == "StorageBuffer16BitAccess" ||
  3263. capability == "UniformAndStorageBuffer16BitAccess";
  3264. }
  3265. storage_class_ok = true;
  3266. } else if (storage_class == "PushConstant") {
  3267. if (type_8bit) {
  3268. capability_ok = capability == "StoragePushConstant8";
  3269. } else {
  3270. capability_ok = capability == "StoragePushConstant16";
  3271. }
  3272. storage_class_ok = true;
  3273. } else if (storage_class == "Uniform") {
  3274. if (type_8bit) {
  3275. capability_ok = capability == "UniformAndStorageBuffer8BitAccess" ||
  3276. (capability == "StorageBuffer8BitAccess" && buffer_block);
  3277. } else {
  3278. capability_ok =
  3279. capability == "UniformAndStorageBuffer16BitAccess" ||
  3280. (capability == "StorageBuffer16BitAccess" && buffer_block);
  3281. }
  3282. storage_class_ok = true;
  3283. } else if (storage_class == "Workgroup") {
  3284. if (type_8bit) {
  3285. capability_ok =
  3286. capability == "WorkgroupMemoryExplicitLayout8BitAccessKHR";
  3287. } else {
  3288. capability_ok =
  3289. capability == "WorkgroupMemoryExplicitLayout16BitAccessKHR";
  3290. }
  3291. storage_class_ok = true;
  3292. }
  3293. CompileSuccessfully(generator.Build(), target);
  3294. spv_result_t result = ValidateInstructions(target);
  3295. if (target < SPV_ENV_UNIVERSAL_1_4 &&
  3296. (capability == "WorkgroupMemoryExplicitLayout8BitAccessKHR" ||
  3297. capability == "WorkgroupMemoryExplicitLayout16BitAccessKHR")) {
  3298. EXPECT_EQ(SPV_ERROR_WRONG_VERSION, result);
  3299. EXPECT_THAT(getDiagnosticString(),
  3300. HasSubstr("requires SPIR-V version 1.4 or later"));
  3301. } else if (buffer_block && target > SPV_ENV_UNIVERSAL_1_3) {
  3302. EXPECT_EQ(SPV_ERROR_WRONG_VERSION, result);
  3303. EXPECT_THAT(getDiagnosticString(),
  3304. HasSubstr("requires SPIR-V version 1.3 or earlier"));
  3305. } else if (capability_ok) {
  3306. EXPECT_EQ(SPV_SUCCESS, result);
  3307. } else {
  3308. EXPECT_EQ(SPV_ERROR_INVALID_ID, result);
  3309. if (storage_class_ok) {
  3310. std::string message = std::string("Allocating a variable containing a ") +
  3311. (type_8bit ? "8" : "16") + "-bit element in " +
  3312. storage_class +
  3313. " storage class requires an additional capability";
  3314. EXPECT_THAT(getDiagnosticString(), HasSubstr(message));
  3315. } else {
  3316. std::string message =
  3317. std::string("Cannot allocate a variable containing a ") +
  3318. (type_8bit ? "8" : "16") + "-bit type in " + storage_class +
  3319. " storage class";
  3320. EXPECT_THAT(getDiagnosticString(), HasSubstr(message));
  3321. }
  3322. }
  3323. }
  3324. INSTANTIATE_TEST_SUITE_P(
  3325. Storage8, ValidateSizedVariable,
  3326. Combine(Values("UniformConstant", "Input", "Output", "Workgroup",
  3327. "CrossWorkgroup", "Private", "StorageBuffer", "Uniform"),
  3328. Values("StorageBuffer8BitAccess",
  3329. "UniformAndStorageBuffer8BitAccess", "StoragePushConstant8",
  3330. "WorkgroupMemoryExplicitLayout8BitAccessKHR"),
  3331. Values("%char", "%char4", "%char_buffer_block"),
  3332. Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_4)));
  3333. INSTANTIATE_TEST_SUITE_P(
  3334. Storage16, ValidateSizedVariable,
  3335. Combine(Values("UniformConstant", "Input", "Output", "Workgroup",
  3336. "CrossWorkgroup", "Private", "StorageBuffer", "Uniform"),
  3337. Values("StorageBuffer16BitAccess",
  3338. "UniformAndStorageBuffer16BitAccess",
  3339. "StoragePushConstant16", "StorageInputOutput16",
  3340. "WorkgroupMemoryExplicitLayout16BitAccessKHR"),
  3341. Values("%short", "%half", "%short4", "%half4", "%mat4x4",
  3342. "%short_buffer_block", "%half_buffer_block"),
  3343. Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_4)));
  3344. using ValidateSizedLoadStore =
  3345. spvtest::ValidateBase<std::tuple<std::string, uint32_t, std::string>>;
  3346. CodeGenerator GetSizedLoadStoreCodeGenerator(const std::string& base_type,
  3347. uint32_t width) {
  3348. CodeGenerator generator;
  3349. generator.capabilities_ = "OpCapability Shader\nOpCapability Linkage\n";
  3350. if (width == 8) {
  3351. generator.capabilities_ +=
  3352. "OpCapability UniformAndStorageBuffer8BitAccess\n";
  3353. generator.extensions_ = "OpExtension \"SPV_KHR_8bit_storage\"\n";
  3354. } else {
  3355. generator.capabilities_ +=
  3356. "OpCapability UniformAndStorageBuffer16BitAccess\n";
  3357. generator.extensions_ = "OpExtension \"SPV_KHR_16bit_storage\"\n";
  3358. }
  3359. generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
  3360. generator.before_types_ = R"(OpDecorate %block Block
  3361. OpMemberDecorate %block 0 Offset 0
  3362. OpMemberDecorate %struct 0 Offset 0
  3363. )";
  3364. generator.types_ = R"(%void = OpTypeVoid
  3365. %int = OpTypeInt 32 0
  3366. %int_0 = OpConstant %int 0
  3367. %int_1 = OpConstant %int 1
  3368. %int_2 = OpConstant %int 2
  3369. %int_3 = OpConstant %int 3
  3370. )";
  3371. if (width == 8) {
  3372. generator.types_ += R"(%scalar = OpTypeInt 8 0
  3373. %vector = OpTypeVector %scalar 4
  3374. %struct = OpTypeStruct %vector
  3375. )";
  3376. } else if (base_type == "int") {
  3377. generator.types_ += R"(%scalar = OpTypeInt 16 0
  3378. %vector = OpTypeVector %scalar 4
  3379. %struct = OpTypeStruct %vector
  3380. )";
  3381. } else {
  3382. generator.types_ += R"(%scalar = OpTypeFloat 16
  3383. %vector = OpTypeVector %scalar 4
  3384. %matrix = OpTypeMatrix %vector 4
  3385. %struct = OpTypeStruct %matrix
  3386. %ptr_ssbo_matrix = OpTypePointer StorageBuffer %matrix
  3387. )";
  3388. generator.before_types_ += R"(OpMemberDecorate %struct 0 RowMajor
  3389. OpMemberDecorate %struct 0 MatrixStride 16
  3390. )";
  3391. }
  3392. generator.types_ += R"(%block = OpTypeStruct %struct
  3393. %ptr_ssbo_block = OpTypePointer StorageBuffer %block
  3394. %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
  3395. %ptr_ssbo_vector = OpTypePointer StorageBuffer %vector
  3396. %ptr_ssbo_scalar = OpTypePointer StorageBuffer %scalar
  3397. %ld_var = OpVariable %ptr_ssbo_block StorageBuffer
  3398. %st_var = OpVariable %ptr_ssbo_block StorageBuffer
  3399. )";
  3400. generator.after_types_ = R"(%void_fn = OpTypeFunction %void
  3401. %func = OpFunction %void None %void_fn
  3402. %entry = OpLabel
  3403. )";
  3404. generator.add_at_the_end_ = "OpReturn\nOpFunctionEnd\n";
  3405. return generator;
  3406. }
  3407. TEST_P(ValidateSizedLoadStore, Load) {
  3408. std::string base_type = std::get<0>(GetParam());
  3409. uint32_t width = std::get<1>(GetParam());
  3410. std::string mem_type = std::get<2>(GetParam());
  3411. CodeGenerator generator = GetSizedLoadStoreCodeGenerator(base_type, width);
  3412. generator.after_types_ +=
  3413. "%ld_gep = OpAccessChain %ptr_ssbo_" + mem_type + " %ld_var %int_0";
  3414. if (mem_type != "struct") {
  3415. generator.after_types_ += " %int_0";
  3416. if (mem_type != "matrix" && base_type == "float") {
  3417. generator.after_types_ += " %int_0";
  3418. }
  3419. if (mem_type == "scalar") {
  3420. generator.after_types_ += " %int_0";
  3421. }
  3422. }
  3423. generator.after_types_ += "\n";
  3424. generator.after_types_ += "%ld = OpLoad %" + mem_type + " %ld_gep\n";
  3425. CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3);
  3426. if (mem_type == "struct") {
  3427. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3428. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3429. EXPECT_THAT(
  3430. getDiagnosticString(),
  3431. HasSubstr(
  3432. "8- or 16-bit loads must be a scalar, vector or matrix type"));
  3433. } else {
  3434. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3435. }
  3436. }
  3437. TEST_P(ValidateSizedLoadStore, Store) {
  3438. std::string base_type = std::get<0>(GetParam());
  3439. uint32_t width = std::get<1>(GetParam());
  3440. std::string mem_type = std::get<2>(GetParam());
  3441. CodeGenerator generator = GetSizedLoadStoreCodeGenerator(base_type, width);
  3442. generator.after_types_ +=
  3443. "%ld_gep = OpAccessChain %ptr_ssbo_" + mem_type + " %ld_var %int_0";
  3444. if (mem_type != "struct") {
  3445. generator.after_types_ += " %int_0";
  3446. if (mem_type != "matrix" && base_type == "float") {
  3447. generator.after_types_ += " %int_0";
  3448. }
  3449. if (mem_type == "scalar") {
  3450. generator.after_types_ += " %int_0";
  3451. }
  3452. }
  3453. generator.after_types_ += "\n";
  3454. generator.after_types_ += "%ld = OpLoad %" + mem_type + " %ld_gep\n";
  3455. generator.after_types_ +=
  3456. "%st_gep = OpAccessChain %ptr_ssbo_" + mem_type + " %st_var %int_0";
  3457. if (mem_type != "struct") {
  3458. generator.after_types_ += " %int_0";
  3459. if (mem_type != "matrix" && base_type == "float") {
  3460. generator.after_types_ += " %int_0";
  3461. }
  3462. if (mem_type == "scalar") {
  3463. generator.after_types_ += " %int_0";
  3464. }
  3465. }
  3466. generator.after_types_ += "\n";
  3467. generator.after_types_ += "OpStore %st_gep %ld\n";
  3468. CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3);
  3469. if (mem_type == "struct") {
  3470. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3471. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3472. // Can only catch the load.
  3473. EXPECT_THAT(
  3474. getDiagnosticString(),
  3475. HasSubstr(
  3476. "8- or 16-bit loads must be a scalar, vector or matrix type"));
  3477. } else {
  3478. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3479. }
  3480. }
  3481. INSTANTIATE_TEST_SUITE_P(LoadStoreInt8, ValidateSizedLoadStore,
  3482. Combine(Values("int"), Values(8u),
  3483. Values("scalar", "vector", "struct")));
  3484. INSTANTIATE_TEST_SUITE_P(LoadStoreInt16, ValidateSizedLoadStore,
  3485. Combine(Values("int"), Values(16u),
  3486. Values("scalar", "vector", "struct")));
  3487. INSTANTIATE_TEST_SUITE_P(LoadStoreFloat16, ValidateSizedLoadStore,
  3488. Combine(Values("float"), Values(16u),
  3489. Values("scalar", "vector", "matrix",
  3490. "struct")));
  3491. TEST_F(ValidateMemory, SmallStorageCopyMemoryChar) {
  3492. const std::string spirv = R"(
  3493. OpCapability Shader
  3494. OpCapability Linkage
  3495. OpCapability UniformAndStorageBuffer8BitAccess
  3496. OpExtension "SPV_KHR_8bit_storage"
  3497. OpMemoryModel Logical GLSL450
  3498. OpDecorate %block Block
  3499. OpMemberDecorate %block 0 Offset 0
  3500. %void = OpTypeVoid
  3501. %int = OpTypeInt 32 0
  3502. %int_0 = OpConstant %int 0
  3503. %char = OpTypeInt 8 0
  3504. %block = OpTypeStruct %char
  3505. %ptr_ssbo_block = OpTypePointer StorageBuffer %block
  3506. %in = OpVariable %ptr_ssbo_block StorageBuffer
  3507. %out = OpVariable %ptr_ssbo_block StorageBuffer
  3508. %void_fn = OpTypeFunction %void
  3509. %func = OpFunction %void None %void_fn
  3510. %entry = OpLabel
  3511. OpCopyMemory %out %in
  3512. OpReturn
  3513. OpFunctionEnd
  3514. )";
  3515. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  3516. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3517. EXPECT_THAT(
  3518. getDiagnosticString(),
  3519. HasSubstr("Cannot copy memory of objects containing 8- or 16-bit types"));
  3520. }
  3521. TEST_F(ValidateMemory, SmallStorageCopyMemoryShort) {
  3522. const std::string spirv = R"(
  3523. OpCapability Shader
  3524. OpCapability Linkage
  3525. OpCapability UniformAndStorageBuffer16BitAccess
  3526. OpExtension "SPV_KHR_16bit_storage"
  3527. OpMemoryModel Logical GLSL450
  3528. OpDecorate %block Block
  3529. OpMemberDecorate %block 0 Offset 0
  3530. %void = OpTypeVoid
  3531. %int = OpTypeInt 32 0
  3532. %int_0 = OpConstant %int 0
  3533. %short = OpTypeInt 16 0
  3534. %block = OpTypeStruct %short
  3535. %ptr_ssbo_block = OpTypePointer StorageBuffer %block
  3536. %in = OpVariable %ptr_ssbo_block StorageBuffer
  3537. %out = OpVariable %ptr_ssbo_block StorageBuffer
  3538. %void_fn = OpTypeFunction %void
  3539. %func = OpFunction %void None %void_fn
  3540. %entry = OpLabel
  3541. OpCopyMemory %out %in
  3542. OpReturn
  3543. OpFunctionEnd
  3544. )";
  3545. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  3546. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3547. EXPECT_THAT(
  3548. getDiagnosticString(),
  3549. HasSubstr("Cannot copy memory of objects containing 8- or 16-bit types"));
  3550. }
  3551. TEST_F(ValidateMemory, SmallStorageCopyMemoryHalf) {
  3552. const std::string spirv = R"(
  3553. OpCapability Shader
  3554. OpCapability Linkage
  3555. OpCapability UniformAndStorageBuffer16BitAccess
  3556. OpExtension "SPV_KHR_16bit_storage"
  3557. OpMemoryModel Logical GLSL450
  3558. OpDecorate %block Block
  3559. OpMemberDecorate %block 0 Offset 0
  3560. %void = OpTypeVoid
  3561. %int = OpTypeInt 32 0
  3562. %int_0 = OpConstant %int 0
  3563. %half = OpTypeFloat 16
  3564. %block = OpTypeStruct %half
  3565. %ptr_ssbo_block = OpTypePointer StorageBuffer %block
  3566. %in = OpVariable %ptr_ssbo_block StorageBuffer
  3567. %out = OpVariable %ptr_ssbo_block StorageBuffer
  3568. %void_fn = OpTypeFunction %void
  3569. %func = OpFunction %void None %void_fn
  3570. %entry = OpLabel
  3571. OpCopyMemory %out %in
  3572. OpReturn
  3573. OpFunctionEnd
  3574. )";
  3575. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  3576. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3577. EXPECT_THAT(
  3578. getDiagnosticString(),
  3579. HasSubstr("Cannot copy memory of objects containing 8- or 16-bit types"));
  3580. }
  3581. TEST_F(ValidateMemory, SmallStorageVariableArrayBufferBlockShort) {
  3582. const std::string spirv = R"(
  3583. OpCapability Shader
  3584. OpCapability Linkage
  3585. OpCapability StorageBuffer16BitAccess
  3586. OpExtension "SPV_KHR_16bit_storage"
  3587. OpMemoryModel Logical GLSL450
  3588. OpDecorate %block BufferBlock
  3589. OpMemberDecorate %block 0 Offset 0
  3590. %void = OpTypeVoid
  3591. %short = OpTypeInt 16 0
  3592. %int = OpTypeInt 32 0
  3593. %int_4 = OpConstant %int 4
  3594. %block = OpTypeStruct %short
  3595. %block_array = OpTypeArray %block %int_4
  3596. %ptr_block_array = OpTypePointer Uniform %block_array
  3597. %var = OpVariable %ptr_block_array Uniform
  3598. )";
  3599. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  3600. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3601. }
  3602. TEST_F(ValidateMemory, SmallStorageVariableArrayBufferBlockChar) {
  3603. const std::string spirv = R"(
  3604. OpCapability Shader
  3605. OpCapability Linkage
  3606. OpCapability StorageBuffer8BitAccess
  3607. OpExtension "SPV_KHR_8bit_storage"
  3608. OpMemoryModel Logical GLSL450
  3609. OpDecorate %block BufferBlock
  3610. OpMemberDecorate %block 0 Offset 0
  3611. %void = OpTypeVoid
  3612. %char = OpTypeInt 8 0
  3613. %int = OpTypeInt 32 0
  3614. %int_4 = OpConstant %int 4
  3615. %block = OpTypeStruct %char
  3616. %block_array = OpTypeArray %block %int_4
  3617. %ptr_block_array = OpTypePointer Uniform %block_array
  3618. %var = OpVariable %ptr_block_array Uniform
  3619. )";
  3620. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  3621. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3622. }
  3623. TEST_F(ValidateMemory, SmallStorageVariableArrayBufferBlockHalf) {
  3624. const std::string spirv = R"(
  3625. OpCapability Shader
  3626. OpCapability Linkage
  3627. OpCapability StorageBuffer16BitAccess
  3628. OpExtension "SPV_KHR_16bit_storage"
  3629. OpMemoryModel Logical GLSL450
  3630. OpDecorate %block BufferBlock
  3631. OpMemberDecorate %block 0 Offset 0
  3632. %void = OpTypeVoid
  3633. %half = OpTypeFloat 16
  3634. %int = OpTypeInt 32 0
  3635. %int_4 = OpConstant %int 4
  3636. %block = OpTypeStruct %half
  3637. %block_array = OpTypeArray %block %int_4
  3638. %ptr_block_array = OpTypePointer Uniform %block_array
  3639. %var = OpVariable %ptr_block_array Uniform
  3640. )";
  3641. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  3642. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3643. }
  3644. TEST_F(ValidateMemory, VulkanStorageBufferNotAStruct) {
  3645. const std::string spirv = R"(
  3646. OpCapability Shader
  3647. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3648. OpMemoryModel Logical GLSL450
  3649. OpEntryPoint GLCompute %main "main"
  3650. OpExecutionMode %main LocalSize 1 1 1
  3651. %void = OpTypeVoid
  3652. %uint = OpTypeInt 32 0
  3653. %ptr_ssbo = OpTypePointer StorageBuffer %uint
  3654. %var = OpVariable %ptr_ssbo StorageBuffer
  3655. %void_fn = OpTypeFunction %void
  3656. %main = OpFunction %void None %void_fn
  3657. %entry = OpLabel
  3658. OpReturn
  3659. OpFunctionEnd
  3660. )";
  3661. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  3662. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3663. EXPECT_THAT(
  3664. getDiagnosticString(),
  3665. HasSubstr("From Vulkan spec, section 14.5.2:\nVariables identified with "
  3666. "the StorageBuffer storage class are used to access "
  3667. "transparent buffer backed resources. Such variables must be "
  3668. "typed as OpTypeStruct, or an array of this type"));
  3669. }
  3670. TEST_F(ValidateMemory, VulkanStorageBufferRuntimeArrayNotAStruct) {
  3671. const std::string spirv = R"(
  3672. OpCapability Shader
  3673. OpCapability RuntimeDescriptorArrayEXT
  3674. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3675. OpExtension "SPV_EXT_descriptor_indexing"
  3676. OpMemoryModel Logical GLSL450
  3677. OpEntryPoint GLCompute %main "main"
  3678. OpExecutionMode %main LocalSize 1 1 1
  3679. %void = OpTypeVoid
  3680. %uint = OpTypeInt 32 0
  3681. %array = OpTypeRuntimeArray %uint
  3682. %ptr_ssbo = OpTypePointer StorageBuffer %array
  3683. %var = OpVariable %ptr_ssbo StorageBuffer
  3684. %void_fn = OpTypeFunction %void
  3685. %main = OpFunction %void None %void_fn
  3686. %entry = OpLabel
  3687. OpReturn
  3688. OpFunctionEnd
  3689. )";
  3690. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  3691. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3692. EXPECT_THAT(
  3693. getDiagnosticString(),
  3694. HasSubstr("From Vulkan spec, section 14.5.2:\nVariables identified with "
  3695. "the StorageBuffer storage class are used to access "
  3696. "transparent buffer backed resources. Such variables must be "
  3697. "typed as OpTypeStruct, or an array of this type"));
  3698. }
  3699. TEST_F(ValidateMemory, VulkanStorageBufferArrayNotAStruct) {
  3700. const std::string spirv = R"(
  3701. OpCapability Shader
  3702. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3703. OpMemoryModel Logical GLSL450
  3704. OpEntryPoint GLCompute %main "main"
  3705. OpExecutionMode %main LocalSize 1 1 1
  3706. %void = OpTypeVoid
  3707. %uint = OpTypeInt 32 0
  3708. %uint_4 = OpConstant %uint 4
  3709. %array = OpTypeArray %uint %uint_4
  3710. %ptr_ssbo = OpTypePointer StorageBuffer %array
  3711. %var = OpVariable %ptr_ssbo StorageBuffer
  3712. %void_fn = OpTypeFunction %void
  3713. %main = OpFunction %void None %void_fn
  3714. %entry = OpLabel
  3715. OpReturn
  3716. OpFunctionEnd
  3717. )";
  3718. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  3719. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3720. EXPECT_THAT(
  3721. getDiagnosticString(),
  3722. HasSubstr("From Vulkan spec, section 14.5.2:\nVariables identified with "
  3723. "the StorageBuffer storage class are used to access "
  3724. "transparent buffer backed resources. Such variables must be "
  3725. "typed as OpTypeStruct, or an array of this type"));
  3726. }
  3727. TEST_F(ValidateMemory, PhysicalStorageBufferPtrEqual) {
  3728. const std::string spirv = R"(
  3729. OpCapability Shader
  3730. OpCapability Int64
  3731. OpCapability PhysicalStorageBufferAddresses
  3732. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  3733. OpEntryPoint GLCompute %main "main"
  3734. OpExecutionMode %main LocalSize 1 1 1
  3735. %void = OpTypeVoid
  3736. %bool = OpTypeBool
  3737. %long = OpTypeInt 64 0
  3738. %long_0 = OpConstant %long 0
  3739. %ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
  3740. %void_fn = OpTypeFunction %void
  3741. %main = OpFunction %void None %void_fn
  3742. %entry = OpLabel
  3743. %conv = OpConvertUToPtr %ptr_pssbo_long %long_0
  3744. %eq = OpPtrEqual %bool %conv %conv
  3745. OpReturn
  3746. OpFunctionEnd
  3747. )";
  3748. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  3749. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  3750. EXPECT_THAT(
  3751. getDiagnosticString(),
  3752. HasSubstr(
  3753. "Cannot use a pointer in the PhysicalStorageBuffer storage class"));
  3754. }
  3755. TEST_F(ValidateMemory, PhysicalStorageBufferPtrNotEqual) {
  3756. const std::string spirv = R"(
  3757. OpCapability Shader
  3758. OpCapability Int64
  3759. OpCapability PhysicalStorageBufferAddresses
  3760. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  3761. OpEntryPoint GLCompute %main "main"
  3762. OpExecutionMode %main LocalSize 1 1 1
  3763. %void = OpTypeVoid
  3764. %bool = OpTypeBool
  3765. %long = OpTypeInt 64 0
  3766. %long_0 = OpConstant %long 0
  3767. %ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
  3768. %void_fn = OpTypeFunction %void
  3769. %main = OpFunction %void None %void_fn
  3770. %entry = OpLabel
  3771. %conv = OpConvertUToPtr %ptr_pssbo_long %long_0
  3772. %neq = OpPtrNotEqual %bool %conv %conv
  3773. OpReturn
  3774. OpFunctionEnd
  3775. )";
  3776. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  3777. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  3778. EXPECT_THAT(
  3779. getDiagnosticString(),
  3780. HasSubstr(
  3781. "Cannot use a pointer in the PhysicalStorageBuffer storage class"));
  3782. }
  3783. TEST_F(ValidateMemory, PhysicalStorageBufferPtrDiff) {
  3784. const std::string spirv = R"(
  3785. OpCapability Shader
  3786. OpCapability Int64
  3787. OpCapability PhysicalStorageBufferAddresses
  3788. OpCapability VariablePointers
  3789. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  3790. OpEntryPoint GLCompute %main "main"
  3791. OpExecutionMode %main LocalSize 1 1 1
  3792. %void = OpTypeVoid
  3793. %long = OpTypeInt 64 0
  3794. %long_0 = OpConstant %long 0
  3795. %ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
  3796. %void_fn = OpTypeFunction %void
  3797. %main = OpFunction %void None %void_fn
  3798. %entry = OpLabel
  3799. %conv = OpConvertUToPtr %ptr_pssbo_long %long_0
  3800. %diff = OpPtrDiff %long %conv %conv
  3801. OpReturn
  3802. OpFunctionEnd
  3803. )";
  3804. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  3805. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  3806. EXPECT_THAT(
  3807. getDiagnosticString(),
  3808. HasSubstr(
  3809. "Cannot use a pointer in the PhysicalStorageBuffer storage class"));
  3810. }
  3811. TEST_F(ValidateMemory, VulkanInitializerWithWorkgroupStorageClassBad) {
  3812. std::string spirv = R"(
  3813. OpCapability Shader
  3814. OpCapability VulkanMemoryModelKHR
  3815. OpExtension "SPV_KHR_vulkan_memory_model"
  3816. OpMemoryModel Logical VulkanKHR
  3817. OpEntryPoint Fragment %func "func"
  3818. OpExecutionMode %func OriginUpperLeft
  3819. %float = OpTypeFloat 32
  3820. %float_ptr = OpTypePointer Workgroup %float
  3821. %init_val = OpConstant %float 1.0
  3822. %1 = OpVariable %float_ptr Workgroup %init_val
  3823. %void = OpTypeVoid
  3824. %functy = OpTypeFunction %void
  3825. %func = OpFunction %void None %functy
  3826. %2 = OpLabel
  3827. OpReturn
  3828. OpFunctionEnd
  3829. )";
  3830. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
  3831. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3832. EXPECT_THAT(getDiagnosticString(),
  3833. HasSubstr("Variable initializers in Workgroup storage class are "
  3834. "limited to OpConstantNull"));
  3835. }
  3836. TEST_F(ValidateMemory, VulkanInitializerWithWorkgroupStorageClassGood) {
  3837. std::string spirv = R"(
  3838. OpCapability Shader
  3839. OpCapability VulkanMemoryModelKHR
  3840. OpExtension "SPV_KHR_vulkan_memory_model"
  3841. OpMemoryModel Logical VulkanKHR
  3842. OpEntryPoint Fragment %func "func"
  3843. OpExecutionMode %func OriginUpperLeft
  3844. %float = OpTypeFloat 32
  3845. %float_ptr = OpTypePointer Workgroup %float
  3846. %init_val = OpConstantNull %float
  3847. %1 = OpVariable %float_ptr Workgroup %init_val
  3848. %void = OpTypeVoid
  3849. %functy = OpTypeFunction %void
  3850. %func = OpFunction %void None %functy
  3851. %2 = OpLabel
  3852. OpReturn
  3853. OpFunctionEnd
  3854. )";
  3855. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
  3856. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3857. }
  3858. } // namespace
  3859. } // namespace val
  3860. } // namespace spvtools