val_memory_test.cpp 158 KB

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