val_decoration_test.cpp 386 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070
  1. // Copyright (c) 2017 Google Inc.
  2. // Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
  3. // reserved.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. // Validation tests for decorations
  17. #include <string>
  18. #include <vector>
  19. #include "gmock/gmock.h"
  20. #include "source/val/decoration.h"
  21. #include "test/unit_spirv.h"
  22. #include "test/val/val_code_generator.h"
  23. #include "test/val/val_fixtures.h"
  24. namespace spvtools {
  25. namespace val {
  26. namespace {
  27. using ::testing::Combine;
  28. using ::testing::Eq;
  29. using ::testing::HasSubstr;
  30. using ::testing::Values;
  31. struct TestResult {
  32. TestResult(spv_result_t in_validation_result = SPV_SUCCESS,
  33. const std::string& in_error_str = "")
  34. : validation_result(in_validation_result), error_str(in_error_str) {}
  35. spv_result_t validation_result;
  36. const std::string error_str;
  37. };
  38. using ValidateDecorations = spvtest::ValidateBase<bool>;
  39. using ValidateDecorationString = spvtest::ValidateBase<std::string>;
  40. using ValidateVulkanCombineDecorationResult =
  41. spvtest::ValidateBase<std::tuple<const char*, const char*, TestResult>>;
  42. TEST_F(ValidateDecorations, ValidateOpDecorateRegistration) {
  43. std::string spirv = R"(
  44. OpCapability Shader
  45. OpCapability Linkage
  46. OpMemoryModel Logical GLSL450
  47. OpDecorate %1 Location 4
  48. OpDecorate %1 Centroid
  49. %2 = OpTypeFloat 32
  50. %3 = OpTypePointer Output %2
  51. %1 = OpVariable %3 Output
  52. ; Since %1 is used first in Decoration, it gets id 1.
  53. )";
  54. const uint32_t id = 1;
  55. CompileSuccessfully(spirv);
  56. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  57. // Must have 2 decorations.
  58. EXPECT_THAT(
  59. vstate_->id_decorations(id),
  60. Eq(std::set<Decoration>{Decoration(spv::Decoration::Location, {4}),
  61. Decoration(spv::Decoration::Centroid)}));
  62. }
  63. TEST_F(ValidateDecorations, ValidateOpMemberDecorateRegistration) {
  64. std::string spirv = R"(
  65. OpCapability Shader
  66. OpCapability Linkage
  67. OpMemoryModel Logical GLSL450
  68. OpDecorate %_arr_double_uint_6 ArrayStride 4
  69. OpMemberDecorate %_struct_115 2 NonReadable
  70. OpMemberDecorate %_struct_115 2 Offset 2
  71. OpDecorate %_struct_115 BufferBlock
  72. %float = OpTypeFloat 32
  73. %uint = OpTypeInt 32 0
  74. %uint_6 = OpConstant %uint 6
  75. %_arr_double_uint_6 = OpTypeArray %float %uint_6
  76. %_struct_115 = OpTypeStruct %float %float %_arr_double_uint_6
  77. )";
  78. CompileSuccessfully(spirv);
  79. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  80. // The array must have 1 decoration.
  81. const uint32_t arr_id = 1;
  82. EXPECT_THAT(
  83. vstate_->id_decorations(arr_id),
  84. Eq(std::set<Decoration>{Decoration(spv::Decoration::ArrayStride, {4})}));
  85. // The struct must have 3 decorations.
  86. const uint32_t struct_id = 2;
  87. EXPECT_THAT(
  88. vstate_->id_decorations(struct_id),
  89. Eq(std::set<Decoration>{Decoration(spv::Decoration::NonReadable, {}, 2),
  90. Decoration(spv::Decoration::Offset, {2}, 2),
  91. Decoration(spv::Decoration::BufferBlock)}));
  92. }
  93. TEST_F(ValidateDecorations, ValidateOpMemberDecorateOutOfBound) {
  94. std::string spirv = R"(
  95. OpCapability Shader
  96. OpMemoryModel Logical GLSL450
  97. OpEntryPoint Fragment %1 "Main"
  98. OpExecutionMode %1 OriginUpperLeft
  99. OpMemberDecorate %_struct_2 1 RelaxedPrecision
  100. %void = OpTypeVoid
  101. %4 = OpTypeFunction %void
  102. %float = OpTypeFloat 32
  103. %_struct_2 = OpTypeStruct %float
  104. %1 = OpFunction %void None %4
  105. %6 = OpLabel
  106. OpReturn
  107. OpFunctionEnd
  108. )";
  109. CompileSuccessfully(spirv);
  110. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  111. EXPECT_THAT(getDiagnosticString(),
  112. HasSubstr("Index 1 provided in OpMemberDecorate for struct <id> "
  113. "'2[%_struct_2]' is out of bounds. The structure has 1 "
  114. "members. Largest valid index is 0."));
  115. }
  116. TEST_F(ValidateDecorations, ValidateGroupDecorateRegistration) {
  117. std::string spirv = R"(
  118. OpCapability Shader
  119. OpCapability Linkage
  120. OpMemoryModel Logical GLSL450
  121. OpDecorate %1 DescriptorSet 0
  122. OpDecorate %1 RelaxedPrecision
  123. OpDecorate %1 Restrict
  124. %1 = OpDecorationGroup
  125. OpGroupDecorate %1 %2 %3
  126. OpGroupDecorate %1 %4
  127. %float = OpTypeFloat 32
  128. %_runtimearr_float = OpTypeRuntimeArray %float
  129. %_struct_9 = OpTypeStruct %_runtimearr_float
  130. %_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
  131. %2 = OpVariable %_ptr_Uniform__struct_9 Uniform
  132. %_struct_10 = OpTypeStruct %_runtimearr_float
  133. %_ptr_Uniform__struct_10 = OpTypePointer Uniform %_struct_10
  134. %3 = OpVariable %_ptr_Uniform__struct_10 Uniform
  135. %_struct_11 = OpTypeStruct %_runtimearr_float
  136. %_ptr_Uniform__struct_11 = OpTypePointer Uniform %_struct_11
  137. %4 = OpVariable %_ptr_Uniform__struct_11 Uniform
  138. )";
  139. CompileSuccessfully(spirv);
  140. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  141. // Decoration group has 3 decorations.
  142. auto expected_decorations =
  143. std::set<Decoration>{Decoration(spv::Decoration::DescriptorSet, {0}),
  144. Decoration(spv::Decoration::RelaxedPrecision),
  145. Decoration(spv::Decoration::Restrict)};
  146. // Decoration group is applied to id 1, 2, 3, and 4. Note that id 1 (which is
  147. // the decoration group id) also has all the decorations.
  148. EXPECT_THAT(vstate_->id_decorations(1), Eq(expected_decorations));
  149. EXPECT_THAT(vstate_->id_decorations(2), Eq(expected_decorations));
  150. EXPECT_THAT(vstate_->id_decorations(3), Eq(expected_decorations));
  151. EXPECT_THAT(vstate_->id_decorations(4), Eq(expected_decorations));
  152. }
  153. TEST_F(ValidateDecorations, ValidateGroupMemberDecorateRegistration) {
  154. std::string spirv = R"(
  155. OpCapability Shader
  156. OpCapability Linkage
  157. OpMemoryModel Logical GLSL450
  158. OpDecorate %1 Offset 3
  159. %1 = OpDecorationGroup
  160. OpGroupMemberDecorate %1 %_struct_1 3 %_struct_2 3 %_struct_3 3
  161. %float = OpTypeFloat 32
  162. %_runtimearr = OpTypeRuntimeArray %float
  163. %_struct_1 = OpTypeStruct %float %float %float %_runtimearr
  164. %_struct_2 = OpTypeStruct %float %float %float %_runtimearr
  165. %_struct_3 = OpTypeStruct %float %float %float %_runtimearr
  166. )";
  167. CompileSuccessfully(spirv);
  168. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  169. // Decoration group has 1 decoration.
  170. auto expected_decorations =
  171. std::set<Decoration>{Decoration(spv::Decoration::Offset, {3}, 3)};
  172. // Decoration group is applied to id 2, 3, and 4.
  173. EXPECT_THAT(vstate_->id_decorations(2), Eq(expected_decorations));
  174. EXPECT_THAT(vstate_->id_decorations(3), Eq(expected_decorations));
  175. EXPECT_THAT(vstate_->id_decorations(4), Eq(expected_decorations));
  176. }
  177. TEST_F(ValidateDecorations, LinkageImportUsedForInitializedVariableBad) {
  178. std::string spirv = R"(
  179. OpCapability Shader
  180. OpCapability Linkage
  181. OpMemoryModel Logical GLSL450
  182. OpDecorate %target LinkageAttributes "link_ptr" Import
  183. %float = OpTypeFloat 32
  184. %_ptr_float = OpTypePointer Uniform %float
  185. %zero = OpConstantNull %float
  186. %target = OpVariable %_ptr_float Uniform %zero
  187. )";
  188. CompileSuccessfully(spirv);
  189. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  190. EXPECT_THAT(getDiagnosticString(),
  191. HasSubstr("A module-scope OpVariable with initialization value "
  192. "cannot be marked with the Import Linkage Type."));
  193. }
  194. TEST_F(ValidateDecorations, LinkageExportUsedForInitializedVariableGood) {
  195. std::string spirv = R"(
  196. OpCapability Shader
  197. OpCapability Linkage
  198. OpMemoryModel Logical GLSL450
  199. OpDecorate %target LinkageAttributes "link_ptr" Export
  200. %float = OpTypeFloat 32
  201. %_ptr_float = OpTypePointer Uniform %float
  202. %zero = OpConstantNull %float
  203. %target = OpVariable %_ptr_float Uniform %zero
  204. )";
  205. CompileSuccessfully(spirv);
  206. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  207. }
  208. TEST_F(ValidateDecorations, StructAllMembersHaveBuiltInDecorationsGood) {
  209. std::string spirv = R"(
  210. OpCapability Shader
  211. OpCapability Linkage
  212. OpMemoryModel Logical GLSL450
  213. OpDecorate %_struct_1 Block
  214. OpMemberDecorate %_struct_1 0 BuiltIn Position
  215. OpMemberDecorate %_struct_1 1 BuiltIn Position
  216. OpMemberDecorate %_struct_1 2 BuiltIn Position
  217. OpMemberDecorate %_struct_1 3 BuiltIn Position
  218. %float = OpTypeFloat 32
  219. %_runtimearr = OpTypeRuntimeArray %float
  220. %_struct_1 = OpTypeStruct %float %float %float %_runtimearr
  221. )";
  222. CompileSuccessfully(spirv);
  223. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  224. }
  225. TEST_F(ValidateDecorations, MixedBuiltInDecorationsBad) {
  226. std::string spirv = R"(
  227. OpCapability Shader
  228. OpCapability Linkage
  229. OpMemoryModel Logical GLSL450
  230. OpDecorate %_struct_1 Block
  231. OpMemberDecorate %_struct_1 0 BuiltIn Position
  232. OpMemberDecorate %_struct_1 1 BuiltIn Position
  233. %float = OpTypeFloat 32
  234. %_runtimearr = OpTypeRuntimeArray %float
  235. %_struct_1 = OpTypeStruct %float %float %float %_runtimearr
  236. )";
  237. CompileSuccessfully(spirv);
  238. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  239. EXPECT_THAT(
  240. getDiagnosticString(),
  241. HasSubstr("When BuiltIn decoration is applied to a structure-type "
  242. "member, all members of that structure type must also be "
  243. "decorated with BuiltIn (No allowed mixing of built-in "
  244. "variables and non-built-in variables within a single "
  245. "structure). Structure id 1 does not meet this requirement."));
  246. }
  247. TEST_F(ValidateDecorations, StructContainsBuiltInStructBad) {
  248. std::string spirv = R"(
  249. OpCapability Shader
  250. OpCapability Linkage
  251. OpMemoryModel Logical GLSL450
  252. OpDecorate %_struct_1 Block
  253. OpMemberDecorate %_struct_1 0 BuiltIn Position
  254. OpMemberDecorate %_struct_1 1 BuiltIn Position
  255. OpMemberDecorate %_struct_1 2 BuiltIn Position
  256. OpMemberDecorate %_struct_1 3 BuiltIn Position
  257. %float = OpTypeFloat 32
  258. %_runtimearr = OpTypeRuntimeArray %float
  259. %_struct_1 = OpTypeStruct %float %float %float %_runtimearr
  260. %_struct_2 = OpTypeStruct %_struct_1
  261. )";
  262. CompileSuccessfully(spirv);
  263. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  264. EXPECT_THAT(
  265. getDiagnosticString(),
  266. HasSubstr("Structure <id> '1[%_struct_1]' contains members with "
  267. "BuiltIn decoration. Therefore this structure may not "
  268. "be contained as a member of another structure type. "
  269. "Structure <id> '4[%_struct_4]' contains structure <id> "
  270. "'1[%_struct_1]'."));
  271. }
  272. TEST_F(ValidateDecorations, StructContainsNonBuiltInStructGood) {
  273. std::string spirv = R"(
  274. OpCapability Shader
  275. OpCapability Linkage
  276. OpMemoryModel Logical GLSL450
  277. %float = OpTypeFloat 32
  278. %_struct_1 = OpTypeStruct %float
  279. %_struct_2 = OpTypeStruct %_struct_1
  280. )";
  281. CompileSuccessfully(spirv);
  282. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  283. }
  284. TEST_F(ValidateDecorations, MultipleBuiltInObjectsConsumedByOpEntryPointBad) {
  285. std::string spirv = R"(
  286. OpCapability Shader
  287. OpCapability Geometry
  288. OpMemoryModel Logical GLSL450
  289. OpEntryPoint Geometry %main "main" %in_1 %in_2
  290. OpExecutionMode %main InputPoints
  291. OpExecutionMode %main OutputPoints
  292. OpDecorate %struct_1 Block
  293. OpDecorate %struct_2 Block
  294. OpMemberDecorate %struct_1 0 BuiltIn InvocationId
  295. OpMemberDecorate %struct_2 0 BuiltIn Position
  296. %int = OpTypeInt 32 1
  297. %void = OpTypeVoid
  298. %func = OpTypeFunction %void
  299. %float = OpTypeFloat 32
  300. %struct_1 = OpTypeStruct %int
  301. %struct_2 = OpTypeStruct %float
  302. %ptr_builtin_1 = OpTypePointer Input %struct_1
  303. %ptr_builtin_2 = OpTypePointer Input %struct_2
  304. %in_1 = OpVariable %ptr_builtin_1 Input
  305. %in_2 = OpVariable %ptr_builtin_2 Input
  306. %main = OpFunction %void None %func
  307. %5 = OpLabel
  308. OpReturn
  309. OpFunctionEnd
  310. )";
  311. CompileSuccessfully(spirv);
  312. EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateAndRetrieveValidationState());
  313. EXPECT_THAT(getDiagnosticString(),
  314. HasSubstr("There must be at most one object per Storage Class "
  315. "that can contain a structure type containing members "
  316. "decorated with BuiltIn, consumed per entry-point."));
  317. }
  318. TEST_F(ValidateDecorations,
  319. OneBuiltInObjectPerStorageClassConsumedByOpEntryPointGood) {
  320. std::string spirv = R"(
  321. OpCapability Shader
  322. OpCapability Geometry
  323. OpMemoryModel Logical GLSL450
  324. OpEntryPoint Geometry %main "main" %in_1 %out_1
  325. OpExecutionMode %main InputPoints
  326. OpExecutionMode %main OutputPoints
  327. OpDecorate %struct_1 Block
  328. OpDecorate %struct_2 Block
  329. OpMemberDecorate %struct_1 0 BuiltIn InvocationId
  330. OpMemberDecorate %struct_2 0 BuiltIn Position
  331. %int = OpTypeInt 32 1
  332. %void = OpTypeVoid
  333. %func = OpTypeFunction %void
  334. %float = OpTypeFloat 32
  335. %struct_1 = OpTypeStruct %int
  336. %struct_2 = OpTypeStruct %float
  337. %ptr_builtin_1 = OpTypePointer Input %struct_1
  338. %ptr_builtin_2 = OpTypePointer Output %struct_2
  339. %in_1 = OpVariable %ptr_builtin_1 Input
  340. %out_1 = OpVariable %ptr_builtin_2 Output
  341. %main = OpFunction %void None %func
  342. %5 = OpLabel
  343. OpReturn
  344. OpFunctionEnd
  345. )";
  346. CompileSuccessfully(spirv);
  347. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  348. }
  349. TEST_F(ValidateDecorations, NoBuiltInObjectsConsumedByOpEntryPointGood) {
  350. std::string spirv = R"(
  351. OpCapability Shader
  352. OpCapability Geometry
  353. OpMemoryModel Logical GLSL450
  354. OpEntryPoint Geometry %main "main" %in_1 %out_1
  355. OpExecutionMode %main InputPoints
  356. OpExecutionMode %main OutputPoints
  357. %int = OpTypeInt 32 1
  358. %void = OpTypeVoid
  359. %func = OpTypeFunction %void
  360. %float = OpTypeFloat 32
  361. %struct_1 = OpTypeStruct %int
  362. %struct_2 = OpTypeStruct %float
  363. %ptr_builtin_1 = OpTypePointer Input %struct_1
  364. %ptr_builtin_2 = OpTypePointer Output %struct_2
  365. %in_1 = OpVariable %ptr_builtin_1 Input
  366. %out_1 = OpVariable %ptr_builtin_2 Output
  367. %main = OpFunction %void None %func
  368. %5 = OpLabel
  369. OpReturn
  370. OpFunctionEnd
  371. )";
  372. CompileSuccessfully(spirv);
  373. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  374. }
  375. TEST_F(ValidateDecorations, EntryPointFunctionHasLinkageAttributeBad) {
  376. std::string spirv = R"(
  377. OpCapability Shader
  378. OpCapability Linkage
  379. OpMemoryModel Logical GLSL450
  380. OpEntryPoint GLCompute %main "main"
  381. OpDecorate %main LinkageAttributes "import_main" Import
  382. %1 = OpTypeVoid
  383. %2 = OpTypeFunction %1
  384. %main = OpFunction %1 None %2
  385. %4 = OpLabel
  386. OpReturn
  387. OpFunctionEnd
  388. )";
  389. CompileSuccessfully(spirv.c_str());
  390. EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
  391. EXPECT_THAT(
  392. getDiagnosticString(),
  393. HasSubstr("The LinkageAttributes Decoration (Linkage name: import_main) "
  394. "cannot be applied to function id 1 because it is targeted by "
  395. "an OpEntryPoint instruction."));
  396. }
  397. TEST_F(ValidateDecorations, FunctionDeclarationWithoutImportLinkageBad) {
  398. std::string spirv = R"(
  399. OpCapability Shader
  400. OpCapability Linkage
  401. OpMemoryModel Logical GLSL450
  402. %void = OpTypeVoid
  403. %func = OpTypeFunction %void
  404. %main = OpFunction %void None %func
  405. OpFunctionEnd
  406. )";
  407. CompileSuccessfully(spirv);
  408. EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateAndRetrieveValidationState());
  409. EXPECT_THAT(
  410. getDiagnosticString(),
  411. HasSubstr("Function declaration (id 3) must have a LinkageAttributes "
  412. "decoration with the Import Linkage type."));
  413. }
  414. TEST_F(ValidateDecorations, FunctionDeclarationWithImportLinkageGood) {
  415. std::string spirv = R"(
  416. OpCapability Shader
  417. OpCapability Linkage
  418. OpMemoryModel Logical GLSL450
  419. OpDecorate %main LinkageAttributes "link_fn" Import
  420. %void = OpTypeVoid
  421. %func = OpTypeFunction %void
  422. %main = OpFunction %void None %func
  423. OpFunctionEnd
  424. )";
  425. CompileSuccessfully(spirv);
  426. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  427. }
  428. TEST_F(ValidateDecorations, FunctionDeclarationWithExportLinkageBad) {
  429. std::string spirv = R"(
  430. OpCapability Shader
  431. OpCapability Linkage
  432. OpMemoryModel Logical GLSL450
  433. OpDecorate %main LinkageAttributes "link_fn" Export
  434. %void = OpTypeVoid
  435. %func = OpTypeFunction %void
  436. %main = OpFunction %void None %func
  437. OpFunctionEnd
  438. )";
  439. CompileSuccessfully(spirv);
  440. EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateAndRetrieveValidationState());
  441. EXPECT_THAT(
  442. getDiagnosticString(),
  443. HasSubstr("Function declaration (id 1) must have a LinkageAttributes "
  444. "decoration with the Import Linkage type."));
  445. }
  446. TEST_F(ValidateDecorations, FunctionDefinitionWithImportLinkageBad) {
  447. std::string spirv = R"(
  448. OpCapability Shader
  449. OpCapability Linkage
  450. OpMemoryModel Logical GLSL450
  451. OpDecorate %main LinkageAttributes "link_fn" Import
  452. %void = OpTypeVoid
  453. %func = OpTypeFunction %void
  454. %main = OpFunction %void None %func
  455. %label = OpLabel
  456. OpReturn
  457. OpFunctionEnd
  458. )";
  459. CompileSuccessfully(spirv);
  460. EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateAndRetrieveValidationState());
  461. EXPECT_THAT(getDiagnosticString(),
  462. HasSubstr("Function definition (id 1) may not be decorated with "
  463. "Import Linkage type."));
  464. }
  465. TEST_F(ValidateDecorations, FunctionDefinitionWithoutImportLinkageGood) {
  466. std::string spirv = R"(
  467. OpCapability Shader
  468. OpCapability Linkage
  469. OpMemoryModel Logical GLSL450
  470. %void = OpTypeVoid
  471. %func = OpTypeFunction %void
  472. %main = OpFunction %void None %func
  473. %label = OpLabel
  474. OpReturn
  475. OpFunctionEnd
  476. )";
  477. CompileSuccessfully(spirv);
  478. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  479. }
  480. TEST_F(ValidateDecorations, BuiltinVariablesGoodVulkan) {
  481. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  482. std::string spirv = R"(
  483. OpCapability Shader
  484. OpMemoryModel Logical GLSL450
  485. OpEntryPoint Fragment %main "main" %gl_FragCoord %_entryPointOutput
  486. OpExecutionMode %main OriginUpperLeft
  487. OpSource HLSL 500
  488. OpDecorate %gl_FragCoord BuiltIn FragCoord
  489. OpDecorate %_entryPointOutput Location 0
  490. %void = OpTypeVoid
  491. %3 = OpTypeFunction %void
  492. %float = OpTypeFloat 32
  493. %v4float = OpTypeVector %float 4
  494. %float_0 = OpConstant %float 0
  495. %14 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  496. %_ptr_Input_v4float = OpTypePointer Input %v4float
  497. %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
  498. %_ptr_Output_v4float = OpTypePointer Output %v4float
  499. %_entryPointOutput = OpVariable %_ptr_Output_v4float Output
  500. %main = OpFunction %void None %3
  501. %5 = OpLabel
  502. OpStore %_entryPointOutput %14
  503. OpReturn
  504. OpFunctionEnd
  505. )";
  506. CompileSuccessfully(spirv, env);
  507. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  508. }
  509. TEST_F(ValidateDecorations, BuiltinVariablesWithLocationDecorationVulkan) {
  510. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  511. std::string spirv = R"(
  512. OpCapability Shader
  513. OpMemoryModel Logical GLSL450
  514. OpEntryPoint Fragment %main "main" %gl_FragCoord %_entryPointOutput
  515. OpExecutionMode %main OriginUpperLeft
  516. OpSource HLSL 500
  517. OpDecorate %gl_FragCoord BuiltIn FragCoord
  518. OpDecorate %gl_FragCoord Location 0
  519. OpDecorate %_entryPointOutput Location 0
  520. %void = OpTypeVoid
  521. %3 = OpTypeFunction %void
  522. %float = OpTypeFloat 32
  523. %v4float = OpTypeVector %float 4
  524. %float_0 = OpConstant %float 0
  525. %14 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  526. %_ptr_Input_v4float = OpTypePointer Input %v4float
  527. %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
  528. %_ptr_Output_v4float = OpTypePointer Output %v4float
  529. %_entryPointOutput = OpVariable %_ptr_Output_v4float Output
  530. %main = OpFunction %void None %3
  531. %5 = OpLabel
  532. OpStore %_entryPointOutput %14
  533. OpReturn
  534. OpFunctionEnd
  535. )";
  536. CompileSuccessfully(spirv, env);
  537. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  538. EXPECT_THAT(getDiagnosticString(),
  539. AnyVUID("VUID-StandaloneSpirv-Location-04915"));
  540. EXPECT_THAT(getDiagnosticString(),
  541. HasSubstr("A BuiltIn variable (id 2) cannot have any Location or "
  542. "Component decorations"));
  543. }
  544. TEST_F(ValidateDecorations, BuiltinVariablesWithComponentDecorationVulkan) {
  545. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  546. std::string spirv = R"(
  547. OpCapability Shader
  548. OpMemoryModel Logical GLSL450
  549. OpEntryPoint Fragment %main "main" %gl_FragCoord %_entryPointOutput
  550. OpExecutionMode %main OriginUpperLeft
  551. OpSource HLSL 500
  552. OpDecorate %gl_FragCoord BuiltIn FragCoord
  553. OpDecorate %gl_FragCoord Component 0
  554. OpDecorate %_entryPointOutput Location 0
  555. %void = OpTypeVoid
  556. %3 = OpTypeFunction %void
  557. %float = OpTypeFloat 32
  558. %v4float = OpTypeVector %float 4
  559. %float_0 = OpConstant %float 0
  560. %14 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  561. %_ptr_Input_v4float = OpTypePointer Input %v4float
  562. %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
  563. %_ptr_Output_v4float = OpTypePointer Output %v4float
  564. %_entryPointOutput = OpVariable %_ptr_Output_v4float Output
  565. %main = OpFunction %void None %3
  566. %5 = OpLabel
  567. OpStore %_entryPointOutput %14
  568. OpReturn
  569. OpFunctionEnd
  570. )";
  571. CompileSuccessfully(spirv, env);
  572. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  573. EXPECT_THAT(getDiagnosticString(),
  574. AnyVUID("VUID-StandaloneSpirv-Location-04915"));
  575. EXPECT_THAT(getDiagnosticString(),
  576. HasSubstr("A BuiltIn variable (id 2) cannot have any Location or "
  577. "Component decorations"));
  578. }
  579. TEST_F(ValidateDecorations, LocationDecorationOnNumericTypeBad) {
  580. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  581. std::string spirv = R"(
  582. OpCapability Shader
  583. OpMemoryModel Logical GLSL450
  584. OpEntryPoint Fragment %main "main" %fragCoord
  585. OpExecutionMode %main OriginUpperLeft
  586. OpDecorate %fragCoord Location 0
  587. OpDecorate %v4float Location 1
  588. %void = OpTypeVoid
  589. %voidfn = OpTypeFunction %void
  590. %float = OpTypeFloat 32
  591. %v4float = OpTypeVector %float 4
  592. %ptr_v4float = OpTypePointer Output %v4float
  593. %fragCoord = OpVariable %ptr_v4float Output
  594. %non_interface = OpVariable %ptr_v4float Output
  595. %main = OpFunction %void None %voidfn
  596. %label = OpLabel
  597. OpReturn
  598. OpFunctionEnd
  599. )";
  600. CompileSuccessfully(spirv, env);
  601. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  602. EXPECT_THAT(getDiagnosticString(),
  603. HasSubstr("Location decoration on target <id> '3[%v4float]' must "
  604. "be a variable"));
  605. }
  606. TEST_F(ValidateDecorations, LocationDecorationOnStructBad) {
  607. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  608. std::string spirv = R"(
  609. OpCapability Shader
  610. OpMemoryModel Logical GLSL450
  611. OpEntryPoint Fragment %main "main" %fragCoord
  612. OpExecutionMode %main OriginUpperLeft
  613. OpDecorate %fragCoord Location 0
  614. OpDecorate %struct Location 1
  615. %void = OpTypeVoid
  616. %voidfn = OpTypeFunction %void
  617. %float = OpTypeFloat 32
  618. %struct = OpTypeStruct %float
  619. %v4float = OpTypeVector %float 4
  620. %ptr_v4float = OpTypePointer Output %v4float
  621. %fragCoord = OpVariable %ptr_v4float Output
  622. %non_interface = OpVariable %ptr_v4float Output
  623. %main = OpFunction %void None %voidfn
  624. %label = OpLabel
  625. OpReturn
  626. OpFunctionEnd
  627. )";
  628. CompileSuccessfully(spirv, env);
  629. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  630. EXPECT_THAT(getDiagnosticString(),
  631. HasSubstr("Location decoration on target <id> '3[%_struct_3]' "
  632. "must be a variable"));
  633. }
  634. TEST_F(ValidateDecorations,
  635. LocationDecorationUnusedNonInterfaceVariableVulkan_Ignored) {
  636. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  637. std::string spirv = R"(
  638. OpCapability Shader
  639. OpMemoryModel Logical GLSL450
  640. OpEntryPoint Fragment %main "main" %fragCoord
  641. OpExecutionMode %main OriginUpperLeft
  642. OpSource GLSL 450
  643. OpDecorate %fragCoord Location 0
  644. OpDecorate %non_interface Location 1
  645. %void = OpTypeVoid
  646. %voidfn = OpTypeFunction %void
  647. %float = OpTypeFloat 32
  648. %v4float = OpTypeVector %float 4
  649. %ptr_v4float = OpTypePointer Output %v4float
  650. %fragCoord = OpVariable %ptr_v4float Output
  651. %non_interface = OpVariable %ptr_v4float Output
  652. %main = OpFunction %void None %voidfn
  653. %label = OpLabel
  654. OpReturn
  655. OpFunctionEnd
  656. )";
  657. CompileSuccessfully(spirv, env);
  658. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  659. EXPECT_EQ(getDiagnosticString(), "");
  660. }
  661. TEST_F(ValidateDecorations,
  662. LocationDecorationNonInterfaceStructVulkan_Ignored) {
  663. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  664. std::string spirv = R"(
  665. OpCapability Shader
  666. OpMemoryModel Logical GLSL450
  667. OpEntryPoint Fragment %main "main" %fragCoord
  668. OpExecutionMode %main OriginUpperLeft
  669. OpDecorate %fragCoord Location 0
  670. OpMemberDecorate %block 0 Location 2
  671. OpMemberDecorate %block 0 Component 1
  672. OpDecorate %block Block
  673. %void = OpTypeVoid
  674. %voidfn = OpTypeFunction %void
  675. %float = OpTypeFloat 32
  676. %vec3 = OpTypeVector %float 3
  677. %outvar_ptr = OpTypePointer Output %vec3
  678. %fragCoord = OpVariable %outvar_ptr Output
  679. %block = OpTypeStruct %vec3
  680. %invar_ptr = OpTypePointer Input %block
  681. %non_interface = OpVariable %invar_ptr Input
  682. %main = OpFunction %void None %voidfn
  683. %label = OpLabel
  684. OpReturn
  685. OpFunctionEnd
  686. )";
  687. CompileSuccessfully(spirv, env);
  688. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  689. EXPECT_EQ(getDiagnosticString(), "");
  690. }
  691. TEST_F(ValidateDecorations, LocationDecorationNonInterfaceStructVulkanGood) {
  692. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  693. std::string spirv = R"(
  694. OpCapability Shader
  695. OpMemoryModel Logical GLSL450
  696. OpEntryPoint Fragment %main "main" %fragCoord %interface
  697. OpExecutionMode %main OriginUpperLeft
  698. OpDecorate %fragCoord Location 0
  699. OpMemberDecorate %block 0 Location 2
  700. OpMemberDecorate %block 0 Component 1
  701. OpDecorate %block Block
  702. %void = OpTypeVoid
  703. %voidfn = OpTypeFunction %void
  704. %float = OpTypeFloat 32
  705. %vec3 = OpTypeVector %float 3
  706. %outvar_ptr = OpTypePointer Output %vec3
  707. %fragCoord = OpVariable %outvar_ptr Output
  708. %block = OpTypeStruct %vec3
  709. %invar_ptr = OpTypePointer Input %block
  710. %interface = OpVariable %invar_ptr Input ;; this variable is unused. Ignore it
  711. %main = OpFunction %void None %voidfn
  712. %label = OpLabel
  713. OpReturn
  714. OpFunctionEnd
  715. )";
  716. CompileSuccessfully(spirv, env);
  717. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  718. }
  719. TEST_F(ValidateDecorations, LocationDecorationVariableNonStructVulkanBad) {
  720. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  721. std::string spirv = R"(
  722. OpCapability Shader
  723. OpMemoryModel Logical GLSL450
  724. OpEntryPoint Fragment %main "main" %fragCoord %nonblock_var
  725. OpExecutionMode %main OriginUpperLeft
  726. OpSource GLSL 450
  727. OpDecorate %fragCoord Location 0
  728. %void = OpTypeVoid
  729. %voidfn = OpTypeFunction %void
  730. %float = OpTypeFloat 32
  731. %v4float = OpTypeVector %float 4
  732. %ptr_v4float = OpTypePointer Output %v4float
  733. %fragCoord = OpVariable %ptr_v4float Output
  734. %nonblock_var = OpVariable %ptr_v4float Output
  735. %main = OpFunction %void None %voidfn
  736. %label = OpLabel
  737. OpReturn
  738. OpFunctionEnd
  739. )";
  740. CompileSuccessfully(spirv, env);
  741. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateAndRetrieveValidationState(env));
  742. EXPECT_THAT(getDiagnosticString(),
  743. AnyVUID("VUID-StandaloneSpirv-Location-04916"));
  744. EXPECT_THAT(getDiagnosticString(),
  745. HasSubstr("Variable must be decorated with a location"));
  746. }
  747. TEST_F(ValidateDecorations, LocationDecorationVariableStructNoBlockVulkanBad) {
  748. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  749. std::string spirv = R"(
  750. OpCapability Shader
  751. OpMemoryModel Logical GLSL450
  752. OpEntryPoint Fragment %main "main" %fragCoord %block_var
  753. OpExecutionMode %main OriginUpperLeft
  754. OpSource GLSL 450
  755. OpDecorate %fragCoord Location 0
  756. %void = OpTypeVoid
  757. %voidfn = OpTypeFunction %void
  758. %float = OpTypeFloat 32
  759. %v4float = OpTypeVector %float 4
  760. %ptr_v4float = OpTypePointer Output %v4float
  761. %fragCoord = OpVariable %ptr_v4float Output
  762. %block = OpTypeStruct %v4float
  763. %block_ptr = OpTypePointer Output %block
  764. %block_var = OpVariable %block_ptr Output
  765. %main = OpFunction %void None %voidfn
  766. %label = OpLabel
  767. OpReturn
  768. OpFunctionEnd
  769. )";
  770. CompileSuccessfully(spirv, env);
  771. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateAndRetrieveValidationState(env));
  772. EXPECT_THAT(getDiagnosticString(),
  773. AnyVUID("VUID-StandaloneSpirv-Location-04917"));
  774. EXPECT_THAT(getDiagnosticString(),
  775. HasSubstr("Variable must be decorated with a location"));
  776. }
  777. TEST_F(ValidateDecorations, LocationDecorationVariableNoBlockVulkanGood) {
  778. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  779. std::string spirv = R"(
  780. OpCapability Shader
  781. OpMemoryModel Logical GLSL450
  782. OpEntryPoint Fragment %main "main" %fragCoord %block_var
  783. OpExecutionMode %main OriginUpperLeft
  784. OpSource GLSL 450
  785. OpDecorate %fragCoord Location 0
  786. OpDecorate %block_var Location 1
  787. %void = OpTypeVoid
  788. %voidfn = OpTypeFunction %void
  789. %float = OpTypeFloat 32
  790. %v4float = OpTypeVector %float 4
  791. %ptr_v4float = OpTypePointer Output %v4float
  792. %fragCoord = OpVariable %ptr_v4float Output
  793. %block = OpTypeStruct %v4float
  794. %block_ptr = OpTypePointer Output %block
  795. %block_var = OpVariable %block_ptr Output
  796. %main = OpFunction %void None %voidfn
  797. %label = OpLabel
  798. OpReturn
  799. OpFunctionEnd
  800. )";
  801. CompileSuccessfully(spirv, env);
  802. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  803. }
  804. TEST_F(ValidateDecorations, LocationDecorationVariableExtraMemeberVulkan) {
  805. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  806. std::string spirv = R"(
  807. OpCapability Shader
  808. OpMemoryModel Logical GLSL450
  809. OpEntryPoint Fragment %main "main" %fragCoord %block_var
  810. OpExecutionMode %main OriginUpperLeft
  811. OpSource GLSL 450
  812. OpDecorate %fragCoord Location 0
  813. OpDecorate %block Block
  814. OpDecorate %block_var Location 1
  815. OpMemberDecorate %block 0 Location 1
  816. %void = OpTypeVoid
  817. %voidfn = OpTypeFunction %void
  818. %float = OpTypeFloat 32
  819. %v4float = OpTypeVector %float 4
  820. %ptr_v4float = OpTypePointer Output %v4float
  821. %fragCoord = OpVariable %ptr_v4float Output
  822. %block = OpTypeStruct %v4float
  823. %block_ptr = OpTypePointer Output %block
  824. %block_var = OpVariable %block_ptr Output
  825. %main = OpFunction %void None %voidfn
  826. %label = OpLabel
  827. OpReturn
  828. OpFunctionEnd
  829. )";
  830. CompileSuccessfully(spirv, env);
  831. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateAndRetrieveValidationState(env));
  832. EXPECT_THAT(getDiagnosticString(),
  833. AnyVUID("VUID-StandaloneSpirv-Location-04918"));
  834. EXPECT_THAT(getDiagnosticString(),
  835. HasSubstr("Members cannot be assigned a location"));
  836. }
  837. TEST_F(ValidateDecorations, LocationDecorationVariableMissingMemeberVulkan) {
  838. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  839. std::string spirv = R"(
  840. OpCapability Shader
  841. OpMemoryModel Logical GLSL450
  842. OpEntryPoint Fragment %main "main" %fragCoord %block_var
  843. OpExecutionMode %main OriginUpperLeft
  844. OpSource GLSL 450
  845. OpDecorate %fragCoord Location 0
  846. OpDecorate %block Block
  847. OpMemberDecorate %block 0 Location 1
  848. %void = OpTypeVoid
  849. %voidfn = OpTypeFunction %void
  850. %float = OpTypeFloat 32
  851. %v4float = OpTypeVector %float 4
  852. %ptr_v4float = OpTypePointer Output %v4float
  853. %fragCoord = OpVariable %ptr_v4float Output
  854. %block = OpTypeStruct %v4float %v4float
  855. %block_ptr = OpTypePointer Output %block
  856. %block_var = OpVariable %block_ptr Output
  857. %main = OpFunction %void None %voidfn
  858. %label = OpLabel
  859. OpReturn
  860. OpFunctionEnd
  861. )";
  862. CompileSuccessfully(spirv, env);
  863. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateAndRetrieveValidationState(env));
  864. EXPECT_THAT(getDiagnosticString(),
  865. AnyVUID("VUID-StandaloneSpirv-Location-04919"));
  866. EXPECT_THAT(getDiagnosticString(),
  867. HasSubstr("Member index 1 is missing a location assignment"));
  868. }
  869. TEST_F(ValidateDecorations, LocationDecorationVariableOnlyMemeberVulkanGood) {
  870. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  871. std::string spirv = R"(
  872. OpCapability Shader
  873. OpMemoryModel Logical GLSL450
  874. OpEntryPoint Fragment %main "main" %fragCoord %block_var
  875. OpExecutionMode %main OriginUpperLeft
  876. OpSource GLSL 450
  877. OpDecorate %fragCoord Location 0
  878. OpDecorate %block Block
  879. OpMemberDecorate %block 0 Location 1
  880. OpMemberDecorate %block 1 Location 4
  881. %void = OpTypeVoid
  882. %voidfn = OpTypeFunction %void
  883. %float = OpTypeFloat 32
  884. %v4float = OpTypeVector %float 4
  885. %ptr_v4float = OpTypePointer Output %v4float
  886. %fragCoord = OpVariable %ptr_v4float Output
  887. %block = OpTypeStruct %v4float %v4float
  888. %block_ptr = OpTypePointer Output %block
  889. %block_var = OpVariable %block_ptr Output
  890. %main = OpFunction %void None %voidfn
  891. %label = OpLabel
  892. OpReturn
  893. OpFunctionEnd
  894. )";
  895. CompileSuccessfully(spirv, env);
  896. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  897. }
  898. // #version 440
  899. // #extension GL_EXT_nonuniform_qualifier : enable
  900. // layout(binding = 1) uniform sampler2D s2d[];
  901. // layout(location = 0) in nonuniformEXT int i;
  902. // void main()
  903. // {
  904. // vec4 v = texture(s2d[i], vec2(0.3));
  905. // }
  906. TEST_F(ValidateDecorations, RuntimeArrayOfDescriptorSetsIsAllowed) {
  907. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  908. std::string spirv = R"(
  909. OpCapability Shader
  910. OpCapability ShaderNonUniformEXT
  911. OpCapability RuntimeDescriptorArrayEXT
  912. OpCapability SampledImageArrayNonUniformIndexingEXT
  913. OpExtension "SPV_EXT_descriptor_indexing"
  914. %1 = OpExtInstImport "GLSL.std.450"
  915. OpMemoryModel Logical GLSL450
  916. OpEntryPoint Vertex %main "main" %i
  917. OpSource GLSL 440
  918. OpSourceExtension "GL_EXT_nonuniform_qualifier"
  919. OpName %main "main"
  920. OpName %v "v"
  921. OpName %s2d "s2d"
  922. OpName %i "i"
  923. OpDecorate %s2d DescriptorSet 0
  924. OpDecorate %s2d Binding 1
  925. OpDecorate %i Location 0
  926. OpDecorate %i NonUniformEXT
  927. OpDecorate %18 NonUniformEXT
  928. OpDecorate %21 NonUniformEXT
  929. %void = OpTypeVoid
  930. %3 = OpTypeFunction %void
  931. %float = OpTypeFloat 32
  932. %v4float = OpTypeVector %float 4
  933. %_ptr_Function_v4float = OpTypePointer Function %v4float
  934. %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
  935. %11 = OpTypeSampledImage %10
  936. %_runtimearr_11 = OpTypeRuntimeArray %11
  937. %_ptr_Uniform__runtimearr_11 = OpTypePointer Uniform %_runtimearr_11
  938. %s2d = OpVariable %_ptr_Uniform__runtimearr_11 Uniform
  939. %int = OpTypeInt 32 1
  940. %_ptr_Input_int = OpTypePointer Input %int
  941. %i = OpVariable %_ptr_Input_int Input
  942. %_ptr_Uniform_11 = OpTypePointer Uniform %11
  943. %v2float = OpTypeVector %float 2
  944. %float_0_300000012 = OpConstant %float 0.300000012
  945. %24 = OpConstantComposite %v2float %float_0_300000012 %float_0_300000012
  946. %float_0 = OpConstant %float 0
  947. %main = OpFunction %void None %3
  948. %5 = OpLabel
  949. %v = OpVariable %_ptr_Function_v4float Function
  950. %18 = OpLoad %int %i
  951. %20 = OpAccessChain %_ptr_Uniform_11 %s2d %18
  952. %21 = OpLoad %11 %20
  953. %26 = OpImageSampleExplicitLod %v4float %21 %24 Lod %float_0
  954. OpStore %v %26
  955. OpReturn
  956. OpFunctionEnd
  957. )";
  958. CompileSuccessfully(spirv, env);
  959. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  960. }
  961. TEST_F(ValidateDecorations, BlockDecoratingArrayBad) {
  962. std::string spirv = R"(
  963. OpCapability Shader
  964. %1 = OpExtInstImport "GLSL.std.450"
  965. OpMemoryModel Logical GLSL450
  966. OpEntryPoint GLCompute %main "main"
  967. OpExecutionMode %main LocalSize 1 1 1
  968. OpSource GLSL 430
  969. OpDecorate %Output Block
  970. %void = OpTypeVoid
  971. %3 = OpTypeFunction %void
  972. %float = OpTypeFloat 32
  973. %int = OpTypeInt 32 1
  974. %int_3 = OpConstant %int 3
  975. %Output = OpTypeArray %float %int_3
  976. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  977. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  978. %main = OpFunction %void None %3
  979. %5 = OpLabel
  980. OpReturn
  981. OpFunctionEnd
  982. )";
  983. CompileSuccessfully(spirv);
  984. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  985. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
  986. }
  987. TEST_F(ValidateDecorations, BlockDecoratingIntBad) {
  988. std::string spirv = R"(
  989. OpCapability Shader
  990. %1 = OpExtInstImport "GLSL.std.450"
  991. OpMemoryModel Logical GLSL450
  992. OpEntryPoint GLCompute %main "main"
  993. OpExecutionMode %main LocalSize 1 1 1
  994. OpSource GLSL 430
  995. OpDecorate %Output Block
  996. %void = OpTypeVoid
  997. %3 = OpTypeFunction %void
  998. %Output = OpTypeInt 32 1
  999. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1000. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1001. %main = OpFunction %void None %3
  1002. %5 = OpLabel
  1003. OpReturn
  1004. OpFunctionEnd
  1005. )";
  1006. CompileSuccessfully(spirv);
  1007. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1008. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
  1009. }
  1010. TEST_F(ValidateDecorations, BlockMissingOffsetBad) {
  1011. std::string spirv = R"(
  1012. OpCapability Shader
  1013. %1 = OpExtInstImport "GLSL.std.450"
  1014. OpMemoryModel Logical GLSL450
  1015. OpEntryPoint GLCompute %main "main"
  1016. OpExecutionMode %main LocalSize 1 1 1
  1017. OpSource GLSL 430
  1018. OpDecorate %Output Block
  1019. %void = OpTypeVoid
  1020. %3 = OpTypeFunction %void
  1021. %float = OpTypeFloat 32
  1022. %Output = OpTypeStruct %float
  1023. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1024. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1025. %main = OpFunction %void None %3
  1026. %5 = OpLabel
  1027. OpReturn
  1028. OpFunctionEnd
  1029. )";
  1030. CompileSuccessfully(spirv);
  1031. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1032. EXPECT_THAT(getDiagnosticString(),
  1033. HasSubstr("must be explicitly laid out with Offset decorations"));
  1034. }
  1035. TEST_F(ValidateDecorations, BufferBlockMissingOffsetBad) {
  1036. std::string spirv = R"(
  1037. OpCapability Shader
  1038. %1 = OpExtInstImport "GLSL.std.450"
  1039. OpMemoryModel Logical GLSL450
  1040. OpEntryPoint GLCompute %main "main"
  1041. OpExecutionMode %main LocalSize 1 1 1
  1042. OpSource GLSL 430
  1043. OpDecorate %Output BufferBlock
  1044. %void = OpTypeVoid
  1045. %3 = OpTypeFunction %void
  1046. %float = OpTypeFloat 32
  1047. %Output = OpTypeStruct %float
  1048. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1049. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1050. %main = OpFunction %void None %3
  1051. %5 = OpLabel
  1052. OpReturn
  1053. OpFunctionEnd
  1054. )";
  1055. CompileSuccessfully(spirv);
  1056. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1057. EXPECT_THAT(getDiagnosticString(),
  1058. HasSubstr("must be explicitly laid out with Offset decorations"));
  1059. }
  1060. TEST_F(ValidateDecorations, BlockNestedStructMissingOffsetBad) {
  1061. std::string spirv = R"(
  1062. OpCapability Shader
  1063. %1 = OpExtInstImport "GLSL.std.450"
  1064. OpMemoryModel Logical GLSL450
  1065. OpEntryPoint GLCompute %main "main"
  1066. OpExecutionMode %main LocalSize 1 1 1
  1067. OpSource GLSL 430
  1068. OpMemberDecorate %S 0 Offset 0
  1069. OpMemberDecorate %Output 0 Offset 0
  1070. OpMemberDecorate %Output 1 Offset 16
  1071. OpMemberDecorate %Output 2 Offset 32
  1072. OpDecorate %Output Block
  1073. %void = OpTypeVoid
  1074. %3 = OpTypeFunction %void
  1075. %float = OpTypeFloat 32
  1076. %v4float = OpTypeVector %float 4
  1077. %v3float = OpTypeVector %float 3
  1078. %int = OpTypeInt 32 1
  1079. %S = OpTypeStruct %v3float %int
  1080. %Output = OpTypeStruct %float %v4float %S
  1081. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1082. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1083. %main = OpFunction %void None %3
  1084. %5 = OpLabel
  1085. OpReturn
  1086. OpFunctionEnd
  1087. )";
  1088. CompileSuccessfully(spirv);
  1089. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1090. EXPECT_THAT(getDiagnosticString(),
  1091. HasSubstr("must be explicitly laid out with Offset decorations"));
  1092. }
  1093. TEST_F(ValidateDecorations, BufferBlockNestedStructMissingOffsetBad) {
  1094. std::string spirv = R"(
  1095. OpCapability Shader
  1096. %1 = OpExtInstImport "GLSL.std.450"
  1097. OpMemoryModel Logical GLSL450
  1098. OpEntryPoint GLCompute %main "main"
  1099. OpExecutionMode %main LocalSize 1 1 1
  1100. OpSource GLSL 430
  1101. OpMemberDecorate %S 0 Offset 0
  1102. OpMemberDecorate %Output 0 Offset 0
  1103. OpMemberDecorate %Output 1 Offset 16
  1104. OpMemberDecorate %Output 2 Offset 32
  1105. OpDecorate %Output BufferBlock
  1106. %void = OpTypeVoid
  1107. %3 = OpTypeFunction %void
  1108. %float = OpTypeFloat 32
  1109. %v4float = OpTypeVector %float 4
  1110. %v3float = OpTypeVector %float 3
  1111. %int = OpTypeInt 32 1
  1112. %S = OpTypeStruct %v3float %int
  1113. %Output = OpTypeStruct %float %v4float %S
  1114. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1115. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1116. %main = OpFunction %void None %3
  1117. %5 = OpLabel
  1118. OpReturn
  1119. OpFunctionEnd
  1120. )";
  1121. CompileSuccessfully(spirv);
  1122. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1123. EXPECT_THAT(getDiagnosticString(),
  1124. HasSubstr("must be explicitly laid out with Offset decorations"));
  1125. }
  1126. TEST_F(ValidateDecorations, BlockGLSLSharedBad) {
  1127. std::string spirv = R"(
  1128. OpCapability Shader
  1129. %1 = OpExtInstImport "GLSL.std.450"
  1130. OpMemoryModel Logical GLSL450
  1131. OpEntryPoint GLCompute %main "main"
  1132. OpExecutionMode %main LocalSize 1 1 1
  1133. OpSource GLSL 430
  1134. OpDecorate %Output Block
  1135. OpDecorate %Output GLSLShared
  1136. OpMemberDecorate %Output 0 Offset 0
  1137. %void = OpTypeVoid
  1138. %3 = OpTypeFunction %void
  1139. %float = OpTypeFloat 32
  1140. %Output = OpTypeStruct %float
  1141. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1142. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1143. %main = OpFunction %void None %3
  1144. %5 = OpLabel
  1145. OpReturn
  1146. OpFunctionEnd
  1147. )";
  1148. CompileSuccessfully(spirv);
  1149. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  1150. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  1151. EXPECT_THAT(
  1152. getDiagnosticString(),
  1153. HasSubstr(
  1154. "'GLSLShared' is not valid for the Vulkan execution environment"));
  1155. EXPECT_THAT(getDiagnosticString(),
  1156. HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
  1157. }
  1158. TEST_F(ValidateDecorations, BufferBlockGLSLSharedBad) {
  1159. std::string spirv = R"(
  1160. OpCapability Shader
  1161. %1 = OpExtInstImport "GLSL.std.450"
  1162. OpMemoryModel Logical GLSL450
  1163. OpEntryPoint GLCompute %main "main"
  1164. OpExecutionMode %main LocalSize 1 1 1
  1165. OpSource GLSL 430
  1166. OpDecorate %Output BufferBlock
  1167. OpDecorate %Output GLSLShared
  1168. OpMemberDecorate %Output 0 Offset 0
  1169. %void = OpTypeVoid
  1170. %3 = OpTypeFunction %void
  1171. %float = OpTypeFloat 32
  1172. %Output = OpTypeStruct %float
  1173. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1174. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1175. %main = OpFunction %void None %3
  1176. %5 = OpLabel
  1177. OpReturn
  1178. OpFunctionEnd
  1179. )";
  1180. CompileSuccessfully(spirv);
  1181. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  1182. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  1183. EXPECT_THAT(
  1184. getDiagnosticString(),
  1185. HasSubstr(
  1186. "'GLSLShared' is not valid for the Vulkan execution environment"));
  1187. EXPECT_THAT(getDiagnosticString(),
  1188. HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
  1189. }
  1190. TEST_F(ValidateDecorations, BlockNestedStructGLSLSharedBad) {
  1191. std::string spirv = R"(
  1192. OpCapability Shader
  1193. %1 = OpExtInstImport "GLSL.std.450"
  1194. OpMemoryModel Logical GLSL450
  1195. OpEntryPoint GLCompute %main "main"
  1196. OpExecutionMode %main LocalSize 1 1 1
  1197. OpSource GLSL 430
  1198. OpMemberDecorate %S 0 Offset 0
  1199. OpDecorate %S GLSLShared
  1200. OpMemberDecorate %Output 0 Offset 0
  1201. OpMemberDecorate %Output 1 Offset 16
  1202. OpMemberDecorate %Output 2 Offset 32
  1203. OpDecorate %Output Block
  1204. %void = OpTypeVoid
  1205. %3 = OpTypeFunction %void
  1206. %float = OpTypeFloat 32
  1207. %v4float = OpTypeVector %float 4
  1208. %int = OpTypeInt 32 1
  1209. %S = OpTypeStruct %int
  1210. %Output = OpTypeStruct %float %v4float %S
  1211. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1212. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1213. %main = OpFunction %void None %3
  1214. %5 = OpLabel
  1215. OpReturn
  1216. OpFunctionEnd
  1217. )";
  1218. CompileSuccessfully(spirv);
  1219. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  1220. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  1221. EXPECT_THAT(
  1222. getDiagnosticString(),
  1223. HasSubstr(
  1224. "'GLSLShared' is not valid for the Vulkan execution environment"));
  1225. EXPECT_THAT(getDiagnosticString(),
  1226. HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
  1227. }
  1228. TEST_F(ValidateDecorations, BufferBlockNestedStructGLSLSharedBad) {
  1229. std::string spirv = R"(
  1230. OpCapability Shader
  1231. %1 = OpExtInstImport "GLSL.std.450"
  1232. OpMemoryModel Logical GLSL450
  1233. OpEntryPoint GLCompute %main "main"
  1234. OpExecutionMode %main LocalSize 1 1 1
  1235. OpSource GLSL 430
  1236. OpMemberDecorate %S 0 Offset 0
  1237. OpDecorate %S GLSLShared
  1238. OpMemberDecorate %Output 0 Offset 0
  1239. OpMemberDecorate %Output 1 Offset 16
  1240. OpMemberDecorate %Output 2 Offset 32
  1241. OpDecorate %Output BufferBlock
  1242. %void = OpTypeVoid
  1243. %3 = OpTypeFunction %void
  1244. %float = OpTypeFloat 32
  1245. %v4float = OpTypeVector %float 4
  1246. %int = OpTypeInt 32 1
  1247. %S = OpTypeStruct %int
  1248. %Output = OpTypeStruct %float %v4float %S
  1249. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1250. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1251. %main = OpFunction %void None %3
  1252. %5 = OpLabel
  1253. OpReturn
  1254. OpFunctionEnd
  1255. )";
  1256. CompileSuccessfully(spirv);
  1257. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  1258. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  1259. EXPECT_THAT(
  1260. getDiagnosticString(),
  1261. HasSubstr(
  1262. "'GLSLShared' is not valid for the Vulkan execution environment"));
  1263. EXPECT_THAT(getDiagnosticString(),
  1264. HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
  1265. }
  1266. TEST_F(ValidateDecorations, BlockGLSLPackedBad) {
  1267. std::string spirv = R"(
  1268. OpCapability Shader
  1269. %1 = OpExtInstImport "GLSL.std.450"
  1270. OpMemoryModel Logical GLSL450
  1271. OpEntryPoint GLCompute %main "main"
  1272. OpExecutionMode %main LocalSize 1 1 1
  1273. OpSource GLSL 430
  1274. OpDecorate %Output Block
  1275. OpDecorate %Output GLSLPacked
  1276. OpMemberDecorate %Output 0 Offset 0
  1277. %void = OpTypeVoid
  1278. %3 = OpTypeFunction %void
  1279. %float = OpTypeFloat 32
  1280. %Output = OpTypeStruct %float
  1281. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1282. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1283. %main = OpFunction %void None %3
  1284. %5 = OpLabel
  1285. OpReturn
  1286. OpFunctionEnd
  1287. )";
  1288. CompileSuccessfully(spirv);
  1289. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  1290. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  1291. EXPECT_THAT(
  1292. getDiagnosticString(),
  1293. HasSubstr(
  1294. "'GLSLPacked' is not valid for the Vulkan execution environment"));
  1295. EXPECT_THAT(getDiagnosticString(),
  1296. HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
  1297. }
  1298. TEST_F(ValidateDecorations, BufferBlockGLSLPackedBad) {
  1299. std::string spirv = R"(
  1300. OpCapability Shader
  1301. %1 = OpExtInstImport "GLSL.std.450"
  1302. OpMemoryModel Logical GLSL450
  1303. OpEntryPoint GLCompute %main "main"
  1304. OpExecutionMode %main LocalSize 1 1 1
  1305. OpSource GLSL 430
  1306. OpDecorate %Output BufferBlock
  1307. OpDecorate %Output GLSLPacked
  1308. OpMemberDecorate %Output 0 Offset 0
  1309. %void = OpTypeVoid
  1310. %3 = OpTypeFunction %void
  1311. %float = OpTypeFloat 32
  1312. %Output = OpTypeStruct %float
  1313. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1314. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1315. %main = OpFunction %void None %3
  1316. %5 = OpLabel
  1317. OpReturn
  1318. OpFunctionEnd
  1319. )";
  1320. CompileSuccessfully(spirv);
  1321. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  1322. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  1323. EXPECT_THAT(
  1324. getDiagnosticString(),
  1325. HasSubstr(
  1326. "'GLSLPacked' is not valid for the Vulkan execution environment"));
  1327. EXPECT_THAT(getDiagnosticString(),
  1328. HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
  1329. }
  1330. TEST_F(ValidateDecorations, BlockNestedStructGLSLPackedBad) {
  1331. std::string spirv = R"(
  1332. OpCapability Shader
  1333. %1 = OpExtInstImport "GLSL.std.450"
  1334. OpMemoryModel Logical GLSL450
  1335. OpEntryPoint GLCompute %main "main"
  1336. OpExecutionMode %main LocalSize 1 1 1
  1337. OpSource GLSL 430
  1338. OpMemberDecorate %S 0 Offset 0
  1339. OpDecorate %S GLSLPacked
  1340. OpMemberDecorate %Output 0 Offset 0
  1341. OpMemberDecorate %Output 1 Offset 16
  1342. OpMemberDecorate %Output 2 Offset 32
  1343. OpDecorate %Output Block
  1344. %void = OpTypeVoid
  1345. %3 = OpTypeFunction %void
  1346. %float = OpTypeFloat 32
  1347. %v4float = OpTypeVector %float 4
  1348. %int = OpTypeInt 32 1
  1349. %S = OpTypeStruct %int
  1350. %Output = OpTypeStruct %float %v4float %S
  1351. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1352. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1353. %main = OpFunction %void None %3
  1354. %5 = OpLabel
  1355. OpReturn
  1356. OpFunctionEnd
  1357. )";
  1358. CompileSuccessfully(spirv);
  1359. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  1360. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  1361. EXPECT_THAT(
  1362. getDiagnosticString(),
  1363. HasSubstr(
  1364. "'GLSLPacked' is not valid for the Vulkan execution environment"));
  1365. EXPECT_THAT(getDiagnosticString(),
  1366. HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
  1367. }
  1368. TEST_F(ValidateDecorations, BufferBlockNestedStructGLSLPackedBad) {
  1369. std::string spirv = R"(
  1370. OpCapability Shader
  1371. %1 = OpExtInstImport "GLSL.std.450"
  1372. OpMemoryModel Logical GLSL450
  1373. OpEntryPoint GLCompute %main "main"
  1374. OpExecutionMode %main LocalSize 1 1 1
  1375. OpSource GLSL 430
  1376. OpMemberDecorate %S 0 Offset 0
  1377. OpDecorate %S GLSLPacked
  1378. OpMemberDecorate %Output 0 Offset 0
  1379. OpMemberDecorate %Output 1 Offset 16
  1380. OpMemberDecorate %Output 2 Offset 32
  1381. OpDecorate %Output BufferBlock
  1382. %void = OpTypeVoid
  1383. %3 = OpTypeFunction %void
  1384. %float = OpTypeFloat 32
  1385. %v4float = OpTypeVector %float 4
  1386. %int = OpTypeInt 32 1
  1387. %S = OpTypeStruct %int
  1388. %Output = OpTypeStruct %float %v4float %S
  1389. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1390. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1391. %main = OpFunction %void None %3
  1392. %5 = OpLabel
  1393. OpReturn
  1394. OpFunctionEnd
  1395. )";
  1396. CompileSuccessfully(spirv);
  1397. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  1398. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  1399. EXPECT_THAT(
  1400. getDiagnosticString(),
  1401. HasSubstr(
  1402. "'GLSLPacked' is not valid for the Vulkan execution environment"));
  1403. EXPECT_THAT(getDiagnosticString(),
  1404. HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
  1405. }
  1406. TEST_F(ValidateDecorations, BlockMissingArrayStrideBad) {
  1407. std::string spirv = R"(
  1408. OpCapability Shader
  1409. %1 = OpExtInstImport "GLSL.std.450"
  1410. OpMemoryModel Logical GLSL450
  1411. OpEntryPoint GLCompute %main "main"
  1412. OpExecutionMode %main LocalSize 1 1 1
  1413. OpSource GLSL 430
  1414. OpDecorate %Output Block
  1415. OpMemberDecorate %Output 0 Offset 0
  1416. %void = OpTypeVoid
  1417. %3 = OpTypeFunction %void
  1418. %float = OpTypeFloat 32
  1419. %int = OpTypeInt 32 1
  1420. %int_3 = OpConstant %int 3
  1421. %array = OpTypeArray %float %int_3
  1422. %Output = OpTypeStruct %array
  1423. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1424. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1425. %main = OpFunction %void None %3
  1426. %5 = OpLabel
  1427. OpReturn
  1428. OpFunctionEnd
  1429. )";
  1430. CompileSuccessfully(spirv);
  1431. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1432. EXPECT_THAT(
  1433. getDiagnosticString(),
  1434. HasSubstr("must be explicitly laid out with ArrayStride decorations"));
  1435. }
  1436. TEST_F(ValidateDecorations, BufferBlockMissingArrayStrideBad) {
  1437. std::string spirv = R"(
  1438. OpCapability Shader
  1439. %1 = OpExtInstImport "GLSL.std.450"
  1440. OpMemoryModel Logical GLSL450
  1441. OpEntryPoint GLCompute %main "main"
  1442. OpExecutionMode %main LocalSize 1 1 1
  1443. OpSource GLSL 430
  1444. OpDecorate %Output BufferBlock
  1445. OpMemberDecorate %Output 0 Offset 0
  1446. %void = OpTypeVoid
  1447. %3 = OpTypeFunction %void
  1448. %float = OpTypeFloat 32
  1449. %int = OpTypeInt 32 1
  1450. %int_3 = OpConstant %int 3
  1451. %array = OpTypeArray %float %int_3
  1452. %Output = OpTypeStruct %array
  1453. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1454. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1455. %main = OpFunction %void None %3
  1456. %5 = OpLabel
  1457. OpReturn
  1458. OpFunctionEnd
  1459. )";
  1460. CompileSuccessfully(spirv);
  1461. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1462. EXPECT_THAT(
  1463. getDiagnosticString(),
  1464. HasSubstr("must be explicitly laid out with ArrayStride decorations"));
  1465. }
  1466. TEST_F(ValidateDecorations, BlockNestedStructMissingArrayStrideBad) {
  1467. std::string spirv = R"(
  1468. OpCapability Shader
  1469. %1 = OpExtInstImport "GLSL.std.450"
  1470. OpMemoryModel Logical GLSL450
  1471. OpEntryPoint GLCompute %main "main"
  1472. OpExecutionMode %main LocalSize 1 1 1
  1473. OpSource GLSL 430
  1474. OpMemberDecorate %S 0 Offset 0
  1475. OpMemberDecorate %Output 0 Offset 0
  1476. OpMemberDecorate %Output 1 Offset 16
  1477. OpMemberDecorate %Output 2 Offset 32
  1478. OpDecorate %Output Block
  1479. %void = OpTypeVoid
  1480. %3 = OpTypeFunction %void
  1481. %float = OpTypeFloat 32
  1482. %v4float = OpTypeVector %float 4
  1483. %int = OpTypeInt 32 1
  1484. %int_3 = OpConstant %int 3
  1485. %array = OpTypeArray %float %int_3
  1486. %S = OpTypeStruct %array
  1487. %Output = OpTypeStruct %float %v4float %S
  1488. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1489. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1490. %main = OpFunction %void None %3
  1491. %5 = OpLabel
  1492. OpReturn
  1493. OpFunctionEnd
  1494. )";
  1495. CompileSuccessfully(spirv);
  1496. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1497. EXPECT_THAT(
  1498. getDiagnosticString(),
  1499. HasSubstr("must be explicitly laid out with ArrayStride decorations"));
  1500. }
  1501. TEST_F(ValidateDecorations, BufferBlockNestedStructMissingArrayStrideBad) {
  1502. std::string spirv = R"(
  1503. OpCapability Shader
  1504. %1 = OpExtInstImport "GLSL.std.450"
  1505. OpMemoryModel Logical GLSL450
  1506. OpEntryPoint GLCompute %main "main"
  1507. OpExecutionMode %main LocalSize 1 1 1
  1508. OpSource GLSL 430
  1509. OpMemberDecorate %S 0 Offset 0
  1510. OpMemberDecorate %Output 0 Offset 0
  1511. OpMemberDecorate %Output 1 Offset 16
  1512. OpMemberDecorate %Output 2 Offset 32
  1513. OpDecorate %Output BufferBlock
  1514. %void = OpTypeVoid
  1515. %3 = OpTypeFunction %void
  1516. %float = OpTypeFloat 32
  1517. %v4float = OpTypeVector %float 4
  1518. %int = OpTypeInt 32 1
  1519. %int_3 = OpConstant %int 3
  1520. %array = OpTypeArray %float %int_3
  1521. %S = OpTypeStruct %array
  1522. %Output = OpTypeStruct %float %v4float %S
  1523. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1524. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1525. %main = OpFunction %void None %3
  1526. %5 = OpLabel
  1527. OpReturn
  1528. OpFunctionEnd
  1529. )";
  1530. CompileSuccessfully(spirv);
  1531. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1532. EXPECT_THAT(
  1533. getDiagnosticString(),
  1534. HasSubstr("must be explicitly laid out with ArrayStride decorations"));
  1535. }
  1536. TEST_F(ValidateDecorations, BlockMissingMatrixStrideBad) {
  1537. std::string spirv = R"(
  1538. OpCapability Shader
  1539. %1 = OpExtInstImport "GLSL.std.450"
  1540. OpMemoryModel Logical GLSL450
  1541. OpEntryPoint GLCompute %main "main"
  1542. OpExecutionMode %main LocalSize 1 1 1
  1543. OpSource GLSL 430
  1544. OpDecorate %Output Block
  1545. OpMemberDecorate %Output 0 Offset 0
  1546. %void = OpTypeVoid
  1547. %3 = OpTypeFunction %void
  1548. %float = OpTypeFloat 32
  1549. %v3float = OpTypeVector %float 3
  1550. %matrix = OpTypeMatrix %v3float 4
  1551. %Output = OpTypeStruct %matrix
  1552. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1553. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1554. %main = OpFunction %void None %3
  1555. %5 = OpLabel
  1556. OpReturn
  1557. OpFunctionEnd
  1558. )";
  1559. CompileSuccessfully(spirv);
  1560. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1561. EXPECT_THAT(
  1562. getDiagnosticString(),
  1563. HasSubstr("must be explicitly laid out with MatrixStride decorations"));
  1564. }
  1565. TEST_F(ValidateDecorations, BufferBlockMissingMatrixStrideBad) {
  1566. std::string spirv = R"(
  1567. OpCapability Shader
  1568. %1 = OpExtInstImport "GLSL.std.450"
  1569. OpMemoryModel Logical GLSL450
  1570. OpEntryPoint GLCompute %main "main"
  1571. OpExecutionMode %main LocalSize 1 1 1
  1572. OpSource GLSL 430
  1573. OpDecorate %Output BufferBlock
  1574. OpMemberDecorate %Output 0 Offset 0
  1575. %void = OpTypeVoid
  1576. %3 = OpTypeFunction %void
  1577. %float = OpTypeFloat 32
  1578. %v3float = OpTypeVector %float 3
  1579. %matrix = OpTypeMatrix %v3float 4
  1580. %Output = OpTypeStruct %matrix
  1581. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1582. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1583. %main = OpFunction %void None %3
  1584. %5 = OpLabel
  1585. OpReturn
  1586. OpFunctionEnd
  1587. )";
  1588. CompileSuccessfully(spirv);
  1589. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1590. EXPECT_THAT(
  1591. getDiagnosticString(),
  1592. HasSubstr("must be explicitly laid out with MatrixStride decorations"));
  1593. }
  1594. TEST_F(ValidateDecorations, BlockMissingMatrixStrideArrayBad) {
  1595. std::string spirv = R"(
  1596. OpCapability Shader
  1597. %1 = OpExtInstImport "GLSL.std.450"
  1598. OpMemoryModel Logical GLSL450
  1599. OpEntryPoint GLCompute %main "main"
  1600. OpExecutionMode %main LocalSize 1 1 1
  1601. OpSource GLSL 430
  1602. OpDecorate %Output Block
  1603. OpMemberDecorate %Output 0 Offset 0
  1604. %void = OpTypeVoid
  1605. %3 = OpTypeFunction %void
  1606. %float = OpTypeFloat 32
  1607. %v3float = OpTypeVector %float 3
  1608. %matrix = OpTypeMatrix %v3float 4
  1609. %int = OpTypeInt 32 1
  1610. %int_3 = OpConstant %int 3
  1611. %array = OpTypeArray %matrix %int_3
  1612. %Output = OpTypeStruct %matrix
  1613. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1614. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1615. %main = OpFunction %void None %3
  1616. %5 = OpLabel
  1617. OpReturn
  1618. OpFunctionEnd
  1619. )";
  1620. CompileSuccessfully(spirv);
  1621. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1622. EXPECT_THAT(
  1623. getDiagnosticString(),
  1624. HasSubstr("must be explicitly laid out with MatrixStride decorations"));
  1625. }
  1626. TEST_F(ValidateDecorations, BufferBlockMissingMatrixStrideArrayBad) {
  1627. std::string spirv = R"(
  1628. OpCapability Shader
  1629. %1 = OpExtInstImport "GLSL.std.450"
  1630. OpMemoryModel Logical GLSL450
  1631. OpEntryPoint GLCompute %main "main"
  1632. OpExecutionMode %main LocalSize 1 1 1
  1633. OpSource GLSL 430
  1634. OpDecorate %Output BufferBlock
  1635. OpMemberDecorate %Output 0 Offset 0
  1636. %void = OpTypeVoid
  1637. %3 = OpTypeFunction %void
  1638. %float = OpTypeFloat 32
  1639. %v3float = OpTypeVector %float 3
  1640. %matrix = OpTypeMatrix %v3float 4
  1641. %int = OpTypeInt 32 1
  1642. %int_3 = OpConstant %int 3
  1643. %array = OpTypeArray %matrix %int_3
  1644. %Output = OpTypeStruct %matrix
  1645. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1646. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1647. %main = OpFunction %void None %3
  1648. %5 = OpLabel
  1649. OpReturn
  1650. OpFunctionEnd
  1651. )";
  1652. CompileSuccessfully(spirv);
  1653. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1654. EXPECT_THAT(
  1655. getDiagnosticString(),
  1656. HasSubstr("must be explicitly laid out with MatrixStride decorations"));
  1657. }
  1658. TEST_F(ValidateDecorations, BlockNestedStructMissingMatrixStrideBad) {
  1659. std::string spirv = R"(
  1660. OpCapability Shader
  1661. %1 = OpExtInstImport "GLSL.std.450"
  1662. OpMemoryModel Logical GLSL450
  1663. OpEntryPoint GLCompute %main "main"
  1664. OpExecutionMode %main LocalSize 1 1 1
  1665. OpSource GLSL 430
  1666. OpMemberDecorate %S 0 Offset 0
  1667. OpMemberDecorate %Output 0 Offset 0
  1668. OpMemberDecorate %Output 1 Offset 16
  1669. OpMemberDecorate %Output 2 Offset 32
  1670. OpDecorate %Output Block
  1671. %void = OpTypeVoid
  1672. %3 = OpTypeFunction %void
  1673. %float = OpTypeFloat 32
  1674. %v3float = OpTypeVector %float 3
  1675. %v4float = OpTypeVector %float 4
  1676. %matrix = OpTypeMatrix %v3float 4
  1677. %S = OpTypeStruct %matrix
  1678. %Output = OpTypeStruct %float %v4float %S
  1679. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1680. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1681. %main = OpFunction %void None %3
  1682. %5 = OpLabel
  1683. OpReturn
  1684. OpFunctionEnd
  1685. )";
  1686. CompileSuccessfully(spirv);
  1687. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1688. EXPECT_THAT(
  1689. getDiagnosticString(),
  1690. HasSubstr("must be explicitly laid out with MatrixStride decorations"));
  1691. }
  1692. TEST_F(ValidateDecorations, BufferBlockNestedStructMissingMatrixStrideBad) {
  1693. std::string spirv = R"(
  1694. OpCapability Shader
  1695. %1 = OpExtInstImport "GLSL.std.450"
  1696. OpMemoryModel Logical GLSL450
  1697. OpEntryPoint GLCompute %main "main"
  1698. OpExecutionMode %main LocalSize 1 1 1
  1699. OpSource GLSL 430
  1700. OpMemberDecorate %S 0 Offset 0
  1701. OpMemberDecorate %Output 0 Offset 0
  1702. OpMemberDecorate %Output 1 Offset 16
  1703. OpMemberDecorate %Output 2 Offset 32
  1704. OpDecorate %Output BufferBlock
  1705. %void = OpTypeVoid
  1706. %3 = OpTypeFunction %void
  1707. %float = OpTypeFloat 32
  1708. %v3float = OpTypeVector %float 3
  1709. %v4float = OpTypeVector %float 4
  1710. %matrix = OpTypeMatrix %v3float 4
  1711. %S = OpTypeStruct %matrix
  1712. %Output = OpTypeStruct %float %v4float %S
  1713. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1714. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1715. %main = OpFunction %void None %3
  1716. %5 = OpLabel
  1717. OpReturn
  1718. OpFunctionEnd
  1719. )";
  1720. CompileSuccessfully(spirv);
  1721. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1722. EXPECT_THAT(
  1723. getDiagnosticString(),
  1724. HasSubstr("must be explicitly laid out with MatrixStride decorations"));
  1725. }
  1726. TEST_F(ValidateDecorations, BlockStandardUniformBufferLayout) {
  1727. std::string spirv = R"(
  1728. OpCapability Shader
  1729. %1 = OpExtInstImport "GLSL.std.450"
  1730. OpMemoryModel Logical GLSL450
  1731. OpEntryPoint GLCompute %main "main"
  1732. OpExecutionMode %main LocalSize 1 1 1
  1733. OpSource GLSL 430
  1734. OpMemberDecorate %F 0 Offset 0
  1735. OpMemberDecorate %F 1 Offset 8
  1736. OpDecorate %_arr_float_uint_2 ArrayStride 16
  1737. OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 48
  1738. OpMemberDecorate %O 0 Offset 0
  1739. OpMemberDecorate %O 1 Offset 16
  1740. OpMemberDecorate %O 2 Offset 32
  1741. OpMemberDecorate %O 3 Offset 64
  1742. OpMemberDecorate %O 4 ColMajor
  1743. OpMemberDecorate %O 4 Offset 80
  1744. OpMemberDecorate %O 4 MatrixStride 16
  1745. OpDecorate %_arr_O_uint_2 ArrayStride 176
  1746. OpMemberDecorate %Output 0 Offset 0
  1747. OpMemberDecorate %Output 1 Offset 8
  1748. OpMemberDecorate %Output 2 Offset 16
  1749. OpMemberDecorate %Output 3 Offset 32
  1750. OpMemberDecorate %Output 4 Offset 48
  1751. OpMemberDecorate %Output 5 Offset 64
  1752. OpMemberDecorate %Output 6 ColMajor
  1753. OpMemberDecorate %Output 6 Offset 96
  1754. OpMemberDecorate %Output 6 MatrixStride 16
  1755. OpMemberDecorate %Output 7 Offset 128
  1756. OpDecorate %Output Block
  1757. %void = OpTypeVoid
  1758. %3 = OpTypeFunction %void
  1759. %float = OpTypeFloat 32
  1760. %v2float = OpTypeVector %float 2
  1761. %v3float = OpTypeVector %float 3
  1762. %int = OpTypeInt 32 1
  1763. %uint = OpTypeInt 32 0
  1764. %v2uint = OpTypeVector %uint 2
  1765. %F = OpTypeStruct %int %v2uint
  1766. %uint_2 = OpConstant %uint 2
  1767. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  1768. %mat2v3float = OpTypeMatrix %v3float 2
  1769. %v3uint = OpTypeVector %uint 3
  1770. %mat3v3float = OpTypeMatrix %v3float 3
  1771. %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
  1772. %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
  1773. %_arr_O_uint_2 = OpTypeArray %O %uint_2
  1774. %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
  1775. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  1776. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  1777. %main = OpFunction %void None %3
  1778. %5 = OpLabel
  1779. OpReturn
  1780. OpFunctionEnd
  1781. )";
  1782. CompileSuccessfully(spirv);
  1783. EXPECT_EQ(SPV_SUCCESS,
  1784. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  1785. }
  1786. TEST_F(ValidateDecorations, BlockLayoutPermitsTightVec3ScalarPackingGood) {
  1787. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
  1788. std::string spirv = R"(
  1789. OpCapability Shader
  1790. OpMemoryModel Logical GLSL450
  1791. OpEntryPoint Vertex %main "main"
  1792. OpSource GLSL 450
  1793. OpMemberDecorate %S 0 Offset 0
  1794. OpMemberDecorate %S 1 Offset 12
  1795. OpDecorate %S Block
  1796. OpDecorate %B DescriptorSet 0
  1797. OpDecorate %B Binding 0
  1798. %void = OpTypeVoid
  1799. %3 = OpTypeFunction %void
  1800. %float = OpTypeFloat 32
  1801. %v3float = OpTypeVector %float 3
  1802. %S = OpTypeStruct %v3float %float
  1803. %_ptr_Uniform_S = OpTypePointer Uniform %S
  1804. %B = OpVariable %_ptr_Uniform_S Uniform
  1805. %main = OpFunction %void None %3
  1806. %5 = OpLabel
  1807. OpReturn
  1808. OpFunctionEnd
  1809. )";
  1810. CompileSuccessfully(spirv);
  1811. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
  1812. << getDiagnosticString();
  1813. }
  1814. TEST_F(ValidateDecorations, BlockCantAppearWithinABlockBad) {
  1815. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1587
  1816. std::string spirv = R"(
  1817. OpCapability Shader
  1818. OpMemoryModel Logical GLSL450
  1819. OpEntryPoint Vertex %main "main"
  1820. OpSource GLSL 450
  1821. OpMemberDecorate %S 0 Offset 0
  1822. OpMemberDecorate %S 1 Offset 16
  1823. OpMemberDecorate %S2 0 Offset 0
  1824. OpMemberDecorate %S2 1 Offset 12
  1825. OpDecorate %S Block
  1826. OpDecorate %S2 Block
  1827. OpDecorate %B DescriptorSet 0
  1828. OpDecorate %B Binding 0
  1829. %void = OpTypeVoid
  1830. %3 = OpTypeFunction %void
  1831. %float = OpTypeFloat 32
  1832. %S2 = OpTypeStruct %float %float
  1833. %S = OpTypeStruct %float %S2
  1834. %_ptr_Uniform_S = OpTypePointer Uniform %S
  1835. %B = OpVariable %_ptr_Uniform_S Uniform
  1836. %main = OpFunction %void None %3
  1837. %5 = OpLabel
  1838. OpReturn
  1839. OpFunctionEnd
  1840. )";
  1841. CompileSuccessfully(spirv);
  1842. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1843. EXPECT_THAT(getDiagnosticString(),
  1844. HasSubstr("rules: A Block or BufferBlock cannot be nested within "
  1845. "another Block or BufferBlock."));
  1846. }
  1847. TEST_F(ValidateDecorations, BufferblockCantAppearWithinABufferblockBad) {
  1848. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1587
  1849. std::string spirv = R"(
  1850. OpCapability Shader
  1851. OpMemoryModel Logical GLSL450
  1852. OpEntryPoint Vertex %main "main"
  1853. OpSource GLSL 450
  1854. OpMemberDecorate %S 0 Offset 0
  1855. OpMemberDecorate %S 1 Offset 16
  1856. OpMemberDecorate %S2 0 Offset 0
  1857. OpMemberDecorate %S2 1 Offset 16
  1858. OpMemberDecorate %S3 0 Offset 0
  1859. OpMemberDecorate %S3 1 Offset 12
  1860. OpDecorate %S BufferBlock
  1861. OpDecorate %S3 BufferBlock
  1862. OpDecorate %B DescriptorSet 0
  1863. OpDecorate %B Binding 0
  1864. %void = OpTypeVoid
  1865. %3 = OpTypeFunction %void
  1866. %float = OpTypeFloat 32
  1867. %S3 = OpTypeStruct %float %float
  1868. %S2 = OpTypeStruct %float %S3
  1869. %S = OpTypeStruct %float %S2
  1870. %_ptr_Uniform_S = OpTypePointer Uniform %S
  1871. %B = OpVariable %_ptr_Uniform_S Uniform
  1872. %main = OpFunction %void None %3
  1873. %5 = OpLabel
  1874. OpReturn
  1875. OpFunctionEnd
  1876. )";
  1877. CompileSuccessfully(spirv);
  1878. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1879. EXPECT_THAT(getDiagnosticString(),
  1880. HasSubstr("rules: A Block or BufferBlock cannot be nested within "
  1881. "another Block or BufferBlock."));
  1882. }
  1883. TEST_F(ValidateDecorations, BufferblockCantAppearWithinABlockBad) {
  1884. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1587
  1885. std::string spirv = R"(
  1886. OpCapability Shader
  1887. OpMemoryModel Logical GLSL450
  1888. OpEntryPoint Vertex %main "main"
  1889. OpSource GLSL 450
  1890. OpMemberDecorate %S 0 Offset 0
  1891. OpMemberDecorate %S 1 Offset 16
  1892. OpMemberDecorate %S2 0 Offset 0
  1893. OpMemberDecorate %S2 1 Offset 16
  1894. OpMemberDecorate %S3 0 Offset 0
  1895. OpMemberDecorate %S3 1 Offset 12
  1896. OpDecorate %S Block
  1897. OpDecorate %S3 BufferBlock
  1898. OpDecorate %B DescriptorSet 0
  1899. OpDecorate %B Binding 0
  1900. %void = OpTypeVoid
  1901. %3 = OpTypeFunction %void
  1902. %float = OpTypeFloat 32
  1903. %S3 = OpTypeStruct %float %float
  1904. %S2 = OpTypeStruct %float %S3
  1905. %S = OpTypeStruct %float %S2
  1906. %_ptr_Uniform_S = OpTypePointer Uniform %S
  1907. %B = OpVariable %_ptr_Uniform_S Uniform
  1908. %main = OpFunction %void None %3
  1909. %5 = OpLabel
  1910. OpReturn
  1911. OpFunctionEnd
  1912. )";
  1913. CompileSuccessfully(spirv);
  1914. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1915. EXPECT_THAT(getDiagnosticString(),
  1916. HasSubstr("rules: A Block or BufferBlock cannot be nested within "
  1917. "another Block or BufferBlock."));
  1918. }
  1919. TEST_F(ValidateDecorations, BlockCantAppearWithinABufferblockBad) {
  1920. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1587
  1921. std::string spirv = R"(
  1922. OpCapability Shader
  1923. OpMemoryModel Logical GLSL450
  1924. OpEntryPoint Vertex %main "main"
  1925. OpSource GLSL 450
  1926. OpMemberDecorate %S 0 Offset 0
  1927. OpMemberDecorate %S 1 Offset 16
  1928. OpMemberDecorate %S2 0 Offset 0
  1929. OpMemberDecorate %S2 1 Offset 16
  1930. OpMemberDecorate %S3 0 Offset 0
  1931. OpMemberDecorate %S3 1 Offset 16
  1932. OpMemberDecorate %S4 0 Offset 0
  1933. OpMemberDecorate %S4 1 Offset 12
  1934. OpDecorate %S BufferBlock
  1935. OpDecorate %S4 Block
  1936. OpDecorate %B DescriptorSet 0
  1937. OpDecorate %B Binding 0
  1938. %void = OpTypeVoid
  1939. %3 = OpTypeFunction %void
  1940. %float = OpTypeFloat 32
  1941. %S4 = OpTypeStruct %float %float
  1942. %S3 = OpTypeStruct %float %S4
  1943. %S2 = OpTypeStruct %float %S3
  1944. %S = OpTypeStruct %float %S2
  1945. %_ptr_Uniform_S = OpTypePointer Uniform %S
  1946. %B = OpVariable %_ptr_Uniform_S Uniform
  1947. %main = OpFunction %void None %3
  1948. %5 = OpLabel
  1949. OpReturn
  1950. OpFunctionEnd
  1951. )";
  1952. CompileSuccessfully(spirv);
  1953. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  1954. EXPECT_THAT(getDiagnosticString(),
  1955. HasSubstr("rules: A Block or BufferBlock cannot be nested within "
  1956. "another Block or BufferBlock."));
  1957. }
  1958. TEST_F(ValidateDecorations, BlockCannotAppearWithinBlockArray) {
  1959. const std::string spirv = R"(
  1960. OpCapability Shader
  1961. OpMemoryModel Logical GLSL450
  1962. OpEntryPoint Vertex %main "main"
  1963. OpMemberDecorate %outer 0 Offset 0
  1964. OpMemberDecorate %outer 1 Offset 4
  1965. OpMemberDecorate %outer 2 Offset 20
  1966. OpDecorate %outer Block
  1967. OpMemberDecorate %inner 0 Offset 0
  1968. OpDecorate %inner Block
  1969. %void = OpTypeVoid
  1970. %void_fn = OpTypeFunction %void
  1971. %int = OpTypeInt 32 0
  1972. %int_4 = OpConstant %int 4
  1973. %inner = OpTypeStruct %int
  1974. %array = OpTypeArray %inner %int_4
  1975. %outer = OpTypeStruct %int %array %int
  1976. %main = OpFunction %void None %void_fn
  1977. %entry = OpLabel
  1978. OpReturn
  1979. OpFunctionEnd
  1980. )";
  1981. CompileSuccessfully(spirv);
  1982. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1983. EXPECT_THAT(getDiagnosticString(),
  1984. HasSubstr("rules: A Block or BufferBlock cannot be nested within "
  1985. "another Block or BufferBlock."));
  1986. }
  1987. TEST_F(ValidateDecorations, BlockCannotAppearWithinBlockMultiArray) {
  1988. const std::string spirv = R"(
  1989. OpCapability Shader
  1990. OpMemoryModel Logical GLSL450
  1991. OpEntryPoint Vertex %main "main"
  1992. OpMemberDecorate %outer 0 Offset 0
  1993. OpMemberDecorate %outer 1 Offset 4
  1994. OpDecorate %outer Block
  1995. OpMemberDecorate %inner 0 Offset 0
  1996. OpDecorate %inner Block
  1997. %void = OpTypeVoid
  1998. %void_fn = OpTypeFunction %void
  1999. %int = OpTypeInt 32 0
  2000. %int_4 = OpConstant %int 4
  2001. %inner = OpTypeStruct %int
  2002. %array1 = OpTypeArray %inner %int_4
  2003. %array2 = OpTypeArray %array1 %int_4
  2004. %outer = OpTypeStruct %int %array2
  2005. %main = OpFunction %void None %void_fn
  2006. %entry = OpLabel
  2007. OpReturn
  2008. OpFunctionEnd
  2009. )";
  2010. CompileSuccessfully(spirv);
  2011. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2012. EXPECT_THAT(getDiagnosticString(),
  2013. HasSubstr("rules: A Block or BufferBlock cannot be nested within "
  2014. "another Block or BufferBlock."));
  2015. }
  2016. TEST_F(ValidateDecorations, BlockLayoutForbidsTightScalarVec3PackingBad) {
  2017. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
  2018. std::string spirv = R"(
  2019. OpCapability Shader
  2020. OpMemoryModel Logical GLSL450
  2021. OpEntryPoint Vertex %main "main"
  2022. OpSource GLSL 450
  2023. OpMemberDecorate %S 0 Offset 0
  2024. OpMemberDecorate %S 1 Offset 4
  2025. OpDecorate %S Block
  2026. OpDecorate %B DescriptorSet 0
  2027. OpDecorate %B Binding 0
  2028. %void = OpTypeVoid
  2029. %3 = OpTypeFunction %void
  2030. %float = OpTypeFloat 32
  2031. %v3float = OpTypeVector %float 3
  2032. %S = OpTypeStruct %float %v3float
  2033. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2034. %B = OpVariable %_ptr_Uniform_S Uniform
  2035. %main = OpFunction %void None %3
  2036. %5 = OpLabel
  2037. OpReturn
  2038. OpFunctionEnd
  2039. )";
  2040. CompileSuccessfully(spirv);
  2041. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2042. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2043. EXPECT_THAT(
  2044. getDiagnosticString(),
  2045. HasSubstr("Structure id 2 decorated as Block for variable in Uniform "
  2046. "storage class must follow standard uniform buffer layout "
  2047. "rules: member 1 at offset 4 is not aligned to 16"));
  2048. }
  2049. TEST_F(ValidateDecorations,
  2050. BlockLayoutPermitsTightScalarVec3PackingWithRelaxedLayoutGood) {
  2051. // Same as previous test, but with explicit option to relax block layout.
  2052. std::string spirv = R"(
  2053. OpCapability Shader
  2054. OpMemoryModel Logical GLSL450
  2055. OpEntryPoint Vertex %main "main"
  2056. OpSource GLSL 450
  2057. OpMemberDecorate %S 0 Offset 0
  2058. OpMemberDecorate %S 1 Offset 4
  2059. OpDecorate %S Block
  2060. OpDecorate %B DescriptorSet 0
  2061. OpDecorate %B Binding 0
  2062. %void = OpTypeVoid
  2063. %3 = OpTypeFunction %void
  2064. %float = OpTypeFloat 32
  2065. %v3float = OpTypeVector %float 3
  2066. %S = OpTypeStruct %float %v3float
  2067. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2068. %B = OpVariable %_ptr_Uniform_S Uniform
  2069. %main = OpFunction %void None %3
  2070. %5 = OpLabel
  2071. OpReturn
  2072. OpFunctionEnd
  2073. )";
  2074. CompileSuccessfully(spirv);
  2075. spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
  2076. EXPECT_EQ(SPV_SUCCESS,
  2077. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2078. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2079. }
  2080. TEST_F(ValidateDecorations,
  2081. BlockLayoutPermitsTightScalarVec3PackingBadOffsetWithRelaxedLayoutBad) {
  2082. // Same as previous test, but with the vector not aligned to its scalar
  2083. // element. Use offset 5 instead of a multiple of 4.
  2084. std::string spirv = R"(
  2085. OpCapability Shader
  2086. OpMemoryModel Logical GLSL450
  2087. OpEntryPoint Vertex %main "main"
  2088. OpSource GLSL 450
  2089. OpMemberDecorate %S 0 Offset 0
  2090. OpMemberDecorate %S 1 Offset 5
  2091. OpDecorate %S Block
  2092. OpDecorate %B DescriptorSet 0
  2093. OpDecorate %B Binding 0
  2094. %void = OpTypeVoid
  2095. %3 = OpTypeFunction %void
  2096. %float = OpTypeFloat 32
  2097. %v3float = OpTypeVector %float 3
  2098. %S = OpTypeStruct %float %v3float
  2099. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2100. %B = OpVariable %_ptr_Uniform_S Uniform
  2101. %main = OpFunction %void None %3
  2102. %5 = OpLabel
  2103. OpReturn
  2104. OpFunctionEnd
  2105. )";
  2106. CompileSuccessfully(spirv);
  2107. spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
  2108. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2109. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2110. EXPECT_THAT(
  2111. getDiagnosticString(),
  2112. HasSubstr(
  2113. "Structure id 2 decorated as Block for variable in Uniform storage "
  2114. "class must follow relaxed uniform buffer layout rules: member 1 at "
  2115. "offset 5 is not aligned to scalar element size 4"));
  2116. }
  2117. TEST_F(ValidateDecorations,
  2118. BlockLayoutPermitsTightScalarVec3PackingWithVulkan1_1Good) {
  2119. // Same as previous test, but with Vulkan 1.1. Vulkan 1.1 included
  2120. // VK_KHR_relaxed_block_layout in core.
  2121. std::string spirv = R"(
  2122. OpCapability Shader
  2123. OpMemoryModel Logical GLSL450
  2124. OpEntryPoint Vertex %main "main"
  2125. OpSource GLSL 450
  2126. OpMemberDecorate %S 0 Offset 0
  2127. OpMemberDecorate %S 1 Offset 4
  2128. OpDecorate %S Block
  2129. OpDecorate %B DescriptorSet 0
  2130. OpDecorate %B Binding 0
  2131. %void = OpTypeVoid
  2132. %3 = OpTypeFunction %void
  2133. %float = OpTypeFloat 32
  2134. %v3float = OpTypeVector %float 3
  2135. %S = OpTypeStruct %float %v3float
  2136. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2137. %B = OpVariable %_ptr_Uniform_S Uniform
  2138. %main = OpFunction %void None %3
  2139. %5 = OpLabel
  2140. OpReturn
  2141. OpFunctionEnd
  2142. )";
  2143. CompileSuccessfully(spirv);
  2144. EXPECT_EQ(SPV_SUCCESS,
  2145. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  2146. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2147. }
  2148. TEST_F(ValidateDecorations,
  2149. BlockLayoutPermitsTightScalarVec3PackingWithScalarLayoutGood) {
  2150. // Same as previous test, but with scalar block layout.
  2151. std::string spirv = R"(
  2152. OpCapability Shader
  2153. OpMemoryModel Logical GLSL450
  2154. OpEntryPoint Vertex %main "main"
  2155. OpSource GLSL 450
  2156. OpMemberDecorate %S 0 Offset 0
  2157. OpMemberDecorate %S 1 Offset 4
  2158. OpDecorate %S Block
  2159. OpDecorate %B DescriptorSet 0
  2160. OpDecorate %B Binding 0
  2161. %void = OpTypeVoid
  2162. %3 = OpTypeFunction %void
  2163. %float = OpTypeFloat 32
  2164. %v3float = OpTypeVector %float 3
  2165. %S = OpTypeStruct %float %v3float
  2166. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2167. %B = OpVariable %_ptr_Uniform_S Uniform
  2168. %main = OpFunction %void None %3
  2169. %5 = OpLabel
  2170. OpReturn
  2171. OpFunctionEnd
  2172. )";
  2173. CompileSuccessfully(spirv);
  2174. spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
  2175. EXPECT_EQ(SPV_SUCCESS,
  2176. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2177. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2178. }
  2179. TEST_F(ValidateDecorations,
  2180. BlockLayoutPermitsScalarAlignedArrayWithScalarLayoutGood) {
  2181. // The array at offset 4 is ok with scalar block layout.
  2182. std::string spirv = R"(
  2183. OpCapability Shader
  2184. OpMemoryModel Logical GLSL450
  2185. OpEntryPoint Vertex %main "main"
  2186. OpSource GLSL 450
  2187. OpMemberDecorate %S 0 Offset 0
  2188. OpMemberDecorate %S 1 Offset 4
  2189. OpDecorate %S Block
  2190. OpDecorate %B DescriptorSet 0
  2191. OpDecorate %B Binding 0
  2192. OpDecorate %arr_float ArrayStride 4
  2193. %void = OpTypeVoid
  2194. %3 = OpTypeFunction %void
  2195. %uint = OpTypeInt 32 0
  2196. %uint_3 = OpConstant %uint 3
  2197. %float = OpTypeFloat 32
  2198. %arr_float = OpTypeArray %float %uint_3
  2199. %S = OpTypeStruct %float %arr_float
  2200. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2201. %B = OpVariable %_ptr_Uniform_S Uniform
  2202. %main = OpFunction %void None %3
  2203. %5 = OpLabel
  2204. OpReturn
  2205. OpFunctionEnd
  2206. )";
  2207. CompileSuccessfully(spirv);
  2208. spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
  2209. EXPECT_EQ(SPV_SUCCESS,
  2210. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2211. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2212. }
  2213. TEST_F(ValidateDecorations,
  2214. BlockLayoutPermitsScalarAlignedArrayOfVec3WithScalarLayoutGood) {
  2215. // The array at offset 4 is ok with scalar block layout, even though
  2216. // its elements are vec3.
  2217. // This is the same as the previous case, but the array elements are vec3
  2218. // instead of float.
  2219. std::string spirv = R"(
  2220. OpCapability Shader
  2221. OpMemoryModel Logical GLSL450
  2222. OpEntryPoint Vertex %main "main"
  2223. OpSource GLSL 450
  2224. OpMemberDecorate %S 0 Offset 0
  2225. OpMemberDecorate %S 1 Offset 4
  2226. OpDecorate %S Block
  2227. OpDecorate %B DescriptorSet 0
  2228. OpDecorate %B Binding 0
  2229. OpDecorate %arr_vec3 ArrayStride 12
  2230. %void = OpTypeVoid
  2231. %3 = OpTypeFunction %void
  2232. %uint = OpTypeInt 32 0
  2233. %uint_3 = OpConstant %uint 3
  2234. %float = OpTypeFloat 32
  2235. %vec3 = OpTypeVector %float 3
  2236. %arr_vec3 = OpTypeArray %vec3 %uint_3
  2237. %S = OpTypeStruct %float %arr_vec3
  2238. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2239. %B = OpVariable %_ptr_Uniform_S Uniform
  2240. %main = OpFunction %void None %3
  2241. %5 = OpLabel
  2242. OpReturn
  2243. OpFunctionEnd
  2244. )";
  2245. CompileSuccessfully(spirv);
  2246. spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
  2247. EXPECT_EQ(SPV_SUCCESS,
  2248. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2249. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2250. }
  2251. TEST_F(ValidateDecorations,
  2252. BlockLayoutPermitsScalarAlignedStructWithScalarLayoutGood) {
  2253. // Scalar block layout permits the struct at offset 4, even though
  2254. // it contains a vector with base alignment 8 and scalar alignment 4.
  2255. std::string spirv = R"(
  2256. OpCapability Shader
  2257. OpMemoryModel Logical GLSL450
  2258. OpEntryPoint Vertex %main "main"
  2259. OpSource GLSL 450
  2260. OpMemberDecorate %S 0 Offset 0
  2261. OpMemberDecorate %S 1 Offset 4
  2262. OpMemberDecorate %st 0 Offset 0
  2263. OpMemberDecorate %st 1 Offset 8
  2264. OpDecorate %S Block
  2265. OpDecorate %B DescriptorSet 0
  2266. OpDecorate %B Binding 0
  2267. %void = OpTypeVoid
  2268. %3 = OpTypeFunction %void
  2269. %float = OpTypeFloat 32
  2270. %vec2 = OpTypeVector %float 2
  2271. %st = OpTypeStruct %vec2 %float
  2272. %S = OpTypeStruct %float %st
  2273. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2274. %B = OpVariable %_ptr_Uniform_S Uniform
  2275. %main = OpFunction %void None %3
  2276. %5 = OpLabel
  2277. OpReturn
  2278. OpFunctionEnd
  2279. )";
  2280. CompileSuccessfully(spirv);
  2281. spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
  2282. EXPECT_EQ(SPV_SUCCESS,
  2283. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2284. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2285. }
  2286. TEST_F(
  2287. ValidateDecorations,
  2288. BlockLayoutPermitsFieldsInBaseAlignmentPaddingAtEndOfStructWithScalarLayoutGood) {
  2289. // Scalar block layout permits fields in what would normally be the padding at
  2290. // the end of a struct.
  2291. std::string spirv = R"(
  2292. OpCapability Shader
  2293. OpCapability Float64
  2294. OpMemoryModel Logical GLSL450
  2295. OpEntryPoint Vertex %main "main"
  2296. OpSource GLSL 450
  2297. OpMemberDecorate %st 0 Offset 0
  2298. OpMemberDecorate %st 1 Offset 8
  2299. OpMemberDecorate %S 0 Offset 0
  2300. OpMemberDecorate %S 1 Offset 12
  2301. OpDecorate %S Block
  2302. OpDecorate %B DescriptorSet 0
  2303. OpDecorate %B Binding 0
  2304. %void = OpTypeVoid
  2305. %3 = OpTypeFunction %void
  2306. %float = OpTypeFloat 32
  2307. %double = OpTypeFloat 64
  2308. %st = OpTypeStruct %double %float
  2309. %S = OpTypeStruct %st %float
  2310. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2311. %B = OpVariable %_ptr_Uniform_S Uniform
  2312. %main = OpFunction %void None %3
  2313. %5 = OpLabel
  2314. OpReturn
  2315. OpFunctionEnd
  2316. )";
  2317. CompileSuccessfully(spirv);
  2318. spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
  2319. EXPECT_EQ(SPV_SUCCESS,
  2320. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2321. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2322. }
  2323. TEST_F(
  2324. ValidateDecorations,
  2325. BlockLayoutPermitsStraddlingVectorWithScalarLayoutOverrideRelaxBlockLayoutGood) {
  2326. // Same as previous, but set relaxed block layout first. Scalar layout always
  2327. // wins.
  2328. std::string spirv = R"(
  2329. OpCapability Shader
  2330. OpMemoryModel Logical GLSL450
  2331. OpEntryPoint Vertex %main "main"
  2332. OpSource GLSL 450
  2333. OpMemberDecorate %S 0 Offset 0
  2334. OpMemberDecorate %S 1 Offset 4
  2335. OpDecorate %S Block
  2336. OpDecorate %B DescriptorSet 0
  2337. OpDecorate %B Binding 0
  2338. %void = OpTypeVoid
  2339. %3 = OpTypeFunction %void
  2340. %float = OpTypeFloat 32
  2341. %vec4 = OpTypeVector %float 4
  2342. %S = OpTypeStruct %float %vec4
  2343. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2344. %B = OpVariable %_ptr_Uniform_S Uniform
  2345. %main = OpFunction %void None %3
  2346. %5 = OpLabel
  2347. OpReturn
  2348. OpFunctionEnd
  2349. )";
  2350. CompileSuccessfully(spirv);
  2351. spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
  2352. spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
  2353. EXPECT_EQ(SPV_SUCCESS,
  2354. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2355. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2356. }
  2357. TEST_F(
  2358. ValidateDecorations,
  2359. BlockLayoutPermitsStraddlingVectorWithRelaxedLayoutOverridenByScalarBlockLayoutGood) {
  2360. // Same as previous, but set scalar block layout first. Scalar layout always
  2361. // wins.
  2362. std::string spirv = R"(
  2363. OpCapability Shader
  2364. OpMemoryModel Logical GLSL450
  2365. OpEntryPoint Vertex %main "main"
  2366. OpSource GLSL 450
  2367. OpMemberDecorate %S 0 Offset 0
  2368. OpMemberDecorate %S 1 Offset 4
  2369. OpDecorate %S Block
  2370. OpDecorate %B DescriptorSet 0
  2371. OpDecorate %B Binding 0
  2372. %void = OpTypeVoid
  2373. %3 = OpTypeFunction %void
  2374. %float = OpTypeFloat 32
  2375. %vec4 = OpTypeVector %float 4
  2376. %S = OpTypeStruct %float %vec4
  2377. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2378. %B = OpVariable %_ptr_Uniform_S Uniform
  2379. %main = OpFunction %void None %3
  2380. %5 = OpLabel
  2381. OpReturn
  2382. OpFunctionEnd
  2383. )";
  2384. CompileSuccessfully(spirv);
  2385. spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
  2386. spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
  2387. EXPECT_EQ(SPV_SUCCESS,
  2388. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2389. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2390. }
  2391. TEST_F(ValidateDecorations, BufferBlock16bitStandardStorageBufferLayout) {
  2392. std::string spirv = R"(
  2393. OpCapability Shader
  2394. OpCapability StorageUniform16
  2395. OpExtension "SPV_KHR_16bit_storage"
  2396. OpMemoryModel Logical GLSL450
  2397. OpEntryPoint GLCompute %main "main"
  2398. OpExecutionMode %main LocalSize 1 1 1
  2399. OpDecorate %f32arr ArrayStride 4
  2400. OpDecorate %f16arr ArrayStride 2
  2401. OpMemberDecorate %SSBO32 0 Offset 0
  2402. OpMemberDecorate %SSBO16 0 Offset 0
  2403. OpDecorate %SSBO32 BufferBlock
  2404. OpDecorate %SSBO16 BufferBlock
  2405. %void = OpTypeVoid
  2406. %voidf = OpTypeFunction %void
  2407. %u32 = OpTypeInt 32 0
  2408. %i32 = OpTypeInt 32 1
  2409. %f32 = OpTypeFloat 32
  2410. %uvec3 = OpTypeVector %u32 3
  2411. %c_i32_32 = OpConstant %i32 32
  2412. %c_i32_128 = OpConstant %i32 128
  2413. %f32arr = OpTypeArray %f32 %c_i32_128
  2414. %f16 = OpTypeFloat 16
  2415. %f16arr = OpTypeArray %f16 %c_i32_128
  2416. %SSBO32 = OpTypeStruct %f32arr
  2417. %SSBO16 = OpTypeStruct %f16arr
  2418. %_ptr_Uniform_SSBO32 = OpTypePointer Uniform %SSBO32
  2419. %varSSBO32 = OpVariable %_ptr_Uniform_SSBO32 Uniform
  2420. %_ptr_Uniform_SSBO16 = OpTypePointer Uniform %SSBO16
  2421. %varSSBO16 = OpVariable %_ptr_Uniform_SSBO16 Uniform
  2422. %main = OpFunction %void None %voidf
  2423. %label = OpLabel
  2424. OpReturn
  2425. OpFunctionEnd
  2426. )";
  2427. CompileSuccessfully(spirv);
  2428. EXPECT_EQ(SPV_SUCCESS,
  2429. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2430. }
  2431. TEST_F(ValidateDecorations, BlockArrayExtendedAlignmentGood) {
  2432. // For uniform buffer, Array base alignment is 16, and ArrayStride
  2433. // must be a multiple of 16.
  2434. std::string spirv = R"(
  2435. OpCapability Shader
  2436. OpMemoryModel Logical GLSL450
  2437. OpEntryPoint Vertex %main "main"
  2438. OpSource GLSL 450
  2439. OpDecorate %_arr_float_uint_2 ArrayStride 16
  2440. OpMemberDecorate %S 0 Offset 0
  2441. OpMemberDecorate %S 1 Offset 16
  2442. OpDecorate %S Block
  2443. %void = OpTypeVoid
  2444. %3 = OpTypeFunction %void
  2445. %float = OpTypeFloat 32
  2446. %v2float = OpTypeVector %float 2
  2447. %uint = OpTypeInt 32 0
  2448. %uint_2 = OpConstant %uint 2
  2449. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  2450. %S = OpTypeStruct %v2float %_arr_float_uint_2
  2451. %_ptr_PushConstant_S = OpTypePointer PushConstant %S
  2452. %u = OpVariable %_ptr_PushConstant_S PushConstant
  2453. %main = OpFunction %void None %3
  2454. %5 = OpLabel
  2455. OpReturn
  2456. OpFunctionEnd
  2457. )";
  2458. CompileSuccessfully(spirv);
  2459. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  2460. << getDiagnosticString();
  2461. }
  2462. TEST_F(ValidateDecorations, BlockArrayBaseAlignmentBad) {
  2463. // For uniform buffer, Array base alignment is 16.
  2464. std::string spirv = R"(
  2465. OpCapability Shader
  2466. OpMemoryModel Logical GLSL450
  2467. OpEntryPoint Vertex %main "main"
  2468. OpSource GLSL 450
  2469. OpDecorate %_arr_float_uint_2 ArrayStride 16
  2470. OpMemberDecorate %S 0 Offset 0
  2471. OpMemberDecorate %S 1 Offset 8
  2472. OpDecorate %S Block
  2473. %void = OpTypeVoid
  2474. %3 = OpTypeFunction %void
  2475. %float = OpTypeFloat 32
  2476. %v2float = OpTypeVector %float 2
  2477. %uint = OpTypeInt 32 0
  2478. %uint_2 = OpConstant %uint 2
  2479. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  2480. %S = OpTypeStruct %v2float %_arr_float_uint_2
  2481. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2482. %u = OpVariable %_ptr_Uniform_S Uniform
  2483. %main = OpFunction %void None %3
  2484. %5 = OpLabel
  2485. OpReturn
  2486. OpFunctionEnd
  2487. )";
  2488. CompileSuccessfully(spirv);
  2489. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2490. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2491. EXPECT_THAT(
  2492. getDiagnosticString(),
  2493. HasSubstr(
  2494. "Structure id 3 decorated as Block for variable in Uniform "
  2495. "storage class must follow standard uniform buffer layout rules: "
  2496. "member 1 at offset 8 is not aligned to 16"));
  2497. }
  2498. TEST_F(ValidateDecorations, BlockArrayBaseAlignmentWithRelaxedLayoutStillBad) {
  2499. // For uniform buffer, Array base alignment is 16, and ArrayStride
  2500. // must be a multiple of 16. This case uses relaxed block layout. Relaxed
  2501. // layout only relaxes rules for vector alignment, not array alignment.
  2502. std::string spirv = R"(
  2503. OpCapability Shader
  2504. OpMemoryModel Logical GLSL450
  2505. OpEntryPoint Vertex %main "main"
  2506. OpSource GLSL 450
  2507. OpDecorate %_arr_float_uint_2 ArrayStride 16
  2508. OpDecorate %u DescriptorSet 0
  2509. OpDecorate %u Binding 0
  2510. OpMemberDecorate %S 0 Offset 0
  2511. OpMemberDecorate %S 1 Offset 8
  2512. OpDecorate %S Block
  2513. %void = OpTypeVoid
  2514. %3 = OpTypeFunction %void
  2515. %float = OpTypeFloat 32
  2516. %v2float = OpTypeVector %float 2
  2517. %uint = OpTypeInt 32 0
  2518. %uint_2 = OpConstant %uint 2
  2519. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  2520. %S = OpTypeStruct %v2float %_arr_float_uint_2
  2521. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2522. %u = OpVariable %_ptr_Uniform_S Uniform
  2523. %main = OpFunction %void None %3
  2524. %5 = OpLabel
  2525. OpReturn
  2526. OpFunctionEnd
  2527. )";
  2528. CompileSuccessfully(spirv);
  2529. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2530. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2531. spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
  2532. EXPECT_THAT(
  2533. getDiagnosticString(),
  2534. HasSubstr(
  2535. "Structure id 4 decorated as Block for variable in Uniform "
  2536. "storage class must follow standard uniform buffer layout rules: "
  2537. "member 1 at offset 8 is not aligned to 16"));
  2538. }
  2539. TEST_F(ValidateDecorations, BlockArrayBaseAlignmentWithVulkan1_1StillBad) {
  2540. // Same as previous test, but with Vulkan 1.1, which includes
  2541. // VK_KHR_relaxed_block_layout in core.
  2542. std::string spirv = R"(
  2543. OpCapability Shader
  2544. OpMemoryModel Logical GLSL450
  2545. OpEntryPoint Vertex %main "main"
  2546. OpSource GLSL 450
  2547. OpDecorate %_arr_float_uint_2 ArrayStride 16
  2548. OpDecorate %u DescriptorSet 0
  2549. OpDecorate %u Binding 0
  2550. OpMemberDecorate %S 0 Offset 0
  2551. OpMemberDecorate %S 1 Offset 8
  2552. OpDecorate %S Block
  2553. %void = OpTypeVoid
  2554. %3 = OpTypeFunction %void
  2555. %float = OpTypeFloat 32
  2556. %v2float = OpTypeVector %float 2
  2557. %uint = OpTypeInt 32 0
  2558. %uint_2 = OpConstant %uint 2
  2559. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  2560. %S = OpTypeStruct %v2float %_arr_float_uint_2
  2561. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2562. %u = OpVariable %_ptr_Uniform_S Uniform
  2563. %main = OpFunction %void None %3
  2564. %5 = OpLabel
  2565. OpReturn
  2566. OpFunctionEnd
  2567. )";
  2568. CompileSuccessfully(spirv);
  2569. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2570. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  2571. EXPECT_THAT(
  2572. getDiagnosticString(),
  2573. HasSubstr(
  2574. "Structure id 4 decorated as Block for variable in Uniform "
  2575. "storage class must follow relaxed uniform buffer layout rules: "
  2576. "member 1 at offset 8 is not aligned to 16"));
  2577. }
  2578. TEST_F(ValidateDecorations,
  2579. BlockArrayBaseAlignmentWithBlockStandardLayoutGood) {
  2580. // Same as previous test, but with VK_KHR_uniform_buffer_standard_layout
  2581. std::string spirv = R"(
  2582. OpCapability Shader
  2583. OpMemoryModel Logical GLSL450
  2584. OpEntryPoint Vertex %main "main"
  2585. OpSource GLSL 450
  2586. OpDecorate %_arr_float_uint_2 ArrayStride 16
  2587. OpDecorate %u DescriptorSet 0
  2588. OpDecorate %u Binding 0
  2589. OpMemberDecorate %S 0 Offset 0
  2590. OpMemberDecorate %S 1 Offset 8
  2591. OpDecorate %S Block
  2592. %void = OpTypeVoid
  2593. %3 = OpTypeFunction %void
  2594. %float = OpTypeFloat 32
  2595. %v2float = OpTypeVector %float 2
  2596. %uint = OpTypeInt 32 0
  2597. %uint_2 = OpConstant %uint 2
  2598. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  2599. %S = OpTypeStruct %v2float %_arr_float_uint_2
  2600. %_ptr_Uniform_S = OpTypePointer Uniform %S
  2601. %u = OpVariable %_ptr_Uniform_S Uniform
  2602. %main = OpFunction %void None %3
  2603. %5 = OpLabel
  2604. OpReturn
  2605. OpFunctionEnd
  2606. )";
  2607. CompileSuccessfully(spirv);
  2608. spvValidatorOptionsSetUniformBufferStandardLayout(getValidatorOptions(),
  2609. true);
  2610. EXPECT_EQ(SPV_SUCCESS,
  2611. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2612. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2613. }
  2614. TEST_F(ValidateDecorations, VulkanBufferBlockOnStorageBufferBad) {
  2615. std::string spirv = R"(
  2616. OpCapability Shader
  2617. OpExtension "SPV_KHR_storage_buffer_storage_class"
  2618. OpMemoryModel Logical GLSL450
  2619. OpEntryPoint Fragment %1 "main"
  2620. OpExecutionMode %1 OriginUpperLeft
  2621. OpDecorate %struct BufferBlock
  2622. %void = OpTypeVoid
  2623. %voidfn = OpTypeFunction %void
  2624. %float = OpTypeFloat 32
  2625. %struct = OpTypeStruct %float
  2626. %ptr = OpTypePointer StorageBuffer %struct
  2627. %var = OpVariable %ptr StorageBuffer
  2628. %1 = OpFunction %void None %voidfn
  2629. %label = OpLabel
  2630. OpReturn
  2631. OpFunctionEnd
  2632. )";
  2633. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  2634. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2635. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  2636. EXPECT_THAT(getDiagnosticString(),
  2637. AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
  2638. EXPECT_THAT(getDiagnosticString(),
  2639. HasSubstr("In Vulkan, BufferBlock is disallowed on variables in "
  2640. "the StorageBuffer storage class"));
  2641. }
  2642. TEST_F(ValidateDecorations, PushConstantArrayBaseAlignmentGood) {
  2643. // Tests https://github.com/KhronosGroup/SPIRV-Tools/issues/1664
  2644. // From GLSL vertex shader:
  2645. // #version 450
  2646. // layout(push_constant) uniform S { vec2 v; float arr[2]; } u;
  2647. // void main() { }
  2648. std::string spirv = R"(
  2649. OpCapability Shader
  2650. OpMemoryModel Logical GLSL450
  2651. OpEntryPoint Vertex %main "main"
  2652. OpSource GLSL 450
  2653. OpDecorate %_arr_float_uint_2 ArrayStride 4
  2654. OpMemberDecorate %S 0 Offset 0
  2655. OpMemberDecorate %S 1 Offset 8
  2656. OpDecorate %S Block
  2657. %void = OpTypeVoid
  2658. %3 = OpTypeFunction %void
  2659. %float = OpTypeFloat 32
  2660. %v2float = OpTypeVector %float 2
  2661. %uint = OpTypeInt 32 0
  2662. %uint_2 = OpConstant %uint 2
  2663. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  2664. %S = OpTypeStruct %v2float %_arr_float_uint_2
  2665. %_ptr_PushConstant_S = OpTypePointer PushConstant %S
  2666. %u = OpVariable %_ptr_PushConstant_S PushConstant
  2667. %main = OpFunction %void None %3
  2668. %5 = OpLabel
  2669. OpReturn
  2670. OpFunctionEnd
  2671. )";
  2672. CompileSuccessfully(spirv);
  2673. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
  2674. << getDiagnosticString();
  2675. }
  2676. TEST_F(ValidateDecorations, PushConstantArrayBadAlignmentBad) {
  2677. // Like the previous test, but with offset 7 instead of 8.
  2678. std::string spirv = R"(
  2679. OpCapability Shader
  2680. OpMemoryModel Logical GLSL450
  2681. OpEntryPoint Vertex %main "main"
  2682. OpSource GLSL 450
  2683. OpDecorate %_arr_float_uint_2 ArrayStride 4
  2684. OpMemberDecorate %S 0 Offset 0
  2685. OpMemberDecorate %S 1 Offset 7
  2686. OpDecorate %S Block
  2687. %void = OpTypeVoid
  2688. %3 = OpTypeFunction %void
  2689. %float = OpTypeFloat 32
  2690. %v2float = OpTypeVector %float 2
  2691. %uint = OpTypeInt 32 0
  2692. %uint_2 = OpConstant %uint 2
  2693. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  2694. %S = OpTypeStruct %v2float %_arr_float_uint_2
  2695. %_ptr_PushConstant_S = OpTypePointer PushConstant %S
  2696. %u = OpVariable %_ptr_PushConstant_S PushConstant
  2697. %main = OpFunction %void None %3
  2698. %5 = OpLabel
  2699. OpReturn
  2700. OpFunctionEnd
  2701. )";
  2702. CompileSuccessfully(spirv);
  2703. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2704. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2705. EXPECT_THAT(
  2706. getDiagnosticString(),
  2707. HasSubstr(
  2708. "Structure id 3 decorated as Block for variable in PushConstant "
  2709. "storage class must follow standard storage buffer layout rules: "
  2710. "member 1 at offset 7 is not aligned to 4"));
  2711. }
  2712. TEST_F(ValidateDecorations,
  2713. PushConstantLayoutPermitsTightVec3ScalarPackingGood) {
  2714. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
  2715. std::string spirv = R"(
  2716. OpCapability Shader
  2717. OpMemoryModel Logical GLSL450
  2718. OpEntryPoint Vertex %main "main"
  2719. OpSource GLSL 450
  2720. OpMemberDecorate %S 0 Offset 0
  2721. OpMemberDecorate %S 1 Offset 12
  2722. OpDecorate %S Block
  2723. %void = OpTypeVoid
  2724. %3 = OpTypeFunction %void
  2725. %float = OpTypeFloat 32
  2726. %v3float = OpTypeVector %float 3
  2727. %S = OpTypeStruct %v3float %float
  2728. %_ptr_PushConstant_S = OpTypePointer PushConstant %S
  2729. %B = OpVariable %_ptr_PushConstant_S PushConstant
  2730. %main = OpFunction %void None %3
  2731. %5 = OpLabel
  2732. OpReturn
  2733. OpFunctionEnd
  2734. )";
  2735. CompileSuccessfully(spirv);
  2736. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
  2737. << getDiagnosticString();
  2738. }
  2739. TEST_F(ValidateDecorations,
  2740. PushConstantLayoutForbidsTightScalarVec3PackingBad) {
  2741. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
  2742. std::string spirv = R"(
  2743. OpCapability Shader
  2744. OpMemoryModel Logical GLSL450
  2745. OpEntryPoint Vertex %main "main"
  2746. OpSource GLSL 450
  2747. OpMemberDecorate %S 0 Offset 0
  2748. OpMemberDecorate %S 1 Offset 4
  2749. OpDecorate %S Block
  2750. %void = OpTypeVoid
  2751. %3 = OpTypeFunction %void
  2752. %float = OpTypeFloat 32
  2753. %v3float = OpTypeVector %float 3
  2754. %S = OpTypeStruct %float %v3float
  2755. %_ptr_Uniform_S = OpTypePointer PushConstant %S
  2756. %B = OpVariable %_ptr_Uniform_S PushConstant
  2757. %main = OpFunction %void None %3
  2758. %5 = OpLabel
  2759. OpReturn
  2760. OpFunctionEnd
  2761. )";
  2762. CompileSuccessfully(spirv);
  2763. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2764. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  2765. EXPECT_THAT(
  2766. getDiagnosticString(),
  2767. HasSubstr(
  2768. "Structure id 2 decorated as Block for variable in PushConstant "
  2769. "storage class must follow standard storage buffer layout "
  2770. "rules: member 1 at offset 4 is not aligned to 16"));
  2771. }
  2772. TEST_F(ValidateDecorations, PushConstantMissingBlockGood) {
  2773. std::string spirv = R"(
  2774. OpCapability Shader
  2775. OpMemoryModel Logical GLSL450
  2776. OpEntryPoint Fragment %1 "main"
  2777. OpExecutionMode %1 OriginUpperLeft
  2778. OpMemberDecorate %struct 0 Offset 0
  2779. %void = OpTypeVoid
  2780. %voidfn = OpTypeFunction %void
  2781. %float = OpTypeFloat 32
  2782. %struct = OpTypeStruct %float
  2783. %ptr = OpTypePointer PushConstant %struct
  2784. %pc = OpVariable %ptr PushConstant
  2785. %1 = OpFunction %void None %voidfn
  2786. %label = OpLabel
  2787. OpReturn
  2788. OpFunctionEnd
  2789. )";
  2790. CompileSuccessfully(spirv);
  2791. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  2792. << getDiagnosticString();
  2793. }
  2794. TEST_F(ValidateDecorations, VulkanPushConstantMissingBlockBad) {
  2795. std::string spirv = R"(
  2796. OpCapability Shader
  2797. OpMemoryModel Logical GLSL450
  2798. OpEntryPoint Fragment %1 "main"
  2799. OpExecutionMode %1 OriginUpperLeft
  2800. OpMemberDecorate %struct 0 Offset 0
  2801. %void = OpTypeVoid
  2802. %voidfn = OpTypeFunction %void
  2803. %float = OpTypeFloat 32
  2804. %struct = OpTypeStruct %float
  2805. %ptr = OpTypePointer PushConstant %struct
  2806. %pc = OpVariable %ptr PushConstant
  2807. %1 = OpFunction %void None %voidfn
  2808. %label = OpLabel
  2809. OpReturn
  2810. OpFunctionEnd
  2811. )";
  2812. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  2813. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2814. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  2815. EXPECT_THAT(getDiagnosticString(),
  2816. AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
  2817. EXPECT_THAT(getDiagnosticString(),
  2818. HasSubstr("PushConstant id '2' is missing Block decoration.\n"
  2819. "From Vulkan spec:\n"
  2820. "Such variables must be identified with a Block "
  2821. "decoration"));
  2822. }
  2823. TEST_F(ValidateDecorations, MultiplePushConstantsSingleEntryPointGood) {
  2824. std::string spirv = R"(
  2825. OpCapability Shader
  2826. OpMemoryModel Logical GLSL450
  2827. OpEntryPoint Fragment %1 "main"
  2828. OpExecutionMode %1 OriginUpperLeft
  2829. OpDecorate %struct Block
  2830. OpMemberDecorate %struct 0 Offset 0
  2831. %void = OpTypeVoid
  2832. %voidfn = OpTypeFunction %void
  2833. %float = OpTypeFloat 32
  2834. %int = OpTypeInt 32 0
  2835. %int_0 = OpConstant %int 0
  2836. %struct = OpTypeStruct %float
  2837. %ptr = OpTypePointer PushConstant %struct
  2838. %ptr_float = OpTypePointer PushConstant %float
  2839. %pc1 = OpVariable %ptr PushConstant
  2840. %pc2 = OpVariable %ptr PushConstant
  2841. %1 = OpFunction %void None %voidfn
  2842. %label = OpLabel
  2843. %2 = OpAccessChain %ptr_float %pc1 %int_0
  2844. %3 = OpLoad %float %2
  2845. %4 = OpAccessChain %ptr_float %pc2 %int_0
  2846. %5 = OpLoad %float %4
  2847. OpReturn
  2848. OpFunctionEnd
  2849. )";
  2850. CompileSuccessfully(spirv);
  2851. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  2852. << getDiagnosticString();
  2853. }
  2854. TEST_F(ValidateDecorations,
  2855. VulkanMultiplePushConstantsDifferentEntryPointGood) {
  2856. std::string spirv = R"(
  2857. OpCapability Shader
  2858. OpMemoryModel Logical GLSL450
  2859. OpEntryPoint Vertex %1 "func1"
  2860. OpEntryPoint Fragment %2 "func2"
  2861. OpExecutionMode %2 OriginUpperLeft
  2862. OpDecorate %struct Block
  2863. OpMemberDecorate %struct 0 Offset 0
  2864. %void = OpTypeVoid
  2865. %voidfn = OpTypeFunction %void
  2866. %float = OpTypeFloat 32
  2867. %int = OpTypeInt 32 0
  2868. %int_0 = OpConstant %int 0
  2869. %struct = OpTypeStruct %float
  2870. %ptr = OpTypePointer PushConstant %struct
  2871. %ptr_float = OpTypePointer PushConstant %float
  2872. %pc1 = OpVariable %ptr PushConstant
  2873. %pc2 = OpVariable %ptr PushConstant
  2874. %1 = OpFunction %void None %voidfn
  2875. %label1 = OpLabel
  2876. %3 = OpAccessChain %ptr_float %pc1 %int_0
  2877. %4 = OpLoad %float %3
  2878. OpReturn
  2879. OpFunctionEnd
  2880. %2 = OpFunction %void None %voidfn
  2881. %label2 = OpLabel
  2882. %5 = OpAccessChain %ptr_float %pc2 %int_0
  2883. %6 = OpLoad %float %5
  2884. OpReturn
  2885. OpFunctionEnd
  2886. )";
  2887. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  2888. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1))
  2889. << getDiagnosticString();
  2890. }
  2891. TEST_F(ValidateDecorations,
  2892. VulkanMultiplePushConstantsUnusedSingleEntryPointGood) {
  2893. std::string spirv = R"(
  2894. OpCapability Shader
  2895. OpMemoryModel Logical GLSL450
  2896. OpEntryPoint Fragment %1 "main"
  2897. OpExecutionMode %1 OriginUpperLeft
  2898. OpDecorate %struct Block
  2899. OpMemberDecorate %struct 0 Offset 0
  2900. %void = OpTypeVoid
  2901. %voidfn = OpTypeFunction %void
  2902. %float = OpTypeFloat 32
  2903. %int = OpTypeInt 32 0
  2904. %int_0 = OpConstant %int 0
  2905. %struct = OpTypeStruct %float
  2906. %ptr = OpTypePointer PushConstant %struct
  2907. %ptr_float = OpTypePointer PushConstant %float
  2908. %pc1 = OpVariable %ptr PushConstant
  2909. %pc2 = OpVariable %ptr PushConstant
  2910. %1 = OpFunction %void None %voidfn
  2911. %label = OpLabel
  2912. OpReturn
  2913. OpFunctionEnd
  2914. )";
  2915. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  2916. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1))
  2917. << getDiagnosticString();
  2918. }
  2919. TEST_F(ValidateDecorations, VulkanMultiplePushConstantsSingleEntryPointBad) {
  2920. std::string spirv = R"(
  2921. OpCapability Shader
  2922. OpMemoryModel Logical GLSL450
  2923. OpEntryPoint Fragment %1 "main"
  2924. OpExecutionMode %1 OriginUpperLeft
  2925. OpDecorate %struct Block
  2926. OpMemberDecorate %struct 0 Offset 0
  2927. %void = OpTypeVoid
  2928. %voidfn = OpTypeFunction %void
  2929. %float = OpTypeFloat 32
  2930. %int = OpTypeInt 32 0
  2931. %int_0 = OpConstant %int 0
  2932. %struct = OpTypeStruct %float
  2933. %ptr = OpTypePointer PushConstant %struct
  2934. %ptr_float = OpTypePointer PushConstant %float
  2935. %pc1 = OpVariable %ptr PushConstant
  2936. %pc2 = OpVariable %ptr PushConstant
  2937. %1 = OpFunction %void None %voidfn
  2938. %label = OpLabel
  2939. %2 = OpAccessChain %ptr_float %pc1 %int_0
  2940. %3 = OpLoad %float %2
  2941. %4 = OpAccessChain %ptr_float %pc2 %int_0
  2942. %5 = OpLoad %float %4
  2943. OpReturn
  2944. OpFunctionEnd
  2945. )";
  2946. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  2947. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  2948. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  2949. EXPECT_THAT(getDiagnosticString(),
  2950. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-06674"));
  2951. EXPECT_THAT(
  2952. getDiagnosticString(),
  2953. HasSubstr(
  2954. "Entry point id '1' uses more than one PushConstant interface.\n"
  2955. "From Vulkan spec:\n"
  2956. "There must be no more than one push constant block "
  2957. "statically used per shader entry point."));
  2958. }
  2959. TEST_F(ValidateDecorations,
  2960. VulkanMultiplePushConstantsDifferentEntryPointSubFunctionGood) {
  2961. std::string spirv = R"(
  2962. OpCapability Shader
  2963. OpMemoryModel Logical GLSL450
  2964. OpEntryPoint Vertex %1 "func1"
  2965. OpEntryPoint Fragment %2 "func2"
  2966. OpExecutionMode %2 OriginUpperLeft
  2967. OpDecorate %struct Block
  2968. OpMemberDecorate %struct 0 Offset 0
  2969. %void = OpTypeVoid
  2970. %voidfn = OpTypeFunction %void
  2971. %float = OpTypeFloat 32
  2972. %int = OpTypeInt 32 0
  2973. %int_0 = OpConstant %int 0
  2974. %struct = OpTypeStruct %float
  2975. %ptr = OpTypePointer PushConstant %struct
  2976. %ptr_float = OpTypePointer PushConstant %float
  2977. %pc1 = OpVariable %ptr PushConstant
  2978. %pc2 = OpVariable %ptr PushConstant
  2979. %sub1 = OpFunction %void None %voidfn
  2980. %label_sub1 = OpLabel
  2981. %3 = OpAccessChain %ptr_float %pc1 %int_0
  2982. %4 = OpLoad %float %3
  2983. OpReturn
  2984. OpFunctionEnd
  2985. %sub2 = OpFunction %void None %voidfn
  2986. %label_sub2 = OpLabel
  2987. %5 = OpAccessChain %ptr_float %pc2 %int_0
  2988. %6 = OpLoad %float %5
  2989. OpReturn
  2990. OpFunctionEnd
  2991. %1 = OpFunction %void None %voidfn
  2992. %label1 = OpLabel
  2993. %call1 = OpFunctionCall %void %sub1
  2994. OpReturn
  2995. OpFunctionEnd
  2996. %2 = OpFunction %void None %voidfn
  2997. %label2 = OpLabel
  2998. %call2 = OpFunctionCall %void %sub2
  2999. OpReturn
  3000. OpFunctionEnd
  3001. )";
  3002. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3003. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1))
  3004. << getDiagnosticString();
  3005. }
  3006. TEST_F(ValidateDecorations,
  3007. VulkanMultiplePushConstantsSingleEntryPointSubFunctionBad) {
  3008. std::string spirv = R"(
  3009. OpCapability Shader
  3010. OpMemoryModel Logical GLSL450
  3011. OpEntryPoint Fragment %1 "main"
  3012. OpExecutionMode %1 OriginUpperLeft
  3013. OpDecorate %struct Block
  3014. OpMemberDecorate %struct 0 Offset 0
  3015. %void = OpTypeVoid
  3016. %voidfn = OpTypeFunction %void
  3017. %float = OpTypeFloat 32
  3018. %int = OpTypeInt 32 0
  3019. %int_0 = OpConstant %int 0
  3020. %struct = OpTypeStruct %float
  3021. %ptr = OpTypePointer PushConstant %struct
  3022. %ptr_float = OpTypePointer PushConstant %float
  3023. %pc1 = OpVariable %ptr PushConstant
  3024. %pc2 = OpVariable %ptr PushConstant
  3025. %sub1 = OpFunction %void None %voidfn
  3026. %label_sub1 = OpLabel
  3027. %3 = OpAccessChain %ptr_float %pc1 %int_0
  3028. %4 = OpLoad %float %3
  3029. OpReturn
  3030. OpFunctionEnd
  3031. %sub2 = OpFunction %void None %voidfn
  3032. %label_sub2 = OpLabel
  3033. %5 = OpAccessChain %ptr_float %pc2 %int_0
  3034. %6 = OpLoad %float %5
  3035. OpReturn
  3036. OpFunctionEnd
  3037. %1 = OpFunction %void None %voidfn
  3038. %label1 = OpLabel
  3039. %call1 = OpFunctionCall %void %sub1
  3040. %call2 = OpFunctionCall %void %sub2
  3041. OpReturn
  3042. OpFunctionEnd
  3043. )";
  3044. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3045. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3046. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  3047. EXPECT_THAT(getDiagnosticString(),
  3048. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-06674"));
  3049. EXPECT_THAT(
  3050. getDiagnosticString(),
  3051. HasSubstr(
  3052. "Entry point id '1' uses more than one PushConstant interface.\n"
  3053. "From Vulkan spec:\n"
  3054. "There must be no more than one push constant block "
  3055. "statically used per shader entry point."));
  3056. }
  3057. TEST_F(ValidateDecorations,
  3058. VulkanMultiplePushConstantsSingleEntryPointInterfaceBad) {
  3059. std::string spirv = R"(
  3060. OpCapability Shader
  3061. OpMemoryModel Logical GLSL450
  3062. OpEntryPoint Vertex %func1 "func1" %pc1 %pc2
  3063. OpDecorate %struct Block
  3064. OpMemberDecorate %struct 0 Offset 0
  3065. %void = OpTypeVoid
  3066. %voidfn = OpTypeFunction %void
  3067. %float = OpTypeFloat 32
  3068. %int = OpTypeInt 32 0
  3069. %int_0 = OpConstant %int 0
  3070. %struct = OpTypeStruct %float
  3071. %ptr = OpTypePointer PushConstant %struct
  3072. %ptr_float = OpTypePointer PushConstant %float
  3073. %pc1 = OpVariable %ptr PushConstant
  3074. %pc2 = OpVariable %ptr PushConstant
  3075. %func1 = OpFunction %void None %voidfn
  3076. %label1 = OpLabel
  3077. %access1 = OpAccessChain %ptr_float %pc1 %int_0
  3078. %load1 = OpLoad %float %access1
  3079. OpReturn
  3080. OpFunctionEnd
  3081. %func2 = OpFunction %void None %voidfn
  3082. %label2 = OpLabel
  3083. %access2 = OpAccessChain %ptr_float %pc2 %int_0
  3084. %load2 = OpLoad %float %access2
  3085. OpReturn
  3086. OpFunctionEnd
  3087. )";
  3088. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  3089. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  3090. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
  3091. EXPECT_THAT(getDiagnosticString(),
  3092. AnyVUID("VUID-StandaloneSpirv-OpVariable-06673"));
  3093. EXPECT_THAT(getDiagnosticString(),
  3094. HasSubstr("Entry-point has more than one variable with the "
  3095. "PushConstant storage class in the interface"));
  3096. }
  3097. TEST_F(ValidateDecorations, VulkanUniformMissingDescriptorSetBad) {
  3098. std::string spirv = R"(
  3099. OpCapability Shader
  3100. OpMemoryModel Logical GLSL450
  3101. OpEntryPoint Fragment %1 "main"
  3102. OpExecutionMode %1 OriginUpperLeft
  3103. OpDecorate %struct Block
  3104. OpMemberDecorate %struct 0 Offset 0
  3105. OpDecorate %var Binding 0
  3106. %void = OpTypeVoid
  3107. %voidfn = OpTypeFunction %void
  3108. %float = OpTypeFloat 32
  3109. %struct = OpTypeStruct %float
  3110. %ptr = OpTypePointer Uniform %struct
  3111. %ptr_float = OpTypePointer Uniform %float
  3112. %var = OpVariable %ptr Uniform
  3113. %int = OpTypeInt 32 0
  3114. %int_0 = OpConstant %int 0
  3115. %1 = OpFunction %void None %voidfn
  3116. %label = OpLabel
  3117. %2 = OpAccessChain %ptr_float %var %int_0
  3118. %3 = OpLoad %float %2
  3119. OpReturn
  3120. OpFunctionEnd
  3121. )";
  3122. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3123. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3124. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  3125. EXPECT_THAT(getDiagnosticString(),
  3126. AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
  3127. EXPECT_THAT(getDiagnosticString(),
  3128. HasSubstr("Uniform id '3' is missing DescriptorSet decoration.\n"
  3129. "From Vulkan spec:\n"
  3130. "These variables must have DescriptorSet and Binding "
  3131. "decorations specified"));
  3132. }
  3133. TEST_F(ValidateDecorations, VulkanUniformMissingBindingBad) {
  3134. std::string spirv = R"(
  3135. OpCapability Shader
  3136. OpMemoryModel Logical GLSL450
  3137. OpEntryPoint Fragment %1 "main"
  3138. OpExecutionMode %1 OriginUpperLeft
  3139. OpDecorate %struct Block
  3140. OpMemberDecorate %struct 0 Offset 0
  3141. OpDecorate %var DescriptorSet 0
  3142. %void = OpTypeVoid
  3143. %voidfn = OpTypeFunction %void
  3144. %float = OpTypeFloat 32
  3145. %struct = OpTypeStruct %float
  3146. %ptr = OpTypePointer Uniform %struct
  3147. %ptr_float = OpTypePointer Uniform %float
  3148. %var = OpVariable %ptr Uniform
  3149. %int = OpTypeInt 32 0
  3150. %int_0 = OpConstant %int 0
  3151. %1 = OpFunction %void None %voidfn
  3152. %label = OpLabel
  3153. %2 = OpAccessChain %ptr_float %var %int_0
  3154. %3 = OpLoad %float %2
  3155. OpReturn
  3156. OpFunctionEnd
  3157. )";
  3158. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3159. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3160. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  3161. EXPECT_THAT(getDiagnosticString(),
  3162. AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
  3163. EXPECT_THAT(getDiagnosticString(),
  3164. HasSubstr("Uniform id '3' is missing Binding decoration.\n"
  3165. "From Vulkan spec:\n"
  3166. "These variables must have DescriptorSet and Binding "
  3167. "decorations specified"));
  3168. }
  3169. TEST_F(ValidateDecorations, VulkanUniformConstantMissingDescriptorSetBad) {
  3170. std::string spirv = R"(
  3171. OpCapability Shader
  3172. OpMemoryModel Logical GLSL450
  3173. OpEntryPoint Fragment %1 "main"
  3174. OpExecutionMode %1 OriginUpperLeft
  3175. OpDecorate %var Binding 0
  3176. %void = OpTypeVoid
  3177. %voidfn = OpTypeFunction %void
  3178. %sampler = OpTypeSampler
  3179. %ptr = OpTypePointer UniformConstant %sampler
  3180. %var = OpVariable %ptr UniformConstant
  3181. %1 = OpFunction %void None %voidfn
  3182. %label = OpLabel
  3183. %2 = OpLoad %sampler %var
  3184. OpReturn
  3185. OpFunctionEnd
  3186. )";
  3187. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3188. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3189. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  3190. EXPECT_THAT(getDiagnosticString(),
  3191. AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
  3192. EXPECT_THAT(
  3193. getDiagnosticString(),
  3194. HasSubstr("UniformConstant id '2' is missing DescriptorSet decoration.\n"
  3195. "From Vulkan spec:\n"
  3196. "These variables must have DescriptorSet and Binding "
  3197. "decorations specified"));
  3198. }
  3199. TEST_F(ValidateDecorations, VulkanUniformConstantMissingBindingBad) {
  3200. std::string spirv = R"(
  3201. OpCapability Shader
  3202. OpMemoryModel Logical GLSL450
  3203. OpEntryPoint Fragment %1 "main"
  3204. OpExecutionMode %1 OriginUpperLeft
  3205. OpDecorate %var DescriptorSet 0
  3206. %void = OpTypeVoid
  3207. %voidfn = OpTypeFunction %void
  3208. %sampler = OpTypeSampler
  3209. %ptr = OpTypePointer UniformConstant %sampler
  3210. %var = OpVariable %ptr UniformConstant
  3211. %1 = OpFunction %void None %voidfn
  3212. %label = OpLabel
  3213. %2 = OpLoad %sampler %var
  3214. OpReturn
  3215. OpFunctionEnd
  3216. )";
  3217. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3218. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3219. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  3220. EXPECT_THAT(getDiagnosticString(),
  3221. AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
  3222. EXPECT_THAT(
  3223. getDiagnosticString(),
  3224. HasSubstr("UniformConstant id '2' is missing Binding decoration.\n"
  3225. "From Vulkan spec:\n"
  3226. "These variables must have DescriptorSet and Binding "
  3227. "decorations specified"));
  3228. }
  3229. TEST_F(ValidateDecorations, VulkanStorageBufferMissingDescriptorSetBad) {
  3230. std::string spirv = R"(
  3231. OpCapability Shader
  3232. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3233. OpMemoryModel Logical GLSL450
  3234. OpEntryPoint Fragment %1 "main"
  3235. OpExecutionMode %1 OriginUpperLeft
  3236. OpDecorate %struct Block
  3237. OpDecorate %var Binding 0
  3238. %void = OpTypeVoid
  3239. %voidfn = OpTypeFunction %void
  3240. %float = OpTypeFloat 32
  3241. %struct = OpTypeStruct %float
  3242. %ptr = OpTypePointer StorageBuffer %struct
  3243. %var = OpVariable %ptr StorageBuffer
  3244. %ptr_float = OpTypePointer StorageBuffer %float
  3245. %int = OpTypeInt 32 0
  3246. %int_0 = OpConstant %int 0
  3247. %1 = OpFunction %void None %voidfn
  3248. %label = OpLabel
  3249. %2 = OpAccessChain %ptr_float %var %int_0
  3250. %3 = OpLoad %float %2
  3251. OpReturn
  3252. OpFunctionEnd
  3253. )";
  3254. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3255. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3256. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  3257. EXPECT_THAT(getDiagnosticString(),
  3258. AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
  3259. EXPECT_THAT(
  3260. getDiagnosticString(),
  3261. HasSubstr("StorageBuffer id '3' is missing DescriptorSet decoration.\n"
  3262. "From Vulkan spec:\n"
  3263. "These variables must have DescriptorSet and Binding "
  3264. "decorations specified"));
  3265. }
  3266. TEST_F(ValidateDecorations, VulkanStorageBufferMissingBindingBad) {
  3267. std::string spirv = R"(
  3268. OpCapability Shader
  3269. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3270. OpMemoryModel Logical GLSL450
  3271. OpEntryPoint Fragment %1 "main"
  3272. OpExecutionMode %1 OriginUpperLeft
  3273. OpDecorate %struct Block
  3274. OpDecorate %var DescriptorSet 0
  3275. %void = OpTypeVoid
  3276. %voidfn = OpTypeFunction %void
  3277. %float = OpTypeFloat 32
  3278. %struct = OpTypeStruct %float
  3279. %ptr = OpTypePointer StorageBuffer %struct
  3280. %var = OpVariable %ptr StorageBuffer
  3281. %ptr_float = OpTypePointer StorageBuffer %float
  3282. %int = OpTypeInt 32 0
  3283. %int_0 = OpConstant %int 0
  3284. %1 = OpFunction %void None %voidfn
  3285. %label = OpLabel
  3286. %2 = OpAccessChain %ptr_float %var %int_0
  3287. %3 = OpLoad %float %2
  3288. OpReturn
  3289. OpFunctionEnd
  3290. )";
  3291. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3292. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3293. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  3294. EXPECT_THAT(getDiagnosticString(),
  3295. AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
  3296. EXPECT_THAT(getDiagnosticString(),
  3297. HasSubstr("StorageBuffer id '3' is missing Binding decoration.\n"
  3298. "From Vulkan spec:\n"
  3299. "These variables must have DescriptorSet and Binding "
  3300. "decorations specified"));
  3301. }
  3302. TEST_F(ValidateDecorations,
  3303. VulkanStorageBufferMissingDescriptorSetSubFunctionBad) {
  3304. std::string spirv = R"(
  3305. OpCapability Shader
  3306. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3307. OpMemoryModel Logical GLSL450
  3308. OpEntryPoint Fragment %1 "main"
  3309. OpExecutionMode %1 OriginUpperLeft
  3310. OpDecorate %struct Block
  3311. OpDecorate %var Binding 0
  3312. %void = OpTypeVoid
  3313. %voidfn = OpTypeFunction %void
  3314. %float = OpTypeFloat 32
  3315. %struct = OpTypeStruct %float
  3316. %ptr = OpTypePointer StorageBuffer %struct
  3317. %var = OpVariable %ptr StorageBuffer
  3318. %ptr_float = OpTypePointer StorageBuffer %float
  3319. %int = OpTypeInt 32 0
  3320. %int_0 = OpConstant %int 0
  3321. %1 = OpFunction %void None %voidfn
  3322. %label = OpLabel
  3323. %call = OpFunctionCall %void %2
  3324. OpReturn
  3325. OpFunctionEnd
  3326. %2 = OpFunction %void None %voidfn
  3327. %label2 = OpLabel
  3328. %3 = OpAccessChain %ptr_float %var %int_0
  3329. %4 = OpLoad %float %3
  3330. OpReturn
  3331. OpFunctionEnd
  3332. )";
  3333. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3334. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3335. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  3336. EXPECT_THAT(getDiagnosticString(),
  3337. AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
  3338. EXPECT_THAT(
  3339. getDiagnosticString(),
  3340. HasSubstr("StorageBuffer id '3' is missing DescriptorSet decoration.\n"
  3341. "From Vulkan spec:\n"
  3342. "These variables must have DescriptorSet and Binding "
  3343. "decorations specified"));
  3344. }
  3345. TEST_F(ValidateDecorations,
  3346. VulkanStorageBufferMissingDescriptorAndBindingUnusedGood) {
  3347. std::string spirv = R"(
  3348. OpCapability Shader
  3349. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3350. OpMemoryModel Logical GLSL450
  3351. OpEntryPoint Fragment %1 "main"
  3352. OpExecutionMode %1 OriginUpperLeft
  3353. OpDecorate %struct Block
  3354. OpMemberDecorate %struct 0 Offset 0
  3355. %void = OpTypeVoid
  3356. %voidfn = OpTypeFunction %void
  3357. %float = OpTypeFloat 32
  3358. %struct = OpTypeStruct %float
  3359. %ptr = OpTypePointer StorageBuffer %struct
  3360. %var = OpVariable %ptr StorageBuffer
  3361. %1 = OpFunction %void None %voidfn
  3362. %label = OpLabel
  3363. OpReturn
  3364. OpFunctionEnd
  3365. )";
  3366. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3367. EXPECT_EQ(SPV_SUCCESS,
  3368. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
  3369. }
  3370. TEST_F(ValidateDecorations, UniformMissingDescriptorSetGood) {
  3371. std::string spirv = R"(
  3372. OpCapability Shader
  3373. OpMemoryModel Logical GLSL450
  3374. OpEntryPoint Fragment %1 "main"
  3375. OpExecutionMode %1 OriginUpperLeft
  3376. OpDecorate %struct Block
  3377. OpMemberDecorate %struct 0 Offset 0
  3378. OpDecorate %var Binding 0
  3379. %void = OpTypeVoid
  3380. %voidfn = OpTypeFunction %void
  3381. %float = OpTypeFloat 32
  3382. %struct = OpTypeStruct %float
  3383. %ptr = OpTypePointer Uniform %struct
  3384. %var = OpVariable %ptr Uniform
  3385. %1 = OpFunction %void None %voidfn
  3386. %label = OpLabel
  3387. OpReturn
  3388. OpFunctionEnd
  3389. )";
  3390. CompileSuccessfully(spirv);
  3391. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  3392. << getDiagnosticString();
  3393. }
  3394. TEST_F(ValidateDecorations, UniformMissingBindingGood) {
  3395. std::string spirv = R"(
  3396. OpCapability Shader
  3397. OpMemoryModel Logical GLSL450
  3398. OpEntryPoint Fragment %1 "main"
  3399. OpExecutionMode %1 OriginUpperLeft
  3400. OpDecorate %struct Block
  3401. OpMemberDecorate %struct 0 Offset 0
  3402. OpDecorate %var DescriptorSet 0
  3403. %void = OpTypeVoid
  3404. %voidfn = OpTypeFunction %void
  3405. %float = OpTypeFloat 32
  3406. %struct = OpTypeStruct %float
  3407. %ptr = OpTypePointer Uniform %struct
  3408. %var = OpVariable %ptr Uniform
  3409. %1 = OpFunction %void None %voidfn
  3410. %label = OpLabel
  3411. OpReturn
  3412. OpFunctionEnd
  3413. )";
  3414. CompileSuccessfully(spirv);
  3415. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  3416. << getDiagnosticString();
  3417. }
  3418. TEST_F(ValidateDecorations, UniformConstantMissingDescriptorSetGood) {
  3419. std::string spirv = R"(
  3420. OpCapability Shader
  3421. OpMemoryModel Logical GLSL450
  3422. OpEntryPoint Fragment %1 "main"
  3423. OpExecutionMode %1 OriginUpperLeft
  3424. OpDecorate %var Binding 0
  3425. %void = OpTypeVoid
  3426. %voidfn = OpTypeFunction %void
  3427. %sampler = OpTypeSampler
  3428. %ptr = OpTypePointer UniformConstant %sampler
  3429. %var = OpVariable %ptr UniformConstant
  3430. %1 = OpFunction %void None %voidfn
  3431. %label = OpLabel
  3432. OpReturn
  3433. OpFunctionEnd
  3434. )";
  3435. CompileSuccessfully(spirv);
  3436. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  3437. << getDiagnosticString();
  3438. }
  3439. TEST_F(ValidateDecorations, UniformConstantMissingBindingGood) {
  3440. std::string spirv = R"(
  3441. OpCapability Shader
  3442. OpMemoryModel Logical GLSL450
  3443. OpEntryPoint Fragment %1 "main"
  3444. OpExecutionMode %1 OriginUpperLeft
  3445. OpDecorate %var DescriptorSet 0
  3446. %void = OpTypeVoid
  3447. %voidfn = OpTypeFunction %void
  3448. %sampler = OpTypeSampler
  3449. %ptr = OpTypePointer UniformConstant %sampler
  3450. %var = OpVariable %ptr UniformConstant
  3451. %1 = OpFunction %void None %voidfn
  3452. %label = OpLabel
  3453. OpReturn
  3454. OpFunctionEnd
  3455. )";
  3456. CompileSuccessfully(spirv);
  3457. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  3458. << getDiagnosticString();
  3459. }
  3460. TEST_F(ValidateDecorations, StorageBufferMissingDescriptorSetGood) {
  3461. std::string spirv = R"(
  3462. OpCapability Shader
  3463. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3464. OpMemoryModel Logical GLSL450
  3465. OpEntryPoint Fragment %1 "main"
  3466. OpExecutionMode %1 OriginUpperLeft
  3467. OpDecorate %struct BufferBlock
  3468. OpDecorate %var Binding 0
  3469. %void = OpTypeVoid
  3470. %voidfn = OpTypeFunction %void
  3471. %float = OpTypeFloat 32
  3472. %struct = OpTypeStruct %float
  3473. %ptr = OpTypePointer StorageBuffer %struct
  3474. %var = OpVariable %ptr StorageBuffer
  3475. %1 = OpFunction %void None %voidfn
  3476. %label = OpLabel
  3477. OpReturn
  3478. OpFunctionEnd
  3479. )";
  3480. CompileSuccessfully(spirv);
  3481. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  3482. << getDiagnosticString();
  3483. }
  3484. TEST_F(ValidateDecorations, StorageBufferMissingBindingGood) {
  3485. std::string spirv = R"(
  3486. OpCapability Shader
  3487. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3488. OpMemoryModel Logical GLSL450
  3489. OpEntryPoint Fragment %1 "main"
  3490. OpExecutionMode %1 OriginUpperLeft
  3491. OpDecorate %struct BufferBlock
  3492. OpDecorate %var DescriptorSet 0
  3493. %void = OpTypeVoid
  3494. %voidfn = OpTypeFunction %void
  3495. %float = OpTypeFloat 32
  3496. %struct = OpTypeStruct %float
  3497. %ptr = OpTypePointer StorageBuffer %struct
  3498. %var = OpVariable %ptr StorageBuffer
  3499. %1 = OpFunction %void None %voidfn
  3500. %label = OpLabel
  3501. OpReturn
  3502. OpFunctionEnd
  3503. )";
  3504. CompileSuccessfully(spirv);
  3505. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  3506. << getDiagnosticString();
  3507. }
  3508. TEST_F(ValidateDecorations, StorageBufferStorageClassArrayBaseAlignmentGood) {
  3509. // Spot check buffer rules when using StorageBuffer storage class with Block
  3510. // decoration.
  3511. std::string spirv = R"(
  3512. OpCapability Shader
  3513. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3514. OpMemoryModel Logical GLSL450
  3515. OpEntryPoint Vertex %main "main"
  3516. OpSource GLSL 450
  3517. OpDecorate %_arr_float_uint_2 ArrayStride 4
  3518. OpMemberDecorate %S 0 Offset 0
  3519. OpMemberDecorate %S 1 Offset 8
  3520. OpDecorate %S Block
  3521. OpDecorate %u DescriptorSet 0
  3522. OpDecorate %u Binding 0
  3523. %void = OpTypeVoid
  3524. %3 = OpTypeFunction %void
  3525. %float = OpTypeFloat 32
  3526. %v2float = OpTypeVector %float 2
  3527. %uint = OpTypeInt 32 0
  3528. %uint_2 = OpConstant %uint 2
  3529. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  3530. %S = OpTypeStruct %v2float %_arr_float_uint_2
  3531. %_ptr_Uniform_S = OpTypePointer StorageBuffer %S
  3532. %u = OpVariable %_ptr_Uniform_S StorageBuffer
  3533. %main = OpFunction %void None %3
  3534. %5 = OpLabel
  3535. OpReturn
  3536. OpFunctionEnd
  3537. )";
  3538. CompileSuccessfully(spirv);
  3539. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
  3540. << getDiagnosticString();
  3541. }
  3542. TEST_F(ValidateDecorations, StorageBufferStorageClassArrayBadAlignmentBad) {
  3543. // Like the previous test, but with offset 7.
  3544. std::string spirv = R"(
  3545. OpCapability Shader
  3546. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3547. OpMemoryModel Logical GLSL450
  3548. OpEntryPoint Vertex %main "main"
  3549. OpSource GLSL 450
  3550. OpDecorate %_arr_float_uint_2 ArrayStride 4
  3551. OpMemberDecorate %S 0 Offset 0
  3552. OpMemberDecorate %S 1 Offset 7
  3553. OpDecorate %S Block
  3554. OpDecorate %u DescriptorSet 0
  3555. OpDecorate %u Binding 0
  3556. %void = OpTypeVoid
  3557. %3 = OpTypeFunction %void
  3558. %float = OpTypeFloat 32
  3559. %v2float = OpTypeVector %float 2
  3560. %uint = OpTypeInt 32 0
  3561. %uint_2 = OpConstant %uint 2
  3562. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  3563. %S = OpTypeStruct %v2float %_arr_float_uint_2
  3564. %_ptr_Uniform_S = OpTypePointer StorageBuffer %S
  3565. %u = OpVariable %_ptr_Uniform_S StorageBuffer
  3566. %main = OpFunction %void None %3
  3567. %5 = OpLabel
  3568. OpReturn
  3569. OpFunctionEnd
  3570. )";
  3571. CompileSuccessfully(spirv);
  3572. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3573. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  3574. EXPECT_THAT(
  3575. getDiagnosticString(),
  3576. HasSubstr(
  3577. "Structure id 3 decorated as Block for variable in StorageBuffer "
  3578. "storage class must follow standard storage buffer layout rules: "
  3579. "member 1 at offset 7 is not aligned to 4"));
  3580. }
  3581. TEST_F(ValidateDecorations, BufferBlockStandardStorageBufferLayout) {
  3582. std::string spirv = R"(
  3583. OpCapability Shader
  3584. %1 = OpExtInstImport "GLSL.std.450"
  3585. OpMemoryModel Logical GLSL450
  3586. OpEntryPoint GLCompute %main "main"
  3587. OpExecutionMode %main LocalSize 1 1 1
  3588. OpSource GLSL 430
  3589. OpMemberDecorate %F 0 Offset 0
  3590. OpMemberDecorate %F 1 Offset 8
  3591. OpDecorate %_arr_float_uint_2 ArrayStride 4
  3592. OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 48
  3593. OpMemberDecorate %O 0 Offset 0
  3594. OpMemberDecorate %O 1 Offset 16
  3595. OpMemberDecorate %O 2 Offset 24
  3596. OpMemberDecorate %O 3 Offset 32
  3597. OpMemberDecorate %O 4 ColMajor
  3598. OpMemberDecorate %O 4 Offset 48
  3599. OpMemberDecorate %O 4 MatrixStride 16
  3600. OpDecorate %_arr_O_uint_2 ArrayStride 144
  3601. OpMemberDecorate %Output 0 Offset 0
  3602. OpMemberDecorate %Output 1 Offset 8
  3603. OpMemberDecorate %Output 2 Offset 16
  3604. OpMemberDecorate %Output 3 Offset 32
  3605. OpMemberDecorate %Output 4 Offset 48
  3606. OpMemberDecorate %Output 5 Offset 52
  3607. OpMemberDecorate %Output 6 ColMajor
  3608. OpMemberDecorate %Output 6 Offset 64
  3609. OpMemberDecorate %Output 6 MatrixStride 16
  3610. OpMemberDecorate %Output 7 Offset 96
  3611. OpDecorate %Output BufferBlock
  3612. %void = OpTypeVoid
  3613. %3 = OpTypeFunction %void
  3614. %float = OpTypeFloat 32
  3615. %v2float = OpTypeVector %float 2
  3616. %v3float = OpTypeVector %float 3
  3617. %int = OpTypeInt 32 1
  3618. %uint = OpTypeInt 32 0
  3619. %v2uint = OpTypeVector %uint 2
  3620. %F = OpTypeStruct %int %v2uint
  3621. %uint_2 = OpConstant %uint 2
  3622. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  3623. %mat2v3float = OpTypeMatrix %v3float 2
  3624. %v3uint = OpTypeVector %uint 3
  3625. %mat3v3float = OpTypeMatrix %v3float 3
  3626. %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
  3627. %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
  3628. %_arr_O_uint_2 = OpTypeArray %O %uint_2
  3629. %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
  3630. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  3631. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  3632. %main = OpFunction %void None %3
  3633. %5 = OpLabel
  3634. OpReturn
  3635. OpFunctionEnd
  3636. )";
  3637. CompileSuccessfully(spirv);
  3638. EXPECT_EQ(SPV_SUCCESS,
  3639. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  3640. }
  3641. TEST_F(ValidateDecorations,
  3642. StorageBufferLayoutPermitsTightVec3ScalarPackingGood) {
  3643. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
  3644. std::string spirv = R"(
  3645. OpCapability Shader
  3646. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3647. OpMemoryModel Logical GLSL450
  3648. OpEntryPoint Vertex %main "main"
  3649. OpSource GLSL 450
  3650. OpMemberDecorate %S 0 Offset 0
  3651. OpMemberDecorate %S 1 Offset 12
  3652. OpDecorate %S Block
  3653. OpDecorate %B DescriptorSet 0
  3654. OpDecorate %B Binding 0
  3655. %void = OpTypeVoid
  3656. %3 = OpTypeFunction %void
  3657. %float = OpTypeFloat 32
  3658. %v3float = OpTypeVector %float 3
  3659. %S = OpTypeStruct %v3float %float
  3660. %_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
  3661. %B = OpVariable %_ptr_StorageBuffer_S StorageBuffer
  3662. %main = OpFunction %void None %3
  3663. %5 = OpLabel
  3664. OpReturn
  3665. OpFunctionEnd
  3666. )";
  3667. CompileSuccessfully(spirv);
  3668. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
  3669. << getDiagnosticString();
  3670. }
  3671. TEST_F(ValidateDecorations,
  3672. StorageBufferLayoutForbidsTightScalarVec3PackingBad) {
  3673. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
  3674. std::string spirv = R"(
  3675. OpCapability Shader
  3676. OpExtension "SPV_KHR_storage_buffer_storage_class"
  3677. OpMemoryModel Logical GLSL450
  3678. OpEntryPoint Vertex %main "main"
  3679. OpSource GLSL 450
  3680. OpMemberDecorate %S 0 Offset 0
  3681. OpMemberDecorate %S 1 Offset 4
  3682. OpDecorate %S Block
  3683. OpDecorate %B DescriptorSet 0
  3684. OpDecorate %B Binding 0
  3685. %void = OpTypeVoid
  3686. %3 = OpTypeFunction %void
  3687. %float = OpTypeFloat 32
  3688. %v3float = OpTypeVector %float 3
  3689. %S = OpTypeStruct %float %v3float
  3690. %_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
  3691. %B = OpVariable %_ptr_StorageBuffer_S StorageBuffer
  3692. %main = OpFunction %void None %3
  3693. %5 = OpLabel
  3694. OpReturn
  3695. OpFunctionEnd
  3696. )";
  3697. CompileSuccessfully(spirv);
  3698. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3699. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  3700. EXPECT_THAT(
  3701. getDiagnosticString(),
  3702. HasSubstr(
  3703. "Structure id 2 decorated as Block for variable in StorageBuffer "
  3704. "storage class must follow standard storage buffer layout "
  3705. "rules: member 1 at offset 4 is not aligned to 16"));
  3706. }
  3707. TEST_F(ValidateDecorations,
  3708. BlockStandardUniformBufferLayoutIncorrectOffset0Bad) {
  3709. std::string spirv = R"(
  3710. OpCapability Shader
  3711. %1 = OpExtInstImport "GLSL.std.450"
  3712. OpMemoryModel Logical GLSL450
  3713. OpEntryPoint GLCompute %main "main"
  3714. OpExecutionMode %main LocalSize 1 1 1
  3715. OpSource GLSL 430
  3716. OpMemberDecorate %F 0 Offset 0
  3717. OpMemberDecorate %F 1 Offset 8
  3718. OpDecorate %_arr_float_uint_2 ArrayStride 16
  3719. OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 48
  3720. OpMemberDecorate %O 0 Offset 0
  3721. OpMemberDecorate %O 1 Offset 16
  3722. OpMemberDecorate %O 2 Offset 24
  3723. OpMemberDecorate %O 3 Offset 33
  3724. OpMemberDecorate %O 4 ColMajor
  3725. OpMemberDecorate %O 4 Offset 80
  3726. OpMemberDecorate %O 4 MatrixStride 16
  3727. OpDecorate %_arr_O_uint_2 ArrayStride 176
  3728. OpMemberDecorate %Output 0 Offset 0
  3729. OpMemberDecorate %Output 1 Offset 8
  3730. OpMemberDecorate %Output 2 Offset 16
  3731. OpMemberDecorate %Output 3 Offset 32
  3732. OpMemberDecorate %Output 4 Offset 48
  3733. OpMemberDecorate %Output 5 Offset 64
  3734. OpMemberDecorate %Output 6 ColMajor
  3735. OpMemberDecorate %Output 6 Offset 96
  3736. OpMemberDecorate %Output 6 MatrixStride 16
  3737. OpMemberDecorate %Output 7 Offset 128
  3738. OpDecorate %Output Block
  3739. %void = OpTypeVoid
  3740. %3 = OpTypeFunction %void
  3741. %float = OpTypeFloat 32
  3742. %v2float = OpTypeVector %float 2
  3743. %v3float = OpTypeVector %float 3
  3744. %int = OpTypeInt 32 1
  3745. %uint = OpTypeInt 32 0
  3746. %v2uint = OpTypeVector %uint 2
  3747. %F = OpTypeStruct %int %v2uint
  3748. %uint_2 = OpConstant %uint 2
  3749. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  3750. %mat2v3float = OpTypeMatrix %v3float 2
  3751. %v3uint = OpTypeVector %uint 3
  3752. %mat3v3float = OpTypeMatrix %v3float 3
  3753. %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
  3754. %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
  3755. %_arr_O_uint_2 = OpTypeArray %O %uint_2
  3756. %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
  3757. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  3758. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  3759. %main = OpFunction %void None %3
  3760. %5 = OpLabel
  3761. OpReturn
  3762. OpFunctionEnd
  3763. )";
  3764. CompileSuccessfully(spirv);
  3765. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3766. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  3767. EXPECT_THAT(
  3768. getDiagnosticString(),
  3769. HasSubstr("Structure id 6 decorated as Block for variable in Uniform "
  3770. "storage class must follow standard uniform buffer layout "
  3771. "rules: member 2 at offset 152 is not aligned to 16"));
  3772. }
  3773. TEST_F(ValidateDecorations,
  3774. BlockStandardUniformBufferLayoutIncorrectOffset1Bad) {
  3775. std::string spirv = R"(
  3776. OpCapability Shader
  3777. %1 = OpExtInstImport "GLSL.std.450"
  3778. OpMemoryModel Logical GLSL450
  3779. OpEntryPoint GLCompute %main "main"
  3780. OpExecutionMode %main LocalSize 1 1 1
  3781. OpSource GLSL 430
  3782. OpMemberDecorate %F 0 Offset 0
  3783. OpMemberDecorate %F 1 Offset 8
  3784. OpDecorate %_arr_float_uint_2 ArrayStride 16
  3785. OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 48
  3786. OpMemberDecorate %O 0 Offset 0
  3787. OpMemberDecorate %O 1 Offset 16
  3788. OpMemberDecorate %O 2 Offset 32
  3789. OpMemberDecorate %O 3 Offset 64
  3790. OpMemberDecorate %O 4 ColMajor
  3791. OpMemberDecorate %O 4 Offset 80
  3792. OpMemberDecorate %O 4 MatrixStride 16
  3793. OpDecorate %_arr_O_uint_2 ArrayStride 176
  3794. OpMemberDecorate %Output 0 Offset 0
  3795. OpMemberDecorate %Output 1 Offset 8
  3796. OpMemberDecorate %Output 2 Offset 16
  3797. OpMemberDecorate %Output 3 Offset 32
  3798. OpMemberDecorate %Output 4 Offset 48
  3799. OpMemberDecorate %Output 5 Offset 71
  3800. OpMemberDecorate %Output 6 ColMajor
  3801. OpMemberDecorate %Output 6 Offset 96
  3802. OpMemberDecorate %Output 6 MatrixStride 16
  3803. OpMemberDecorate %Output 7 Offset 128
  3804. OpDecorate %Output Block
  3805. %void = OpTypeVoid
  3806. %3 = OpTypeFunction %void
  3807. %float = OpTypeFloat 32
  3808. %v2float = OpTypeVector %float 2
  3809. %v3float = OpTypeVector %float 3
  3810. %int = OpTypeInt 32 1
  3811. %uint = OpTypeInt 32 0
  3812. %v2uint = OpTypeVector %uint 2
  3813. %F = OpTypeStruct %int %v2uint
  3814. %uint_2 = OpConstant %uint 2
  3815. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  3816. %mat2v3float = OpTypeMatrix %v3float 2
  3817. %v3uint = OpTypeVector %uint 3
  3818. %mat3v3float = OpTypeMatrix %v3float 3
  3819. %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
  3820. %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
  3821. %_arr_O_uint_2 = OpTypeArray %O %uint_2
  3822. %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
  3823. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  3824. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  3825. %main = OpFunction %void None %3
  3826. %5 = OpLabel
  3827. OpReturn
  3828. OpFunctionEnd
  3829. )";
  3830. CompileSuccessfully(spirv);
  3831. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3832. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  3833. EXPECT_THAT(
  3834. getDiagnosticString(),
  3835. HasSubstr("Structure id 8 decorated as Block for variable in Uniform "
  3836. "storage class must follow standard uniform buffer layout "
  3837. "rules: member 5 at offset 71 is not aligned to 16"));
  3838. }
  3839. TEST_F(ValidateDecorations, BlockUniformBufferLayoutIncorrectArrayStrideBad) {
  3840. std::string spirv = R"(
  3841. OpCapability Shader
  3842. %1 = OpExtInstImport "GLSL.std.450"
  3843. OpMemoryModel Logical GLSL450
  3844. OpEntryPoint GLCompute %main "main"
  3845. OpExecutionMode %main LocalSize 1 1 1
  3846. OpSource GLSL 430
  3847. OpMemberDecorate %F 0 Offset 0
  3848. OpMemberDecorate %F 1 Offset 8
  3849. OpDecorate %_arr_float_uint_2 ArrayStride 16
  3850. OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 49
  3851. OpMemberDecorate %O 0 Offset 0
  3852. OpMemberDecorate %O 1 Offset 16
  3853. OpMemberDecorate %O 2 Offset 32
  3854. OpMemberDecorate %O 3 Offset 64
  3855. OpMemberDecorate %O 4 ColMajor
  3856. OpMemberDecorate %O 4 Offset 80
  3857. OpMemberDecorate %O 4 MatrixStride 16
  3858. OpDecorate %_arr_O_uint_2 ArrayStride 176
  3859. OpMemberDecorate %Output 0 Offset 0
  3860. OpMemberDecorate %Output 1 Offset 8
  3861. OpMemberDecorate %Output 2 Offset 16
  3862. OpMemberDecorate %Output 3 Offset 32
  3863. OpMemberDecorate %Output 4 Offset 48
  3864. OpMemberDecorate %Output 5 Offset 64
  3865. OpMemberDecorate %Output 6 ColMajor
  3866. OpMemberDecorate %Output 6 Offset 96
  3867. OpMemberDecorate %Output 6 MatrixStride 16
  3868. OpMemberDecorate %Output 7 Offset 128
  3869. OpDecorate %Output Block
  3870. %void = OpTypeVoid
  3871. %3 = OpTypeFunction %void
  3872. %float = OpTypeFloat 32
  3873. %v2float = OpTypeVector %float 2
  3874. %v3float = OpTypeVector %float 3
  3875. %int = OpTypeInt 32 1
  3876. %uint = OpTypeInt 32 0
  3877. %v2uint = OpTypeVector %uint 2
  3878. %F = OpTypeStruct %int %v2uint
  3879. %uint_2 = OpConstant %uint 2
  3880. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  3881. %mat2v3float = OpTypeMatrix %v3float 2
  3882. %v3uint = OpTypeVector %uint 3
  3883. %mat3v3float = OpTypeMatrix %v3float 3
  3884. %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
  3885. %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
  3886. %_arr_O_uint_2 = OpTypeArray %O %uint_2
  3887. %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
  3888. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  3889. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  3890. %main = OpFunction %void None %3
  3891. %5 = OpLabel
  3892. OpReturn
  3893. OpFunctionEnd
  3894. )";
  3895. CompileSuccessfully(spirv);
  3896. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3897. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  3898. EXPECT_THAT(
  3899. getDiagnosticString(),
  3900. HasSubstr(
  3901. "Structure id 6 decorated as Block for variable in Uniform storage "
  3902. "class must follow standard uniform buffer layout rules: member 4 "
  3903. "contains "
  3904. "an array with stride 49 not satisfying alignment to 16"));
  3905. }
  3906. TEST_F(ValidateDecorations,
  3907. BufferBlockStandardStorageBufferLayoutImproperStraddleBad) {
  3908. std::string spirv = R"(
  3909. OpCapability Shader
  3910. %1 = OpExtInstImport "GLSL.std.450"
  3911. OpMemoryModel Logical GLSL450
  3912. OpEntryPoint GLCompute %main "main"
  3913. OpExecutionMode %main LocalSize 1 1 1
  3914. OpSource GLSL 430
  3915. OpMemberDecorate %Output 0 Offset 0
  3916. OpMemberDecorate %Output 1 Offset 8
  3917. OpDecorate %Output BufferBlock
  3918. %void = OpTypeVoid
  3919. %3 = OpTypeFunction %void
  3920. %float = OpTypeFloat 32
  3921. %v3float = OpTypeVector %float 3
  3922. %Output = OpTypeStruct %float %v3float
  3923. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  3924. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  3925. %main = OpFunction %void None %3
  3926. %5 = OpLabel
  3927. OpReturn
  3928. OpFunctionEnd
  3929. )";
  3930. CompileSuccessfully(spirv);
  3931. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3932. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  3933. EXPECT_THAT(
  3934. getDiagnosticString(),
  3935. HasSubstr("Structure id 3 decorated as BufferBlock for variable in "
  3936. "Uniform storage class must follow standard storage buffer "
  3937. "layout rules: member 1 at offset 8 is not aligned to 16"));
  3938. }
  3939. TEST_F(ValidateDecorations,
  3940. BlockUniformBufferLayoutOffsetInsideArrayPaddingBad) {
  3941. // In this case the 2nd member fits entirely within the padding.
  3942. std::string spirv = R"(
  3943. OpCapability Shader
  3944. %1 = OpExtInstImport "GLSL.std.450"
  3945. OpMemoryModel Logical GLSL450
  3946. OpEntryPoint GLCompute %main "main"
  3947. OpExecutionMode %main LocalSize 1 1 1
  3948. OpSource GLSL 430
  3949. OpDecorate %_arr_float_uint_2 ArrayStride 16
  3950. OpMemberDecorate %Output 0 Offset 0
  3951. OpMemberDecorate %Output 1 Offset 20
  3952. OpDecorate %Output Block
  3953. %void = OpTypeVoid
  3954. %3 = OpTypeFunction %void
  3955. %float = OpTypeFloat 32
  3956. %uint = OpTypeInt 32 0
  3957. %v2uint = OpTypeVector %uint 2
  3958. %uint_2 = OpConstant %uint 2
  3959. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  3960. %Output = OpTypeStruct %_arr_float_uint_2 %float
  3961. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  3962. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  3963. %main = OpFunction %void None %3
  3964. %5 = OpLabel
  3965. OpReturn
  3966. OpFunctionEnd
  3967. )";
  3968. CompileSuccessfully(spirv);
  3969. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3970. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  3971. EXPECT_THAT(
  3972. getDiagnosticString(),
  3973. HasSubstr(
  3974. "Structure id 4 decorated as Block for variable in Uniform storage "
  3975. "class must follow standard uniform buffer layout rules: member 1 at "
  3976. "offset 20 overlaps previous member ending at offset 31"));
  3977. }
  3978. TEST_F(ValidateDecorations,
  3979. BlockUniformBufferLayoutOffsetInsideStructPaddingBad) {
  3980. // In this case the 2nd member fits entirely within the padding.
  3981. std::string spirv = R"(
  3982. OpCapability Shader
  3983. OpMemoryModel Logical GLSL450
  3984. OpEntryPoint GLCompute %1 "main"
  3985. OpExecutionMode %1 LocalSize 1 1 1
  3986. OpMemberDecorate %_struct_6 0 Offset 0
  3987. OpMemberDecorate %_struct_2 0 Offset 0
  3988. OpMemberDecorate %_struct_2 1 Offset 4
  3989. OpDecorate %_struct_2 Block
  3990. %void = OpTypeVoid
  3991. %4 = OpTypeFunction %void
  3992. %float = OpTypeFloat 32
  3993. %_struct_6 = OpTypeStruct %float
  3994. %_struct_2 = OpTypeStruct %_struct_6 %float
  3995. %_ptr_Uniform__struct_2 = OpTypePointer Uniform %_struct_2
  3996. %8 = OpVariable %_ptr_Uniform__struct_2 Uniform
  3997. %1 = OpFunction %void None %4
  3998. %9 = OpLabel
  3999. OpReturn
  4000. OpFunctionEnd
  4001. )";
  4002. CompileSuccessfully(spirv);
  4003. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  4004. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  4005. EXPECT_THAT(
  4006. getDiagnosticString(),
  4007. HasSubstr(
  4008. "Structure id 3 decorated as Block for variable in Uniform storage "
  4009. "class must follow standard uniform buffer layout rules: member 1 at "
  4010. "offset 4 overlaps previous member ending at offset 15"));
  4011. }
  4012. TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderGoodUniversal1_0) {
  4013. std::string spirv = R"(
  4014. OpCapability Shader
  4015. %1 = OpExtInstImport "GLSL.std.450"
  4016. OpMemoryModel Logical GLSL450
  4017. OpEntryPoint GLCompute %main "main"
  4018. OpExecutionMode %main LocalSize 1 1 1
  4019. OpMemberDecorate %Outer 0 Offset 4
  4020. OpMemberDecorate %Outer 1 Offset 0
  4021. OpDecorate %Outer Block
  4022. OpDecorate %O DescriptorSet 0
  4023. OpDecorate %O Binding 0
  4024. %void = OpTypeVoid
  4025. %3 = OpTypeFunction %void
  4026. %uint = OpTypeInt 32 0
  4027. %Outer = OpTypeStruct %uint %uint
  4028. %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
  4029. %O = OpVariable %_ptr_Uniform_Outer Uniform
  4030. %main = OpFunction %void None %3
  4031. %5 = OpLabel
  4032. OpReturn
  4033. OpFunctionEnd
  4034. )";
  4035. CompileSuccessfully(spirv);
  4036. EXPECT_EQ(SPV_SUCCESS,
  4037. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_0));
  4038. }
  4039. TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderGoodOpenGL4_5) {
  4040. std::string spirv = R"(
  4041. OpCapability Shader
  4042. %1 = OpExtInstImport "GLSL.std.450"
  4043. OpMemoryModel Logical GLSL450
  4044. OpEntryPoint GLCompute %main "main"
  4045. OpExecutionMode %main LocalSize 1 1 1
  4046. OpMemberDecorate %Outer 0 Offset 4
  4047. OpMemberDecorate %Outer 1 Offset 0
  4048. OpDecorate %Outer Block
  4049. OpDecorate %O DescriptorSet 0
  4050. OpDecorate %O Binding 0
  4051. %void = OpTypeVoid
  4052. %3 = OpTypeFunction %void
  4053. %uint = OpTypeInt 32 0
  4054. %Outer = OpTypeStruct %uint %uint
  4055. %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
  4056. %O = OpVariable %_ptr_Uniform_Outer Uniform
  4057. %main = OpFunction %void None %3
  4058. %5 = OpLabel
  4059. OpReturn
  4060. OpFunctionEnd
  4061. )";
  4062. CompileSuccessfully(spirv);
  4063. EXPECT_EQ(SPV_SUCCESS,
  4064. ValidateAndRetrieveValidationState(SPV_ENV_OPENGL_4_5));
  4065. }
  4066. TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderGoodVulkan1_1) {
  4067. std::string spirv = R"(
  4068. OpCapability Shader
  4069. %1 = OpExtInstImport "GLSL.std.450"
  4070. OpMemoryModel Logical GLSL450
  4071. OpEntryPoint GLCompute %main "main"
  4072. OpExecutionMode %main LocalSize 1 1 1
  4073. OpMemberDecorate %Outer 0 Offset 4
  4074. OpMemberDecorate %Outer 1 Offset 0
  4075. OpDecorate %Outer Block
  4076. OpDecorate %O DescriptorSet 0
  4077. OpDecorate %O Binding 0
  4078. %void = OpTypeVoid
  4079. %3 = OpTypeFunction %void
  4080. %uint = OpTypeInt 32 0
  4081. %Outer = OpTypeStruct %uint %uint
  4082. %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
  4083. %O = OpVariable %_ptr_Uniform_Outer Uniform
  4084. %main = OpFunction %void None %3
  4085. %5 = OpLabel
  4086. OpReturn
  4087. OpFunctionEnd
  4088. )";
  4089. CompileSuccessfully(spirv);
  4090. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1))
  4091. << getDiagnosticString();
  4092. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4093. }
  4094. TEST_F(ValidateDecorations, BlockLayoutOffsetOverlapBad) {
  4095. std::string spirv = R"(
  4096. OpCapability Shader
  4097. %1 = OpExtInstImport "GLSL.std.450"
  4098. OpMemoryModel Logical GLSL450
  4099. OpEntryPoint GLCompute %main "main"
  4100. OpExecutionMode %main LocalSize 1 1 1
  4101. OpMemberDecorate %Outer 0 Offset 0
  4102. OpMemberDecorate %Outer 1 Offset 16
  4103. OpMemberDecorate %Inner 0 Offset 0
  4104. OpMemberDecorate %Inner 1 Offset 16
  4105. OpDecorate %Outer Block
  4106. OpDecorate %O DescriptorSet 0
  4107. OpDecorate %O Binding 0
  4108. %void = OpTypeVoid
  4109. %3 = OpTypeFunction %void
  4110. %uint = OpTypeInt 32 0
  4111. %Inner = OpTypeStruct %uint %uint
  4112. %Outer = OpTypeStruct %Inner %uint
  4113. %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
  4114. %O = OpVariable %_ptr_Uniform_Outer Uniform
  4115. %main = OpFunction %void None %3
  4116. %5 = OpLabel
  4117. OpReturn
  4118. OpFunctionEnd
  4119. )";
  4120. CompileSuccessfully(spirv);
  4121. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  4122. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  4123. EXPECT_THAT(
  4124. getDiagnosticString(),
  4125. HasSubstr(
  4126. "Structure id 3 decorated as Block for variable in Uniform storage "
  4127. "class must follow standard uniform buffer layout rules: member 1 at "
  4128. "offset 16 overlaps previous member ending at offset 31"));
  4129. }
  4130. TEST_F(ValidateDecorations, BufferBlockEmptyStruct) {
  4131. std::string spirv = R"(
  4132. OpCapability Shader
  4133. %1 = OpExtInstImport "GLSL.std.450"
  4134. OpMemoryModel Logical GLSL450
  4135. OpEntryPoint GLCompute %main "main"
  4136. OpExecutionMode %main LocalSize 1 1 1
  4137. OpSource GLSL 430
  4138. OpMemberDecorate %Output 0 Offset 0
  4139. OpDecorate %Output BufferBlock
  4140. %void = OpTypeVoid
  4141. %3 = OpTypeFunction %void
  4142. %S = OpTypeStruct
  4143. %Output = OpTypeStruct %S
  4144. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  4145. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  4146. %main = OpFunction %void None %3
  4147. %5 = OpLabel
  4148. OpReturn
  4149. OpFunctionEnd
  4150. )";
  4151. CompileSuccessfully(spirv);
  4152. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  4153. }
  4154. TEST_F(ValidateDecorations, RowMajorMatrixTightPackingGood) {
  4155. // Row major matrix rule:
  4156. // A row-major matrix of C columns has a base alignment equal to
  4157. // the base alignment of a vector of C matrix components.
  4158. // Note: The "matrix component" is the scalar element type.
  4159. // The matrix has 3 columns and 2 rows (C=3, R=2).
  4160. // So the base alignment of b is the same as a vector of 3 floats, which is 16
  4161. // bytes. The matrix consists of two of these, and therefore occupies 2 x 16
  4162. // bytes, or 32 bytes.
  4163. //
  4164. // So the offsets can be:
  4165. // a -> 0
  4166. // b -> 16
  4167. // c -> 48
  4168. // d -> 60 ; d fits at bytes 12-15 after offset of c. Tight (vec3;float)
  4169. // packing
  4170. std::string spirv = R"(
  4171. OpCapability Shader
  4172. OpMemoryModel Logical GLSL450
  4173. OpEntryPoint Vertex %1 "main"
  4174. OpSource GLSL 450
  4175. OpMemberDecorate %_struct_2 0 Offset 0
  4176. OpMemberDecorate %_struct_2 1 RowMajor
  4177. OpMemberDecorate %_struct_2 1 Offset 16
  4178. OpMemberDecorate %_struct_2 1 MatrixStride 16
  4179. OpMemberDecorate %_struct_2 2 Offset 48
  4180. OpMemberDecorate %_struct_2 3 Offset 60
  4181. OpDecorate %_struct_2 Block
  4182. OpDecorate %3 DescriptorSet 0
  4183. OpDecorate %3 Binding 0
  4184. %void = OpTypeVoid
  4185. %5 = OpTypeFunction %void
  4186. %float = OpTypeFloat 32
  4187. %v4float = OpTypeVector %float 4
  4188. %v2float = OpTypeVector %float 2
  4189. %mat3v2float = OpTypeMatrix %v2float 3
  4190. %v3float = OpTypeVector %float 3
  4191. %_struct_2 = OpTypeStruct %v4float %mat3v2float %v3float %float
  4192. %_ptr_Uniform__struct_2 = OpTypePointer Uniform %_struct_2
  4193. %3 = OpVariable %_ptr_Uniform__struct_2 Uniform
  4194. %1 = OpFunction %void None %5
  4195. %12 = OpLabel
  4196. OpReturn
  4197. OpFunctionEnd
  4198. )";
  4199. CompileSuccessfully(spirv);
  4200. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
  4201. << getDiagnosticString();
  4202. }
  4203. TEST_F(ValidateDecorations, ArrayArrayRowMajorMatrixTightPackingGood) {
  4204. // Like the previous case, but we have an array of arrays of matrices.
  4205. // The RowMajor decoration goes on the struct member (surprisingly).
  4206. std::string spirv = R"(
  4207. OpCapability Shader
  4208. OpMemoryModel Logical GLSL450
  4209. OpEntryPoint Vertex %1 "main"
  4210. OpSource GLSL 450
  4211. OpMemberDecorate %_struct_2 0 Offset 0
  4212. OpMemberDecorate %_struct_2 1 RowMajor
  4213. OpMemberDecorate %_struct_2 1 Offset 16
  4214. OpMemberDecorate %_struct_2 1 MatrixStride 16
  4215. OpMemberDecorate %_struct_2 2 Offset 80
  4216. OpMemberDecorate %_struct_2 3 Offset 92
  4217. OpDecorate %arr_mat ArrayStride 32
  4218. OpDecorate %arr_arr_mat ArrayStride 32
  4219. OpDecorate %_struct_2 Block
  4220. OpDecorate %3 DescriptorSet 0
  4221. OpDecorate %3 Binding 0
  4222. %void = OpTypeVoid
  4223. %5 = OpTypeFunction %void
  4224. %float = OpTypeFloat 32
  4225. %v4float = OpTypeVector %float 4
  4226. %v2float = OpTypeVector %float 2
  4227. %mat3v2float = OpTypeMatrix %v2float 3
  4228. %uint = OpTypeInt 32 0
  4229. %uint_1 = OpConstant %uint 1
  4230. %uint_2 = OpConstant %uint 2
  4231. %arr_mat = OpTypeArray %mat3v2float %uint_1
  4232. %arr_arr_mat = OpTypeArray %arr_mat %uint_2
  4233. %v3float = OpTypeVector %float 3
  4234. %_struct_2 = OpTypeStruct %v4float %arr_arr_mat %v3float %float
  4235. %_ptr_Uniform__struct_2 = OpTypePointer Uniform %_struct_2
  4236. %3 = OpVariable %_ptr_Uniform__struct_2 Uniform
  4237. %1 = OpFunction %void None %5
  4238. %12 = OpLabel
  4239. OpReturn
  4240. OpFunctionEnd
  4241. )";
  4242. CompileSuccessfully(spirv);
  4243. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
  4244. << getDiagnosticString();
  4245. }
  4246. TEST_F(ValidateDecorations, ArrayArrayRowMajorMatrixNextMemberOverlapsBad) {
  4247. // Like the previous case, but the offset of member 2 overlaps the matrix.
  4248. std::string spirv = R"(
  4249. OpCapability Shader
  4250. OpMemoryModel Logical GLSL450
  4251. OpEntryPoint Vertex %1 "main"
  4252. OpSource GLSL 450
  4253. OpMemberDecorate %_struct_2 0 Offset 0
  4254. OpMemberDecorate %_struct_2 1 RowMajor
  4255. OpMemberDecorate %_struct_2 1 Offset 16
  4256. OpMemberDecorate %_struct_2 1 MatrixStride 16
  4257. OpMemberDecorate %_struct_2 2 Offset 64
  4258. OpMemberDecorate %_struct_2 3 Offset 92
  4259. OpDecorate %arr_mat ArrayStride 32
  4260. OpDecorate %arr_arr_mat ArrayStride 32
  4261. OpDecorate %_struct_2 Block
  4262. OpDecorate %3 DescriptorSet 0
  4263. OpDecorate %3 Binding 0
  4264. %void = OpTypeVoid
  4265. %5 = OpTypeFunction %void
  4266. %float = OpTypeFloat 32
  4267. %v4float = OpTypeVector %float 4
  4268. %v2float = OpTypeVector %float 2
  4269. %mat3v2float = OpTypeMatrix %v2float 3
  4270. %uint = OpTypeInt 32 0
  4271. %uint_1 = OpConstant %uint 1
  4272. %uint_2 = OpConstant %uint 2
  4273. %arr_mat = OpTypeArray %mat3v2float %uint_1
  4274. %arr_arr_mat = OpTypeArray %arr_mat %uint_2
  4275. %v3float = OpTypeVector %float 3
  4276. %_struct_2 = OpTypeStruct %v4float %arr_arr_mat %v3float %float
  4277. %_ptr_Uniform__struct_2 = OpTypePointer Uniform %_struct_2
  4278. %3 = OpVariable %_ptr_Uniform__struct_2 Uniform
  4279. %1 = OpFunction %void None %5
  4280. %12 = OpLabel
  4281. OpReturn
  4282. OpFunctionEnd
  4283. )";
  4284. CompileSuccessfully(spirv);
  4285. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  4286. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  4287. EXPECT_THAT(
  4288. getDiagnosticString(),
  4289. HasSubstr(
  4290. "Structure id 2 decorated as Block for variable in Uniform storage "
  4291. "class must follow standard uniform buffer layout rules: member 2 at "
  4292. "offset 64 overlaps previous member ending at offset 79"));
  4293. }
  4294. TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackGood) {
  4295. // Original GLSL
  4296. // #version 450
  4297. // layout (set=0,binding=0) buffer S {
  4298. // uvec3 arr[2][2]; // first 3 elements are 16 bytes, last is 12
  4299. // uint i; // Can't have offset 60 = 3x16 + 12
  4300. // } B;
  4301. // void main() {}
  4302. std::string spirv = R"(
  4303. OpCapability Shader
  4304. OpMemoryModel Logical GLSL450
  4305. OpEntryPoint Vertex %1 "main"
  4306. OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
  4307. OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
  4308. OpMemberDecorate %_struct_4 0 Offset 0
  4309. OpMemberDecorate %_struct_4 1 Offset 64
  4310. OpDecorate %_struct_4 BufferBlock
  4311. OpDecorate %5 DescriptorSet 0
  4312. OpDecorate %5 Binding 0
  4313. %void = OpTypeVoid
  4314. %7 = OpTypeFunction %void
  4315. %uint = OpTypeInt 32 0
  4316. %v3uint = OpTypeVector %uint 3
  4317. %uint_2 = OpConstant %uint 2
  4318. %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
  4319. %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
  4320. %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
  4321. %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
  4322. %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
  4323. %1 = OpFunction %void None %7
  4324. %12 = OpLabel
  4325. OpReturn
  4326. OpFunctionEnd
  4327. )";
  4328. CompileSuccessfully(spirv);
  4329. EXPECT_EQ(SPV_SUCCESS,
  4330. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  4331. }
  4332. TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackGoodScalar) {
  4333. // Original GLSL
  4334. // #version 450
  4335. // layout (set=0,binding=0) buffer S {
  4336. // uvec3 arr[2][2]; // first 3 elements are 16 bytes, last is 12
  4337. // uint i; // Can have offset 60 = 3x16 + 12
  4338. // } B;
  4339. // void main() {}
  4340. std::string spirv = R"(
  4341. OpCapability Shader
  4342. OpMemoryModel Logical GLSL450
  4343. OpEntryPoint Vertex %1 "main"
  4344. OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
  4345. OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
  4346. OpMemberDecorate %_struct_4 0 Offset 0
  4347. OpMemberDecorate %_struct_4 1 Offset 60
  4348. OpDecorate %_struct_4 BufferBlock
  4349. OpDecorate %5 DescriptorSet 0
  4350. OpDecorate %5 Binding 0
  4351. %void = OpTypeVoid
  4352. %7 = OpTypeFunction %void
  4353. %uint = OpTypeInt 32 0
  4354. %v3uint = OpTypeVector %uint 3
  4355. %uint_2 = OpConstant %uint 2
  4356. %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
  4357. %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
  4358. %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
  4359. %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
  4360. %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
  4361. %1 = OpFunction %void None %7
  4362. %12 = OpLabel
  4363. OpReturn
  4364. OpFunctionEnd
  4365. )";
  4366. options_->scalar_block_layout = true;
  4367. CompileSuccessfully(spirv);
  4368. EXPECT_EQ(SPV_SUCCESS,
  4369. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  4370. }
  4371. TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackBad) {
  4372. // Like previous but, the offset of the second member is too small.
  4373. std::string spirv = R"(
  4374. OpCapability Shader
  4375. OpMemoryModel Logical GLSL450
  4376. OpEntryPoint Vertex %1 "main"
  4377. OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
  4378. OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
  4379. OpMemberDecorate %_struct_4 0 Offset 0
  4380. OpMemberDecorate %_struct_4 1 Offset 60
  4381. OpDecorate %_struct_4 BufferBlock
  4382. OpDecorate %5 DescriptorSet 0
  4383. OpDecorate %5 Binding 0
  4384. %void = OpTypeVoid
  4385. %7 = OpTypeFunction %void
  4386. %uint = OpTypeInt 32 0
  4387. %v3uint = OpTypeVector %uint 3
  4388. %uint_2 = OpConstant %uint 2
  4389. %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
  4390. %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
  4391. %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
  4392. %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
  4393. %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
  4394. %1 = OpFunction %void None %7
  4395. %12 = OpLabel
  4396. OpReturn
  4397. OpFunctionEnd
  4398. )";
  4399. CompileSuccessfully(spirv);
  4400. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  4401. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  4402. EXPECT_THAT(getDiagnosticString(),
  4403. HasSubstr("Structure id 4 decorated as BufferBlock for variable "
  4404. "in Uniform storage class must follow standard storage "
  4405. "buffer layout rules: member 1 at offset 60 overlaps "
  4406. "previous member ending at offset 63"));
  4407. }
  4408. TEST_F(ValidateDecorations, UniformBufferArraySizeCalculationPackGood) {
  4409. // Like the corresponding buffer block case, but the array padding must
  4410. // count for the last element as well, and so the offset of the second
  4411. // member must be at least 64.
  4412. std::string spirv = R"(
  4413. OpCapability Shader
  4414. OpMemoryModel Logical GLSL450
  4415. OpEntryPoint Vertex %1 "main"
  4416. OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
  4417. OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
  4418. OpMemberDecorate %_struct_4 0 Offset 0
  4419. OpMemberDecorate %_struct_4 1 Offset 64
  4420. OpDecorate %_struct_4 Block
  4421. OpDecorate %5 DescriptorSet 0
  4422. OpDecorate %5 Binding 0
  4423. %void = OpTypeVoid
  4424. %7 = OpTypeFunction %void
  4425. %uint = OpTypeInt 32 0
  4426. %v3uint = OpTypeVector %uint 3
  4427. %uint_2 = OpConstant %uint 2
  4428. %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
  4429. %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
  4430. %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
  4431. %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
  4432. %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
  4433. %1 = OpFunction %void None %7
  4434. %12 = OpLabel
  4435. OpReturn
  4436. OpFunctionEnd
  4437. )";
  4438. CompileSuccessfully(spirv);
  4439. EXPECT_EQ(SPV_SUCCESS,
  4440. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  4441. }
  4442. TEST_F(ValidateDecorations, UniformBufferArraySizeCalculationPackBad) {
  4443. // Like previous but, the offset of the second member is too small.
  4444. std::string spirv = R"(
  4445. OpCapability Shader
  4446. OpMemoryModel Logical GLSL450
  4447. OpEntryPoint Vertex %1 "main"
  4448. OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
  4449. OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
  4450. OpMemberDecorate %_struct_4 0 Offset 0
  4451. OpMemberDecorate %_struct_4 1 Offset 60
  4452. OpDecorate %_struct_4 Block
  4453. OpDecorate %5 DescriptorSet 0
  4454. OpDecorate %5 Binding 0
  4455. %void = OpTypeVoid
  4456. %7 = OpTypeFunction %void
  4457. %uint = OpTypeInt 32 0
  4458. %v3uint = OpTypeVector %uint 3
  4459. %uint_2 = OpConstant %uint 2
  4460. %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
  4461. %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
  4462. %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
  4463. %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
  4464. %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
  4465. %1 = OpFunction %void None %7
  4466. %12 = OpLabel
  4467. OpReturn
  4468. OpFunctionEnd
  4469. )";
  4470. CompileSuccessfully(spirv);
  4471. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  4472. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  4473. EXPECT_THAT(
  4474. getDiagnosticString(),
  4475. HasSubstr(
  4476. "Structure id 4 decorated as Block for variable in Uniform storage "
  4477. "class must follow standard uniform buffer layout rules: member 1 at "
  4478. "offset 60 overlaps previous member ending at offset 63"));
  4479. }
  4480. TEST_F(ValidateDecorations, LayoutNotCheckedWhenSkipBlockLayout) {
  4481. // Checks that block layout is not verified in skipping block layout mode.
  4482. // Even for obviously wrong layout.
  4483. std::string spirv = R"(
  4484. OpCapability Shader
  4485. OpMemoryModel Logical GLSL450
  4486. OpEntryPoint Vertex %main "main"
  4487. OpSource GLSL 450
  4488. OpMemberDecorate %S 0 Offset 3 ; wrong alignment
  4489. OpMemberDecorate %S 1 Offset 3 ; same offset as before!
  4490. OpDecorate %S Block
  4491. OpDecorate %B DescriptorSet 0
  4492. OpDecorate %B Binding 0
  4493. %void = OpTypeVoid
  4494. %3 = OpTypeFunction %void
  4495. %float = OpTypeFloat 32
  4496. %v3float = OpTypeVector %float 3
  4497. %S = OpTypeStruct %float %v3float
  4498. %_ptr_Uniform_S = OpTypePointer Uniform %S
  4499. %B = OpVariable %_ptr_Uniform_S Uniform
  4500. %main = OpFunction %void None %3
  4501. %5 = OpLabel
  4502. OpReturn
  4503. OpFunctionEnd
  4504. )";
  4505. CompileSuccessfully(spirv);
  4506. spvValidatorOptionsSetSkipBlockLayout(getValidatorOptions(), true);
  4507. EXPECT_EQ(SPV_SUCCESS,
  4508. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  4509. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4510. }
  4511. TEST_F(ValidateDecorations, EntryPointVariableWrongStorageClass) {
  4512. const std::string spirv = R"(
  4513. OpCapability Shader
  4514. OpMemoryModel Logical GLSL450
  4515. OpEntryPoint Fragment %1 "func" %var
  4516. OpExecutionMode %1 OriginUpperLeft
  4517. %void = OpTypeVoid
  4518. %int = OpTypeInt 32 0
  4519. %ptr_int_Workgroup = OpTypePointer Workgroup %int
  4520. %var = OpVariable %ptr_int_Workgroup Workgroup
  4521. %func_ty = OpTypeFunction %void
  4522. %1 = OpFunction %void None %func_ty
  4523. %2 = OpLabel
  4524. OpReturn
  4525. OpFunctionEnd
  4526. )";
  4527. CompileSuccessfully(spirv);
  4528. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4529. EXPECT_THAT(getDiagnosticString(),
  4530. HasSubstr("OpEntryPoint interfaces must be OpVariables with "
  4531. "Storage Class of Input(1) or Output(3). Found Storage "
  4532. "Class 4 for Entry Point id 1."));
  4533. }
  4534. TEST_F(ValidateDecorations, VulkanMemoryModelNonCoherent) {
  4535. const std::string spirv = R"(
  4536. OpCapability Shader
  4537. OpCapability VulkanMemoryModelKHR
  4538. OpCapability Linkage
  4539. OpExtension "SPV_KHR_vulkan_memory_model"
  4540. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4541. OpMemoryModel Logical VulkanKHR
  4542. OpDecorate %1 Coherent
  4543. %2 = OpTypeInt 32 0
  4544. %3 = OpTypePointer StorageBuffer %2
  4545. %1 = OpVariable %3 StorageBuffer
  4546. )";
  4547. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4548. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4549. EXPECT_THAT(getDiagnosticString(),
  4550. HasSubstr("Coherent decoration targeting '1[%1]' is "
  4551. "banned when using the Vulkan memory model."));
  4552. }
  4553. TEST_F(ValidateDecorations, VulkanMemoryModelNoCoherentMember) {
  4554. const std::string spirv = R"(
  4555. OpCapability Shader
  4556. OpCapability VulkanMemoryModelKHR
  4557. OpCapability Linkage
  4558. OpExtension "SPV_KHR_vulkan_memory_model"
  4559. OpMemoryModel Logical VulkanKHR
  4560. OpMemberDecorate %1 0 Coherent
  4561. %2 = OpTypeInt 32 0
  4562. %1 = OpTypeStruct %2 %2
  4563. )";
  4564. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4565. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4566. EXPECT_THAT(
  4567. getDiagnosticString(),
  4568. HasSubstr(
  4569. "Coherent decoration targeting '1[%_struct_1]' (member index 0) "
  4570. "is banned when using the Vulkan memory model."));
  4571. }
  4572. TEST_F(ValidateDecorations, VulkanMemoryModelNoVolatile) {
  4573. const std::string spirv = R"(
  4574. OpCapability Shader
  4575. OpCapability VulkanMemoryModelKHR
  4576. OpCapability Linkage
  4577. OpExtension "SPV_KHR_vulkan_memory_model"
  4578. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4579. OpMemoryModel Logical VulkanKHR
  4580. OpDecorate %1 Volatile
  4581. %2 = OpTypeInt 32 0
  4582. %3 = OpTypePointer StorageBuffer %2
  4583. %1 = OpVariable %3 StorageBuffer
  4584. )";
  4585. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4586. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4587. EXPECT_THAT(getDiagnosticString(),
  4588. HasSubstr("Volatile decoration targeting '1[%1]' is banned when "
  4589. "using the Vulkan memory model."));
  4590. }
  4591. TEST_F(ValidateDecorations, VulkanMemoryModelNoVolatileMember) {
  4592. const std::string spirv = R"(
  4593. OpCapability Shader
  4594. OpCapability VulkanMemoryModelKHR
  4595. OpCapability Linkage
  4596. OpExtension "SPV_KHR_vulkan_memory_model"
  4597. OpMemoryModel Logical VulkanKHR
  4598. OpMemberDecorate %1 1 Volatile
  4599. %2 = OpTypeInt 32 0
  4600. %1 = OpTypeStruct %2 %2
  4601. )";
  4602. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4603. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4604. EXPECT_THAT(getDiagnosticString(),
  4605. HasSubstr("Volatile decoration targeting '1[%_struct_1]' (member "
  4606. "index 1) is banned when using the Vulkan memory "
  4607. "model."));
  4608. }
  4609. TEST_F(ValidateDecorations, FPRoundingModeGood) {
  4610. std::string spirv = R"(
  4611. OpCapability Shader
  4612. OpCapability Linkage
  4613. OpCapability StorageBuffer16BitAccess
  4614. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4615. OpExtension "SPV_KHR_variable_pointers"
  4616. OpExtension "SPV_KHR_16bit_storage"
  4617. OpMemoryModel Logical GLSL450
  4618. OpEntryPoint GLCompute %main "main"
  4619. OpDecorate %_ FPRoundingMode RTE
  4620. %half = OpTypeFloat 16
  4621. %float = OpTypeFloat 32
  4622. %float_1_25 = OpConstant %float 1.25
  4623. %half_ptr = OpTypePointer StorageBuffer %half
  4624. %half_ptr_var = OpVariable %half_ptr StorageBuffer
  4625. %void = OpTypeVoid
  4626. %func = OpTypeFunction %void
  4627. %main = OpFunction %void None %func
  4628. %main_entry = OpLabel
  4629. %_ = OpFConvert %half %float_1_25
  4630. OpStore %half_ptr_var %_
  4631. OpReturn
  4632. OpFunctionEnd
  4633. )";
  4634. CompileSuccessfully(spirv);
  4635. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  4636. }
  4637. TEST_F(ValidateDecorations, FPRoundingModeVectorGood) {
  4638. std::string spirv = R"(
  4639. OpCapability Shader
  4640. OpCapability Linkage
  4641. OpCapability StorageBuffer16BitAccess
  4642. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4643. OpExtension "SPV_KHR_variable_pointers"
  4644. OpExtension "SPV_KHR_16bit_storage"
  4645. OpMemoryModel Logical GLSL450
  4646. OpEntryPoint GLCompute %main "main"
  4647. OpDecorate %_ FPRoundingMode RTE
  4648. %half = OpTypeFloat 16
  4649. %float = OpTypeFloat 32
  4650. %v2half = OpTypeVector %half 2
  4651. %v2float = OpTypeVector %float 2
  4652. %float_1_25 = OpConstant %float 1.25
  4653. %floats = OpConstantComposite %v2float %float_1_25 %float_1_25
  4654. %halfs_ptr = OpTypePointer StorageBuffer %v2half
  4655. %halfs_ptr_var = OpVariable %halfs_ptr StorageBuffer
  4656. %void = OpTypeVoid
  4657. %func = OpTypeFunction %void
  4658. %main = OpFunction %void None %func
  4659. %main_entry = OpLabel
  4660. %_ = OpFConvert %v2half %floats
  4661. OpStore %halfs_ptr_var %_
  4662. OpReturn
  4663. OpFunctionEnd
  4664. )";
  4665. CompileSuccessfully(spirv);
  4666. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  4667. }
  4668. TEST_F(ValidateDecorations, FPRoundingModeNotOpFConvert) {
  4669. std::string spirv = R"(
  4670. OpCapability Shader
  4671. OpCapability Linkage
  4672. OpCapability StorageBuffer16BitAccess
  4673. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4674. OpExtension "SPV_KHR_variable_pointers"
  4675. OpExtension "SPV_KHR_16bit_storage"
  4676. OpMemoryModel Logical GLSL450
  4677. OpEntryPoint GLCompute %main "main"
  4678. OpDecorate %_ FPRoundingMode RTE
  4679. %short = OpTypeInt 16 1
  4680. %int = OpTypeInt 32 1
  4681. %int_17 = OpConstant %int 17
  4682. %short_ptr = OpTypePointer StorageBuffer %short
  4683. %short_ptr_var = OpVariable %short_ptr StorageBuffer
  4684. %void = OpTypeVoid
  4685. %func = OpTypeFunction %void
  4686. %main = OpFunction %void None %func
  4687. %main_entry = OpLabel
  4688. %_ = OpSConvert %short %int_17
  4689. OpStore %short_ptr_var %_
  4690. OpReturn
  4691. OpFunctionEnd
  4692. )";
  4693. CompileSuccessfully(spirv);
  4694. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  4695. EXPECT_THAT(getDiagnosticString(),
  4696. HasSubstr("FPRoundingMode decoration can be applied only to a "
  4697. "width-only conversion instruction for floating-point "
  4698. "object."));
  4699. }
  4700. TEST_F(ValidateDecorations, FPRoundingModeNoOpStoreGood) {
  4701. std::string spirv = R"(
  4702. OpCapability Shader
  4703. OpCapability Linkage
  4704. OpCapability StorageBuffer16BitAccess
  4705. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4706. OpExtension "SPV_KHR_variable_pointers"
  4707. OpExtension "SPV_KHR_16bit_storage"
  4708. OpMemoryModel Logical GLSL450
  4709. OpEntryPoint GLCompute %main "main"
  4710. OpDecorate %_ FPRoundingMode RTE
  4711. %half = OpTypeFloat 16
  4712. %float = OpTypeFloat 32
  4713. %float_1_25 = OpConstant %float 1.25
  4714. %half_ptr = OpTypePointer StorageBuffer %half
  4715. %half_ptr_var = OpVariable %half_ptr StorageBuffer
  4716. %void = OpTypeVoid
  4717. %func = OpTypeFunction %void
  4718. %main = OpFunction %void None %func
  4719. %main_entry = OpLabel
  4720. %_ = OpFConvert %half %float_1_25
  4721. OpReturn
  4722. OpFunctionEnd
  4723. )";
  4724. CompileSuccessfully(spirv);
  4725. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  4726. }
  4727. TEST_F(ValidateDecorations, FPRoundingModeFConvert64to16Good) {
  4728. std::string spirv = R"(
  4729. OpCapability Shader
  4730. OpCapability Linkage
  4731. OpCapability StorageBuffer16BitAccess
  4732. OpCapability Float64
  4733. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4734. OpExtension "SPV_KHR_variable_pointers"
  4735. OpExtension "SPV_KHR_16bit_storage"
  4736. OpMemoryModel Logical GLSL450
  4737. OpEntryPoint GLCompute %main "main"
  4738. OpDecorate %_ FPRoundingMode RTE
  4739. %half = OpTypeFloat 16
  4740. %double = OpTypeFloat 64
  4741. %double_1_25 = OpConstant %double 1.25
  4742. %half_ptr = OpTypePointer StorageBuffer %half
  4743. %half_ptr_var = OpVariable %half_ptr StorageBuffer
  4744. %void = OpTypeVoid
  4745. %func = OpTypeFunction %void
  4746. %main = OpFunction %void None %func
  4747. %main_entry = OpLabel
  4748. %_ = OpFConvert %half %double_1_25
  4749. OpStore %half_ptr_var %_
  4750. OpReturn
  4751. OpFunctionEnd
  4752. )";
  4753. CompileSuccessfully(spirv);
  4754. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  4755. }
  4756. TEST_F(ValidateDecorations, FPRoundingModeNotStoreInFloat16) {
  4757. std::string spirv = R"(
  4758. OpCapability Shader
  4759. OpCapability Linkage
  4760. OpCapability StorageBuffer16BitAccess
  4761. OpCapability Float64
  4762. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4763. OpExtension "SPV_KHR_variable_pointers"
  4764. OpExtension "SPV_KHR_16bit_storage"
  4765. OpMemoryModel Logical GLSL450
  4766. OpEntryPoint GLCompute %main "main"
  4767. OpDecorate %_ FPRoundingMode RTE
  4768. %float = OpTypeFloat 32
  4769. %double = OpTypeFloat 64
  4770. %double_1_25 = OpConstant %double 1.25
  4771. %float_ptr = OpTypePointer StorageBuffer %float
  4772. %float_ptr_var = OpVariable %float_ptr StorageBuffer
  4773. %void = OpTypeVoid
  4774. %func = OpTypeFunction %void
  4775. %main = OpFunction %void None %func
  4776. %main_entry = OpLabel
  4777. %_ = OpFConvert %float %double_1_25
  4778. OpStore %float_ptr_var %_
  4779. OpReturn
  4780. OpFunctionEnd
  4781. )";
  4782. CompileSuccessfully(spirv);
  4783. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  4784. EXPECT_THAT(
  4785. getDiagnosticString(),
  4786. HasSubstr("FPRoundingMode decoration can be applied only to the "
  4787. "Object operand of an OpStore storing through a "
  4788. "pointer to a 16-bit floating-point scalar or vector object."));
  4789. }
  4790. TEST_F(ValidateDecorations, FPRoundingModeMultipleOpStoreGood) {
  4791. std::string spirv = R"(
  4792. OpCapability Shader
  4793. OpCapability Linkage
  4794. OpCapability StorageBuffer16BitAccess
  4795. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4796. OpExtension "SPV_KHR_variable_pointers"
  4797. OpExtension "SPV_KHR_16bit_storage"
  4798. OpMemoryModel Logical GLSL450
  4799. OpEntryPoint GLCompute %main "main"
  4800. OpDecorate %_ FPRoundingMode RTE
  4801. %half = OpTypeFloat 16
  4802. %float = OpTypeFloat 32
  4803. %float_1_25 = OpConstant %float 1.25
  4804. %half_ptr = OpTypePointer StorageBuffer %half
  4805. %half_ptr_var_0 = OpVariable %half_ptr StorageBuffer
  4806. %half_ptr_var_1 = OpVariable %half_ptr StorageBuffer
  4807. %half_ptr_var_2 = OpVariable %half_ptr StorageBuffer
  4808. %void = OpTypeVoid
  4809. %func = OpTypeFunction %void
  4810. %main = OpFunction %void None %func
  4811. %main_entry = OpLabel
  4812. %_ = OpFConvert %half %float_1_25
  4813. OpStore %half_ptr_var_0 %_
  4814. OpStore %half_ptr_var_1 %_
  4815. OpStore %half_ptr_var_2 %_
  4816. OpReturn
  4817. OpFunctionEnd
  4818. )";
  4819. CompileSuccessfully(spirv);
  4820. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  4821. }
  4822. TEST_F(ValidateDecorations, FPRoundingModeMultipleUsesBad) {
  4823. std::string spirv = R"(
  4824. OpCapability Shader
  4825. OpCapability Linkage
  4826. OpCapability StorageBuffer16BitAccess
  4827. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4828. OpExtension "SPV_KHR_variable_pointers"
  4829. OpExtension "SPV_KHR_16bit_storage"
  4830. OpMemoryModel Logical GLSL450
  4831. OpEntryPoint GLCompute %main "main"
  4832. OpDecorate %_ FPRoundingMode RTE
  4833. %half = OpTypeFloat 16
  4834. %float = OpTypeFloat 32
  4835. %float_1_25 = OpConstant %float 1.25
  4836. %half_ptr = OpTypePointer StorageBuffer %half
  4837. %half_ptr_var_0 = OpVariable %half_ptr StorageBuffer
  4838. %half_ptr_var_1 = OpVariable %half_ptr StorageBuffer
  4839. %void = OpTypeVoid
  4840. %func = OpTypeFunction %void
  4841. %main = OpFunction %void None %func
  4842. %main_entry = OpLabel
  4843. %_ = OpFConvert %half %float_1_25
  4844. OpStore %half_ptr_var_0 %_
  4845. %result = OpFAdd %half %_ %_
  4846. OpStore %half_ptr_var_1 %_
  4847. OpReturn
  4848. OpFunctionEnd
  4849. )";
  4850. CompileSuccessfully(spirv);
  4851. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  4852. EXPECT_THAT(getDiagnosticString(),
  4853. HasSubstr("FPRoundingMode decoration can be applied only to the "
  4854. "Object operand of an OpStore."));
  4855. }
  4856. TEST_F(ValidateDecorations, VulkanFPRoundingModeGood) {
  4857. std::string spirv = R"(
  4858. OpCapability Shader
  4859. OpCapability StorageBuffer16BitAccess
  4860. %1 = OpExtInstImport "GLSL.std.450"
  4861. OpMemoryModel Logical GLSL450
  4862. OpEntryPoint GLCompute %main "main" %_
  4863. OpExecutionMode %main LocalSize 1 1 1
  4864. OpMemberDecorate %ssbo 0 Offset 0
  4865. OpDecorate %ssbo Block
  4866. OpDecorate %_ DescriptorSet 0
  4867. OpDecorate %_ Binding 0
  4868. OpDecorate %17 FPRoundingMode RTE
  4869. %void = OpTypeVoid
  4870. %3 = OpTypeFunction %void
  4871. %float = OpTypeFloat 32
  4872. %_ptr_Function_float = OpTypePointer Function %float
  4873. %float_1 = OpConstant %float 1
  4874. %half = OpTypeFloat 16
  4875. %ssbo = OpTypeStruct %half
  4876. %_ptr_StorageBuffer_ssbo = OpTypePointer StorageBuffer %ssbo
  4877. %_ = OpVariable %_ptr_StorageBuffer_ssbo StorageBuffer
  4878. %int = OpTypeInt 32 1
  4879. %int_0 = OpConstant %int 0
  4880. %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
  4881. %main = OpFunction %void None %3
  4882. %5 = OpLabel
  4883. %b = OpVariable %_ptr_Function_float Function
  4884. OpStore %b %float_1
  4885. %16 = OpLoad %float %b
  4886. %17 = OpFConvert %half %16
  4887. %19 = OpAccessChain %_ptr_StorageBuffer_half %_ %int_0
  4888. OpStore %19 %17
  4889. OpReturn
  4890. OpFunctionEnd
  4891. )";
  4892. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  4893. EXPECT_EQ(SPV_SUCCESS,
  4894. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
  4895. }
  4896. TEST_F(ValidateDecorations, VulkanFPRoundingModeBadMode) {
  4897. std::string spirv = R"(
  4898. OpCapability Shader
  4899. OpCapability StorageBuffer16BitAccess
  4900. %1 = OpExtInstImport "GLSL.std.450"
  4901. OpMemoryModel Logical GLSL450
  4902. OpEntryPoint GLCompute %main "main" %_
  4903. OpExecutionMode %main LocalSize 1 1 1
  4904. OpMemberDecorate %ssbo 0 Offset 0
  4905. OpDecorate %ssbo Block
  4906. OpDecorate %_ DescriptorSet 0
  4907. OpDecorate %_ Binding 0
  4908. OpDecorate %17 FPRoundingMode RTP
  4909. %void = OpTypeVoid
  4910. %3 = OpTypeFunction %void
  4911. %float = OpTypeFloat 32
  4912. %_ptr_Function_float = OpTypePointer Function %float
  4913. %float_1 = OpConstant %float 1
  4914. %half = OpTypeFloat 16
  4915. %ssbo = OpTypeStruct %half
  4916. %_ptr_StorageBuffer_ssbo = OpTypePointer StorageBuffer %ssbo
  4917. %_ = OpVariable %_ptr_StorageBuffer_ssbo StorageBuffer
  4918. %int = OpTypeInt 32 1
  4919. %int_0 = OpConstant %int 0
  4920. %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
  4921. %main = OpFunction %void None %3
  4922. %5 = OpLabel
  4923. %b = OpVariable %_ptr_Function_float Function
  4924. OpStore %b %float_1
  4925. %16 = OpLoad %float %b
  4926. %17 = OpFConvert %half %16
  4927. %19 = OpAccessChain %_ptr_StorageBuffer_half %_ %int_0
  4928. OpStore %19 %17
  4929. OpReturn
  4930. OpFunctionEnd
  4931. )";
  4932. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  4933. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  4934. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
  4935. EXPECT_THAT(getDiagnosticString(),
  4936. AnyVUID("VUID-StandaloneSpirv-FPRoundingMode-04675"));
  4937. EXPECT_THAT(
  4938. getDiagnosticString(),
  4939. HasSubstr("In Vulkan, the FPRoundingMode mode must only by RTE or RTZ."));
  4940. }
  4941. TEST_F(ValidateDecorations, GroupDecorateTargetsDecorationGroup) {
  4942. std::string spirv = R"(
  4943. OpCapability Shader
  4944. OpCapability Linkage
  4945. OpMemoryModel Logical GLSL450
  4946. %1 = OpDecorationGroup
  4947. OpGroupDecorate %1 %1
  4948. )";
  4949. CompileSuccessfully(spirv);
  4950. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4951. EXPECT_THAT(getDiagnosticString(),
  4952. HasSubstr("OpGroupDecorate may not target OpDecorationGroup <id> "
  4953. "'1[%1]'"));
  4954. }
  4955. TEST_F(ValidateDecorations, GroupDecorateTargetsDecorationGroup2) {
  4956. std::string spirv = R"(
  4957. OpCapability Shader
  4958. OpCapability Linkage
  4959. OpMemoryModel Logical GLSL450
  4960. %1 = OpDecorationGroup
  4961. OpGroupDecorate %1 %2 %1
  4962. %2 = OpTypeVoid
  4963. )";
  4964. CompileSuccessfully(spirv);
  4965. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4966. EXPECT_THAT(getDiagnosticString(),
  4967. HasSubstr("OpGroupDecorate may not target OpDecorationGroup <id> "
  4968. "'1[%1]'"));
  4969. }
  4970. TEST_F(ValidateDecorations, RecurseThroughRuntimeArray) {
  4971. const std::string spirv = R"(
  4972. OpCapability Shader
  4973. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4974. OpMemoryModel Logical GLSL450
  4975. OpEntryPoint GLCompute %main "main"
  4976. OpExecutionMode %main LocalSize 1 1 1
  4977. OpDecorate %outer Block
  4978. OpMemberDecorate %inner 0 Offset 0
  4979. OpMemberDecorate %inner 1 Offset 1
  4980. OpDecorate %runtime ArrayStride 16
  4981. OpMemberDecorate %outer 0 Offset 0
  4982. %int = OpTypeInt 32 0
  4983. %inner = OpTypeStruct %int %int
  4984. %runtime = OpTypeRuntimeArray %inner
  4985. %outer = OpTypeStruct %runtime
  4986. %outer_ptr = OpTypePointer StorageBuffer %outer
  4987. %var = OpVariable %outer_ptr StorageBuffer
  4988. %void = OpTypeVoid
  4989. %void_fn = OpTypeFunction %void
  4990. %main = OpFunction %void None %void_fn
  4991. %entry = OpLabel
  4992. OpReturn
  4993. OpFunctionEnd
  4994. )";
  4995. CompileSuccessfully(spirv);
  4996. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4997. EXPECT_THAT(
  4998. getDiagnosticString(),
  4999. HasSubstr(
  5000. "Structure id 3 decorated as Block for variable in StorageBuffer "
  5001. "storage class must follow standard storage buffer layout "
  5002. "rules: member 1 at offset 1 is not aligned to 4"));
  5003. }
  5004. TEST_F(ValidateDecorations, VulkanStructWithoutDecorationWithRuntimeArray) {
  5005. std::string str = R"(
  5006. OpCapability Shader
  5007. OpMemoryModel Logical GLSL450
  5008. OpEntryPoint Fragment %func "func"
  5009. OpExecutionMode %func OriginUpperLeft
  5010. OpDecorate %array_t ArrayStride 4
  5011. OpMemberDecorate %struct_t 0 Offset 0
  5012. OpMemberDecorate %struct_t 1 Offset 4
  5013. %uint_t = OpTypeInt 32 0
  5014. %array_t = OpTypeRuntimeArray %uint_t
  5015. %struct_t = OpTypeStruct %uint_t %array_t
  5016. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  5017. %2 = OpVariable %struct_ptr StorageBuffer
  5018. %void = OpTypeVoid
  5019. %func_t = OpTypeFunction %void
  5020. %func = OpFunction %void None %func_t
  5021. %1 = OpLabel
  5022. OpReturn
  5023. OpFunctionEnd
  5024. )";
  5025. CompileSuccessfully(str.c_str(), SPV_ENV_VULKAN_1_1);
  5026. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  5027. EXPECT_THAT(getDiagnosticString(),
  5028. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  5029. EXPECT_THAT(getDiagnosticString(),
  5030. HasSubstr("Vulkan, OpTypeStruct containing an OpTypeRuntimeArray "
  5031. "must be decorated with Block or BufferBlock."));
  5032. }
  5033. TEST_F(ValidateDecorations, EmptyStructAtNonZeroOffsetGood) {
  5034. const std::string spirv = R"(
  5035. OpCapability Shader
  5036. OpMemoryModel Logical GLSL450
  5037. OpEntryPoint GLCompute %main "main"
  5038. OpExecutionMode %main LocalSize 1 1 1
  5039. OpDecorate %struct Block
  5040. OpMemberDecorate %struct 0 Offset 0
  5041. OpMemberDecorate %struct 1 Offset 16
  5042. OpDecorate %var DescriptorSet 0
  5043. OpDecorate %var Binding 0
  5044. %void = OpTypeVoid
  5045. %float = OpTypeFloat 32
  5046. %empty = OpTypeStruct
  5047. %struct = OpTypeStruct %float %empty
  5048. %ptr_struct_ubo = OpTypePointer Uniform %struct
  5049. %var = OpVariable %ptr_struct_ubo Uniform
  5050. %voidfn = OpTypeFunction %void
  5051. %main = OpFunction %void None %voidfn
  5052. %entry = OpLabel
  5053. OpReturn
  5054. OpFunctionEnd
  5055. )";
  5056. CompileSuccessfully(spirv);
  5057. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5058. }
  5059. // Uniform and UniformId decorations
  5060. TEST_F(ValidateDecorations, UniformDecorationGood) {
  5061. const std::string spirv = R"(
  5062. OpCapability Shader
  5063. OpMemoryModel Logical Simple
  5064. OpEntryPoint GLCompute %main "main"
  5065. OpExecutionMode %main LocalSize 1 1 1
  5066. OpDecorate %int0 Uniform
  5067. OpDecorate %var Uniform
  5068. OpDecorate %val Uniform
  5069. %void = OpTypeVoid
  5070. %int = OpTypeInt 32 1
  5071. %int0 = OpConstantNull %int
  5072. %intptr = OpTypePointer Private %int
  5073. %var = OpVariable %intptr Private
  5074. %fn = OpTypeFunction %void
  5075. %main = OpFunction %void None %fn
  5076. %entry = OpLabel
  5077. %val = OpLoad %int %var
  5078. OpReturn
  5079. OpFunctionEnd
  5080. )";
  5081. CompileSuccessfully(spirv);
  5082. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5083. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5084. }
  5085. // Returns SPIR-V assembly for a shader that uses a given decoration
  5086. // instruction.
  5087. std::string ShaderWithUniformLikeDecoration(const std::string& inst) {
  5088. return std::string(R"(
  5089. OpCapability Shader
  5090. OpMemoryModel Logical Simple
  5091. OpEntryPoint GLCompute %main "main"
  5092. OpExecutionMode %main LocalSize 1 1 1
  5093. OpName %subgroupscope "subgroupscope"
  5094. OpName %call "call"
  5095. OpName %myfunc "myfunc"
  5096. OpName %int0 "int0"
  5097. OpName %float0 "float0"
  5098. OpName %fn "fn"
  5099. )") + inst +
  5100. R"(
  5101. %void = OpTypeVoid
  5102. %float = OpTypeFloat 32
  5103. %int = OpTypeInt 32 1
  5104. %int0 = OpConstantNull %int
  5105. %int_99 = OpConstant %int 99
  5106. %subgroupscope = OpConstant %int 3
  5107. %float0 = OpConstantNull %float
  5108. %fn = OpTypeFunction %void
  5109. %myfunc = OpFunction %void None %fn
  5110. %myfuncentry = OpLabel
  5111. OpReturn
  5112. OpFunctionEnd
  5113. %main = OpFunction %void None %fn
  5114. %entry = OpLabel
  5115. %call = OpFunctionCall %void %myfunc
  5116. OpReturn
  5117. OpFunctionEnd
  5118. )";
  5119. }
  5120. TEST_F(ValidateDecorations, UniformIdDecorationWithScopeIdV13Bad) {
  5121. const std::string spirv = ShaderWithUniformLikeDecoration(
  5122. "OpDecorateId %int0 UniformId %subgroupscope");
  5123. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5124. EXPECT_EQ(SPV_ERROR_WRONG_VERSION,
  5125. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5126. EXPECT_THAT(getDiagnosticString(),
  5127. HasSubstr("requires SPIR-V version 1.4 or later\n"
  5128. " OpDecorateId %int0 UniformId %subgroupscope"))
  5129. << spirv;
  5130. }
  5131. TEST_F(ValidateDecorations, UniformIdDecorationWithScopeIdV13BadTargetV14) {
  5132. const std::string spirv = ShaderWithUniformLikeDecoration(
  5133. "OpDecorateId %int0 UniformId %subgroupscope");
  5134. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5135. EXPECT_EQ(SPV_ERROR_WRONG_VERSION,
  5136. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5137. EXPECT_THAT(getDiagnosticString(),
  5138. HasSubstr("requires SPIR-V version 1.4 or later"));
  5139. }
  5140. TEST_F(ValidateDecorations, UniformIdDecorationWithScopeIdV14Good) {
  5141. const std::string spirv = ShaderWithUniformLikeDecoration(
  5142. "OpDecorateId %int0 UniformId %subgroupscope");
  5143. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  5144. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5145. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5146. }
  5147. TEST_F(ValidateDecorations, UniformDecorationTargetsTypeBad) {
  5148. const std::string spirv =
  5149. ShaderWithUniformLikeDecoration("OpDecorate %fn Uniform");
  5150. CompileSuccessfully(spirv);
  5151. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5152. EXPECT_THAT(getDiagnosticString(),
  5153. HasSubstr("Uniform decoration applied to a non-object"));
  5154. EXPECT_THAT(getDiagnosticString(), HasSubstr("%fn = OpTypeFunction %void"));
  5155. }
  5156. TEST_F(ValidateDecorations, UniformIdDecorationTargetsTypeBad) {
  5157. const std::string spirv = ShaderWithUniformLikeDecoration(
  5158. "OpDecorateId %fn UniformId %subgroupscope");
  5159. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  5160. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5161. EXPECT_THAT(getDiagnosticString(),
  5162. HasSubstr("UniformId decoration applied to a non-object"));
  5163. EXPECT_THAT(getDiagnosticString(), HasSubstr("%fn = OpTypeFunction %void"));
  5164. }
  5165. TEST_F(ValidateDecorations, UniformDecorationTargetsVoidValueBad) {
  5166. const std::string spirv =
  5167. ShaderWithUniformLikeDecoration("OpDecorate %call Uniform");
  5168. CompileSuccessfully(spirv);
  5169. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5170. EXPECT_THAT(getDiagnosticString(),
  5171. HasSubstr("Uniform decoration applied to a value with void type\n"
  5172. " %call = OpFunctionCall %void %myfunc"));
  5173. }
  5174. TEST_F(ValidateDecorations, UniformIdDecorationTargetsVoidValueBad) {
  5175. const std::string spirv = ShaderWithUniformLikeDecoration(
  5176. "OpDecorateId %call UniformId %subgroupscope");
  5177. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  5178. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4))
  5179. << spirv;
  5180. EXPECT_THAT(
  5181. getDiagnosticString(),
  5182. HasSubstr("UniformId decoration applied to a value with void type\n"
  5183. " %call = OpFunctionCall %void %myfunc"));
  5184. }
  5185. TEST_F(ValidateDecorations,
  5186. UniformDecorationWithScopeIdV14IdIsFloatValueIsBad) {
  5187. const std::string spirv =
  5188. ShaderWithUniformLikeDecoration("OpDecorateId %int0 UniformId %float0");
  5189. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  5190. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  5191. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5192. EXPECT_THAT(getDiagnosticString(),
  5193. HasSubstr("ConstantNull: expected scope to be a 32-bit int"));
  5194. }
  5195. TEST_F(ValidateDecorations,
  5196. UniformDecorationWithScopeIdV14IdIsInvalidIntValueBad) {
  5197. const std::string spirv =
  5198. ShaderWithUniformLikeDecoration("OpDecorateId %int0 UniformId %int_99");
  5199. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  5200. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  5201. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5202. EXPECT_THAT(
  5203. getDiagnosticString(),
  5204. HasSubstr("Invalid scope value:\n %int_99 = OpConstant %int 99\n"));
  5205. }
  5206. TEST_F(ValidateDecorations, UniformDecorationWithScopeIdV14VulkanEnv) {
  5207. const std::string spirv =
  5208. ShaderWithUniformLikeDecoration("OpDecorateId %int0 UniformId %int0");
  5209. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  5210. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  5211. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  5212. EXPECT_THAT(getDiagnosticString(),
  5213. AnyVUID("VUID-StandaloneSpirv-None-04636"));
  5214. EXPECT_THAT(getDiagnosticString(),
  5215. HasSubstr(": in Vulkan environment Execution Scope is limited to "
  5216. "Workgroup and Subgroup"));
  5217. }
  5218. TEST_F(ValidateDecorations, UniformDecorationWithWrongInstructionBad) {
  5219. const std::string spirv =
  5220. ShaderWithUniformLikeDecoration("OpDecorateId %int0 Uniform");
  5221. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_2);
  5222. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_2));
  5223. EXPECT_THAT(getDiagnosticString(),
  5224. HasSubstr("Decorations that don't take ID parameters may not be "
  5225. "used with OpDecorateId\n"
  5226. " OpDecorateId %int0 Uniform"));
  5227. }
  5228. TEST_F(ValidateDecorations, UniformIdDecorationWithWrongInstructionBad) {
  5229. const std::string spirv = ShaderWithUniformLikeDecoration(
  5230. "OpDecorate %int0 UniformId %subgroupscope");
  5231. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  5232. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5233. EXPECT_THAT(
  5234. getDiagnosticString(),
  5235. HasSubstr(
  5236. "Decorations taking ID parameters may not be used with OpDecorateId\n"
  5237. " OpDecorate %int0 UniformId %subgroupscope"));
  5238. }
  5239. TEST_F(ValidateDecorations, MultipleOffsetDecorationsOnSameID) {
  5240. std::string spirv = R"(
  5241. OpCapability Shader
  5242. OpMemoryModel Logical GLSL450
  5243. OpEntryPoint Fragment %1 "main"
  5244. OpExecutionMode %1 OriginUpperLeft
  5245. OpMemberDecorate %struct 0 Offset 0
  5246. OpMemberDecorate %struct 0 Offset 0
  5247. %void = OpTypeVoid
  5248. %voidfn = OpTypeFunction %void
  5249. %float = OpTypeFloat 32
  5250. %struct = OpTypeStruct %float
  5251. %1 = OpFunction %void None %voidfn
  5252. %label = OpLabel
  5253. OpReturn
  5254. OpFunctionEnd
  5255. )";
  5256. CompileSuccessfully(spirv);
  5257. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  5258. EXPECT_THAT(getDiagnosticString(),
  5259. HasSubstr("ID '2', member '0' decorated with Offset multiple "
  5260. "times is not allowed."));
  5261. }
  5262. TEST_F(ValidateDecorations, MultipleArrayStrideDecorationsOnSameID) {
  5263. std::string spirv = R"(
  5264. OpCapability Shader
  5265. OpMemoryModel Logical GLSL450
  5266. OpEntryPoint Fragment %1 "main"
  5267. OpExecutionMode %1 OriginUpperLeft
  5268. OpDecorate %array ArrayStride 4
  5269. OpDecorate %array ArrayStride 4
  5270. %void = OpTypeVoid
  5271. %voidfn = OpTypeFunction %void
  5272. %float = OpTypeFloat 32
  5273. %uint = OpTypeInt 32 0
  5274. %uint_4 = OpConstant %uint 4
  5275. %array = OpTypeArray %float %uint_4
  5276. %1 = OpFunction %void None %voidfn
  5277. %label = OpLabel
  5278. OpReturn
  5279. OpFunctionEnd
  5280. )";
  5281. CompileSuccessfully(spirv);
  5282. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  5283. EXPECT_THAT(getDiagnosticString(),
  5284. HasSubstr("ID '2' decorated with ArrayStride multiple "
  5285. "times is not allowed."));
  5286. }
  5287. TEST_F(ValidateDecorations, MultipleMatrixStrideDecorationsOnSameID) {
  5288. std::string spirv = R"(
  5289. OpCapability Shader
  5290. OpMemoryModel Logical GLSL450
  5291. OpEntryPoint Fragment %1 "main"
  5292. OpExecutionMode %1 OriginUpperLeft
  5293. OpMemberDecorate %struct 0 Offset 0
  5294. OpMemberDecorate %struct 0 ColMajor
  5295. OpMemberDecorate %struct 0 MatrixStride 16
  5296. OpMemberDecorate %struct 0 MatrixStride 16
  5297. %void = OpTypeVoid
  5298. %voidfn = OpTypeFunction %void
  5299. %float = OpTypeFloat 32
  5300. %fvec4 = OpTypeVector %float 4
  5301. %fmat4 = OpTypeMatrix %fvec4 4
  5302. %struct = OpTypeStruct %fmat4
  5303. %1 = OpFunction %void None %voidfn
  5304. %label = OpLabel
  5305. OpReturn
  5306. OpFunctionEnd
  5307. )";
  5308. CompileSuccessfully(spirv);
  5309. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  5310. EXPECT_THAT(getDiagnosticString(),
  5311. HasSubstr("ID '2', member '0' decorated with MatrixStride "
  5312. "multiple times is not allowed."));
  5313. }
  5314. TEST_F(ValidateDecorations, MultipleRowMajorDecorationsOnSameID) {
  5315. std::string spirv = R"(
  5316. OpCapability Shader
  5317. OpMemoryModel Logical GLSL450
  5318. OpEntryPoint Fragment %1 "main"
  5319. OpExecutionMode %1 OriginUpperLeft
  5320. OpMemberDecorate %struct 0 Offset 0
  5321. OpMemberDecorate %struct 0 MatrixStride 16
  5322. OpMemberDecorate %struct 0 RowMajor
  5323. OpMemberDecorate %struct 0 RowMajor
  5324. %void = OpTypeVoid
  5325. %voidfn = OpTypeFunction %void
  5326. %float = OpTypeFloat 32
  5327. %fvec4 = OpTypeVector %float 4
  5328. %fmat4 = OpTypeMatrix %fvec4 4
  5329. %struct = OpTypeStruct %fmat4
  5330. %1 = OpFunction %void None %voidfn
  5331. %label = OpLabel
  5332. OpReturn
  5333. OpFunctionEnd
  5334. )";
  5335. CompileSuccessfully(spirv);
  5336. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  5337. EXPECT_THAT(getDiagnosticString(),
  5338. HasSubstr("ID '2', member '0' decorated with RowMajor multiple "
  5339. "times is not allowed."));
  5340. }
  5341. TEST_F(ValidateDecorations, MultipleColMajorDecorationsOnSameID) {
  5342. std::string spirv = R"(
  5343. OpCapability Shader
  5344. OpMemoryModel Logical GLSL450
  5345. OpEntryPoint Fragment %1 "main"
  5346. OpExecutionMode %1 OriginUpperLeft
  5347. OpMemberDecorate %struct 0 Offset 0
  5348. OpMemberDecorate %struct 0 MatrixStride 16
  5349. OpMemberDecorate %struct 0 ColMajor
  5350. OpMemberDecorate %struct 0 ColMajor
  5351. %void = OpTypeVoid
  5352. %voidfn = OpTypeFunction %void
  5353. %float = OpTypeFloat 32
  5354. %fvec4 = OpTypeVector %float 4
  5355. %fmat4 = OpTypeMatrix %fvec4 4
  5356. %struct = OpTypeStruct %fmat4
  5357. %1 = OpFunction %void None %voidfn
  5358. %label = OpLabel
  5359. OpReturn
  5360. OpFunctionEnd
  5361. )";
  5362. CompileSuccessfully(spirv);
  5363. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  5364. EXPECT_THAT(getDiagnosticString(),
  5365. HasSubstr("ID '2', member '0' decorated with ColMajor multiple "
  5366. "times is not allowed."));
  5367. }
  5368. TEST_F(ValidateDecorations, RowMajorAndColMajorDecorationsOnSameID) {
  5369. std::string spirv = R"(
  5370. OpCapability Shader
  5371. OpMemoryModel Logical GLSL450
  5372. OpEntryPoint Fragment %1 "main"
  5373. OpExecutionMode %1 OriginUpperLeft
  5374. OpMemberDecorate %struct 0 Offset 0
  5375. OpMemberDecorate %struct 0 MatrixStride 16
  5376. OpMemberDecorate %struct 0 ColMajor
  5377. OpMemberDecorate %struct 0 RowMajor
  5378. %void = OpTypeVoid
  5379. %voidfn = OpTypeFunction %void
  5380. %float = OpTypeFloat 32
  5381. %fvec4 = OpTypeVector %float 4
  5382. %fmat4 = OpTypeMatrix %fvec4 4
  5383. %struct = OpTypeStruct %fmat4
  5384. %1 = OpFunction %void None %voidfn
  5385. %label = OpLabel
  5386. OpReturn
  5387. OpFunctionEnd
  5388. )";
  5389. CompileSuccessfully(spirv);
  5390. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  5391. EXPECT_THAT(getDiagnosticString(),
  5392. HasSubstr("ID '2', member '0' decorated with both RowMajor and "
  5393. "ColMajor is not allowed."));
  5394. }
  5395. TEST_F(ValidateDecorations, BlockAndBufferBlockDecorationsOnSameID) {
  5396. std::string spirv = R"(
  5397. OpCapability Shader
  5398. OpMemoryModel Logical GLSL450
  5399. OpEntryPoint Fragment %1 "main"
  5400. OpExecutionMode %1 OriginUpperLeft
  5401. OpDecorate %struct Block
  5402. OpDecorate %struct BufferBlock
  5403. OpMemberDecorate %struct 0 Offset 0
  5404. OpMemberDecorate %struct 0 MatrixStride 16
  5405. OpMemberDecorate %struct 0 RowMajor
  5406. %void = OpTypeVoid
  5407. %voidfn = OpTypeFunction %void
  5408. %float = OpTypeFloat 32
  5409. %fvec4 = OpTypeVector %float 4
  5410. %fmat4 = OpTypeMatrix %fvec4 4
  5411. %struct = OpTypeStruct %fmat4
  5412. %1 = OpFunction %void None %voidfn
  5413. %label = OpLabel
  5414. OpReturn
  5415. OpFunctionEnd
  5416. )";
  5417. CompileSuccessfully(spirv);
  5418. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  5419. EXPECT_THAT(
  5420. getDiagnosticString(),
  5421. HasSubstr(
  5422. "ID '2' decorated with both BufferBlock and Block is not allowed."));
  5423. }
  5424. std::string MakeIntegerShader(
  5425. const std::string& decoration, const std::string& inst,
  5426. const std::string& extension =
  5427. "OpExtension \"SPV_KHR_no_integer_wrap_decoration\"") {
  5428. return R"(
  5429. OpCapability Shader
  5430. OpCapability Linkage
  5431. )" + extension +
  5432. R"(
  5433. %glsl = OpExtInstImport "GLSL.std.450"
  5434. %opencl = OpExtInstImport "OpenCL.std"
  5435. OpMemoryModel Logical GLSL450
  5436. OpEntryPoint GLCompute %main "main"
  5437. OpName %entry "entry"
  5438. )" + decoration +
  5439. R"(
  5440. %void = OpTypeVoid
  5441. %voidfn = OpTypeFunction %void
  5442. %int = OpTypeInt 32 1
  5443. %zero = OpConstantNull %int
  5444. %float = OpTypeFloat 32
  5445. %float0 = OpConstantNull %float
  5446. %main = OpFunction %void None %voidfn
  5447. %entry = OpLabel
  5448. )" + inst +
  5449. R"(
  5450. OpReturn
  5451. OpFunctionEnd)";
  5452. }
  5453. // NoSignedWrap
  5454. TEST_F(ValidateDecorations, NoSignedWrapOnTypeBad) {
  5455. std::string spirv = MakeIntegerShader("OpDecorate %void NoSignedWrap", "");
  5456. CompileSuccessfully(spirv);
  5457. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5458. EXPECT_THAT(
  5459. getDiagnosticString(),
  5460. HasSubstr("NoSignedWrap decoration may not be applied to TypeVoid"));
  5461. }
  5462. TEST_F(ValidateDecorations, NoSignedWrapOnLabelBad) {
  5463. std::string spirv = MakeIntegerShader("OpDecorate %entry NoSignedWrap", "");
  5464. CompileSuccessfully(spirv);
  5465. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5466. EXPECT_THAT(getDiagnosticString(),
  5467. HasSubstr("NoSignedWrap decoration may not be applied to Label"));
  5468. }
  5469. TEST_F(ValidateDecorations, NoSignedWrapRequiresExtensionBad) {
  5470. std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5471. "%val = OpIAdd %int %zero %zero", "");
  5472. CompileSuccessfully(spirv);
  5473. EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
  5474. EXPECT_THAT(getDiagnosticString(),
  5475. HasSubstr("requires one of these extensions: "
  5476. "SPV_KHR_no_integer_wrap_decoration"));
  5477. }
  5478. TEST_F(ValidateDecorations, NoSignedWrapRequiresExtensionV13Bad) {
  5479. std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5480. "%val = OpIAdd %int %zero %zero", "");
  5481. CompileSuccessfully(spirv);
  5482. EXPECT_NE(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5483. EXPECT_THAT(getDiagnosticString(),
  5484. HasSubstr("requires one of these extensions: "
  5485. "SPV_KHR_no_integer_wrap_decoration"));
  5486. }
  5487. TEST_F(ValidateDecorations, NoSignedWrapOkInSPV14Good) {
  5488. std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5489. "%val = OpIAdd %int %zero %zero", "");
  5490. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  5491. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5492. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5493. }
  5494. TEST_F(ValidateDecorations, NoSignedWrapIAddGood) {
  5495. std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5496. "%val = OpIAdd %int %zero %zero");
  5497. CompileSuccessfully(spirv);
  5498. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5499. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5500. }
  5501. TEST_F(ValidateDecorations, NoSignedWrapISubGood) {
  5502. std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5503. "%val = OpISub %int %zero %zero");
  5504. CompileSuccessfully(spirv);
  5505. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5506. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5507. }
  5508. TEST_F(ValidateDecorations, NoSignedWrapIMulGood) {
  5509. std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5510. "%val = OpIMul %int %zero %zero");
  5511. CompileSuccessfully(spirv);
  5512. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5513. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5514. }
  5515. TEST_F(ValidateDecorations, NoSignedWrapShiftLeftLogicalGood) {
  5516. std::string spirv =
  5517. MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5518. "%val = OpShiftLeftLogical %int %zero %zero");
  5519. CompileSuccessfully(spirv);
  5520. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5521. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5522. }
  5523. TEST_F(ValidateDecorations, NoSignedWrapSNegateGood) {
  5524. std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5525. "%val = OpSNegate %int %zero");
  5526. CompileSuccessfully(spirv);
  5527. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5528. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5529. }
  5530. TEST_F(ValidateDecorations, NoSignedWrapSRemBad) {
  5531. std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5532. "%val = OpSRem %int %zero %zero");
  5533. CompileSuccessfully(spirv);
  5534. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5535. EXPECT_THAT(getDiagnosticString(),
  5536. HasSubstr("NoSignedWrap decoration may not be applied to SRem"));
  5537. }
  5538. TEST_F(ValidateDecorations, NoSignedWrapFAddBad) {
  5539. std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5540. "%val = OpFAdd %float %float0 %float0");
  5541. CompileSuccessfully(spirv);
  5542. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5543. EXPECT_THAT(getDiagnosticString(),
  5544. HasSubstr("NoSignedWrap decoration may not be applied to FAdd"));
  5545. }
  5546. TEST_F(ValidateDecorations, NoSignedWrapExtInstOpenCLGood) {
  5547. std::string spirv =
  5548. MakeIntegerShader("OpDecorate %val NoSignedWrap",
  5549. "%val = OpExtInst %int %opencl s_abs %zero");
  5550. CompileSuccessfully(spirv);
  5551. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5552. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5553. }
  5554. TEST_F(ValidateDecorations, NoSignedWrapExtInstGLSLGood) {
  5555. std::string spirv = MakeIntegerShader(
  5556. "OpDecorate %val NoSignedWrap", "%val = OpExtInst %int %glsl SAbs %zero");
  5557. CompileSuccessfully(spirv);
  5558. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5559. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5560. }
  5561. // TODO(dneto): For NoSignedWrap and NoUnsignedWrap, permit
  5562. // "OpExtInst for instruction numbers specified in the extended
  5563. // instruction-set specifications as accepting this decoration."
  5564. // NoUnignedWrap
  5565. TEST_F(ValidateDecorations, NoUnsignedWrapOnTypeBad) {
  5566. std::string spirv = MakeIntegerShader("OpDecorate %void NoUnsignedWrap", "");
  5567. CompileSuccessfully(spirv);
  5568. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5569. EXPECT_THAT(
  5570. getDiagnosticString(),
  5571. HasSubstr("NoUnsignedWrap decoration may not be applied to TypeVoid"));
  5572. }
  5573. TEST_F(ValidateDecorations, NoUnsignedWrapOnLabelBad) {
  5574. std::string spirv = MakeIntegerShader("OpDecorate %entry NoUnsignedWrap", "");
  5575. CompileSuccessfully(spirv);
  5576. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5577. EXPECT_THAT(
  5578. getDiagnosticString(),
  5579. HasSubstr("NoUnsignedWrap decoration may not be applied to Label"));
  5580. }
  5581. TEST_F(ValidateDecorations, NoUnsignedWrapRequiresExtensionBad) {
  5582. std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5583. "%val = OpIAdd %int %zero %zero", "");
  5584. CompileSuccessfully(spirv);
  5585. EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
  5586. EXPECT_THAT(getDiagnosticString(),
  5587. HasSubstr("requires one of these extensions: "
  5588. "SPV_KHR_no_integer_wrap_decoration"));
  5589. }
  5590. TEST_F(ValidateDecorations, NoUnsignedWrapRequiresExtensionV13Bad) {
  5591. std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5592. "%val = OpIAdd %int %zero %zero", "");
  5593. CompileSuccessfully(spirv);
  5594. EXPECT_NE(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5595. EXPECT_THAT(getDiagnosticString(),
  5596. HasSubstr("requires one of these extensions: "
  5597. "SPV_KHR_no_integer_wrap_decoration"));
  5598. }
  5599. TEST_F(ValidateDecorations, NoUnsignedWrapOkInSPV14Good) {
  5600. std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5601. "%val = OpIAdd %int %zero %zero", "");
  5602. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  5603. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5604. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5605. }
  5606. TEST_F(ValidateDecorations, NoUnsignedWrapIAddGood) {
  5607. std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5608. "%val = OpIAdd %int %zero %zero");
  5609. CompileSuccessfully(spirv);
  5610. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5611. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5612. }
  5613. TEST_F(ValidateDecorations, NoUnsignedWrapISubGood) {
  5614. std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5615. "%val = OpISub %int %zero %zero");
  5616. CompileSuccessfully(spirv);
  5617. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5618. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5619. }
  5620. TEST_F(ValidateDecorations, NoUnsignedWrapIMulGood) {
  5621. std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5622. "%val = OpIMul %int %zero %zero");
  5623. CompileSuccessfully(spirv);
  5624. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5625. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5626. }
  5627. TEST_F(ValidateDecorations, NoUnsignedWrapShiftLeftLogicalGood) {
  5628. std::string spirv =
  5629. MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5630. "%val = OpShiftLeftLogical %int %zero %zero");
  5631. CompileSuccessfully(spirv);
  5632. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5633. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5634. }
  5635. TEST_F(ValidateDecorations, NoUnsignedWrapSNegateGood) {
  5636. std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5637. "%val = OpSNegate %int %zero");
  5638. CompileSuccessfully(spirv);
  5639. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5640. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5641. }
  5642. TEST_F(ValidateDecorations, NoUnsignedWrapSRemBad) {
  5643. std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5644. "%val = OpSRem %int %zero %zero");
  5645. CompileSuccessfully(spirv);
  5646. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5647. EXPECT_THAT(
  5648. getDiagnosticString(),
  5649. HasSubstr("NoUnsignedWrap decoration may not be applied to SRem"));
  5650. }
  5651. TEST_F(ValidateDecorations, NoUnsignedWrapFAddBad) {
  5652. std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5653. "%val = OpFAdd %float %float0 %float0");
  5654. CompileSuccessfully(spirv);
  5655. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5656. EXPECT_THAT(
  5657. getDiagnosticString(),
  5658. HasSubstr("NoUnsignedWrap decoration may not be applied to FAdd"));
  5659. }
  5660. TEST_F(ValidateDecorations, NoUnsignedWrapExtInstOpenCLGood) {
  5661. std::string spirv =
  5662. MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5663. "%val = OpExtInst %int %opencl s_abs %zero");
  5664. CompileSuccessfully(spirv);
  5665. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5666. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5667. }
  5668. TEST_F(ValidateDecorations, NoUnsignedWrapExtInstGLSLGood) {
  5669. std::string spirv =
  5670. MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
  5671. "%val = OpExtInst %int %glsl SAbs %zero");
  5672. CompileSuccessfully(spirv);
  5673. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5674. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5675. }
  5676. TEST_F(ValidateDecorations, AliasedandRestrictBad) {
  5677. const std::string body = R"(
  5678. OpCapability Shader
  5679. %1 = OpExtInstImport "GLSL.std.450"
  5680. OpMemoryModel Logical GLSL450
  5681. OpEntryPoint GLCompute %main "main"
  5682. OpExecutionMode %main LocalSize 1 1 1
  5683. OpSource GLSL 430
  5684. OpMemberDecorate %Output 0 Offset 0
  5685. OpDecorate %Output BufferBlock
  5686. OpDecorate %dataOutput Restrict
  5687. OpDecorate %dataOutput Aliased
  5688. %void = OpTypeVoid
  5689. %3 = OpTypeFunction %void
  5690. %float = OpTypeFloat 32
  5691. %Output = OpTypeStruct %float
  5692. %_ptr_Uniform_Output = OpTypePointer Uniform %Output
  5693. %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
  5694. %main = OpFunction %void None %3
  5695. %5 = OpLabel
  5696. OpReturn
  5697. OpFunctionEnd
  5698. )";
  5699. CompileSuccessfully(body.c_str());
  5700. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5701. EXPECT_THAT(
  5702. getDiagnosticString(),
  5703. HasSubstr("decorated with both Aliased and Restrict is not allowed"));
  5704. }
  5705. // TODO(dneto): For NoUnsignedWrap and NoUnsignedWrap, permit
  5706. // "OpExtInst for instruction numbers specified in the extended
  5707. // instruction-set specifications as accepting this decoration."
  5708. TEST_F(ValidateDecorations, PSBAliasedRestrictPointerSuccess) {
  5709. const std::string body = R"(
  5710. OpCapability PhysicalStorageBufferAddresses
  5711. OpCapability Int64
  5712. OpCapability Shader
  5713. OpExtension "SPV_EXT_physical_storage_buffer"
  5714. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  5715. OpEntryPoint Fragment %main "main"
  5716. OpExecutionMode %main OriginUpperLeft
  5717. OpDecorate %val1 RestrictPointer
  5718. %uint64 = OpTypeInt 64 0
  5719. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  5720. %pptr_f = OpTypePointer Function %ptr
  5721. %void = OpTypeVoid
  5722. %voidfn = OpTypeFunction %void
  5723. %main = OpFunction %void None %voidfn
  5724. %entry = OpLabel
  5725. %val1 = OpVariable %pptr_f Function
  5726. OpReturn
  5727. OpFunctionEnd
  5728. )";
  5729. CompileSuccessfully(body.c_str());
  5730. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5731. }
  5732. TEST_F(ValidateDecorations, PSBAliasedRestrictPointerBoth) {
  5733. const std::string body = R"(
  5734. OpCapability PhysicalStorageBufferAddresses
  5735. OpCapability Int64
  5736. OpCapability Shader
  5737. OpExtension "SPV_EXT_physical_storage_buffer"
  5738. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  5739. OpEntryPoint Fragment %main "main"
  5740. OpExecutionMode %main OriginUpperLeft
  5741. OpDecorate %val1 RestrictPointer
  5742. OpDecorate %val1 AliasedPointer
  5743. %uint64 = OpTypeInt 64 0
  5744. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  5745. %pptr_f = OpTypePointer Function %ptr
  5746. %void = OpTypeVoid
  5747. %voidfn = OpTypeFunction %void
  5748. %main = OpFunction %void None %voidfn
  5749. %entry = OpLabel
  5750. %val1 = OpVariable %pptr_f Function
  5751. OpReturn
  5752. OpFunctionEnd
  5753. )";
  5754. CompileSuccessfully(body.c_str());
  5755. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5756. EXPECT_THAT(getDiagnosticString(),
  5757. HasSubstr("decorated with both AliasedPointer and "
  5758. "RestrictPointer is not allowed"));
  5759. }
  5760. TEST_F(ValidateDecorations, PSBAliasedRestrictFunctionParamSuccess) {
  5761. const std::string body = R"(
  5762. OpCapability PhysicalStorageBufferAddresses
  5763. OpCapability Int64
  5764. OpCapability Shader
  5765. OpExtension "SPV_EXT_physical_storage_buffer"
  5766. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  5767. OpEntryPoint Fragment %main "main"
  5768. OpExecutionMode %main OriginUpperLeft
  5769. OpDecorate %fparam Restrict
  5770. %uint64 = OpTypeInt 64 0
  5771. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  5772. %void = OpTypeVoid
  5773. %voidfn = OpTypeFunction %void
  5774. %fnptr = OpTypeFunction %void %ptr
  5775. %main = OpFunction %void None %voidfn
  5776. %entry = OpLabel
  5777. OpReturn
  5778. OpFunctionEnd
  5779. %fn = OpFunction %void None %fnptr
  5780. %fparam = OpFunctionParameter %ptr
  5781. %lab = OpLabel
  5782. OpReturn
  5783. OpFunctionEnd
  5784. )";
  5785. CompileSuccessfully(body.c_str());
  5786. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5787. }
  5788. TEST_F(ValidateDecorations, PSBAliasedRestrictFunctionParamBoth) {
  5789. const std::string body = R"(
  5790. OpCapability PhysicalStorageBufferAddresses
  5791. OpCapability Int64
  5792. OpCapability Shader
  5793. OpExtension "SPV_EXT_physical_storage_buffer"
  5794. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  5795. OpEntryPoint Fragment %main "main"
  5796. OpExecutionMode %main OriginUpperLeft
  5797. OpDecorate %fparam Restrict
  5798. OpDecorate %fparam Aliased
  5799. %uint64 = OpTypeInt 64 0
  5800. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  5801. %void = OpTypeVoid
  5802. %voidfn = OpTypeFunction %void
  5803. %fnptr = OpTypeFunction %void %ptr
  5804. %main = OpFunction %void None %voidfn
  5805. %entry = OpLabel
  5806. OpReturn
  5807. OpFunctionEnd
  5808. %fn = OpFunction %void None %fnptr
  5809. %fparam = OpFunctionParameter %ptr
  5810. %lab = OpLabel
  5811. OpReturn
  5812. OpFunctionEnd
  5813. )";
  5814. CompileSuccessfully(body.c_str());
  5815. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5816. EXPECT_THAT(
  5817. getDiagnosticString(),
  5818. HasSubstr("decorated with both Aliased and Restrict is not allowed"));
  5819. }
  5820. TEST_F(ValidateDecorations, PSBFPRoundingModeSuccess) {
  5821. std::string spirv = R"(
  5822. OpCapability PhysicalStorageBufferAddresses
  5823. OpCapability Shader
  5824. OpCapability Linkage
  5825. OpCapability StorageBuffer16BitAccess
  5826. OpExtension "SPV_EXT_physical_storage_buffer"
  5827. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5828. OpExtension "SPV_KHR_variable_pointers"
  5829. OpExtension "SPV_KHR_16bit_storage"
  5830. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  5831. OpEntryPoint GLCompute %main "main"
  5832. OpDecorate %_ FPRoundingMode RTE
  5833. OpDecorate %half_ptr_var AliasedPointer
  5834. %half = OpTypeFloat 16
  5835. %float = OpTypeFloat 32
  5836. %float_1_25 = OpConstant %float 1.25
  5837. %half_ptr = OpTypePointer PhysicalStorageBuffer %half
  5838. %half_pptr_f = OpTypePointer Function %half_ptr
  5839. %void = OpTypeVoid
  5840. %func = OpTypeFunction %void
  5841. %main = OpFunction %void None %func
  5842. %main_entry = OpLabel
  5843. %half_ptr_var = OpVariable %half_pptr_f Function
  5844. %val1 = OpLoad %half_ptr %half_ptr_var
  5845. %_ = OpFConvert %half %float_1_25
  5846. OpStore %val1 %_ Aligned 2
  5847. OpReturn
  5848. OpFunctionEnd
  5849. )";
  5850. CompileSuccessfully(spirv);
  5851. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  5852. }
  5853. TEST_F(ValidateDecorations, InvalidStraddle) {
  5854. const std::string spirv = R"(
  5855. OpCapability Shader
  5856. OpMemoryModel Logical GLSL450
  5857. OpEntryPoint GLCompute %main "main"
  5858. OpExecutionMode %main LocalSize 1 1 1
  5859. OpMemberDecorate %inner_struct 0 Offset 0
  5860. OpMemberDecorate %inner_struct 1 Offset 4
  5861. OpDecorate %outer_struct Block
  5862. OpMemberDecorate %outer_struct 0 Offset 0
  5863. OpMemberDecorate %outer_struct 1 Offset 8
  5864. OpDecorate %var DescriptorSet 0
  5865. OpDecorate %var Binding 0
  5866. %void = OpTypeVoid
  5867. %float = OpTypeFloat 32
  5868. %float2 = OpTypeVector %float 2
  5869. %inner_struct = OpTypeStruct %float %float2
  5870. %outer_struct = OpTypeStruct %float2 %inner_struct
  5871. %ptr_ssbo_outer = OpTypePointer StorageBuffer %outer_struct
  5872. %var = OpVariable %ptr_ssbo_outer StorageBuffer
  5873. %void_fn = OpTypeFunction %void
  5874. %main = OpFunction %void None %void_fn
  5875. %entry = OpLabel
  5876. OpReturn
  5877. OpFunctionEnd
  5878. )";
  5879. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  5880. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  5881. EXPECT_THAT(getDiagnosticString(),
  5882. HasSubstr("Structure id 2 decorated as Block for variable in "
  5883. "StorageBuffer storage class must follow relaxed "
  5884. "storage buffer layout rules: member 1 is an "
  5885. "improperly straddling vector at offset 12"));
  5886. }
  5887. TEST_F(ValidateDecorations, DescriptorArray) {
  5888. const std::string spirv = R"(
  5889. OpCapability Shader
  5890. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5891. OpMemoryModel Logical GLSL450
  5892. OpEntryPoint GLCompute %main "main"
  5893. OpExecutionMode %main LocalSize 1 1 1
  5894. OpDecorate %struct Block
  5895. OpMemberDecorate %struct 0 Offset 0
  5896. OpMemberDecorate %struct 1 Offset 1
  5897. OpDecorate %var DescriptorSet 0
  5898. OpDecorate %var Binding 0
  5899. %void = OpTypeVoid
  5900. %float = OpTypeFloat 32
  5901. %int = OpTypeInt 32 0
  5902. %int_2 = OpConstant %int 2
  5903. %float2 = OpTypeVector %float 2
  5904. %struct = OpTypeStruct %float %float2
  5905. %struct_array = OpTypeArray %struct %int_2
  5906. %ptr_ssbo_array = OpTypePointer StorageBuffer %struct_array
  5907. %var = OpVariable %ptr_ssbo_array StorageBuffer
  5908. %void_fn = OpTypeFunction %void
  5909. %main = OpFunction %void None %void_fn
  5910. %entry = OpLabel
  5911. OpReturn
  5912. OpFunctionEnd
  5913. )";
  5914. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  5915. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  5916. EXPECT_THAT(getDiagnosticString(),
  5917. HasSubstr("Structure id 2 decorated as Block for variable in "
  5918. "StorageBuffer storage class must follow standard "
  5919. "storage buffer layout rules: member 1 at offset 1 is "
  5920. "not aligned to 8"));
  5921. }
  5922. TEST_F(ValidateDecorations, DescriptorRuntimeArray) {
  5923. const std::string spirv = R"(
  5924. OpCapability Shader
  5925. OpCapability RuntimeDescriptorArrayEXT
  5926. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5927. OpExtension "SPV_EXT_descriptor_indexing"
  5928. OpMemoryModel Logical GLSL450
  5929. OpEntryPoint GLCompute %main "main"
  5930. OpExecutionMode %main LocalSize 1 1 1
  5931. OpDecorate %struct Block
  5932. OpMemberDecorate %struct 0 Offset 0
  5933. OpMemberDecorate %struct 1 Offset 1
  5934. OpDecorate %var DescriptorSet 0
  5935. OpDecorate %var Binding 0
  5936. %void = OpTypeVoid
  5937. %float = OpTypeFloat 32
  5938. %int = OpTypeInt 32 0
  5939. %float2 = OpTypeVector %float 2
  5940. %struct = OpTypeStruct %float %float2
  5941. %struct_array = OpTypeRuntimeArray %struct
  5942. %ptr_ssbo_array = OpTypePointer StorageBuffer %struct_array
  5943. %var = OpVariable %ptr_ssbo_array StorageBuffer
  5944. %void_fn = OpTypeFunction %void
  5945. %main = OpFunction %void None %void_fn
  5946. %entry = OpLabel
  5947. OpReturn
  5948. OpFunctionEnd
  5949. )";
  5950. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  5951. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  5952. EXPECT_THAT(getDiagnosticString(),
  5953. HasSubstr("Structure id 2 decorated as Block for variable in "
  5954. "StorageBuffer storage class must follow standard "
  5955. "storage buffer layout rules: member 1 at offset 1 is "
  5956. "not aligned to 8"));
  5957. }
  5958. TEST_F(ValidateDecorations, MultiDimensionalArray) {
  5959. const std::string spirv = R"(
  5960. OpCapability Shader
  5961. OpMemoryModel Logical GLSL450
  5962. OpEntryPoint GLCompute %main "main"
  5963. OpExecutionMode %main LocalSize 1 1 1
  5964. OpDecorate %struct Block
  5965. OpMemberDecorate %struct 0 Offset 0
  5966. OpDecorate %array_4 ArrayStride 4
  5967. OpDecorate %array_3 ArrayStride 48
  5968. OpDecorate %var DescriptorSet 0
  5969. OpDecorate %var Binding 0
  5970. %void = OpTypeVoid
  5971. %int = OpTypeInt 32 0
  5972. %int_3 = OpConstant %int 3
  5973. %int_4 = OpConstant %int 4
  5974. %array_4 = OpTypeArray %int %int_4
  5975. %array_3 = OpTypeArray %array_4 %int_3
  5976. %struct = OpTypeStruct %array_3
  5977. %ptr_struct = OpTypePointer Uniform %struct
  5978. %var = OpVariable %ptr_struct Uniform
  5979. %void_fn = OpTypeFunction %void
  5980. %main = OpFunction %void None %void_fn
  5981. %entry = OpLabel
  5982. OpReturn
  5983. OpFunctionEnd
  5984. )";
  5985. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  5986. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  5987. EXPECT_THAT(getDiagnosticString(),
  5988. HasSubstr("Structure id 2 decorated as Block for variable in "
  5989. "Uniform storage class must follow standard uniform "
  5990. "buffer layout rules: member 0 contains an array with "
  5991. "stride 4 not satisfying alignment to 16"));
  5992. }
  5993. TEST_F(ValidateDecorations, ImproperStraddleInArray) {
  5994. const std::string spirv = R"(
  5995. OpCapability Shader
  5996. OpMemoryModel Logical GLSL450
  5997. OpEntryPoint GLCompute %main "main"
  5998. OpExecutionMode %main LocalSize 1 1 1
  5999. OpDecorate %struct Block
  6000. OpMemberDecorate %struct 0 Offset 0
  6001. OpDecorate %array ArrayStride 24
  6002. OpMemberDecorate %inner 0 Offset 0
  6003. OpMemberDecorate %inner 1 Offset 4
  6004. OpMemberDecorate %inner 2 Offset 12
  6005. OpMemberDecorate %inner 3 Offset 16
  6006. OpDecorate %var DescriptorSet 0
  6007. OpDecorate %var Binding 0
  6008. %void = OpTypeVoid
  6009. %int = OpTypeInt 32 0
  6010. %int_2 = OpConstant %int 2
  6011. %int2 = OpTypeVector %int 2
  6012. %inner = OpTypeStruct %int %int2 %int %int
  6013. %array = OpTypeArray %inner %int_2
  6014. %struct = OpTypeStruct %array
  6015. %ptr_struct = OpTypePointer StorageBuffer %struct
  6016. %var = OpVariable %ptr_struct StorageBuffer
  6017. %void_fn = OpTypeFunction %void
  6018. %main = OpFunction %void None %void_fn
  6019. %entry = OpLabel
  6020. OpReturn
  6021. OpFunctionEnd
  6022. )";
  6023. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  6024. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  6025. EXPECT_THAT(getDiagnosticString(),
  6026. HasSubstr("Structure id 4 decorated as Block for variable in "
  6027. "StorageBuffer storage class must follow relaxed "
  6028. "storage buffer layout rules: member 1 is an "
  6029. "improperly straddling vector at offset 28"));
  6030. }
  6031. TEST_F(ValidateDecorations, LargeArray) {
  6032. const std::string spirv = R"(
  6033. OpCapability Shader
  6034. OpMemoryModel Logical GLSL450
  6035. OpEntryPoint GLCompute %main "main"
  6036. OpExecutionMode %main LocalSize 1 1 1
  6037. OpDecorate %struct Block
  6038. OpMemberDecorate %struct 0 Offset 0
  6039. OpDecorate %array ArrayStride 24
  6040. OpMemberDecorate %inner 0 Offset 0
  6041. OpMemberDecorate %inner 1 Offset 8
  6042. OpMemberDecorate %inner 2 Offset 16
  6043. OpMemberDecorate %inner 3 Offset 20
  6044. OpDecorate %var DescriptorSet 0
  6045. OpDecorate %var Binding 0
  6046. %void = OpTypeVoid
  6047. %int = OpTypeInt 32 0
  6048. %int_2000000 = OpConstant %int 2000000
  6049. %int2 = OpTypeVector %int 2
  6050. %inner = OpTypeStruct %int %int2 %int %int
  6051. %array = OpTypeArray %inner %int_2000000
  6052. %struct = OpTypeStruct %array
  6053. %ptr_struct = OpTypePointer StorageBuffer %struct
  6054. %var = OpVariable %ptr_struct StorageBuffer
  6055. %void_fn = OpTypeFunction %void
  6056. %main = OpFunction %void None %void_fn
  6057. %entry = OpLabel
  6058. OpReturn
  6059. OpFunctionEnd
  6060. )";
  6061. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  6062. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  6063. }
  6064. // NonWritable
  6065. // Returns a SPIR-V shader module with variables in various storage classes,
  6066. // parameterizable by which ID should be decorated as NonWritable.
  6067. std::string ShaderWithNonWritableTarget(const std::string& target,
  6068. bool member_decorate = false) {
  6069. const std::string decoration_inst =
  6070. std::string(member_decorate ? "OpMemberDecorate " : "OpDecorate ") +
  6071. target + (member_decorate ? " 0" : "");
  6072. return std::string(R"(
  6073. OpCapability Shader
  6074. OpCapability RuntimeDescriptorArrayEXT
  6075. OpExtension "SPV_EXT_descriptor_indexing"
  6076. OpExtension "SPV_KHR_storage_buffer_storage_class"
  6077. OpMemoryModel Logical GLSL450
  6078. OpEntryPoint Vertex %main "main"
  6079. OpName %label "label"
  6080. OpName %param_f "param_f"
  6081. OpName %param_p "param_p"
  6082. OpName %_ptr_imstor "_ptr_imstor"
  6083. OpName %_ptr_imsam "_ptr_imsam"
  6084. OpName %var_wg "var_wg"
  6085. OpName %var_imsam "var_imsam"
  6086. OpName %var_priv "var_priv"
  6087. OpName %var_func "var_func"
  6088. OpName %simple_struct "simple_struct"
  6089. OpDecorate %struct_b Block
  6090. OpDecorate %struct_b_rtarr Block
  6091. OpMemberDecorate %struct_b 0 Offset 0
  6092. OpMemberDecorate %struct_b_rtarr 0 Offset 0
  6093. OpDecorate %rtarr ArrayStride 4
  6094. )") + decoration_inst +
  6095. R"( NonWritable
  6096. %void = OpTypeVoid
  6097. %void_fn = OpTypeFunction %void
  6098. %float = OpTypeFloat 32
  6099. %float_0 = OpConstant %float 0
  6100. %int = OpTypeInt 32 0
  6101. %int_2 = OpConstant %int 2
  6102. %struct_b = OpTypeStruct %float
  6103. %rtarr = OpTypeRuntimeArray %float
  6104. %struct_b_rtarr = OpTypeStruct %rtarr
  6105. %simple_struct = OpTypeStruct %float
  6106. ; storage image
  6107. %imstor = OpTypeImage %float 2D 0 0 0 2 R32f
  6108. ; sampled image
  6109. %imsam = OpTypeImage %float 2D 0 0 0 1 R32f
  6110. %array_imstor = OpTypeArray %imstor %int_2
  6111. %rta_imstor = OpTypeRuntimeArray %imstor
  6112. %_ptr_Uniform_stb = OpTypePointer Uniform %struct_b
  6113. %_ptr_StorageBuffer_stb = OpTypePointer StorageBuffer %struct_b
  6114. %_ptr_StorageBuffer_stb_rtarr = OpTypePointer StorageBuffer %struct_b_rtarr
  6115. %_ptr_Workgroup = OpTypePointer Workgroup %float
  6116. %_ptr_Private = OpTypePointer Private %float
  6117. %_ptr_Function = OpTypePointer Function %float
  6118. %_ptr_imstor = OpTypePointer UniformConstant %imstor
  6119. %_ptr_imsam = OpTypePointer UniformConstant %imsam
  6120. %_ptr_array_imstor = OpTypePointer UniformConstant %array_imstor
  6121. %_ptr_rta_imstor = OpTypePointer UniformConstant %rta_imstor
  6122. %extra_fn = OpTypeFunction %void %float %_ptr_Private %_ptr_imstor
  6123. %var_ubo = OpVariable %_ptr_Uniform_stb Uniform
  6124. %var_ssbo_sb = OpVariable %_ptr_StorageBuffer_stb StorageBuffer
  6125. %var_ssbo_sb_rtarr = OpVariable %_ptr_StorageBuffer_stb_rtarr StorageBuffer
  6126. %var_wg = OpVariable %_ptr_Workgroup Workgroup
  6127. %var_priv = OpVariable %_ptr_Private Private
  6128. %var_imstor = OpVariable %_ptr_imstor UniformConstant
  6129. %var_imsam = OpVariable %_ptr_imsam UniformConstant
  6130. %var_array_imstor = OpVariable %_ptr_array_imstor UniformConstant
  6131. %var_rta_imstor = OpVariable %_ptr_rta_imstor UniformConstant
  6132. %helper = OpFunction %void None %extra_fn
  6133. %param_f = OpFunctionParameter %float
  6134. %param_p = OpFunctionParameter %_ptr_Private
  6135. %param_pimstor = OpFunctionParameter %_ptr_imstor
  6136. %helper_label = OpLabel
  6137. %helper_func_var = OpVariable %_ptr_Function Function
  6138. OpReturn
  6139. OpFunctionEnd
  6140. %main = OpFunction %void None %void_fn
  6141. %label = OpLabel
  6142. %var_func = OpVariable %_ptr_Function Function
  6143. OpReturn
  6144. OpFunctionEnd
  6145. )";
  6146. }
  6147. TEST_F(ValidateDecorations, NonWritableLabelTargetBad) {
  6148. std::string spirv = ShaderWithNonWritableTarget("%label");
  6149. CompileSuccessfully(spirv);
  6150. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6151. EXPECT_THAT(getDiagnosticString(),
  6152. HasSubstr("must be a memory object declaration"));
  6153. }
  6154. TEST_F(ValidateDecorations, NonWritableTypeTargetBad) {
  6155. std::string spirv = ShaderWithNonWritableTarget("%void");
  6156. CompileSuccessfully(spirv);
  6157. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6158. EXPECT_THAT(getDiagnosticString(),
  6159. HasSubstr("must be a memory object declaration"));
  6160. }
  6161. TEST_F(ValidateDecorations, NonWritableValueTargetBad) {
  6162. std::string spirv = ShaderWithNonWritableTarget("%float_0");
  6163. CompileSuccessfully(spirv);
  6164. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6165. EXPECT_THAT(getDiagnosticString(),
  6166. HasSubstr("must be a memory object declaration"));
  6167. }
  6168. TEST_F(ValidateDecorations, NonWritableValueParamBad) {
  6169. std::string spirv = ShaderWithNonWritableTarget("%param_f");
  6170. CompileSuccessfully(spirv);
  6171. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6172. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a pointer type"));
  6173. }
  6174. TEST_F(ValidateDecorations, NonWritablePointerParamButWrongTypeBad) {
  6175. std::string spirv = ShaderWithNonWritableTarget("%param_p");
  6176. CompileSuccessfully(spirv);
  6177. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6178. EXPECT_THAT(
  6179. getDiagnosticString(),
  6180. HasSubstr(
  6181. "Target of NonWritable decoration is invalid: must "
  6182. "point to a storage image, uniform block, or storage "
  6183. "buffer\n %param_p = OpFunctionParameter %_ptr_Private_float"));
  6184. }
  6185. TEST_F(ValidateDecorations, NonWritablePointerParamStorageImageGood) {
  6186. std::string spirv = ShaderWithNonWritableTarget("%param_pimstor");
  6187. CompileSuccessfully(spirv);
  6188. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6189. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6190. }
  6191. TEST_F(ValidateDecorations, NonWritableVarStorageImageGood) {
  6192. std::string spirv = ShaderWithNonWritableTarget("%var_imstor");
  6193. CompileSuccessfully(spirv);
  6194. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6195. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6196. }
  6197. TEST_F(ValidateDecorations, NonWritableVarSampledImageBad) {
  6198. std::string spirv = ShaderWithNonWritableTarget("%var_imsam");
  6199. CompileSuccessfully(spirv);
  6200. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6201. EXPECT_THAT(getDiagnosticString(),
  6202. HasSubstr("Target of NonWritable decoration is invalid: must "
  6203. "point to a storage image, uniform block, or storage "
  6204. "buffer\n %var_imsam"));
  6205. }
  6206. TEST_F(ValidateDecorations, NonWritableVarUboGood) {
  6207. std::string spirv = ShaderWithNonWritableTarget("%var_ubo");
  6208. CompileSuccessfully(spirv);
  6209. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6210. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6211. }
  6212. TEST_F(ValidateDecorations, NonWritableVarSsboInUniformGood) {
  6213. const std::string spirv = R"(
  6214. OpCapability Shader
  6215. OpMemoryModel Logical GLSL450
  6216. OpEntryPoint Vertex %main "main"
  6217. OpDecorate %struct_bb BufferBlock
  6218. OpMemberDecorate %struct_bb 0 Offset 0
  6219. OpDecorate %var_ssbo_u NonWritable
  6220. %void = OpTypeVoid
  6221. %void_fn = OpTypeFunction %void
  6222. %float = OpTypeFloat 32
  6223. %struct_bb = OpTypeStruct %float
  6224. %_ptr_Uniform_stbb = OpTypePointer Uniform %struct_bb
  6225. %var_ssbo_u = OpVariable %_ptr_Uniform_stbb Uniform
  6226. %main = OpFunction %void None %void_fn
  6227. %label = OpLabel
  6228. OpReturn
  6229. OpFunctionEnd
  6230. )";
  6231. CompileSuccessfully(spirv);
  6232. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6233. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6234. }
  6235. TEST_F(ValidateDecorations, NonWritableVarSsboInStorageBufferGood) {
  6236. std::string spirv = ShaderWithNonWritableTarget("%var_ssbo_sb");
  6237. CompileSuccessfully(spirv);
  6238. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6239. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6240. }
  6241. TEST_F(ValidateDecorations, NonWritableMemberOfSsboInStorageBufferGood) {
  6242. std::string spirv = ShaderWithNonWritableTarget("%struct_b_rtarr", true);
  6243. CompileSuccessfully(spirv);
  6244. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6245. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6246. }
  6247. TEST_F(ValidateDecorations, NonWritableMemberOfStructGood) {
  6248. std::string spirv = ShaderWithNonWritableTarget("%simple_struct", true);
  6249. CompileSuccessfully(spirv);
  6250. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6251. }
  6252. TEST_F(ValidateDecorations, NonWritableVarWorkgroupBad) {
  6253. std::string spirv = ShaderWithNonWritableTarget("%var_wg");
  6254. CompileSuccessfully(spirv);
  6255. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6256. EXPECT_THAT(getDiagnosticString(),
  6257. HasSubstr("Target of NonWritable decoration is invalid: must "
  6258. "point to a storage image, uniform block, or storage "
  6259. "buffer\n %var_wg"));
  6260. }
  6261. TEST_F(ValidateDecorations, NonWritableVarWorkgroupV14Bad) {
  6262. std::string spirv = ShaderWithNonWritableTarget("%var_wg");
  6263. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6264. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6265. EXPECT_THAT(getDiagnosticString(),
  6266. HasSubstr("Target of NonWritable decoration is invalid: must "
  6267. "point to a storage image, uniform block, storage "
  6268. "buffer, or variable in Private or Function storage "
  6269. "class\n %var_wg"));
  6270. }
  6271. TEST_F(ValidateDecorations, NonWritableVarPrivateBad) {
  6272. std::string spirv = ShaderWithNonWritableTarget("%var_priv");
  6273. CompileSuccessfully(spirv);
  6274. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6275. EXPECT_THAT(getDiagnosticString(),
  6276. HasSubstr("Target of NonWritable decoration is invalid: must "
  6277. "point to a storage image, uniform block, or storage "
  6278. "buffer\n %var_priv"));
  6279. }
  6280. TEST_F(ValidateDecorations, NonWritableVarPrivateV13Bad) {
  6281. std::string spirv = ShaderWithNonWritableTarget("%var_priv");
  6282. CompileSuccessfully(spirv);
  6283. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6284. EXPECT_THAT(getDiagnosticString(),
  6285. HasSubstr("Target of NonWritable decoration is invalid: must "
  6286. "point to a storage image, uniform block, or storage "
  6287. "buffer\n %var_priv"));
  6288. }
  6289. TEST_F(ValidateDecorations, NonWritableVarPrivateV14Good) {
  6290. std::string spirv = ShaderWithNonWritableTarget("%var_priv");
  6291. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6292. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6293. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6294. }
  6295. TEST_F(ValidateDecorations, NonWritableVarPrivateV13TargetV14Bad) {
  6296. std::string spirv = ShaderWithNonWritableTarget("%var_priv");
  6297. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6298. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6299. EXPECT_THAT(getDiagnosticString(),
  6300. HasSubstr("Target of NonWritable decoration is invalid: must "
  6301. "point to a storage image, uniform block, or storage "
  6302. "buffer\n %var_priv"));
  6303. }
  6304. TEST_F(ValidateDecorations, NonWritableVarFunctionBad) {
  6305. std::string spirv = ShaderWithNonWritableTarget("%var_func");
  6306. CompileSuccessfully(spirv);
  6307. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6308. EXPECT_THAT(getDiagnosticString(),
  6309. HasSubstr("Target of NonWritable decoration is invalid: must "
  6310. "point to a storage image, uniform block, or storage "
  6311. "buffer\n %var_func"));
  6312. }
  6313. TEST_F(ValidateDecorations, NonWritableArrayGood) {
  6314. std::string spirv = ShaderWithNonWritableTarget("%var_array_imstor");
  6315. CompileSuccessfully(spirv);
  6316. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6317. }
  6318. TEST_F(ValidateDecorations, NonWritableRuntimeArrayGood) {
  6319. std::string spirv = ShaderWithNonWritableTarget("%var_rta_imstor");
  6320. CompileSuccessfully(spirv);
  6321. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6322. }
  6323. TEST_P(ValidateVulkanCombineDecorationResult, Decorate) {
  6324. const char* const decoration = std::get<0>(GetParam());
  6325. const char* const vuid = std::get<1>(GetParam());
  6326. const TestResult& test_result = std::get<2>(GetParam());
  6327. CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
  6328. generator.before_types_ = "OpDecorate %u32 ";
  6329. generator.before_types_ += decoration;
  6330. generator.before_types_ += "\n";
  6331. EntryPoint entry_point;
  6332. entry_point.name = "main";
  6333. entry_point.execution_model = "Vertex";
  6334. generator.entry_points_.push_back(std::move(entry_point));
  6335. CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
  6336. ASSERT_EQ(test_result.validation_result,
  6337. ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6338. if (!test_result.error_str.empty()) {
  6339. EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
  6340. }
  6341. if (vuid) {
  6342. EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
  6343. }
  6344. }
  6345. INSTANTIATE_TEST_SUITE_P(
  6346. DecorationAllowListFailure, ValidateVulkanCombineDecorationResult,
  6347. Combine(Values("GLSLShared", "GLSLPacked"),
  6348. Values("VUID-StandaloneSpirv-GLSLShared-04669"),
  6349. Values(TestResult(
  6350. SPV_ERROR_INVALID_ID,
  6351. "is not valid for the Vulkan execution environment."))));
  6352. TEST_F(ValidateDecorations, NonWritableVarFunctionV13Bad) {
  6353. std::string spirv = ShaderWithNonWritableTarget("%var_func");
  6354. CompileSuccessfully(spirv);
  6355. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6356. EXPECT_THAT(getDiagnosticString(),
  6357. HasSubstr("Target of NonWritable decoration is invalid: must "
  6358. "point to a storage image, uniform block, or storage "
  6359. "buffer\n %var_func"));
  6360. }
  6361. TEST_F(ValidateDecorations, NonWritableVarFunctionV14Good) {
  6362. std::string spirv = ShaderWithNonWritableTarget("%var_func");
  6363. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6364. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6365. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6366. }
  6367. TEST_F(ValidateDecorations, NonWritableVarFunctionV13TargetV14Bad) {
  6368. std::string spirv = ShaderWithNonWritableTarget("%var_func");
  6369. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6370. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6371. EXPECT_THAT(getDiagnosticString(),
  6372. HasSubstr("Target of NonWritable decoration is invalid: must "
  6373. "point to a storage image, uniform block, or storage "
  6374. "buffer\n %var_func"));
  6375. }
  6376. TEST_F(ValidateDecorations, BufferBlockV13ValV14Good) {
  6377. std::string spirv = R"(
  6378. OpCapability Shader
  6379. OpCapability Linkage
  6380. OpMemoryModel Logical GLSL450
  6381. OpDecorate %1 BufferBlock
  6382. %1 = OpTypeStruct
  6383. )";
  6384. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6385. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6386. }
  6387. TEST_F(ValidateDecorations, BufferBlockV14Bad) {
  6388. std::string spirv = R"(
  6389. OpCapability Shader
  6390. OpCapability Linkage
  6391. OpMemoryModel Logical GLSL450
  6392. OpDecorate %1 BufferBlock
  6393. %1 = OpTypeStruct
  6394. )";
  6395. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6396. EXPECT_EQ(SPV_ERROR_WRONG_VERSION,
  6397. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6398. EXPECT_THAT(getDiagnosticString(),
  6399. HasSubstr("2nd operand of Decorate: operand BufferBlock(3) "
  6400. "requires SPIR-V version 1.3 or earlier"));
  6401. }
  6402. // Component
  6403. TEST_F(ValidateDecorations, ComponentDecorationBadTarget) {
  6404. std::string spirv = R"(
  6405. OpCapability Shader
  6406. OpMemoryModel Logical GLSL450
  6407. OpEntryPoint Vertex %main "main"
  6408. OpDecorate %t Component 0
  6409. %void = OpTypeVoid
  6410. %3 = OpTypeFunction %void
  6411. %float = OpTypeFloat 32
  6412. %t = OpTypeVector %float 2
  6413. %main = OpFunction %void None %3
  6414. %5 = OpLabel
  6415. OpReturn
  6416. OpFunctionEnd
  6417. )";
  6418. CompileSuccessfully(spirv);
  6419. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  6420. EXPECT_THAT(getDiagnosticString(),
  6421. HasSubstr("must be a memory object declaration"));
  6422. }
  6423. TEST_F(ValidateDecorations, ComponentDecorationBadStorageClass) {
  6424. std::string spirv = R"(
  6425. OpCapability Shader
  6426. OpMemoryModel Logical GLSL450
  6427. OpEntryPoint Vertex %main "main"
  6428. OpDecorate %v Component 0
  6429. %void = OpTypeVoid
  6430. %3 = OpTypeFunction %void
  6431. %float = OpTypeFloat 32
  6432. %t = OpTypeVector %float 2
  6433. %ptr_private = OpTypePointer Private %t
  6434. %v = OpVariable %ptr_private Private
  6435. %main = OpFunction %void None %3
  6436. %5 = OpLabel
  6437. OpReturn
  6438. OpFunctionEnd
  6439. )";
  6440. CompileSuccessfully(spirv);
  6441. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  6442. EXPECT_THAT(getDiagnosticString(),
  6443. HasSubstr("Target of Component decoration is invalid: must "
  6444. "point to a Storage Class of Input(1) or Output(3)"));
  6445. }
  6446. TEST_F(ValidateDecorations, ComponentDecorationBadTypeVulkan) {
  6447. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6448. std::string spirv = R"(
  6449. OpCapability Shader
  6450. OpCapability Matrix
  6451. OpMemoryModel Logical GLSL450
  6452. OpEntryPoint Vertex %main "main"
  6453. OpDecorate %v Component 0
  6454. %void = OpTypeVoid
  6455. %3 = OpTypeFunction %void
  6456. %float = OpTypeFloat 32
  6457. %vtype = OpTypeVector %float 4
  6458. %t = OpTypeMatrix %vtype 4
  6459. %ptr_input = OpTypePointer Input %t
  6460. %v = OpVariable %ptr_input Input
  6461. %main = OpFunction %void None %3
  6462. %5 = OpLabel
  6463. OpReturn
  6464. OpFunctionEnd
  6465. )";
  6466. CompileSuccessfully(spirv, env);
  6467. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6468. EXPECT_THAT(getDiagnosticString(),
  6469. AnyVUID("VUID-StandaloneSpirv-Component-10583"));
  6470. EXPECT_THAT(getDiagnosticString(),
  6471. HasSubstr("Component decoration specified for type"));
  6472. EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a scalar or vector"));
  6473. }
  6474. std::string ShaderWithComponentDecoration(const std::string& type,
  6475. const std::string& decoration) {
  6476. return R"(
  6477. OpCapability Shader
  6478. OpCapability Int64
  6479. OpMemoryModel Logical GLSL450
  6480. OpEntryPoint Fragment %main "main" %entryPointOutput
  6481. OpExecutionMode %main OriginUpperLeft
  6482. OpDecorate %entryPointOutput Location 0
  6483. OpDecorate %entryPointOutput )" +
  6484. decoration + R"(
  6485. %void = OpTypeVoid
  6486. %3 = OpTypeFunction %void
  6487. %float = OpTypeFloat 32
  6488. %v3float = OpTypeVector %float 3
  6489. %v4float = OpTypeVector %float 4
  6490. %uint = OpTypeInt 32 0
  6491. %uint64 = OpTypeInt 64 0
  6492. %v2uint64 = OpTypeVector %uint64 2
  6493. %v3uint64 = OpTypeVector %uint64 3
  6494. %uint_2 = OpConstant %uint 2
  6495. %arr_v3float_uint_2 = OpTypeArray %v3float %uint_2
  6496. %float_0 = OpConstant %float 0
  6497. %_ptr_Output_type = OpTypePointer Output %)" + type + R"(
  6498. %entryPointOutput = OpVariable %_ptr_Output_type Output
  6499. %main = OpFunction %void None %3
  6500. %5 = OpLabel
  6501. OpReturn
  6502. OpFunctionEnd
  6503. )";
  6504. }
  6505. TEST_F(ValidateDecorations, ComponentDecorationIntGood0Vulkan) {
  6506. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6507. std::string spirv = ShaderWithComponentDecoration("uint", "Component 0");
  6508. CompileSuccessfully(spirv, env);
  6509. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6510. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6511. }
  6512. TEST_F(ValidateDecorations, ComponentDecorationIntGood1Vulkan) {
  6513. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6514. std::string spirv = ShaderWithComponentDecoration("uint", "Component 1");
  6515. CompileSuccessfully(spirv, env);
  6516. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6517. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6518. }
  6519. TEST_F(ValidateDecorations, ComponentDecorationIntGood2Vulkan) {
  6520. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6521. std::string spirv = ShaderWithComponentDecoration("uint", "Component 2");
  6522. CompileSuccessfully(spirv, env);
  6523. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6524. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6525. }
  6526. TEST_F(ValidateDecorations, ComponentDecorationIntGood3Vulkan) {
  6527. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6528. std::string spirv = ShaderWithComponentDecoration("uint", "Component 3");
  6529. CompileSuccessfully(spirv, env);
  6530. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6531. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6532. }
  6533. TEST_F(ValidateDecorations, ComponentDecorationIntBad4Vulkan) {
  6534. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6535. std::string spirv = ShaderWithComponentDecoration("uint", "Component 4");
  6536. CompileSuccessfully(spirv, env);
  6537. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6538. EXPECT_THAT(getDiagnosticString(),
  6539. AnyVUID("VUID-StandaloneSpirv-Component-04920"));
  6540. EXPECT_THAT(
  6541. getDiagnosticString(),
  6542. HasSubstr("Component decoration value must not be greater than 3"));
  6543. }
  6544. TEST_F(ValidateDecorations, ComponentDecorationVector3GoodVulkan) {
  6545. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6546. std::string spirv = ShaderWithComponentDecoration("v3float", "Component 1");
  6547. CompileSuccessfully(spirv, env);
  6548. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6549. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6550. }
  6551. TEST_F(ValidateDecorations, ComponentDecorationVector4GoodVulkan) {
  6552. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6553. std::string spirv = ShaderWithComponentDecoration("v4float", "Component 0");
  6554. CompileSuccessfully(spirv, env);
  6555. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6556. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6557. }
  6558. TEST_F(ValidateDecorations, ComponentDecorationVector4Bad1Vulkan) {
  6559. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6560. std::string spirv = ShaderWithComponentDecoration("v4float", "Component 1");
  6561. CompileSuccessfully(spirv, env);
  6562. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6563. EXPECT_THAT(getDiagnosticString(),
  6564. AnyVUID("VUID-StandaloneSpirv-Component-04921"));
  6565. EXPECT_THAT(getDiagnosticString(),
  6566. HasSubstr("Sequence of components starting with 1 "
  6567. "and ending with 4 gets larger than 3"));
  6568. }
  6569. TEST_F(ValidateDecorations, ComponentDecorationVector4Bad3Vulkan) {
  6570. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6571. std::string spirv = ShaderWithComponentDecoration("v4float", "Component 3");
  6572. CompileSuccessfully(spirv, env);
  6573. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6574. EXPECT_THAT(getDiagnosticString(),
  6575. AnyVUID("VUID-StandaloneSpirv-Component-04921"));
  6576. EXPECT_THAT(getDiagnosticString(),
  6577. HasSubstr("Sequence of components starting with 3 "
  6578. "and ending with 6 gets larger than 3"));
  6579. }
  6580. TEST_F(ValidateDecorations, ComponentDecorationArrayGoodVulkan) {
  6581. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6582. std::string spirv =
  6583. ShaderWithComponentDecoration("arr_v3float_uint_2", "Component 1");
  6584. CompileSuccessfully(spirv, env);
  6585. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6586. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6587. }
  6588. TEST_F(ValidateDecorations, ComponentDecorationArrayBadVulkan) {
  6589. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6590. std::string spirv =
  6591. ShaderWithComponentDecoration("arr_v3float_uint_2", "Component 2");
  6592. CompileSuccessfully(spirv, env);
  6593. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6594. EXPECT_THAT(getDiagnosticString(),
  6595. AnyVUID("VUID-StandaloneSpirv-Component-04921"));
  6596. EXPECT_THAT(getDiagnosticString(),
  6597. HasSubstr("Sequence of components starting with 2 "
  6598. "and ending with 4 gets larger than 3"));
  6599. }
  6600. TEST_F(ValidateDecorations, ComponentDecoration64ScalarGoodVulkan) {
  6601. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6602. std::string spirv = ShaderWithComponentDecoration("uint64", "Component 0");
  6603. CompileSuccessfully(spirv, env);
  6604. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6605. }
  6606. TEST_F(ValidateDecorations, ComponentDecoration64Scalar1BadVulkan) {
  6607. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6608. std::string spirv = ShaderWithComponentDecoration("uint64", "Component 1");
  6609. CompileSuccessfully(spirv, env);
  6610. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6611. EXPECT_THAT(getDiagnosticString(),
  6612. AnyVUID("VUID-StandaloneSpirv-Component-04923"));
  6613. EXPECT_THAT(getDiagnosticString(),
  6614. HasSubstr("Component decoration value must not be 1 or 3 for "
  6615. "64-bit data types"));
  6616. }
  6617. TEST_F(ValidateDecorations, ComponentDecoration64Scalar2GoodVulkan) {
  6618. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6619. std::string spirv = ShaderWithComponentDecoration("uint64", "Component 2");
  6620. CompileSuccessfully(spirv, env);
  6621. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6622. }
  6623. TEST_F(ValidateDecorations, ComponentDecoration64Scalar3BadVulkan) {
  6624. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6625. std::string spirv = ShaderWithComponentDecoration("uint64", "Component 3");
  6626. CompileSuccessfully(spirv, env);
  6627. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6628. EXPECT_THAT(getDiagnosticString(),
  6629. AnyVUID("VUID-StandaloneSpirv-Component-04923"));
  6630. EXPECT_THAT(getDiagnosticString(),
  6631. HasSubstr("Component decoration value must not be 1 or 3 for "
  6632. "64-bit data types"));
  6633. }
  6634. TEST_F(ValidateDecorations, ComponentDecoration64Vec0GoodVulkan) {
  6635. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6636. std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 0");
  6637. CompileSuccessfully(spirv, env);
  6638. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  6639. }
  6640. TEST_F(ValidateDecorations, ComponentDecoration64Vec1BadVulkan) {
  6641. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6642. std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 1");
  6643. CompileSuccessfully(spirv, env);
  6644. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6645. EXPECT_THAT(getDiagnosticString(),
  6646. AnyVUID("VUID-StandaloneSpirv-Component-04923"));
  6647. EXPECT_THAT(getDiagnosticString(),
  6648. HasSubstr("Component decoration value must not be 1 or 3 for "
  6649. "64-bit data types"));
  6650. }
  6651. TEST_F(ValidateDecorations, ComponentDecoration64Vec2BadVulkan) {
  6652. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6653. std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 2");
  6654. CompileSuccessfully(spirv, env);
  6655. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6656. EXPECT_THAT(getDiagnosticString(),
  6657. AnyVUID("VUID-StandaloneSpirv-Component-04922"));
  6658. HasSubstr(
  6659. "Sequence of components starting with 2 "
  6660. "and ending with 6 gets larger than 3");
  6661. }
  6662. TEST_F(ValidateDecorations, ComponentDecoration64VecWideBadVulkan) {
  6663. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6664. std::string spirv = ShaderWithComponentDecoration("v3uint64", "Component 0");
  6665. CompileSuccessfully(spirv, env);
  6666. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6667. EXPECT_THAT(getDiagnosticString(),
  6668. AnyVUID("VUID-StandaloneSpirv-Component-07703"));
  6669. EXPECT_THAT(getDiagnosticString(),
  6670. HasSubstr("Component decoration only allowed on 64-bit scalar "
  6671. "and 2-component vector"));
  6672. }
  6673. TEST_F(ValidateDecorations, ComponentDecorationBlockGood) {
  6674. std::string spirv = R"(
  6675. OpCapability Shader
  6676. OpMemoryModel Logical GLSL450
  6677. OpEntryPoint Fragment %4 "main" %9 %12
  6678. OpExecutionMode %4 OriginUpperLeft
  6679. OpDecorate %9 Location 0
  6680. OpMemberDecorate %block 0 Location 2
  6681. OpMemberDecorate %block 0 Component 1
  6682. OpDecorate %block Block
  6683. %2 = OpTypeVoid
  6684. %3 = OpTypeFunction %2
  6685. %float = OpTypeFloat 32
  6686. %vec3 = OpTypeVector %float 3
  6687. %8 = OpTypePointer Output %vec3
  6688. %9 = OpVariable %8 Output
  6689. %block = OpTypeStruct %vec3
  6690. %11 = OpTypePointer Input %block
  6691. %12 = OpVariable %11 Input
  6692. %int = OpTypeInt 32 1
  6693. %14 = OpConstant %int 0
  6694. %15 = OpTypePointer Input %vec3
  6695. %4 = OpFunction %2 None %3
  6696. %5 = OpLabel
  6697. %16 = OpAccessChain %15 %12 %14
  6698. %17 = OpLoad %vec3 %16
  6699. OpStore %9 %17
  6700. OpReturn
  6701. OpFunctionEnd
  6702. )";
  6703. CompileSuccessfully(spirv);
  6704. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  6705. EXPECT_THAT(getDiagnosticString(), Eq(""));
  6706. }
  6707. TEST_F(ValidateDecorations, ComponentDecorationBlockBadVulkan) {
  6708. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  6709. std::string spirv = R"(
  6710. OpCapability Shader
  6711. OpMemoryModel Logical GLSL450
  6712. OpEntryPoint Fragment %4 "main" %9 %12
  6713. OpExecutionMode %4 OriginUpperLeft
  6714. OpDecorate %9 Location 0
  6715. OpMemberDecorate %block 0 Location 2
  6716. OpMemberDecorate %block 0 Component 2
  6717. OpDecorate %block Block
  6718. %2 = OpTypeVoid
  6719. %3 = OpTypeFunction %2
  6720. %float = OpTypeFloat 32
  6721. %vec3 = OpTypeVector %float 3
  6722. %8 = OpTypePointer Output %vec3
  6723. %9 = OpVariable %8 Output
  6724. %block = OpTypeStruct %vec3
  6725. %11 = OpTypePointer Input %block
  6726. %12 = OpVariable %11 Input
  6727. %int = OpTypeInt 32 1
  6728. %14 = OpConstant %int 0
  6729. %15 = OpTypePointer Input %vec3
  6730. %4 = OpFunction %2 None %3
  6731. %5 = OpLabel
  6732. %16 = OpAccessChain %15 %12 %14
  6733. %17 = OpLoad %vec3 %16
  6734. OpStore %9 %17
  6735. OpReturn
  6736. OpFunctionEnd
  6737. )";
  6738. CompileSuccessfully(spirv, env);
  6739. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  6740. EXPECT_THAT(getDiagnosticString(),
  6741. AnyVUID("VUID-StandaloneSpirv-Component-04921"));
  6742. EXPECT_THAT(getDiagnosticString(),
  6743. HasSubstr("Sequence of components starting with 2 "
  6744. "and ending with 4 gets larger than 3"));
  6745. }
  6746. TEST_F(ValidateDecorations, ComponentDecorationFunctionParameter) {
  6747. std::string spirv = R"(
  6748. OpCapability Shader
  6749. OpMemoryModel Logical GLSL450
  6750. OpEntryPoint Vertex %main "main"
  6751. OpDecorate %param_f Component 0
  6752. %void = OpTypeVoid
  6753. %void_fn = OpTypeFunction %void
  6754. %float = OpTypeFloat 32
  6755. %float_0 = OpConstant %float 0
  6756. %int = OpTypeInt 32 0
  6757. %int_2 = OpConstant %int 2
  6758. %struct_b = OpTypeStruct %float
  6759. %extra_fn = OpTypeFunction %void %float
  6760. %helper = OpFunction %void None %extra_fn
  6761. %param_f = OpFunctionParameter %float
  6762. %helper_label = OpLabel
  6763. OpReturn
  6764. OpFunctionEnd
  6765. %main = OpFunction %void None %void_fn
  6766. %label = OpLabel
  6767. OpReturn
  6768. OpFunctionEnd
  6769. )";
  6770. CompileSuccessfully(spirv);
  6771. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
  6772. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a pointer type"));
  6773. }
  6774. TEST_F(ValidateDecorations, VulkanStorageBufferBlock) {
  6775. const std::string spirv = R"(
  6776. OpCapability Shader
  6777. OpExtension "SPV_KHR_storage_buffer_storage_class"
  6778. OpMemoryModel Logical GLSL450
  6779. OpEntryPoint GLCompute %main "main"
  6780. OpExecutionMode %main LocalSize 1 1 1
  6781. OpDecorate %struct Block
  6782. OpMemberDecorate %struct 0 Offset 0
  6783. %void = OpTypeVoid
  6784. %uint = OpTypeInt 32 0
  6785. %struct = OpTypeStruct %uint
  6786. %ptr_ssbo = OpTypePointer StorageBuffer %struct
  6787. %var = OpVariable %ptr_ssbo StorageBuffer
  6788. %void_fn = OpTypeFunction %void
  6789. %main = OpFunction %void None %void_fn
  6790. %entry = OpLabel
  6791. OpReturn
  6792. OpFunctionEnd
  6793. )";
  6794. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6795. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6796. }
  6797. TEST_F(ValidateDecorations, VulkanStorageBufferMissingBlock) {
  6798. const std::string spirv = R"(
  6799. OpCapability Shader
  6800. OpExtension "SPV_KHR_storage_buffer_storage_class"
  6801. OpMemoryModel Logical GLSL450
  6802. OpEntryPoint GLCompute %main "main"
  6803. OpExecutionMode %main LocalSize 1 1 1
  6804. %void = OpTypeVoid
  6805. %uint = OpTypeInt 32 0
  6806. %struct = OpTypeStruct %uint
  6807. %ptr_ssbo = OpTypePointer StorageBuffer %struct
  6808. %var = OpVariable %ptr_ssbo StorageBuffer
  6809. %void_fn = OpTypeFunction %void
  6810. %main = OpFunction %void None %void_fn
  6811. %entry = OpLabel
  6812. OpReturn
  6813. OpFunctionEnd
  6814. )";
  6815. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6816. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6817. EXPECT_THAT(getDiagnosticString(),
  6818. AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
  6819. EXPECT_THAT(getDiagnosticString(),
  6820. HasSubstr("From Vulkan spec:\nSuch variables "
  6821. "must be identified with a Block decoration"));
  6822. }
  6823. TEST_F(ValidateDecorations, VulkanStorageBufferArrayMissingBlock) {
  6824. const std::string spirv = R"(
  6825. OpCapability Shader
  6826. OpExtension "SPV_KHR_storage_buffer_storage_class"
  6827. OpMemoryModel Logical GLSL450
  6828. OpEntryPoint GLCompute %main "main"
  6829. OpExecutionMode %main LocalSize 1 1 1
  6830. %void = OpTypeVoid
  6831. %uint = OpTypeInt 32 0
  6832. %uint_4 = OpConstant %uint 4
  6833. %struct = OpTypeStruct %uint
  6834. %array = OpTypeArray %struct %uint_4
  6835. %ptr_ssbo = OpTypePointer StorageBuffer %array
  6836. %var = OpVariable %ptr_ssbo StorageBuffer
  6837. %void_fn = OpTypeFunction %void
  6838. %main = OpFunction %void None %void_fn
  6839. %entry = OpLabel
  6840. OpReturn
  6841. OpFunctionEnd
  6842. )";
  6843. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6844. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6845. EXPECT_THAT(getDiagnosticString(),
  6846. AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
  6847. EXPECT_THAT(getDiagnosticString(),
  6848. HasSubstr("From Vulkan spec:\nSuch variables "
  6849. "must be identified with a Block decoration"));
  6850. }
  6851. TEST_F(ValidateDecorations, VulkanStorageBufferRuntimeArrayMissingBlock) {
  6852. const std::string spirv = R"(
  6853. OpCapability Shader
  6854. OpCapability RuntimeDescriptorArrayEXT
  6855. OpExtension "SPV_EXT_descriptor_indexing"
  6856. OpExtension "SPV_KHR_storage_buffer_storage_class"
  6857. OpMemoryModel Logical GLSL450
  6858. OpEntryPoint GLCompute %main "main"
  6859. OpExecutionMode %main LocalSize 1 1 1
  6860. %void = OpTypeVoid
  6861. %uint = OpTypeInt 32 0
  6862. %struct = OpTypeStruct %uint
  6863. %array = OpTypeRuntimeArray %struct
  6864. %ptr_ssbo = OpTypePointer StorageBuffer %array
  6865. %var = OpVariable %ptr_ssbo StorageBuffer
  6866. %void_fn = OpTypeFunction %void
  6867. %main = OpFunction %void None %void_fn
  6868. %entry = OpLabel
  6869. OpReturn
  6870. OpFunctionEnd
  6871. )";
  6872. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6873. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6874. EXPECT_THAT(getDiagnosticString(),
  6875. AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
  6876. EXPECT_THAT(getDiagnosticString(),
  6877. HasSubstr("From Vulkan spec:\nSuch variables "
  6878. "must be identified with a Block decoration"));
  6879. }
  6880. TEST_F(ValidateDecorations, VulkanUniformBlock) {
  6881. const std::string spirv = R"(
  6882. OpCapability Shader
  6883. OpMemoryModel Logical GLSL450
  6884. OpEntryPoint GLCompute %main "main"
  6885. OpExecutionMode %main LocalSize 1 1 1
  6886. OpDecorate %struct Block
  6887. OpMemberDecorate %struct 0 Offset 0
  6888. %void = OpTypeVoid
  6889. %uint = OpTypeInt 32 0
  6890. %struct = OpTypeStruct %uint
  6891. %ptr_ubo = OpTypePointer Uniform %struct
  6892. %var = OpVariable %ptr_ubo Uniform
  6893. %void_fn = OpTypeFunction %void
  6894. %main = OpFunction %void None %void_fn
  6895. %entry = OpLabel
  6896. OpReturn
  6897. OpFunctionEnd
  6898. )";
  6899. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6900. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6901. }
  6902. TEST_F(ValidateDecorations, VulkanUniformBufferBlock) {
  6903. const std::string spirv = R"(
  6904. OpCapability Shader
  6905. OpMemoryModel Logical GLSL450
  6906. OpEntryPoint GLCompute %main "main"
  6907. OpExecutionMode %main LocalSize 1 1 1
  6908. OpDecorate %struct BufferBlock
  6909. OpMemberDecorate %struct 0 Offset 0
  6910. %void = OpTypeVoid
  6911. %uint = OpTypeInt 32 0
  6912. %struct = OpTypeStruct %uint
  6913. %ptr_ubo = OpTypePointer Uniform %struct
  6914. %var = OpVariable %ptr_ubo Uniform
  6915. %void_fn = OpTypeFunction %void
  6916. %main = OpFunction %void None %void_fn
  6917. %entry = OpLabel
  6918. OpReturn
  6919. OpFunctionEnd
  6920. )";
  6921. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6922. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6923. }
  6924. TEST_F(ValidateDecorations, VulkanUniformMissingBlock) {
  6925. const std::string spirv = R"(
  6926. OpCapability Shader
  6927. OpMemoryModel Logical GLSL450
  6928. OpEntryPoint GLCompute %main "main"
  6929. OpExecutionMode %main LocalSize 1 1 1
  6930. %void = OpTypeVoid
  6931. %uint = OpTypeInt 32 0
  6932. %struct = OpTypeStruct %uint
  6933. %ptr_ubo = OpTypePointer Uniform %struct
  6934. %var = OpVariable %ptr_ubo Uniform
  6935. %void_fn = OpTypeFunction %void
  6936. %main = OpFunction %void None %void_fn
  6937. %entry = OpLabel
  6938. OpReturn
  6939. OpFunctionEnd
  6940. )";
  6941. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6942. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6943. EXPECT_THAT(getDiagnosticString(),
  6944. AnyVUID("VUID-StandaloneSpirv-Uniform-06676"));
  6945. EXPECT_THAT(getDiagnosticString(),
  6946. HasSubstr("From Vulkan spec:\nSuch variables must be "
  6947. "identified with a Block or BufferBlock decoration"));
  6948. }
  6949. TEST_F(ValidateDecorations, VulkanUniformArrayMissingBlock) {
  6950. const std::string spirv = R"(
  6951. OpCapability Shader
  6952. OpMemoryModel Logical GLSL450
  6953. OpEntryPoint GLCompute %main "main"
  6954. OpExecutionMode %main LocalSize 1 1 1
  6955. %void = OpTypeVoid
  6956. %uint = OpTypeInt 32 0
  6957. %uint_4 = OpConstant %uint 4
  6958. %struct = OpTypeStruct %uint
  6959. %array = OpTypeArray %struct %uint_4
  6960. %ptr_ubo = OpTypePointer Uniform %array
  6961. %var = OpVariable %ptr_ubo Uniform
  6962. %void_fn = OpTypeFunction %void
  6963. %main = OpFunction %void None %void_fn
  6964. %entry = OpLabel
  6965. OpReturn
  6966. OpFunctionEnd
  6967. )";
  6968. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6969. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6970. EXPECT_THAT(getDiagnosticString(),
  6971. AnyVUID("VUID-StandaloneSpirv-Uniform-06676"));
  6972. EXPECT_THAT(getDiagnosticString(),
  6973. HasSubstr("From Vulkan spec:\nSuch variables must be "
  6974. "identified with a Block or BufferBlock decoration"));
  6975. }
  6976. TEST_F(ValidateDecorations, VulkanUniformRuntimeArrayMissingBlock) {
  6977. const std::string spirv = R"(
  6978. OpCapability Shader
  6979. OpCapability RuntimeDescriptorArrayEXT
  6980. OpExtension "SPV_EXT_descriptor_indexing"
  6981. OpMemoryModel Logical GLSL450
  6982. OpEntryPoint GLCompute %main "main"
  6983. OpExecutionMode %main LocalSize 1 1 1
  6984. %void = OpTypeVoid
  6985. %uint = OpTypeInt 32 0
  6986. %struct = OpTypeStruct %uint
  6987. %array = OpTypeRuntimeArray %struct
  6988. %ptr_ubo = OpTypePointer Uniform %array
  6989. %var = OpVariable %ptr_ubo Uniform
  6990. %void_fn = OpTypeFunction %void
  6991. %main = OpFunction %void None %void_fn
  6992. %entry = OpLabel
  6993. OpReturn
  6994. OpFunctionEnd
  6995. )";
  6996. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6997. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6998. EXPECT_THAT(getDiagnosticString(),
  6999. AnyVUID("VUID-StandaloneSpirv-Uniform-06676"));
  7000. EXPECT_THAT(getDiagnosticString(),
  7001. HasSubstr("From Vulkan spec:\nSuch variables must be "
  7002. "identified with a Block or BufferBlock decoration"));
  7003. }
  7004. TEST_F(ValidateDecorations, VulkanArrayStrideZero) {
  7005. const std::string spirv = R"(
  7006. OpCapability Shader
  7007. OpMemoryModel Logical GLSL450
  7008. OpEntryPoint GLCompute %main "main"
  7009. OpExecutionMode %main LocalSize 1 1 1
  7010. OpDecorate %var DescriptorSet 0
  7011. OpDecorate %var Binding 0
  7012. OpDecorate %struct Block
  7013. OpMemberDecorate %struct 0 Offset 0
  7014. OpDecorate %array ArrayStride 0
  7015. %void = OpTypeVoid
  7016. %int = OpTypeInt 32 0
  7017. %int_4 = OpConstant %int 4
  7018. %array = OpTypeArray %int %int_4
  7019. %struct = OpTypeStruct %array
  7020. %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
  7021. %var = OpVariable %ptr_ssbo_struct StorageBuffer
  7022. %void_fn = OpTypeFunction %void
  7023. %main = OpFunction %void None %void_fn
  7024. %entry = OpLabel
  7025. OpReturn
  7026. OpFunctionEnd
  7027. )";
  7028. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  7029. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  7030. EXPECT_THAT(getDiagnosticString(),
  7031. HasSubstr("contains an array with stride 0"));
  7032. }
  7033. TEST_F(ValidateDecorations, VulkanArrayStrideTooSmall) {
  7034. const std::string spirv = R"(
  7035. OpCapability Shader
  7036. OpMemoryModel Logical GLSL450
  7037. OpEntryPoint GLCompute %main "main"
  7038. OpExecutionMode %main LocalSize 1 1 1
  7039. OpDecorate %var DescriptorSet 0
  7040. OpDecorate %var Binding 0
  7041. OpDecorate %struct Block
  7042. OpMemberDecorate %struct 0 Offset 0
  7043. OpDecorate %inner ArrayStride 4
  7044. OpDecorate %outer ArrayStride 4
  7045. %void = OpTypeVoid
  7046. %int = OpTypeInt 32 0
  7047. %int_4 = OpConstant %int 4
  7048. %inner = OpTypeArray %int %int_4
  7049. %outer = OpTypeArray %inner %int_4
  7050. %struct = OpTypeStruct %outer
  7051. %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
  7052. %var = OpVariable %ptr_ssbo_struct StorageBuffer
  7053. %void_fn = OpTypeFunction %void
  7054. %main = OpFunction %void None %void_fn
  7055. %entry = OpLabel
  7056. OpReturn
  7057. OpFunctionEnd
  7058. )";
  7059. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  7060. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  7061. EXPECT_THAT(
  7062. getDiagnosticString(),
  7063. HasSubstr(
  7064. "contains an array with stride 4, but with an element size of 16"));
  7065. }
  7066. TEST_F(ValidateDecorations, FunctionsWithOpGroupDecorate) {
  7067. std::string spirv = R"(
  7068. OpCapability Addresses
  7069. OpCapability Linkage
  7070. OpCapability Kernel
  7071. OpCapability Int8
  7072. %1 = OpExtInstImport "OpenCL.std"
  7073. OpMemoryModel Physical32 OpenCL
  7074. OpName %foo "foo"
  7075. OpName %entry "entry"
  7076. OpName %bar "bar"
  7077. OpName %entry_0 "entry"
  7078. OpName %k "k"
  7079. OpName %entry_1 "entry"
  7080. OpName %b "b"
  7081. OpDecorate %28 FuncParamAttr Zext
  7082. %28 = OpDecorationGroup
  7083. OpDecorate %k LinkageAttributes "k" Export
  7084. OpDecorate %foo LinkageAttributes "foo" Export
  7085. OpDecorate %bar LinkageAttributes "bar" Export
  7086. OpDecorate %b Alignment 1
  7087. OpGroupDecorate %28 %foo %bar
  7088. %uchar = OpTypeInt 8 0
  7089. %bool = OpTypeBool
  7090. %3 = OpTypeFunction %bool
  7091. %void = OpTypeVoid
  7092. %10 = OpTypeFunction %void
  7093. %_ptr_Function_uchar = OpTypePointer Function %uchar
  7094. %true = OpConstantTrue %bool
  7095. %foo = OpFunction %bool DontInline %3
  7096. %entry = OpLabel
  7097. OpReturnValue %true
  7098. OpFunctionEnd
  7099. %bar = OpFunction %bool DontInline %3
  7100. %entry_0 = OpLabel
  7101. OpReturnValue %true
  7102. OpFunctionEnd
  7103. %k = OpFunction %void DontInline %10
  7104. %entry_1 = OpLabel
  7105. %b = OpVariable %_ptr_Function_uchar Function
  7106. OpReturn
  7107. OpFunctionEnd
  7108. )";
  7109. CompileSuccessfully(spirv);
  7110. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  7111. }
  7112. TEST_F(ValidateDecorations, LocationVariableGood) {
  7113. const std::string spirv = R"(
  7114. OpCapability Shader
  7115. OpCapability Linkage
  7116. OpMemoryModel Logical GLSL450
  7117. OpDecorate %in_var Location 0
  7118. %float = OpTypeFloat 32
  7119. %ptr_input_float = OpTypePointer Input %float
  7120. %in_var = OpVariable %ptr_input_float Input
  7121. )";
  7122. CompileSuccessfully(spirv);
  7123. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  7124. }
  7125. TEST_F(ValidateDecorations, LocationStructMemberGood) {
  7126. const std::string spirv = R"(
  7127. OpCapability Shader
  7128. OpCapability Linkage
  7129. OpMemoryModel Logical GLSL450
  7130. OpMemberDecorate %struct 0 Location 0
  7131. %float = OpTypeFloat 32
  7132. %struct = OpTypeStruct %float
  7133. )";
  7134. CompileSuccessfully(spirv);
  7135. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  7136. }
  7137. TEST_F(ValidateDecorations, LocationStructBad) {
  7138. const std::string spirv = R"(
  7139. OpCapability Shader
  7140. OpCapability Linkage
  7141. OpMemoryModel Logical GLSL450
  7142. OpDecorate %struct Location 0
  7143. %float = OpTypeFloat 32
  7144. %struct = OpTypeStruct %float
  7145. )";
  7146. CompileSuccessfully(spirv);
  7147. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7148. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
  7149. }
  7150. TEST_F(ValidateDecorations, LocationFloatBad) {
  7151. const std::string spirv = R"(
  7152. OpCapability Shader
  7153. OpCapability Linkage
  7154. OpMemoryModel Logical GLSL450
  7155. OpDecorate %float Location 0
  7156. %float = OpTypeFloat 32
  7157. )";
  7158. CompileSuccessfully(spirv);
  7159. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7160. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
  7161. }
  7162. TEST_F(ValidateDecorations, WorkgroupSingleBlockVariable) {
  7163. std::string spirv = R"(
  7164. OpCapability Shader
  7165. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7166. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7167. OpMemoryModel Logical GLSL450
  7168. OpEntryPoint GLCompute %main "main" %_
  7169. OpExecutionMode %main LocalSize 8 1 1
  7170. OpMemberDecorate %first 0 Offset 0
  7171. OpDecorate %first Block
  7172. %void = OpTypeVoid
  7173. %3 = OpTypeFunction %void
  7174. %int = OpTypeInt 32 1
  7175. %first = OpTypeStruct %int
  7176. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7177. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7178. %int_0 = OpConstant %int 0
  7179. %int_2 = OpConstant %int 2
  7180. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7181. %main = OpFunction %void None %3
  7182. %5 = OpLabel
  7183. %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
  7184. OpStore %13 %int_2
  7185. OpReturn
  7186. OpFunctionEnd
  7187. )";
  7188. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7189. EXPECT_EQ(SPV_SUCCESS,
  7190. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7191. }
  7192. TEST_F(ValidateDecorations, WorkgroupBlockVariableRequiresV14) {
  7193. std::string spirv = R"(
  7194. OpCapability Shader
  7195. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7196. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7197. OpMemoryModel Logical GLSL450
  7198. OpEntryPoint GLCompute %main "main" %_
  7199. OpExecutionMode %main LocalSize 8 1 1
  7200. OpMemberDecorate %first 0 Offset 0
  7201. OpDecorate %first Block
  7202. %void = OpTypeVoid
  7203. %3 = OpTypeFunction %void
  7204. %int = OpTypeInt 32 1
  7205. %first = OpTypeStruct %int
  7206. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7207. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7208. %int_0 = OpConstant %int 0
  7209. %int_2 = OpConstant %int 2
  7210. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7211. %main = OpFunction %void None %3
  7212. %5 = OpLabel
  7213. %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
  7214. OpStore %13 %int_2
  7215. OpReturn
  7216. OpFunctionEnd
  7217. )";
  7218. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  7219. EXPECT_EQ(SPV_ERROR_WRONG_VERSION,
  7220. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7221. EXPECT_THAT(getDiagnosticString(),
  7222. HasSubstr("requires SPIR-V version 1.4 or later"));
  7223. }
  7224. TEST_F(ValidateDecorations, WorkgroupSingleNonBlockVariable) {
  7225. std::string spirv = R"(
  7226. OpCapability Shader
  7227. OpMemoryModel Logical GLSL450
  7228. OpEntryPoint GLCompute %main "main" %a
  7229. OpExecutionMode %main LocalSize 8 1 1
  7230. %void = OpTypeVoid
  7231. %3 = OpTypeFunction %void
  7232. %int = OpTypeInt 32 1
  7233. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7234. %a = OpVariable %_ptr_Workgroup_int Workgroup
  7235. %int_2 = OpConstant %int 2
  7236. %main = OpFunction %void None %3
  7237. %5 = OpLabel
  7238. OpStore %a %int_2
  7239. OpReturn
  7240. OpFunctionEnd
  7241. )";
  7242. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7243. EXPECT_EQ(SPV_SUCCESS,
  7244. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7245. }
  7246. TEST_F(ValidateDecorations, WorkgroupMultiBlockVariable) {
  7247. std::string spirv = R"(
  7248. OpCapability Shader
  7249. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7250. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7251. OpMemoryModel Logical GLSL450
  7252. OpEntryPoint GLCompute %main "main" %_ %__0
  7253. OpExecutionMode %main LocalSize 8 1 1
  7254. OpMemberDecorate %first 0 Offset 0
  7255. OpDecorate %first Block
  7256. OpMemberDecorate %second 0 Offset 0
  7257. OpDecorate %second Block
  7258. OpDecorate %_ Aliased
  7259. OpDecorate %__0 Aliased
  7260. %void = OpTypeVoid
  7261. %3 = OpTypeFunction %void
  7262. %int = OpTypeInt 32 1
  7263. %first = OpTypeStruct %int
  7264. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7265. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7266. %int_0 = OpConstant %int 0
  7267. %int_2 = OpConstant %int 2
  7268. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7269. %second = OpTypeStruct %int
  7270. %_ptr_Workgroup_second = OpTypePointer Workgroup %second
  7271. %__0 = OpVariable %_ptr_Workgroup_second Workgroup
  7272. %int_3 = OpConstant %int 3
  7273. %main = OpFunction %void None %3
  7274. %5 = OpLabel
  7275. %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
  7276. OpStore %13 %int_2
  7277. %18 = OpAccessChain %_ptr_Workgroup_int %__0 %int_0
  7278. OpStore %18 %int_3
  7279. OpReturn
  7280. OpFunctionEnd
  7281. )";
  7282. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7283. EXPECT_EQ(SPV_SUCCESS,
  7284. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7285. }
  7286. TEST_F(ValidateDecorations, WorkgroupBlockVariableWith8BitType) {
  7287. std::string spirv = R"(
  7288. OpCapability Shader
  7289. OpCapability Int8
  7290. OpCapability WorkgroupMemoryExplicitLayout8BitAccessKHR
  7291. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7292. OpMemoryModel Logical GLSL450
  7293. OpEntryPoint GLCompute %main "main" %_
  7294. OpExecutionMode %main LocalSize 2 1 1
  7295. OpMemberDecorate %first 0 Offset 0
  7296. OpDecorate %first Block
  7297. %void = OpTypeVoid
  7298. %3 = OpTypeFunction %void
  7299. %char = OpTypeInt 8 1
  7300. %first = OpTypeStruct %char
  7301. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7302. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7303. %int = OpTypeInt 32 1
  7304. %int_0 = OpConstant %int 0
  7305. %char_2 = OpConstant %char 2
  7306. %_ptr_Workgroup_char = OpTypePointer Workgroup %char
  7307. %main = OpFunction %void None %3
  7308. %5 = OpLabel
  7309. %14 = OpAccessChain %_ptr_Workgroup_char %_ %int_0
  7310. OpStore %14 %char_2
  7311. OpReturn
  7312. OpFunctionEnd
  7313. )";
  7314. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7315. EXPECT_EQ(SPV_SUCCESS,
  7316. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7317. }
  7318. TEST_F(ValidateDecorations, WorkgroupMultiNonBlockVariable) {
  7319. std::string spirv = R"(
  7320. OpCapability Shader
  7321. OpMemoryModel Logical GLSL450
  7322. OpEntryPoint GLCompute %main "main" %a %b
  7323. OpExecutionMode %main LocalSize 8 1 1
  7324. %void = OpTypeVoid
  7325. %3 = OpTypeFunction %void
  7326. %int = OpTypeInt 32 1
  7327. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7328. %a = OpVariable %_ptr_Workgroup_int Workgroup
  7329. %int_2 = OpConstant %int 2
  7330. %b = OpVariable %_ptr_Workgroup_int Workgroup
  7331. %int_3 = OpConstant %int 3
  7332. %main = OpFunction %void None %3
  7333. %5 = OpLabel
  7334. OpStore %a %int_2
  7335. OpStore %b %int_3
  7336. OpReturn
  7337. OpFunctionEnd
  7338. )";
  7339. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7340. EXPECT_EQ(SPV_SUCCESS,
  7341. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7342. }
  7343. TEST_F(ValidateDecorations, WorkgroupBlockVariableWith16BitType) {
  7344. std::string spirv = R"(
  7345. OpCapability Shader
  7346. OpCapability Float16
  7347. OpCapability Int16
  7348. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7349. OpCapability WorkgroupMemoryExplicitLayout16BitAccessKHR
  7350. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7351. OpMemoryModel Logical GLSL450
  7352. OpEntryPoint GLCompute %main "main" %_
  7353. OpExecutionMode %main LocalSize 2 1 1
  7354. OpMemberDecorate %first 0 Offset 0
  7355. OpMemberDecorate %first 1 Offset 2
  7356. OpDecorate %first Block
  7357. %void = OpTypeVoid
  7358. %3 = OpTypeFunction %void
  7359. %short = OpTypeInt 16 1
  7360. %half = OpTypeFloat 16
  7361. %first = OpTypeStruct %short %half
  7362. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7363. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7364. %int = OpTypeInt 32 1
  7365. %int_0 = OpConstant %int 0
  7366. %short_3 = OpConstant %short 3
  7367. %_ptr_Workgroup_short = OpTypePointer Workgroup %short
  7368. %int_1 = OpConstant %int 1
  7369. %half_0x1_898p_3 = OpConstant %half 0x1.898p+3
  7370. %_ptr_Workgroup_half = OpTypePointer Workgroup %half
  7371. %main = OpFunction %void None %3
  7372. %5 = OpLabel
  7373. %15 = OpAccessChain %_ptr_Workgroup_short %_ %int_0
  7374. OpStore %15 %short_3
  7375. %19 = OpAccessChain %_ptr_Workgroup_half %_ %int_1
  7376. OpStore %19 %half_0x1_898p_3
  7377. OpReturn
  7378. OpFunctionEnd
  7379. )";
  7380. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7381. EXPECT_EQ(SPV_SUCCESS,
  7382. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7383. }
  7384. TEST_F(ValidateDecorations, WorkgroupBlockVariableScalarLayout) {
  7385. std::string spirv = R"(
  7386. OpCapability Shader
  7387. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7388. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7389. OpMemoryModel Logical GLSL450
  7390. OpEntryPoint Vertex %main "main" %B
  7391. OpSource GLSL 450
  7392. OpMemberDecorate %S 0 Offset 0
  7393. OpMemberDecorate %S 1 Offset 4
  7394. OpMemberDecorate %S 2 Offset 16
  7395. OpMemberDecorate %S 3 Offset 28
  7396. OpDecorate %S Block
  7397. OpDecorate %B Aliased
  7398. %void = OpTypeVoid
  7399. %3 = OpTypeFunction %void
  7400. %float = OpTypeFloat 32
  7401. %v3float = OpTypeVector %float 3
  7402. %S = OpTypeStruct %float %v3float %v3float %v3float
  7403. %_ptr_Workgroup_S = OpTypePointer Workgroup %S
  7404. %B = OpVariable %_ptr_Workgroup_S Workgroup
  7405. %main = OpFunction %void None %3
  7406. %5 = OpLabel
  7407. OpReturn
  7408. OpFunctionEnd
  7409. )";
  7410. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7411. spvValidatorOptionsSetWorkgroupScalarBlockLayout(getValidatorOptions(), true);
  7412. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4))
  7413. << getDiagnosticString();
  7414. }
  7415. TEST_F(ValidateDecorations, WorkgroupMixBlockAndNonBlockBad) {
  7416. std::string spirv = R"(
  7417. OpCapability Shader
  7418. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7419. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7420. OpMemoryModel Logical GLSL450
  7421. OpEntryPoint GLCompute %main "main" %_ %b
  7422. OpExecutionMode %main LocalSize 8 1 1
  7423. OpMemberDecorate %first 0 Offset 0
  7424. OpDecorate %first Block
  7425. OpDecorate %_ Aliased
  7426. OpDecorate %b Aliased
  7427. %void = OpTypeVoid
  7428. %3 = OpTypeFunction %void
  7429. %int = OpTypeInt 32 1
  7430. %first = OpTypeStruct %int
  7431. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7432. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7433. %int_0 = OpConstant %int 0
  7434. %int_2 = OpConstant %int 2
  7435. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7436. %b = OpVariable %_ptr_Workgroup_int Workgroup
  7437. %int_3 = OpConstant %int 3
  7438. %main = OpFunction %void None %3
  7439. %5 = OpLabel
  7440. %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
  7441. OpStore %13 %int_2
  7442. OpStore %b %int_3
  7443. OpReturn
  7444. OpFunctionEnd
  7445. )";
  7446. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7447. EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
  7448. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7449. EXPECT_THAT(
  7450. getDiagnosticString(),
  7451. HasSubstr("either all or none of the Workgroup Storage Class variables "
  7452. "in the entry point interface must point to struct types "
  7453. "decorated with Block"));
  7454. }
  7455. TEST_F(ValidateDecorations, WorkgroupMultiBlockVariableMissingAliased) {
  7456. std::string spirv = R"(
  7457. OpCapability Shader
  7458. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7459. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7460. OpMemoryModel Logical GLSL450
  7461. OpEntryPoint GLCompute %main "main" %_ %__0
  7462. OpExecutionMode %main LocalSize 8 1 1
  7463. OpMemberDecorate %first 0 Offset 0
  7464. OpDecorate %first Block
  7465. OpMemberDecorate %second 0 Offset 0
  7466. OpDecorate %second Block
  7467. OpDecorate %_ Aliased
  7468. %void = OpTypeVoid
  7469. %3 = OpTypeFunction %void
  7470. %int = OpTypeInt 32 1
  7471. %first = OpTypeStruct %int
  7472. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7473. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7474. %int_0 = OpConstant %int 0
  7475. %int_2 = OpConstant %int 2
  7476. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7477. %second = OpTypeStruct %int
  7478. %_ptr_Workgroup_second = OpTypePointer Workgroup %second
  7479. %__0 = OpVariable %_ptr_Workgroup_second Workgroup
  7480. %int_3 = OpConstant %int 3
  7481. %main = OpFunction %void None %3
  7482. %5 = OpLabel
  7483. %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
  7484. OpStore %13 %int_2
  7485. %18 = OpAccessChain %_ptr_Workgroup_int %__0 %int_0
  7486. OpStore %18 %int_3
  7487. OpReturn
  7488. OpFunctionEnd
  7489. )";
  7490. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7491. EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
  7492. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7493. EXPECT_THAT(
  7494. getDiagnosticString(),
  7495. HasSubstr("more than one Workgroup Storage Class variable in the "
  7496. "entry point interface point to a type decorated with Block, "
  7497. "all of them must be decorated with Aliased"));
  7498. }
  7499. TEST_F(ValidateDecorations, WorkgroupSingleBlockVariableNotAStruct) {
  7500. std::string spirv = R"(
  7501. OpCapability Shader
  7502. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7503. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7504. OpMemoryModel Logical GLSL450
  7505. OpEntryPoint GLCompute %main "main" %_
  7506. OpExecutionMode %main LocalSize 8 1 1
  7507. OpDecorate %first Block
  7508. %void = OpTypeVoid
  7509. %3 = OpTypeFunction %void
  7510. %int = OpTypeInt 32 1
  7511. %int_3 = OpConstant %int 3
  7512. %first = OpTypeArray %int %int_3
  7513. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7514. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7515. %int_0 = OpConstant %int 0
  7516. %int_2 = OpConstant %int 2
  7517. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7518. %main = OpFunction %void None %3
  7519. %5 = OpLabel
  7520. %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
  7521. OpStore %13 %int_2
  7522. OpReturn
  7523. OpFunctionEnd
  7524. )";
  7525. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7526. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  7527. ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
  7528. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
  7529. }
  7530. TEST_F(ValidateDecorations, WorkgroupSingleBlockVariableMissingLayout) {
  7531. std::string spirv = R"(
  7532. OpCapability Shader
  7533. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7534. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7535. OpMemoryModel Logical GLSL450
  7536. OpEntryPoint GLCompute %main "main" %_
  7537. OpExecutionMode %main LocalSize 8 1 1
  7538. OpDecorate %first Block
  7539. %void = OpTypeVoid
  7540. %3 = OpTypeFunction %void
  7541. %int = OpTypeInt 32 1
  7542. %first = OpTypeStruct %int
  7543. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7544. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7545. %int_0 = OpConstant %int 0
  7546. %int_2 = OpConstant %int 2
  7547. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7548. %main = OpFunction %void None %3
  7549. %5 = OpLabel
  7550. %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
  7551. OpStore %13 %int_2
  7552. OpReturn
  7553. OpFunctionEnd
  7554. )";
  7555. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7556. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  7557. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7558. EXPECT_THAT(
  7559. getDiagnosticString(),
  7560. HasSubstr("Block must be explicitly laid out with Offset decorations"));
  7561. }
  7562. TEST_F(ValidateDecorations, WorkgroupSingleBlockVariableBadLayout) {
  7563. std::string spirv = R"(
  7564. OpCapability Shader
  7565. OpCapability WorkgroupMemoryExplicitLayoutKHR
  7566. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  7567. OpMemoryModel Logical GLSL450
  7568. OpEntryPoint GLCompute %main "main" %_
  7569. OpExecutionMode %main LocalSize 8 1 1
  7570. OpMemberDecorate %first 0 Offset 1
  7571. OpDecorate %first Block
  7572. %void = OpTypeVoid
  7573. %3 = OpTypeFunction %void
  7574. %int = OpTypeInt 32 1
  7575. %first = OpTypeStruct %int
  7576. %_ptr_Workgroup_first = OpTypePointer Workgroup %first
  7577. %_ = OpVariable %_ptr_Workgroup_first Workgroup
  7578. %int_0 = OpConstant %int 0
  7579. %int_2 = OpConstant %int 2
  7580. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  7581. %main = OpFunction %void None %3
  7582. %5 = OpLabel
  7583. %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
  7584. OpStore %13 %int_2
  7585. OpReturn
  7586. OpFunctionEnd
  7587. )";
  7588. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7589. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  7590. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7591. EXPECT_THAT(
  7592. getDiagnosticString(),
  7593. HasSubstr("Block for variable in Workgroup storage class must follow "
  7594. "relaxed storage buffer layout rules: "
  7595. "member 0 at offset 1 is not aligned to 4"));
  7596. }
  7597. TEST_F(ValidateDecorations, WorkgroupBlockNoCapability) {
  7598. std::string spirv = R"(
  7599. OpCapability Shader
  7600. OpMemoryModel Logical GLSL450
  7601. OpEntryPoint GLCompute %main "main" %_
  7602. OpExecutionMode %main LocalSize 1 1 1
  7603. OpMemberDecorate %struct 0 Offset 0
  7604. OpMemberDecorate %struct 1 Offset 4
  7605. OpDecorate %struct Block
  7606. %void = OpTypeVoid
  7607. %3 = OpTypeFunction %void
  7608. %int = OpTypeInt 32 1
  7609. %struct = OpTypeStruct %int %int
  7610. %ptr_workgroup = OpTypePointer Workgroup %struct
  7611. %_ = OpVariable %ptr_workgroup Workgroup
  7612. %main = OpFunction %void None %3
  7613. %5 = OpLabel
  7614. OpReturn
  7615. OpFunctionEnd
  7616. )";
  7617. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  7618. EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
  7619. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7620. EXPECT_THAT(
  7621. getDiagnosticString(),
  7622. HasSubstr(
  7623. "Workgroup Storage Class variables can't be decorated with Block "
  7624. "unless declaring the WorkgroupMemoryExplicitLayoutKHR capability"));
  7625. }
  7626. TEST_F(ValidateDecorations, BadMatrixStrideUniform) {
  7627. const std::string spirv = R"(
  7628. OpCapability Shader
  7629. OpMemoryModel Logical GLSL450
  7630. OpEntryPoint GLCompute %main "main"
  7631. OpExecutionMode %main LocalSize 1 1 1
  7632. OpDecorate %block Block
  7633. OpMemberDecorate %block 0 Offset 0
  7634. OpMemberDecorate %block 0 MatrixStride 3
  7635. OpMemberDecorate %block 0 ColMajor
  7636. OpDecorate %var DescriptorSet 0
  7637. OpDecorate %var Binding 0
  7638. %void = OpTypeVoid
  7639. %float = OpTypeFloat 32
  7640. %float4 = OpTypeVector %float 4
  7641. %matrix4x4 = OpTypeMatrix %float4 4
  7642. %block = OpTypeStruct %matrix4x4
  7643. %block_ptr = OpTypePointer Uniform %block
  7644. %var = OpVariable %block_ptr Uniform
  7645. %void_fn = OpTypeFunction %void
  7646. %main = OpFunction %void None %void_fn
  7647. %entry = OpLabel
  7648. OpReturn
  7649. OpFunctionEnd
  7650. )";
  7651. CompileSuccessfully(spirv);
  7652. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  7653. EXPECT_THAT(
  7654. getDiagnosticString(),
  7655. HasSubstr(
  7656. "Structure id 2 decorated as Block for variable in Uniform storage "
  7657. "class must follow standard uniform buffer layout rules: member 0 is "
  7658. "a matrix with stride 3 not satisfying alignment to 16"));
  7659. }
  7660. TEST_F(ValidateDecorations, BadMatrixStrideStorageBuffer) {
  7661. const std::string spirv = R"(
  7662. OpCapability Shader
  7663. OpExtension "SPV_KHR_storage_buffer_storage_class"
  7664. OpMemoryModel Logical GLSL450
  7665. OpEntryPoint GLCompute %main "main"
  7666. OpExecutionMode %main LocalSize 1 1 1
  7667. OpDecorate %block Block
  7668. OpMemberDecorate %block 0 Offset 0
  7669. OpMemberDecorate %block 0 MatrixStride 3
  7670. OpMemberDecorate %block 0 ColMajor
  7671. OpDecorate %var DescriptorSet 0
  7672. OpDecorate %var Binding 0
  7673. %void = OpTypeVoid
  7674. %float = OpTypeFloat 32
  7675. %float4 = OpTypeVector %float 4
  7676. %matrix4x4 = OpTypeMatrix %float4 4
  7677. %block = OpTypeStruct %matrix4x4
  7678. %block_ptr = OpTypePointer StorageBuffer %block
  7679. %var = OpVariable %block_ptr StorageBuffer
  7680. %void_fn = OpTypeFunction %void
  7681. %main = OpFunction %void None %void_fn
  7682. %entry = OpLabel
  7683. OpReturn
  7684. OpFunctionEnd
  7685. )";
  7686. CompileSuccessfully(spirv);
  7687. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  7688. EXPECT_THAT(
  7689. getDiagnosticString(),
  7690. HasSubstr(
  7691. "Structure id 2 decorated as Block for variable in StorageBuffer "
  7692. "storage class must follow standard storage buffer layout rules: "
  7693. "member 0 is a matrix with stride 3 not satisfying alignment to 16"));
  7694. }
  7695. TEST_F(ValidateDecorations, BadMatrixStridePushConstant) {
  7696. const std::string spirv = R"(
  7697. OpCapability Shader
  7698. OpMemoryModel Logical GLSL450
  7699. OpEntryPoint GLCompute %main "main"
  7700. OpExecutionMode %main LocalSize 1 1 1
  7701. OpDecorate %block Block
  7702. OpMemberDecorate %block 0 Offset 0
  7703. OpMemberDecorate %block 0 MatrixStride 3
  7704. OpMemberDecorate %block 0 ColMajor
  7705. %void = OpTypeVoid
  7706. %float = OpTypeFloat 32
  7707. %float4 = OpTypeVector %float 4
  7708. %matrix4x4 = OpTypeMatrix %float4 4
  7709. %block = OpTypeStruct %matrix4x4
  7710. %block_ptr = OpTypePointer PushConstant %block
  7711. %var = OpVariable %block_ptr PushConstant
  7712. %void_fn = OpTypeFunction %void
  7713. %main = OpFunction %void None %void_fn
  7714. %entry = OpLabel
  7715. OpReturn
  7716. OpFunctionEnd
  7717. )";
  7718. CompileSuccessfully(spirv);
  7719. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  7720. EXPECT_THAT(
  7721. getDiagnosticString(),
  7722. HasSubstr(
  7723. "Structure id 2 decorated as Block for variable in PushConstant "
  7724. "storage class must follow standard storage buffer layout rules: "
  7725. "member 0 is a matrix with stride 3 not satisfying alignment to 16"));
  7726. }
  7727. TEST_F(ValidateDecorations, BadMatrixStrideStorageBufferScalarLayout) {
  7728. const std::string spirv = R"(
  7729. OpCapability Shader
  7730. OpExtension "SPV_KHR_storage_buffer_storage_class"
  7731. OpMemoryModel Logical GLSL450
  7732. OpEntryPoint GLCompute %main "main"
  7733. OpExecutionMode %main LocalSize 1 1 1
  7734. OpDecorate %block Block
  7735. OpMemberDecorate %block 0 Offset 0
  7736. OpMemberDecorate %block 0 MatrixStride 3
  7737. OpMemberDecorate %block 0 RowMajor
  7738. OpDecorate %var DescriptorSet 0
  7739. OpDecorate %var Binding 0
  7740. %void = OpTypeVoid
  7741. %float = OpTypeFloat 32
  7742. %float4 = OpTypeVector %float 4
  7743. %matrix4x4 = OpTypeMatrix %float4 4
  7744. %block = OpTypeStruct %matrix4x4
  7745. %block_ptr = OpTypePointer StorageBuffer %block
  7746. %var = OpVariable %block_ptr StorageBuffer
  7747. %void_fn = OpTypeFunction %void
  7748. %main = OpFunction %void None %void_fn
  7749. %entry = OpLabel
  7750. OpReturn
  7751. OpFunctionEnd
  7752. )";
  7753. options_->scalar_block_layout = true;
  7754. CompileSuccessfully(spirv);
  7755. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  7756. EXPECT_THAT(
  7757. getDiagnosticString(),
  7758. HasSubstr(
  7759. "Structure id 2 decorated as Block for variable in StorageBuffer "
  7760. "storage class must follow scalar storage buffer layout rules: "
  7761. "member 0 is a matrix with stride 3 not satisfying alignment to 4"));
  7762. }
  7763. TEST_F(ValidateDecorations, MissingOffsetStructNestedInArray) {
  7764. const std::string spirv = R"(
  7765. OpCapability Shader
  7766. OpExtension "SPV_KHR_storage_buffer_storage_class"
  7767. OpMemoryModel Logical GLSL450
  7768. OpEntryPoint GLCompute %main "main"
  7769. OpExecutionMode %main LocalSize 1 1 1
  7770. OpDecorate %array ArrayStride 4
  7771. OpDecorate %outer Block
  7772. OpMemberDecorate %outer 0 Offset 0
  7773. OpDecorate %var DescriptorSet 0
  7774. OpDecorate %var Binding 0
  7775. %void = OpTypeVoid
  7776. %int = OpTypeInt 32 0
  7777. %int_4 = OpConstant %int 4
  7778. %inner = OpTypeStruct %int
  7779. %array = OpTypeArray %inner %int_4
  7780. %outer = OpTypeStruct %array
  7781. %ptr_ssbo_outer = OpTypePointer StorageBuffer %outer
  7782. %var = OpVariable %ptr_ssbo_outer StorageBuffer
  7783. %void_fn = OpTypeFunction %void
  7784. %main = OpFunction %void None %void_fn
  7785. %entry = OpLabel
  7786. OpReturn
  7787. OpFunctionEnd
  7788. )";
  7789. CompileSuccessfully(spirv);
  7790. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7791. EXPECT_THAT(getDiagnosticString(),
  7792. HasSubstr("Structure id 3 decorated as Block must be explicitly "
  7793. "laid out with Offset decorations"));
  7794. }
  7795. TEST_F(ValidateDecorations, AllOnesOffset) {
  7796. const std::string spirv = R"(
  7797. OpCapability Shader
  7798. OpMemoryModel Logical GLSL450
  7799. OpEntryPoint GLCompute %main "main"
  7800. OpDecorate %var DescriptorSet 0
  7801. OpDecorate %var Binding 0
  7802. OpDecorate %outer Block
  7803. OpMemberDecorate %outer 0 Offset 0
  7804. OpMemberDecorate %struct 0 Offset 4294967295
  7805. %void = OpTypeVoid
  7806. %int = OpTypeInt 32 0
  7807. %struct = OpTypeStruct %int
  7808. %outer = OpTypeStruct %struct
  7809. %ptr = OpTypePointer Uniform %outer
  7810. %var = OpVariable %ptr Uniform
  7811. %void_fn = OpTypeFunction %void
  7812. %main = OpFunction %void None %void_fn
  7813. %entry = OpLabel
  7814. OpReturn
  7815. OpFunctionEnd
  7816. )";
  7817. CompileSuccessfully(spirv);
  7818. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7819. EXPECT_THAT(getDiagnosticString(),
  7820. HasSubstr("decorated as Block must be explicitly laid out with "
  7821. "Offset decorations"));
  7822. }
  7823. TEST_F(ValidateDecorations, PerVertexVulkanGood) {
  7824. const std::string spirv = R"(
  7825. OpCapability Shader
  7826. OpCapability FragmentBarycentricKHR
  7827. OpExtension "SPV_KHR_fragment_shader_barycentric"
  7828. %1 = OpExtInstImport "GLSL.std.450"
  7829. OpMemoryModel Logical GLSL450
  7830. OpEntryPoint Fragment %main "main" %vertexIDs
  7831. OpExecutionMode %main OriginUpperLeft
  7832. OpDecorate %vertexIDs Location 0
  7833. OpDecorate %vertexIDs PerVertexKHR
  7834. %void = OpTypeVoid
  7835. %func = OpTypeFunction %void
  7836. %float = OpTypeFloat 32
  7837. %uint = OpTypeInt 32 0
  7838. %ptrFloat = OpTypePointer Input %float
  7839. %uint_3 = OpConstant %uint 3
  7840. %floatArray = OpTypeArray %float %uint_3
  7841. %ptrFloatArray = OpTypePointer Input %floatArray
  7842. %vertexIDs = OpVariable %ptrFloatArray Input
  7843. %int = OpTypeInt 32 1
  7844. %int_0 = OpConstant %int 0
  7845. %main = OpFunction %void None %func
  7846. %label = OpLabel
  7847. %access = OpAccessChain %ptrFloat %vertexIDs %int_0
  7848. %load = OpLoad %float %access
  7849. OpReturn
  7850. OpFunctionEnd
  7851. )";
  7852. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  7853. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  7854. }
  7855. TEST_F(ValidateDecorations, PerVertexVulkanOutput) {
  7856. const std::string spirv = R"(
  7857. OpCapability Shader
  7858. OpCapability FragmentBarycentricKHR
  7859. OpExtension "SPV_KHR_fragment_shader_barycentric"
  7860. %1 = OpExtInstImport "GLSL.std.450"
  7861. OpMemoryModel Logical GLSL450
  7862. OpEntryPoint Fragment %main "main" %vertexIDs
  7863. OpExecutionMode %main OriginUpperLeft
  7864. OpDecorate %vertexIDs Location 0
  7865. OpDecorate %vertexIDs PerVertexKHR
  7866. %void = OpTypeVoid
  7867. %func = OpTypeFunction %void
  7868. %float = OpTypeFloat 32
  7869. %uint = OpTypeInt 32 0
  7870. %ptrFloat = OpTypePointer Output %float
  7871. %uint_3 = OpConstant %uint 3
  7872. %floatArray = OpTypeArray %float %uint_3
  7873. %ptrFloatArray = OpTypePointer Output %floatArray
  7874. %vertexIDs = OpVariable %ptrFloatArray Output
  7875. %int = OpTypeInt 32 1
  7876. %int_0 = OpConstant %int 0
  7877. %main = OpFunction %void None %func
  7878. %label = OpLabel
  7879. %access = OpAccessChain %ptrFloat %vertexIDs %int_0
  7880. %load = OpLoad %float %access
  7881. OpReturn
  7882. OpFunctionEnd
  7883. )";
  7884. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  7885. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  7886. EXPECT_THAT(getDiagnosticString(),
  7887. AnyVUID("VUID-StandaloneSpirv-PerVertexKHR-06777"));
  7888. EXPECT_THAT(getDiagnosticString(), HasSubstr("storage class must be Input"));
  7889. }
  7890. TEST_F(ValidateDecorations, PerVertexVulkanNonFragment) {
  7891. const std::string spirv = R"(
  7892. OpCapability Shader
  7893. OpCapability FragmentBarycentricKHR
  7894. OpExtension "SPV_KHR_fragment_shader_barycentric"
  7895. %1 = OpExtInstImport "GLSL.std.450"
  7896. OpMemoryModel Logical GLSL450
  7897. OpEntryPoint Vertex %main "main" %vertexIDs
  7898. OpDecorate %vertexIDs Location 0
  7899. OpDecorate %vertexIDs PerVertexKHR
  7900. %void = OpTypeVoid
  7901. %func = OpTypeFunction %void
  7902. %float = OpTypeFloat 32
  7903. %uint = OpTypeInt 32 0
  7904. %ptrFloat = OpTypePointer Input %float
  7905. %uint_3 = OpConstant %uint 3
  7906. %floatArray = OpTypeArray %float %uint_3
  7907. %ptrFloatArray = OpTypePointer Input %floatArray
  7908. %vertexIDs = OpVariable %ptrFloatArray Input
  7909. %int = OpTypeInt 32 1
  7910. %int_0 = OpConstant %int 0
  7911. %main = OpFunction %void None %func
  7912. %label = OpLabel
  7913. %access = OpAccessChain %ptrFloat %vertexIDs %int_0
  7914. %load = OpLoad %float %access
  7915. OpReturn
  7916. OpFunctionEnd
  7917. )";
  7918. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  7919. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  7920. EXPECT_THAT(getDiagnosticString(),
  7921. AnyVUID("VUID-StandaloneSpirv-PerVertexKHR-06777"));
  7922. EXPECT_THAT(
  7923. getDiagnosticString(),
  7924. HasSubstr(
  7925. "PerVertexKHR can only be applied to Fragment Execution Models"));
  7926. }
  7927. TEST_F(ValidateDecorations, PerVertexVulkanNonArray) {
  7928. const std::string spirv = R"(
  7929. OpCapability Shader
  7930. OpCapability FragmentBarycentricKHR
  7931. OpExtension "SPV_KHR_fragment_shader_barycentric"
  7932. %1 = OpExtInstImport "GLSL.std.450"
  7933. OpMemoryModel Logical GLSL450
  7934. OpEntryPoint Fragment %main "main" %vertexIDs
  7935. OpExecutionMode %main OriginUpperLeft
  7936. OpDecorate %vertexIDs Location 0
  7937. OpDecorate %vertexIDs PerVertexKHR
  7938. %void = OpTypeVoid
  7939. %func = OpTypeFunction %void
  7940. %float = OpTypeFloat 32
  7941. %ptrFloat = OpTypePointer Input %float
  7942. %vertexIDs = OpVariable %ptrFloat Input
  7943. %int = OpTypeInt 32 1
  7944. %int_0 = OpConstant %int 0
  7945. %main = OpFunction %void None %func
  7946. %label = OpLabel
  7947. %load = OpLoad %float %vertexIDs
  7948. OpReturn
  7949. OpFunctionEnd
  7950. )";
  7951. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  7952. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  7953. EXPECT_THAT(getDiagnosticString(),
  7954. AnyVUID("VUID-StandaloneSpirv-Input-06778"));
  7955. EXPECT_THAT(getDiagnosticString(),
  7956. HasSubstr("PerVertexKHR must be declared as arrays"));
  7957. }
  7958. TEST_F(ValidateDecorations, RelaxedPrecisionDecorationOnNumericTypeBad) {
  7959. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  7960. std::string spirv = R"(
  7961. OpCapability Shader
  7962. OpMemoryModel Logical GLSL450
  7963. OpEntryPoint Fragment %main "main"
  7964. OpExecutionMode %main OriginUpperLeft
  7965. OpDecorate %float RelaxedPrecision
  7966. %void = OpTypeVoid
  7967. %voidfn = OpTypeFunction %void
  7968. %float = OpTypeFloat 32
  7969. %main = OpFunction %void None %voidfn
  7970. %label = OpLabel
  7971. OpReturn
  7972. OpFunctionEnd
  7973. )";
  7974. CompileSuccessfully(spirv, env);
  7975. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
  7976. EXPECT_THAT(
  7977. getDiagnosticString(),
  7978. HasSubstr("RelaxPrecision decoration cannot be applied to a type"));
  7979. }
  7980. TEST_F(ValidateDecorations, RelaxedPrecisionDecorationOnStructMember) {
  7981. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  7982. std::string spirv = R"(
  7983. OpCapability Shader
  7984. OpMemoryModel Logical GLSL450
  7985. OpEntryPoint Fragment %main "main"
  7986. OpExecutionMode %main OriginUpperLeft
  7987. OpMemberDecorate %struct 0 RelaxedPrecision
  7988. %void = OpTypeVoid
  7989. %voidfn = OpTypeFunction %void
  7990. %float = OpTypeFloat 32
  7991. %struct = OpTypeStruct %float
  7992. %main = OpFunction %void None %voidfn
  7993. %label = OpLabel
  7994. OpReturn
  7995. OpFunctionEnd
  7996. )";
  7997. CompileSuccessfully(spirv, env);
  7998. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
  7999. }
  8000. TEST_F(ValidateDecorations, VulkanFlatMultipleInterfaceGood) {
  8001. std::string spirv = R"(
  8002. OpCapability Shader
  8003. OpCapability Geometry
  8004. %1 = OpExtInstImport "GLSL.std.450"
  8005. OpMemoryModel Logical GLSL450
  8006. OpEntryPoint Fragment %main "main" %layer %gl_Layer
  8007. OpExecutionMode %main OriginUpperLeft
  8008. OpSource GLSL 450
  8009. OpDecorate %layer Location 0
  8010. OpDecorate %gl_Layer Flat
  8011. OpDecorate %gl_Layer BuiltIn Layer
  8012. %void = OpTypeVoid
  8013. %3 = OpTypeFunction %void
  8014. %int = OpTypeInt 32 1
  8015. %_ptr_Output_int = OpTypePointer Output %int
  8016. %layer = OpVariable %_ptr_Output_int Output
  8017. %_ptr_Input_int = OpTypePointer Input %int
  8018. %gl_Layer = OpVariable %_ptr_Input_int Input
  8019. %main = OpFunction %void None %3
  8020. %5 = OpLabel
  8021. %11 = OpLoad %int %gl_Layer
  8022. OpStore %layer %11
  8023. OpReturn
  8024. OpFunctionEnd
  8025. )";
  8026. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8027. EXPECT_EQ(SPV_SUCCESS,
  8028. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  8029. }
  8030. TEST_F(ValidateDecorations, VulkanFlatMultipleInterfaceBad) {
  8031. std::string spirv = R"(
  8032. OpCapability Shader
  8033. OpCapability Geometry
  8034. %1 = OpExtInstImport "GLSL.std.450"
  8035. OpMemoryModel Logical GLSL450
  8036. OpEntryPoint Fragment %main "main" %layer %gl_Layer
  8037. OpExecutionMode %main OriginUpperLeft
  8038. OpSource GLSL 450
  8039. OpDecorate %layer Location 0
  8040. OpDecorate %gl_Layer BuiltIn Layer
  8041. %void = OpTypeVoid
  8042. %3 = OpTypeFunction %void
  8043. %int = OpTypeInt 32 1
  8044. %_ptr_Output_int = OpTypePointer Output %int
  8045. %layer = OpVariable %_ptr_Output_int Output
  8046. %_ptr_Input_int = OpTypePointer Input %int
  8047. %gl_Layer = OpVariable %_ptr_Input_int Input
  8048. %main = OpFunction %void None %3
  8049. %5 = OpLabel
  8050. %11 = OpLoad %int %gl_Layer
  8051. OpStore %layer %11
  8052. OpReturn
  8053. OpFunctionEnd
  8054. )";
  8055. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8056. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  8057. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  8058. EXPECT_THAT(getDiagnosticString(),
  8059. AnyVUID("VUID-StandaloneSpirv-Flat-04744"));
  8060. EXPECT_THAT(
  8061. getDiagnosticString(),
  8062. HasSubstr(
  8063. "Fragment OpEntryPoint operand 4 with Input interfaces with integer "
  8064. "or float type must have a Flat decoration for Entry Point id 2."));
  8065. }
  8066. TEST_F(ValidateDecorations, VulkanNoFlatFloat32) {
  8067. std::string spirv = R"(
  8068. OpCapability Shader
  8069. %1 = OpExtInstImport "GLSL.std.450"
  8070. OpMemoryModel Logical GLSL450
  8071. OpEntryPoint Fragment %main "main" %in
  8072. OpExecutionMode %main OriginUpperLeft
  8073. OpSource GLSL 450
  8074. OpDecorate %in Location 0
  8075. %void = OpTypeVoid
  8076. %3 = OpTypeFunction %void
  8077. %float = OpTypeFloat 32
  8078. %_ptr_Function_float = OpTypePointer Function %float
  8079. %_ptr_Input_float = OpTypePointer Input %float
  8080. %in = OpVariable %_ptr_Input_float Input
  8081. %main = OpFunction %void None %3
  8082. %5 = OpLabel
  8083. %b = OpVariable %_ptr_Function_float Function
  8084. %11 = OpLoad %float %in
  8085. OpStore %b %11
  8086. OpReturn
  8087. OpFunctionEnd
  8088. )";
  8089. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8090. EXPECT_EQ(SPV_SUCCESS,
  8091. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  8092. }
  8093. TEST_F(ValidateDecorations, VulkanNoFlatFloat64) {
  8094. std::string spirv = R"(
  8095. OpCapability Shader
  8096. OpCapability Float64
  8097. %1 = OpExtInstImport "GLSL.std.450"
  8098. OpMemoryModel Logical GLSL450
  8099. OpEntryPoint Fragment %main "main" %in
  8100. OpExecutionMode %main OriginUpperLeft
  8101. OpSource GLSL 450
  8102. OpDecorate %in Location 0
  8103. %void = OpTypeVoid
  8104. %3 = OpTypeFunction %void
  8105. %double = OpTypeFloat 64
  8106. %_ptr_Function_double = OpTypePointer Function %double
  8107. %_ptr_Input_double = OpTypePointer Input %double
  8108. %in = OpVariable %_ptr_Input_double Input
  8109. %main = OpFunction %void None %3
  8110. %5 = OpLabel
  8111. %b = OpVariable %_ptr_Function_double Function
  8112. %11 = OpLoad %double %in
  8113. OpStore %b %11
  8114. OpReturn
  8115. OpFunctionEnd
  8116. )";
  8117. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8118. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  8119. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  8120. EXPECT_THAT(getDiagnosticString(),
  8121. AnyVUID("VUID-StandaloneSpirv-Flat-04744"));
  8122. EXPECT_THAT(
  8123. getDiagnosticString(),
  8124. HasSubstr(
  8125. "Fragment OpEntryPoint operand 3 with Input interfaces with integer "
  8126. "or float type must have a Flat decoration for Entry Point id 2."));
  8127. }
  8128. TEST_F(ValidateDecorations, VulkanNoFlatVectorFloat64) {
  8129. std::string spirv = R"(
  8130. OpCapability Shader
  8131. OpCapability Float64
  8132. %1 = OpExtInstImport "GLSL.std.450"
  8133. OpMemoryModel Logical GLSL450
  8134. OpEntryPoint Fragment %main "main" %in
  8135. OpExecutionMode %main OriginUpperLeft
  8136. OpSource GLSL 450
  8137. OpDecorate %in Location 0
  8138. %void = OpTypeVoid
  8139. %3 = OpTypeFunction %void
  8140. %double = OpTypeFloat 64
  8141. %v2double = OpTypeVector %double 2
  8142. %_ptr_Function_v2double = OpTypePointer Function %v2double
  8143. %_ptr_Input_v2double = OpTypePointer Input %v2double
  8144. %in = OpVariable %_ptr_Input_v2double Input
  8145. %main = OpFunction %void None %3
  8146. %5 = OpLabel
  8147. %b = OpVariable %_ptr_Function_v2double Function
  8148. %11 = OpLoad %v2double %in
  8149. OpStore %b %11
  8150. OpReturn
  8151. OpFunctionEnd
  8152. )";
  8153. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8154. EXPECT_EQ(SPV_SUCCESS,
  8155. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  8156. }
  8157. TEST_F(ValidateDecorations, VulkanNoFlatIntVector) {
  8158. std::string spirv = R"(
  8159. OpCapability Shader
  8160. %1 = OpExtInstImport "GLSL.std.450"
  8161. OpMemoryModel Logical GLSL450
  8162. OpEntryPoint Fragment %main "main" %in
  8163. OpExecutionMode %main OriginUpperLeft
  8164. OpSource GLSL 450
  8165. OpDecorate %in Location 0
  8166. %void = OpTypeVoid
  8167. %3 = OpTypeFunction %void
  8168. %int = OpTypeInt 32 1
  8169. %v2int = OpTypeVector %int 2
  8170. %_ptr_Function_v2int = OpTypePointer Function %v2int
  8171. %_ptr_Input_v2int = OpTypePointer Input %v2int
  8172. %in = OpVariable %_ptr_Input_v2int Input
  8173. %main = OpFunction %void None %3
  8174. %5 = OpLabel
  8175. %b = OpVariable %_ptr_Function_v2int Function
  8176. %12 = OpLoad %v2int %in
  8177. OpStore %b %12
  8178. OpReturn
  8179. OpFunctionEnd
  8180. )";
  8181. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8182. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  8183. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
  8184. EXPECT_THAT(getDiagnosticString(),
  8185. AnyVUID("VUID-StandaloneSpirv-Flat-04744"));
  8186. EXPECT_THAT(
  8187. getDiagnosticString(),
  8188. HasSubstr(
  8189. "Fragment OpEntryPoint operand 3 with Input interfaces with integer "
  8190. "or float type must have a Flat decoration for Entry Point id 2."));
  8191. }
  8192. TEST_P(ValidateDecorationString, VulkanOutputInvalidInterface) {
  8193. const std::string decoration = GetParam();
  8194. std::stringstream ss;
  8195. ss << R"(
  8196. OpCapability Shader
  8197. OpCapability SampleRateShading
  8198. %1 = OpExtInstImport "GLSL.std.450"
  8199. OpMemoryModel Logical GLSL450
  8200. OpEntryPoint Fragment %main "main" %out
  8201. OpExecutionMode %main OriginUpperLeft
  8202. OpSource GLSL 450
  8203. OpDecorate %out )"
  8204. << decoration << R"(
  8205. OpDecorate %out Location 0
  8206. %void = OpTypeVoid
  8207. %3 = OpTypeFunction %void
  8208. %int = OpTypeInt 32 1
  8209. %_ptr_Output_int = OpTypePointer Output %int
  8210. %out = OpVariable %_ptr_Output_int Output
  8211. %int_1 = OpConstant %int 1
  8212. %main = OpFunction %void None %3
  8213. %5 = OpLabel
  8214. OpStore %out %int_1
  8215. OpReturn
  8216. OpFunctionEnd
  8217. )";
  8218. CompileSuccessfully(ss.str(), SPV_ENV_VULKAN_1_0);
  8219. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8220. EXPECT_THAT(getDiagnosticString(),
  8221. AnyVUID("VUID-StandaloneSpirv-Flat-06201"));
  8222. EXPECT_THAT(
  8223. getDiagnosticString(),
  8224. HasSubstr("decorated variable must not be used in fragment execution "
  8225. "model as an Output storage class for Entry Point id 2."));
  8226. }
  8227. TEST_P(ValidateDecorationString, VulkanVertexInputInvalidInterface) {
  8228. const std::string decoration = GetParam();
  8229. std::stringstream ss;
  8230. ss << R"(
  8231. OpCapability Shader
  8232. OpCapability SampleRateShading
  8233. %1 = OpExtInstImport "GLSL.std.450"
  8234. OpMemoryModel Logical GLSL450
  8235. OpEntryPoint Vertex %main "main" %out %in
  8236. OpSource GLSL 450
  8237. OpDecorate %in )"
  8238. << decoration << R"(
  8239. OpDecorate %out Location 0
  8240. OpDecorate %in Location 0
  8241. %void = OpTypeVoid
  8242. %3 = OpTypeFunction %void
  8243. %int = OpTypeInt 32 1
  8244. %_ptr_Output_int = OpTypePointer Output %int
  8245. %out = OpVariable %_ptr_Output_int Output
  8246. %_ptr_Input_int = OpTypePointer Input %int
  8247. %in = OpVariable %_ptr_Input_int Input
  8248. %main = OpFunction %void None %3
  8249. %5 = OpLabel
  8250. %11 = OpLoad %int %in
  8251. OpStore %out %11
  8252. OpReturn
  8253. OpFunctionEnd
  8254. )";
  8255. CompileSuccessfully(ss.str(), SPV_ENV_VULKAN_1_0);
  8256. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8257. EXPECT_THAT(getDiagnosticString(),
  8258. AnyVUID("VUID-StandaloneSpirv-Flat-06202"));
  8259. EXPECT_THAT(
  8260. getDiagnosticString(),
  8261. HasSubstr("decorated variable must not be used in vertex execution model "
  8262. "as an Input storage class for Entry Point id 2."));
  8263. }
  8264. INSTANTIATE_TEST_SUITE_P(FragmentInputInterface, ValidateDecorationString,
  8265. ::testing::Values("Flat", "NoPerspective", "Sample",
  8266. "Centroid"));
  8267. TEST_F(ValidateDecorations, NVBindlessSamplerArrayInBlock) {
  8268. const std::string spirv = R"(
  8269. OpCapability Shader
  8270. OpCapability BindlessTextureNV
  8271. OpExtension "SPV_NV_bindless_texture"
  8272. %1 = OpExtInstImport "GLSL.std.450"
  8273. OpMemoryModel Logical GLSL450
  8274. OpSamplerImageAddressingModeNV 64
  8275. OpEntryPoint Fragment %main "main"
  8276. OpExecutionMode %main OriginUpperLeft
  8277. OpSource GLSL 450
  8278. OpName %main "main"
  8279. OpName %UBO "UBO"
  8280. OpMemberName %UBO 0 "uboSampler"
  8281. OpName %_ ""
  8282. OpDecorate %array ArrayStride 16
  8283. OpMemberDecorate %UBO 0 Offset 0
  8284. OpDecorate %UBO Block
  8285. OpDecorate %_ DescriptorSet 0
  8286. OpDecorate %_ Binding 2
  8287. %void = OpTypeVoid
  8288. %3 = OpTypeFunction %void
  8289. %float = OpTypeFloat 32
  8290. %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8291. %8 = OpTypeSampledImage %7
  8292. %uint = OpTypeInt 32 0
  8293. %uint_3 = OpConstant %uint 3
  8294. %array = OpTypeArray %8 %uint_3
  8295. %UBO = OpTypeStruct %array
  8296. %pointer = OpTypePointer Uniform %UBO
  8297. %_ = OpVariable %pointer Uniform
  8298. %main = OpFunction %void None %3
  8299. %5 = OpLabel
  8300. OpReturn
  8301. OpFunctionEnd
  8302. )";
  8303. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  8304. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  8305. }
  8306. TEST_F(ValidateDecorations, Std140ColMajorMat2x2) {
  8307. const std::string spirv = R"(
  8308. OpCapability Shader
  8309. OpMemoryModel Logical GLSL450
  8310. OpEntryPoint GLCompute %main "main"
  8311. OpExecutionMode %main LocalSize 1 1 1
  8312. OpDecorate %block Block
  8313. OpMemberDecorate %block 0 Offset 0
  8314. OpMemberDecorate %block 0 ColMajor
  8315. OpMemberDecorate %block 0 MatrixStride 8
  8316. OpDecorate %var DescriptorSet 0
  8317. OpDecorate %var Binding 0
  8318. %void = OpTypeVoid
  8319. %void_fn = OpTypeFunction %void
  8320. %float = OpTypeFloat 32
  8321. %float2 = OpTypeVector %float 2
  8322. %matrix = OpTypeMatrix %float2 2
  8323. %block = OpTypeStruct %matrix
  8324. %ptr_block = OpTypePointer Uniform %block
  8325. %var = OpVariable %ptr_block Uniform
  8326. %main = OpFunction %void None %void_fn
  8327. %entry = OpLabel
  8328. OpReturn
  8329. OpFunctionEnd
  8330. )";
  8331. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8332. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8333. EXPECT_THAT(
  8334. getDiagnosticString(),
  8335. HasSubstr(
  8336. "member 0 is a matrix with stride 8 not satisfying alignment to 16"));
  8337. }
  8338. TEST_F(ValidateDecorations, Std140RowMajorMat2x2) {
  8339. const std::string spirv = R"(
  8340. OpCapability Shader
  8341. OpMemoryModel Logical GLSL450
  8342. OpEntryPoint GLCompute %main "main"
  8343. OpExecutionMode %main LocalSize 1 1 1
  8344. OpDecorate %block Block
  8345. OpMemberDecorate %block 0 Offset 0
  8346. OpMemberDecorate %block 0 RowMajor
  8347. OpMemberDecorate %block 0 MatrixStride 8
  8348. OpDecorate %var DescriptorSet 0
  8349. OpDecorate %var Binding 0
  8350. %void = OpTypeVoid
  8351. %void_fn = OpTypeFunction %void
  8352. %float = OpTypeFloat 32
  8353. %float2 = OpTypeVector %float 2
  8354. %matrix = OpTypeMatrix %float2 2
  8355. %block = OpTypeStruct %matrix
  8356. %ptr_block = OpTypePointer Uniform %block
  8357. %var = OpVariable %ptr_block Uniform
  8358. %main = OpFunction %void None %void_fn
  8359. %entry = OpLabel
  8360. OpReturn
  8361. OpFunctionEnd
  8362. )";
  8363. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8364. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8365. EXPECT_THAT(
  8366. getDiagnosticString(),
  8367. HasSubstr(
  8368. "member 0 is a matrix with stride 8 not satisfying alignment to 16"));
  8369. }
  8370. TEST_F(ValidateDecorations, Std140ColMajorMat4x2) {
  8371. const std::string spirv = R"(
  8372. OpCapability Shader
  8373. OpMemoryModel Logical GLSL450
  8374. OpEntryPoint GLCompute %main "main"
  8375. OpExecutionMode %main LocalSize 1 1 1
  8376. OpDecorate %block Block
  8377. OpMemberDecorate %block 0 Offset 0
  8378. OpMemberDecorate %block 0 ColMajor
  8379. OpMemberDecorate %block 0 MatrixStride 8
  8380. OpDecorate %var DescriptorSet 0
  8381. OpDecorate %var Binding 0
  8382. %void = OpTypeVoid
  8383. %void_fn = OpTypeFunction %void
  8384. %float = OpTypeFloat 32
  8385. %float2 = OpTypeVector %float 2
  8386. %matrix = OpTypeMatrix %float2 4
  8387. %block = OpTypeStruct %matrix
  8388. %ptr_block = OpTypePointer Uniform %block
  8389. %var = OpVariable %ptr_block Uniform
  8390. %main = OpFunction %void None %void_fn
  8391. %entry = OpLabel
  8392. OpReturn
  8393. OpFunctionEnd
  8394. )";
  8395. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8396. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8397. EXPECT_THAT(
  8398. getDiagnosticString(),
  8399. HasSubstr(
  8400. "member 0 is a matrix with stride 8 not satisfying alignment to 16"));
  8401. }
  8402. TEST_F(ValidateDecorations, Std140ColMajorMat2x3) {
  8403. const std::string spirv = R"(
  8404. OpCapability Shader
  8405. OpMemoryModel Logical GLSL450
  8406. OpEntryPoint GLCompute %main "main"
  8407. OpExecutionMode %main LocalSize 1 1 1
  8408. OpDecorate %block Block
  8409. OpMemberDecorate %block 0 Offset 0
  8410. OpMemberDecorate %block 0 ColMajor
  8411. OpMemberDecorate %block 0 MatrixStride 12
  8412. OpDecorate %var DescriptorSet 0
  8413. OpDecorate %var Binding 0
  8414. %void = OpTypeVoid
  8415. %void_fn = OpTypeFunction %void
  8416. %float = OpTypeFloat 32
  8417. %float3 = OpTypeVector %float 3
  8418. %matrix = OpTypeMatrix %float3 2
  8419. %block = OpTypeStruct %matrix
  8420. %ptr_block = OpTypePointer Uniform %block
  8421. %var = OpVariable %ptr_block Uniform
  8422. %main = OpFunction %void None %void_fn
  8423. %entry = OpLabel
  8424. OpReturn
  8425. OpFunctionEnd
  8426. )";
  8427. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8428. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8429. EXPECT_THAT(getDiagnosticString(),
  8430. HasSubstr("member 0 is a matrix with stride 12 not satisfying "
  8431. "alignment to 16"));
  8432. }
  8433. TEST_F(ValidateDecorations, MatrixMissingMajornessUniform) {
  8434. const std::string spirv = R"(
  8435. OpCapability Shader
  8436. OpMemoryModel Logical GLSL450
  8437. OpEntryPoint GLCompute %main "main"
  8438. OpExecutionMode %main LocalSize 1 1 1
  8439. OpDecorate %block Block
  8440. OpMemberDecorate %block 0 Offset 0
  8441. OpMemberDecorate %block 0 MatrixStride 16
  8442. OpDecorate %var DescriptorSet 0
  8443. OpDecorate %var Binding 0
  8444. %void = OpTypeVoid
  8445. %void_fn = OpTypeFunction %void
  8446. %float = OpTypeFloat 32
  8447. %float2 = OpTypeVector %float 2
  8448. %matrix = OpTypeMatrix %float2 2
  8449. %block = OpTypeStruct %matrix
  8450. %ptr_block = OpTypePointer Uniform %block
  8451. %var = OpVariable %ptr_block Uniform
  8452. %main = OpFunction %void None %void_fn
  8453. %entry = OpLabel
  8454. OpReturn
  8455. OpFunctionEnd
  8456. )";
  8457. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8458. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8459. EXPECT_THAT(
  8460. getDiagnosticString(),
  8461. HasSubstr(
  8462. "must be explicitly laid out with RowMajor or ColMajor decorations"));
  8463. }
  8464. TEST_F(ValidateDecorations, MatrixMissingMajornessStorageBuffer) {
  8465. const std::string spirv = R"(
  8466. OpCapability Shader
  8467. OpExtension "SPV_KHR_storage_buffer_storage_class"
  8468. OpMemoryModel Logical GLSL450
  8469. OpEntryPoint GLCompute %main "main"
  8470. OpExecutionMode %main LocalSize 1 1 1
  8471. OpDecorate %block Block
  8472. OpMemberDecorate %block 0 Offset 0
  8473. OpMemberDecorate %block 0 MatrixStride 16
  8474. OpDecorate %var DescriptorSet 0
  8475. OpDecorate %var Binding 0
  8476. %void = OpTypeVoid
  8477. %void_fn = OpTypeFunction %void
  8478. %float = OpTypeFloat 32
  8479. %float2 = OpTypeVector %float 2
  8480. %matrix = OpTypeMatrix %float2 2
  8481. %block = OpTypeStruct %matrix
  8482. %ptr_block = OpTypePointer StorageBuffer %block
  8483. %var = OpVariable %ptr_block StorageBuffer
  8484. %main = OpFunction %void None %void_fn
  8485. %entry = OpLabel
  8486. OpReturn
  8487. OpFunctionEnd
  8488. )";
  8489. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8490. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8491. EXPECT_THAT(
  8492. getDiagnosticString(),
  8493. HasSubstr(
  8494. "must be explicitly laid out with RowMajor or ColMajor decorations"));
  8495. }
  8496. TEST_F(ValidateDecorations, MatrixMissingMajornessPushConstant) {
  8497. const std::string spirv = R"(
  8498. OpCapability Shader
  8499. OpMemoryModel Logical GLSL450
  8500. OpEntryPoint GLCompute %main "main"
  8501. OpExecutionMode %main LocalSize 1 1 1
  8502. OpDecorate %block Block
  8503. OpMemberDecorate %block 0 Offset 0
  8504. OpMemberDecorate %block 0 MatrixStride 16
  8505. %void = OpTypeVoid
  8506. %void_fn = OpTypeFunction %void
  8507. %float = OpTypeFloat 32
  8508. %float2 = OpTypeVector %float 2
  8509. %matrix = OpTypeMatrix %float2 2
  8510. %block = OpTypeStruct %matrix
  8511. %ptr_block = OpTypePointer PushConstant %block
  8512. %var = OpVariable %ptr_block PushConstant
  8513. %main = OpFunction %void None %void_fn
  8514. %entry = OpLabel
  8515. OpReturn
  8516. OpFunctionEnd
  8517. )";
  8518. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8519. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8520. EXPECT_THAT(
  8521. getDiagnosticString(),
  8522. HasSubstr(
  8523. "must be explicitly laid out with RowMajor or ColMajor decorations"));
  8524. }
  8525. TEST_F(ValidateDecorations, StructWithRowAndColMajor) {
  8526. const std::string spirv = R"(
  8527. OpCapability Shader
  8528. OpMemoryModel Logical GLSL450
  8529. OpEntryPoint GLCompute %main "main"
  8530. OpExecutionMode %main LocalSize 1 1 1
  8531. OpDecorate %block Block
  8532. OpMemberDecorate %block 0 Offset 0
  8533. OpMemberDecorate %block 0 MatrixStride 16
  8534. OpMemberDecorate %block 0 ColMajor
  8535. OpMemberDecorate %block 1 Offset 32
  8536. OpMemberDecorate %block 1 MatrixStride 16
  8537. OpMemberDecorate %block 1 RowMajor
  8538. %void = OpTypeVoid
  8539. %void_fn = OpTypeFunction %void
  8540. %float = OpTypeFloat 32
  8541. %float2 = OpTypeVector %float 2
  8542. %matrix = OpTypeMatrix %float2 2
  8543. %block = OpTypeStruct %matrix %matrix
  8544. %ptr_block = OpTypePointer PushConstant %block
  8545. %var = OpVariable %ptr_block PushConstant
  8546. %main = OpFunction %void None %void_fn
  8547. %entry = OpLabel
  8548. OpReturn
  8549. OpFunctionEnd
  8550. )";
  8551. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  8552. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  8553. }
  8554. TEST_F(ValidateDecorations, PhysicalStorageBufferWithOffset) {
  8555. const std::string spirv = R"(
  8556. OpCapability Shader
  8557. OpCapability Int64
  8558. OpCapability PhysicalStorageBufferAddresses
  8559. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  8560. OpEntryPoint GLCompute %main "main" %pc
  8561. OpExecutionMode %main LocalSize 1 1 1
  8562. OpDecorate %pc_block Block
  8563. OpMemberDecorate %pc_block 0 Offset 0
  8564. OpMemberDecorate %pssbo_struct 0 Offset 0
  8565. %void = OpTypeVoid
  8566. %long = OpTypeInt 64 0
  8567. %float = OpTypeFloat 32
  8568. %int = OpTypeInt 32 0
  8569. %int_0 = OpConstant %int 0
  8570. %pc_block = OpTypeStruct %long
  8571. %pc_block_ptr = OpTypePointer PushConstant %pc_block
  8572. %pc_long_ptr = OpTypePointer PushConstant %long
  8573. %pc = OpVariable %pc_block_ptr PushConstant
  8574. %pssbo_struct = OpTypeStruct %float
  8575. %pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_struct
  8576. %void_fn = OpTypeFunction %void
  8577. %main = OpFunction %void None %void_fn
  8578. %entry = OpLabel
  8579. %pc_gep = OpAccessChain %pc_long_ptr %pc %int_0
  8580. %addr = OpLoad %long %pc_gep
  8581. %ptr = OpConvertUToPtr %pssbo_ptr %addr
  8582. OpReturn
  8583. OpFunctionEnd
  8584. )";
  8585. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  8586. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  8587. }
  8588. TEST_F(ValidateDecorations, UntypedVariableDuplicateInterface) {
  8589. const std::string spirv = R"(
  8590. OpCapability Shader
  8591. OpCapability UntypedPointersKHR
  8592. OpCapability WorkgroupMemoryExplicitLayoutKHR
  8593. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  8594. OpExtension "SPV_KHR_untyped_pointers"
  8595. OpMemoryModel Logical GLSL450
  8596. OpEntryPoint GLCompute %main "main" %var %var
  8597. OpName %var "var"
  8598. OpDecorate %struct Block
  8599. OpMemberDecorate %struct 0 Offset 0
  8600. %void = OpTypeVoid
  8601. %int = OpTypeInt 32 0
  8602. %struct = OpTypeStruct %int
  8603. %ptr = OpTypeUntypedPointerKHR Workgroup
  8604. %var = OpUntypedVariableKHR %ptr Workgroup %struct
  8605. %void_fn = OpTypeFunction %void
  8606. %main = OpFunction %void None %void_fn
  8607. %entry = OpLabel
  8608. OpReturn
  8609. OpFunctionEnd
  8610. )";
  8611. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  8612. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8613. EXPECT_THAT(
  8614. getDiagnosticString(),
  8615. HasSubstr("Non-unique OpEntryPoint interface '2[%var]' is disallowed"));
  8616. }
  8617. TEST_F(ValidateDecorations, PhysicalStorageBufferMissingOffset) {
  8618. const std::string spirv = R"(
  8619. OpCapability Shader
  8620. OpCapability Int64
  8621. OpCapability PhysicalStorageBufferAddresses
  8622. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  8623. OpEntryPoint GLCompute %main "main" %pc
  8624. OpExecutionMode %main LocalSize 1 1 1
  8625. OpDecorate %pc_block Block
  8626. OpMemberDecorate %pc_block 0 Offset 0
  8627. %void = OpTypeVoid
  8628. %long = OpTypeInt 64 0
  8629. %float = OpTypeFloat 32
  8630. %int = OpTypeInt 32 0
  8631. %int_0 = OpConstant %int 0
  8632. %pc_block = OpTypeStruct %long
  8633. %pc_block_ptr = OpTypePointer PushConstant %pc_block
  8634. %pc_long_ptr = OpTypePointer PushConstant %long
  8635. %pc = OpVariable %pc_block_ptr PushConstant
  8636. %pssbo_struct = OpTypeStruct %float
  8637. %pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_struct
  8638. %void_fn = OpTypeFunction %void
  8639. %main = OpFunction %void None %void_fn
  8640. %entry = OpLabel
  8641. %pc_gep = OpAccessChain %pc_long_ptr %pc %int_0
  8642. %addr = OpLoad %long %pc_gep
  8643. %ptr = OpConvertUToPtr %pssbo_ptr %addr
  8644. OpReturn
  8645. OpFunctionEnd
  8646. )";
  8647. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  8648. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  8649. EXPECT_THAT(
  8650. getDiagnosticString(),
  8651. HasSubstr("decorated as Block for variable in PhysicalStorageBuffer "
  8652. "storage class must follow relaxed storage buffer layout "
  8653. "rules: member 0 is missing an Offset decoration"));
  8654. }
  8655. TEST_F(ValidateDecorations, PhysicalStorageBufferMissingArrayStride) {
  8656. const std::string spirv = R"(
  8657. OpCapability Shader
  8658. OpCapability Int64
  8659. OpCapability PhysicalStorageBufferAddresses
  8660. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  8661. OpEntryPoint GLCompute %main "main" %pc
  8662. OpExecutionMode %main LocalSize 1 1 1
  8663. OpDecorate %pc_block Block
  8664. OpMemberDecorate %pc_block 0 Offset 0
  8665. %void = OpTypeVoid
  8666. %long = OpTypeInt 64 0
  8667. %float = OpTypeFloat 32
  8668. %int = OpTypeInt 32 0
  8669. %int_0 = OpConstant %int 0
  8670. %int_4 = OpConstant %int 4
  8671. %pc_block = OpTypeStruct %long
  8672. %pc_block_ptr = OpTypePointer PushConstant %pc_block
  8673. %pc_long_ptr = OpTypePointer PushConstant %long
  8674. %pc = OpVariable %pc_block_ptr PushConstant
  8675. %pssbo_array = OpTypeArray %float %int_4
  8676. %pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_array
  8677. %void_fn = OpTypeFunction %void
  8678. %main = OpFunction %void None %void_fn
  8679. %entry = OpLabel
  8680. %pc_gep = OpAccessChain %pc_long_ptr %pc %int_0
  8681. %addr = OpLoad %long %pc_gep
  8682. %ptr = OpConvertUToPtr %pssbo_ptr %addr
  8683. OpReturn
  8684. OpFunctionEnd
  8685. )";
  8686. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  8687. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  8688. EXPECT_THAT(
  8689. getDiagnosticString(),
  8690. HasSubstr(
  8691. "decorated as Block for variable in PhysicalStorageBuffer storage "
  8692. "class must follow relaxed storage buffer layout rules: member 0 "
  8693. "contains an array with stride 0, but with an element size of 4"));
  8694. }
  8695. TEST_F(ValidateDecorations, MatrixArrayMissingMajorness) {
  8696. const std::string spirv = R"(
  8697. OpCapability Shader
  8698. OpMemoryModel Logical GLSL450
  8699. OpEntryPoint GLCompute %main "main"
  8700. OpExecutionMode %main LocalSize 1 1 1
  8701. OpDecorate %var DescriptorSet 0
  8702. OpDecorate %var Binding 0
  8703. OpDecorate %block Block
  8704. OpMemberDecorate %block 0 Offset 0
  8705. OpMemberDecorate %block 0 MatrixStride 16
  8706. OpDecorate %array ArrayStride 32
  8707. %void = OpTypeVoid
  8708. %float = OpTypeFloat 32
  8709. %int = OpTypeInt 32 0
  8710. %int_2 = OpConstant %int 2
  8711. %vec = OpTypeVector %float 2
  8712. %mat = OpTypeMatrix %vec 2
  8713. %array = OpTypeArray %mat %int_2
  8714. %block = OpTypeStruct %array
  8715. %ptr = OpTypePointer Uniform %block
  8716. %var = OpVariable %ptr Uniform
  8717. %void_fn = OpTypeFunction %void
  8718. %main = OpFunction %void None %void_fn
  8719. %entry = OpLabel
  8720. OpReturn
  8721. OpFunctionEnd
  8722. )";
  8723. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  8724. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  8725. EXPECT_THAT(
  8726. getDiagnosticString(),
  8727. HasSubstr(
  8728. "must be explicitly laid out with RowMajor or ColMajor decorations"));
  8729. }
  8730. TEST_F(ValidateDecorations, MatrixArrayMissingStride) {
  8731. const std::string spirv = R"(
  8732. OpCapability Shader
  8733. OpMemoryModel Logical GLSL450
  8734. OpEntryPoint GLCompute %main "main"
  8735. OpExecutionMode %main LocalSize 1 1 1
  8736. OpDecorate %var DescriptorSet 0
  8737. OpDecorate %var Binding 0
  8738. OpDecorate %block Block
  8739. OpMemberDecorate %block 0 Offset 0
  8740. OpMemberDecorate %block 0 ColMajor
  8741. OpDecorate %array ArrayStride 32
  8742. %void = OpTypeVoid
  8743. %float = OpTypeFloat 32
  8744. %int = OpTypeInt 32 0
  8745. %int_2 = OpConstant %int 2
  8746. %vec = OpTypeVector %float 2
  8747. %mat = OpTypeMatrix %vec 2
  8748. %array = OpTypeArray %mat %int_2
  8749. %block = OpTypeStruct %array
  8750. %ptr = OpTypePointer Uniform %block
  8751. %var = OpVariable %ptr Uniform
  8752. %void_fn = OpTypeFunction %void
  8753. %main = OpFunction %void None %void_fn
  8754. %entry = OpLabel
  8755. OpReturn
  8756. OpFunctionEnd
  8757. )";
  8758. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  8759. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  8760. EXPECT_THAT(
  8761. getDiagnosticString(),
  8762. HasSubstr("must be explicitly laid out with MatrixStride decorations"));
  8763. }
  8764. TEST_F(ValidateDecorations, MatrixArrayBadStride) {
  8765. const std::string spirv = R"(
  8766. OpCapability Shader
  8767. OpMemoryModel Logical GLSL450
  8768. OpEntryPoint GLCompute %main "main"
  8769. OpExecutionMode %main LocalSize 1 1 1
  8770. OpDecorate %var DescriptorSet 0
  8771. OpDecorate %var Binding 0
  8772. OpDecorate %block Block
  8773. OpMemberDecorate %block 0 Offset 0
  8774. OpMemberDecorate %block 0 ColMajor
  8775. OpMemberDecorate %block 0 MatrixStride 8
  8776. OpDecorate %array ArrayStride 32
  8777. %void = OpTypeVoid
  8778. %float = OpTypeFloat 32
  8779. %int = OpTypeInt 32 0
  8780. %int_2 = OpConstant %int 2
  8781. %vec = OpTypeVector %float 2
  8782. %mat = OpTypeMatrix %vec 2
  8783. %array = OpTypeArray %mat %int_2
  8784. %block = OpTypeStruct %array
  8785. %ptr = OpTypePointer Uniform %block
  8786. %var = OpVariable %ptr Uniform
  8787. %void_fn = OpTypeFunction %void
  8788. %main = OpFunction %void None %void_fn
  8789. %entry = OpLabel
  8790. OpReturn
  8791. OpFunctionEnd
  8792. )";
  8793. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  8794. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  8795. EXPECT_THAT(
  8796. getDiagnosticString(),
  8797. HasSubstr("is a matrix with stride 8 not satisfying alignment to 16"));
  8798. }
  8799. TEST_F(ValidateDecorations, MatrixArrayArrayMissingMajorness) {
  8800. const std::string spirv = R"(
  8801. OpCapability Shader
  8802. OpMemoryModel Logical GLSL450
  8803. OpEntryPoint GLCompute %main "main"
  8804. OpExecutionMode %main LocalSize 1 1 1
  8805. OpDecorate %var DescriptorSet 0
  8806. OpDecorate %var Binding 0
  8807. OpDecorate %block Block
  8808. OpMemberDecorate %block 0 Offset 0
  8809. OpMemberDecorate %block 0 MatrixStride 16
  8810. OpDecorate %array ArrayStride 32
  8811. OpDecorate %rta ArrayStride 64
  8812. %void = OpTypeVoid
  8813. %float = OpTypeFloat 32
  8814. %int = OpTypeInt 32 0
  8815. %int_2 = OpConstant %int 2
  8816. %vec = OpTypeVector %float 2
  8817. %mat = OpTypeMatrix %vec 2
  8818. %array = OpTypeArray %mat %int_2
  8819. %rta = OpTypeRuntimeArray %array
  8820. %block = OpTypeStruct %rta
  8821. %ptr = OpTypePointer StorageBuffer %block
  8822. %var = OpVariable %ptr StorageBuffer
  8823. %void_fn = OpTypeFunction %void
  8824. %main = OpFunction %void None %void_fn
  8825. %entry = OpLabel
  8826. OpReturn
  8827. OpFunctionEnd
  8828. )";
  8829. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  8830. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  8831. EXPECT_THAT(
  8832. getDiagnosticString(),
  8833. HasSubstr(
  8834. "must be explicitly laid out with RowMajor or ColMajor decorations"));
  8835. }
  8836. TEST_F(ValidateDecorations, MatrixArrayArrayMissingStride) {
  8837. const std::string spirv = R"(
  8838. OpCapability Shader
  8839. OpMemoryModel Logical GLSL450
  8840. OpEntryPoint GLCompute %main "main"
  8841. OpExecutionMode %main LocalSize 1 1 1
  8842. OpDecorate %var DescriptorSet 0
  8843. OpDecorate %var Binding 0
  8844. OpDecorate %block Block
  8845. OpMemberDecorate %block 0 Offset 0
  8846. OpMemberDecorate %block 0 ColMajor
  8847. OpDecorate %array ArrayStride 32
  8848. OpDecorate %rta ArrayStride 64
  8849. %void = OpTypeVoid
  8850. %float = OpTypeFloat 32
  8851. %int = OpTypeInt 32 0
  8852. %int_2 = OpConstant %int 2
  8853. %vec = OpTypeVector %float 2
  8854. %mat = OpTypeMatrix %vec 2
  8855. %array = OpTypeArray %mat %int_2
  8856. %rta = OpTypeRuntimeArray %array
  8857. %block = OpTypeStruct %rta
  8858. %ptr = OpTypePointer StorageBuffer %block
  8859. %var = OpVariable %ptr StorageBuffer
  8860. %void_fn = OpTypeFunction %void
  8861. %main = OpFunction %void None %void_fn
  8862. %entry = OpLabel
  8863. OpReturn
  8864. OpFunctionEnd
  8865. )";
  8866. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  8867. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  8868. EXPECT_THAT(
  8869. getDiagnosticString(),
  8870. HasSubstr("must be explicitly laid out with MatrixStride decorations"));
  8871. }
  8872. TEST_F(ValidateDecorations, MatrixArrayArrayBadStride) {
  8873. const std::string spirv = R"(
  8874. OpCapability Shader
  8875. OpMemoryModel Logical GLSL450
  8876. OpEntryPoint GLCompute %main "main"
  8877. OpExecutionMode %main LocalSize 1 1 1
  8878. OpDecorate %var DescriptorSet 0
  8879. OpDecorate %var Binding 0
  8880. OpDecorate %block Block
  8881. OpMemberDecorate %block 0 Offset 0
  8882. OpMemberDecorate %block 0 ColMajor
  8883. OpMemberDecorate %block 0 MatrixStride 8
  8884. OpDecorate %array ArrayStride 32
  8885. OpDecorate %a ArrayStride 64
  8886. %void = OpTypeVoid
  8887. %float = OpTypeFloat 32
  8888. %int = OpTypeInt 32 0
  8889. %int_2 = OpConstant %int 2
  8890. %vec = OpTypeVector %float 2
  8891. %mat = OpTypeMatrix %vec 2
  8892. %array = OpTypeArray %mat %int_2
  8893. %a = OpTypeArray %array %int_2
  8894. %block = OpTypeStruct %a
  8895. %ptr = OpTypePointer Uniform %block
  8896. %var = OpVariable %ptr Uniform
  8897. %void_fn = OpTypeFunction %void
  8898. %main = OpFunction %void None %void_fn
  8899. %entry = OpLabel
  8900. OpReturn
  8901. OpFunctionEnd
  8902. )";
  8903. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  8904. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  8905. EXPECT_THAT(
  8906. getDiagnosticString(),
  8907. HasSubstr("is a matrix with stride 8 not satisfying alignment to 16"));
  8908. }
  8909. TEST_F(ValidateDecorations, MultipleBuiltinsInputVertex) {
  8910. const std::string body = R"(
  8911. OpCapability Shader
  8912. OpCapability DrawParameters
  8913. OpMemoryModel Logical GLSL450
  8914. OpEntryPoint Vertex %main "main" %_ %gl_BaseInstance1 %gl_BaseInstance2
  8915. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  8916. OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
  8917. OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
  8918. OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
  8919. OpDecorate %gl_PerVertex Block
  8920. OpDecorate %gl_BaseInstance1 BuiltIn BaseInstance
  8921. OpDecorate %gl_BaseInstance2 BuiltIn BaseInstance
  8922. %void = OpTypeVoid
  8923. %3 = OpTypeFunction %void
  8924. %float = OpTypeFloat 32
  8925. %v4float = OpTypeVector %float 4
  8926. %uint = OpTypeInt 32 0
  8927. %uint_1 = OpConstant %uint 1
  8928. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  8929. %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  8930. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  8931. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  8932. %int = OpTypeInt 32 1
  8933. %int_0 = OpConstant %int 0
  8934. %float_0 = OpConstant %float 0
  8935. %17 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  8936. %_ptr_Input_int = OpTypePointer Input %int
  8937. %gl_BaseInstance1 = OpVariable %_ptr_Input_int Input
  8938. %gl_BaseInstance2 = OpVariable %_ptr_Input_int Input
  8939. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8940. %main = OpFunction %void None %3
  8941. %5 = OpLabel
  8942. %20 = OpLoad %int %gl_BaseInstance1
  8943. %21 = OpConvertSToF %float %20
  8944. %22 = OpVectorTimesScalar %v4float %17 %21
  8945. %24 = OpAccessChain %_ptr_Output_v4float %_ %int_0
  8946. OpStore %24 %22
  8947. OpReturn
  8948. OpFunctionEnd
  8949. )";
  8950. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  8951. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  8952. EXPECT_THAT(getDiagnosticString(),
  8953. HasSubstr("OpEntryPoint contains duplicate input variables with "
  8954. "BaseInstance builtin"));
  8955. EXPECT_THAT(getDiagnosticString(),
  8956. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09658"));
  8957. }
  8958. TEST_F(ValidateDecorations, MultipleBuiltinsInputMesh) {
  8959. const std::string body = R"(
  8960. OpCapability DrawParameters
  8961. OpCapability MeshShadingEXT
  8962. OpExtension "SPV_EXT_mesh_shader"
  8963. OpMemoryModel Logical GLSL450
  8964. OpEntryPoint MeshEXT %main "main" %gl_DrawID_1 %gl_DrawID_2
  8965. OpExecutionMode %main LocalSize 1 1 1
  8966. OpExecutionMode %main OutputVertices 32
  8967. OpExecutionMode %main OutputPrimitivesEXT 32
  8968. OpExecutionMode %main OutputTrianglesEXT
  8969. OpDecorate %gl_DrawID_1 BuiltIn DrawIndex
  8970. OpDecorate %gl_DrawID_2 BuiltIn DrawIndex
  8971. %void = OpTypeVoid
  8972. %3 = OpTypeFunction %void
  8973. %int = OpTypeInt 32 1
  8974. %_ptr_Input_int = OpTypePointer Input %int
  8975. %gl_DrawID_1 = OpVariable %_ptr_Input_int Input
  8976. %gl_DrawID_2 = OpVariable %_ptr_Input_int Input
  8977. %uint = OpTypeInt 32 0
  8978. %main = OpFunction %void None %3
  8979. %5 = OpLabel
  8980. %9 = OpLoad %int %gl_DrawID_1
  8981. %11 = OpBitcast %uint %9
  8982. %12 = OpLoad %int %gl_DrawID_2
  8983. %13 = OpBitcast %uint %12
  8984. OpSetMeshOutputsEXT %11 %13
  8985. OpReturn
  8986. OpFunctionEnd
  8987. )";
  8988. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  8989. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  8990. EXPECT_THAT(getDiagnosticString(),
  8991. HasSubstr("OpEntryPoint contains duplicate input variables with "
  8992. "DrawIndex builtin"));
  8993. EXPECT_THAT(getDiagnosticString(),
  8994. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09658"));
  8995. }
  8996. TEST_F(ValidateDecorations, MultipleBuiltinsInputCompute) {
  8997. const std::string body = R"(
  8998. OpCapability Shader
  8999. OpMemoryModel Logical GLSL450
  9000. OpEntryPoint GLCompute %main "main" %_ %gl_WorkGroupID_1 %gl_WorkGroupID_2
  9001. OpExecutionMode %main LocalSize 1 1 1
  9002. OpMemberDecorate %Buffers 0 Offset 0
  9003. OpDecorate %Buffers Block
  9004. OpDecorate %_ DescriptorSet 0
  9005. OpDecorate %_ Binding 0
  9006. OpDecorate %gl_WorkGroupID_1 BuiltIn WorkgroupId
  9007. OpDecorate %gl_WorkGroupID_2 BuiltIn WorkgroupId
  9008. %void = OpTypeVoid
  9009. %3 = OpTypeFunction %void
  9010. %uint = OpTypeInt 32 0
  9011. %v3uint = OpTypeVector %uint 3
  9012. %Buffers = OpTypeStruct %v3uint
  9013. %_ptr_StorageBuffer_Buffers = OpTypePointer StorageBuffer %Buffers
  9014. %_ = OpVariable %_ptr_StorageBuffer_Buffers StorageBuffer
  9015. %int = OpTypeInt 32 1
  9016. %int_0 = OpConstant %int 0
  9017. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  9018. %gl_WorkGroupID_1 = OpVariable %_ptr_Input_v3uint Input
  9019. %gl_WorkGroupID_2 = OpVariable %_ptr_Input_v3uint Input
  9020. %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
  9021. %main = OpFunction %void None %3
  9022. %5 = OpLabel
  9023. %15 = OpLoad %v3uint %gl_WorkGroupID_1
  9024. %16 = OpLoad %v3uint %gl_WorkGroupID_2
  9025. %17 = OpIAdd %v3uint %15 %16
  9026. %19 = OpAccessChain %_ptr_StorageBuffer_v3uint %_ %int_0
  9027. OpStore %19 %17
  9028. OpReturn
  9029. OpFunctionEnd
  9030. )";
  9031. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  9032. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  9033. EXPECT_THAT(getDiagnosticString(),
  9034. HasSubstr("OpEntryPoint contains duplicate input variables with "
  9035. "WorkgroupId builtin"));
  9036. EXPECT_THAT(getDiagnosticString(),
  9037. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09658"));
  9038. }
  9039. TEST_F(ValidateDecorations, MultipleBuiltinsOutputFragment) {
  9040. const std::string body = R"(
  9041. OpCapability Shader
  9042. OpMemoryModel Logical GLSL450
  9043. OpEntryPoint Fragment %main "main" %gl_FragDepth_1 %gl_FragDepth_2
  9044. OpExecutionMode %main OriginUpperLeft
  9045. OpExecutionMode %main DepthReplacing
  9046. OpDecorate %gl_FragDepth_1 BuiltIn FragDepth
  9047. OpDecorate %gl_FragDepth_2 BuiltIn FragDepth
  9048. %void = OpTypeVoid
  9049. %3 = OpTypeFunction %void
  9050. %float = OpTypeFloat 32
  9051. %_ptr_Output_float = OpTypePointer Output %float
  9052. %gl_FragDepth_1 = OpVariable %_ptr_Output_float Output
  9053. %gl_FragDepth_2 = OpVariable %_ptr_Output_float Output
  9054. %float_1 = OpConstant %float 1
  9055. %main = OpFunction %void None %3
  9056. %5 = OpLabel
  9057. OpStore %gl_FragDepth_1 %float_1
  9058. %10 = OpLoad %float %gl_FragDepth_1
  9059. %11 = OpFAdd %float %10 %float_1
  9060. OpStore %gl_FragDepth_2 %11
  9061. OpReturn
  9062. OpFunctionEnd
  9063. )";
  9064. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  9065. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  9066. EXPECT_THAT(getDiagnosticString(),
  9067. HasSubstr("OpEntryPoint contains duplicate output variables with "
  9068. "FragDepth builtin"));
  9069. EXPECT_THAT(getDiagnosticString(),
  9070. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09659"));
  9071. }
  9072. TEST_F(ValidateDecorations, MultipleBuiltinsRayTmaxKHR) {
  9073. const std::string body = R"(
  9074. OpCapability RayTracingKHR
  9075. OpExtension "SPV_KHR_ray_tracing"
  9076. OpMemoryModel Logical GLSL450
  9077. OpEntryPoint AnyHitKHR %main "main" %gl_RayTmaxEXT %gl_HitTEXT %incomingPayload
  9078. OpDecorate %gl_RayTmaxEXT BuiltIn RayTmaxKHR
  9079. OpDecorate %gl_HitTEXT BuiltIn RayTmaxKHR
  9080. %void = OpTypeVoid
  9081. %3 = OpTypeFunction %void
  9082. %float = OpTypeFloat 32
  9083. %_ptr_Function_float = OpTypePointer Function %float
  9084. %_ptr_Input_float = OpTypePointer Input %float
  9085. %gl_RayTmaxEXT = OpVariable %_ptr_Input_float Input
  9086. %gl_HitTEXT = OpVariable %_ptr_Input_float Input
  9087. %v4float = OpTypeVector %float 4
  9088. %_ptr_IncomingRayPayloadKHR_v4float = OpTypePointer IncomingRayPayloadKHR %v4float
  9089. %incomingPayload = OpVariable %_ptr_IncomingRayPayloadKHR_v4float IncomingRayPayloadKHR
  9090. %main = OpFunction %void None %3
  9091. %5 = OpLabel
  9092. %a = OpVariable %_ptr_Function_float Function
  9093. %b = OpVariable %_ptr_Function_float Function
  9094. %11 = OpLoad %float %gl_RayTmaxEXT
  9095. OpStore %a %11
  9096. %14 = OpLoad %float %gl_HitTEXT
  9097. OpStore %b %14
  9098. %18 = OpLoad %float %a
  9099. %19 = OpLoad %float %b
  9100. %22 = OpCompositeConstruct %v4float %18 %18 %19 %19
  9101. OpStore %incomingPayload %22
  9102. OpTerminateRayKHR
  9103. OpFunctionEnd
  9104. )";
  9105. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  9106. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  9107. EXPECT_THAT(
  9108. getDiagnosticString(),
  9109. HasSubstr(
  9110. "OpEntryPoint contains duplicate input variables with RayTmax"));
  9111. EXPECT_THAT(getDiagnosticString(),
  9112. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09658"));
  9113. }
  9114. TEST_F(ValidateDecorations, MultipleBuiltinsBlock) {
  9115. const std::string body = R"(
  9116. OpCapability Shader
  9117. OpMemoryModel Logical GLSL450
  9118. OpEntryPoint Vertex %main "main" %var
  9119. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  9120. OpMemberDecorate %gl_PerVertex 1 BuiltIn Position
  9121. OpDecorate %gl_PerVertex Block
  9122. %void = OpTypeVoid
  9123. %3 = OpTypeFunction %void
  9124. %float = OpTypeFloat 32
  9125. %v4float = OpTypeVector %float 4
  9126. %gl_PerVertex = OpTypeStruct %v4float %v4float
  9127. %_ptr_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  9128. %var = OpVariable %_ptr_gl_PerVertex Output
  9129. %int = OpTypeInt 32 1
  9130. %int_0 = OpConstant %int 0
  9131. %int_1 = OpConstant %int 1
  9132. %float_0 = OpConstant %float 0
  9133. %17 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  9134. %ptr_vec4 = OpTypePointer Output %v4float
  9135. %main = OpFunction %void None %3
  9136. %5 = OpLabel
  9137. %19 = OpAccessChain %ptr_vec4 %var %int_0
  9138. OpStore %19 %17
  9139. %22 = OpAccessChain %ptr_vec4 %var %int_1
  9140. OpStore %22 %17
  9141. OpReturn
  9142. OpFunctionEnd
  9143. )";
  9144. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_0);
  9145. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9146. EXPECT_THAT(
  9147. getDiagnosticString(),
  9148. HasSubstr(
  9149. "OpEntryPoint contains duplicate output variables with Position"));
  9150. EXPECT_THAT(getDiagnosticString(),
  9151. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09659"));
  9152. }
  9153. TEST_F(ValidateDecorations, MultipleBuiltinsBlockMixed) {
  9154. const std::string body = R"(
  9155. OpCapability Shader
  9156. OpMemoryModel Logical GLSL450
  9157. OpEntryPoint Vertex %main "main" %var %position
  9158. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  9159. OpDecorate %gl_PerVertex Block
  9160. OpDecorate %position BuiltIn Position
  9161. %void = OpTypeVoid
  9162. %3 = OpTypeFunction %void
  9163. %float = OpTypeFloat 32
  9164. %v4float = OpTypeVector %float 4
  9165. %gl_PerVertex = OpTypeStruct %v4float
  9166. %_ptr_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  9167. %var = OpVariable %_ptr_gl_PerVertex Output
  9168. %int = OpTypeInt 32 1
  9169. %int_0 = OpConstant %int 0
  9170. %int_1 = OpConstant %int 1
  9171. %float_0 = OpConstant %float 0
  9172. %17 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  9173. %ptr_vec4 = OpTypePointer Output %v4float
  9174. %position = OpVariable %ptr_vec4 Output
  9175. %main = OpFunction %void None %3
  9176. %5 = OpLabel
  9177. %19 = OpAccessChain %ptr_vec4 %var %int_0
  9178. OpStore %19 %17
  9179. OpStore %position %17
  9180. OpReturn
  9181. OpFunctionEnd
  9182. )";
  9183. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_0);
  9184. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9185. EXPECT_THAT(
  9186. getDiagnosticString(),
  9187. HasSubstr(
  9188. "OpEntryPoint contains duplicate output variables with Position"));
  9189. EXPECT_THAT(getDiagnosticString(),
  9190. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09659"));
  9191. }
  9192. TEST_F(ValidateDecorations, UntypedVariableWorkgroupRequiresStruct) {
  9193. const std::string spirv = R"(
  9194. OpCapability Shader
  9195. OpCapability UntypedPointersKHR
  9196. OpCapability WorkgroupMemoryExplicitLayoutKHR
  9197. OpExtension "SPV_KHR_untyped_pointers"
  9198. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  9199. OpMemoryModel Logical GLSL450
  9200. OpEntryPoint GLCompute %main "main" %var
  9201. %void = OpTypeVoid
  9202. %int = OpTypeInt 32 0
  9203. %ptr = OpTypeUntypedPointerKHR Workgroup
  9204. %var = OpUntypedVariableKHR %ptr Workgroup %int
  9205. %void_fn = OpTypeFunction %void
  9206. %main = OpFunction %void None %void_fn
  9207. %entry = OpLabel
  9208. OpReturn
  9209. OpFunctionEnd
  9210. )";
  9211. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  9212. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9213. EXPECT_THAT(getDiagnosticString(),
  9214. HasSubstr("Untyped workgroup variables in shaders must be block "
  9215. "decorated structs"));
  9216. }
  9217. TEST_F(ValidateDecorations, UntypedVariableWorkgroupRequiresBlockStruct) {
  9218. const std::string spirv = R"(
  9219. OpCapability Shader
  9220. OpCapability UntypedPointersKHR
  9221. OpCapability WorkgroupMemoryExplicitLayoutKHR
  9222. OpExtension "SPV_KHR_untyped_pointers"
  9223. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  9224. OpMemoryModel Logical GLSL450
  9225. OpEntryPoint GLCompute %main "main" %var
  9226. %void = OpTypeVoid
  9227. %int = OpTypeInt 32 0
  9228. %struct = OpTypeStruct %int
  9229. %ptr = OpTypeUntypedPointerKHR Workgroup
  9230. %var = OpUntypedVariableKHR %ptr Workgroup %struct
  9231. %void_fn = OpTypeFunction %void
  9232. %main = OpFunction %void None %void_fn
  9233. %entry = OpLabel
  9234. OpReturn
  9235. OpFunctionEnd
  9236. )";
  9237. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  9238. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9239. EXPECT_THAT(getDiagnosticString(),
  9240. HasSubstr("Untyped workgroup variables in shaders must be block "
  9241. "decorated"));
  9242. }
  9243. TEST_F(ValidateDecorations, UntypedVariableStorageBufferMissingBlock) {
  9244. const std::string spirv = R"(
  9245. OpCapability Shader
  9246. OpCapability UntypedPointersKHR
  9247. OpExtension "SPV_KHR_untyped_pointers"
  9248. OpExtension "SPV_KHR_storage_buffer_storage_class"
  9249. OpMemoryModel Logical GLSL450
  9250. OpEntryPoint GLCompute %main "main"
  9251. OpExecutionMode %main LocalSize 1 1 1
  9252. OpName %struct "struct"
  9253. %void = OpTypeVoid
  9254. %int = OpTypeInt 32 0
  9255. %struct = OpTypeStruct %int
  9256. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  9257. %var = OpUntypedVariableKHR %ptr StorageBuffer %struct
  9258. %void_fn = OpTypeFunction %void
  9259. %main = OpFunction %void None %void_fn
  9260. %entry = OpLabel
  9261. OpReturn
  9262. OpFunctionEnd
  9263. )";
  9264. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9265. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9266. EXPECT_THAT(getDiagnosticString(),
  9267. HasSubstr("StorageBuffer id '2' is missing Block decoration"));
  9268. }
  9269. TEST_F(ValidateDecorations, UntypedVariableUniformMissingBlock) {
  9270. const std::string spirv = R"(
  9271. OpCapability Shader
  9272. OpCapability UntypedPointersKHR
  9273. OpExtension "SPV_KHR_untyped_pointers"
  9274. OpMemoryModel Logical GLSL450
  9275. OpEntryPoint GLCompute %main "main"
  9276. OpExecutionMode %main LocalSize 1 1 1
  9277. OpName %struct "struct"
  9278. %void = OpTypeVoid
  9279. %int = OpTypeInt 32 0
  9280. %struct = OpTypeStruct %int
  9281. %ptr = OpTypeUntypedPointerKHR Uniform
  9282. %var = OpUntypedVariableKHR %ptr Uniform %struct
  9283. %void_fn = OpTypeFunction %void
  9284. %main = OpFunction %void None %void_fn
  9285. %entry = OpLabel
  9286. OpReturn
  9287. OpFunctionEnd
  9288. )";
  9289. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9290. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9291. EXPECT_THAT(
  9292. getDiagnosticString(),
  9293. HasSubstr("Uniform id '2' is missing Block or BufferBlock decoration"));
  9294. }
  9295. TEST_F(ValidateDecorations, UntypedVariablePushConstantMissingBlock) {
  9296. const std::string spirv = R"(
  9297. OpCapability Shader
  9298. OpCapability UntypedPointersKHR
  9299. OpExtension "SPV_KHR_untyped_pointers"
  9300. OpMemoryModel Logical GLSL450
  9301. OpEntryPoint GLCompute %main "main"
  9302. OpExecutionMode %main LocalSize 1 1 1
  9303. OpName %struct "struct"
  9304. %void = OpTypeVoid
  9305. %int = OpTypeInt 32 0
  9306. %struct = OpTypeStruct %int
  9307. %ptr = OpTypeUntypedPointerKHR PushConstant
  9308. %var = OpUntypedVariableKHR %ptr PushConstant %struct
  9309. %void_fn = OpTypeFunction %void
  9310. %main = OpFunction %void None %void_fn
  9311. %entry = OpLabel
  9312. OpReturn
  9313. OpFunctionEnd
  9314. )";
  9315. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9316. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9317. EXPECT_THAT(getDiagnosticString(),
  9318. HasSubstr("PushConstant id '2' is missing Block decoration"));
  9319. }
  9320. using UntypedVariableSetAndBinding = spvtest::ValidateBase<std::string>;
  9321. TEST_P(UntypedVariableSetAndBinding, MissingSet) {
  9322. const auto sc = GetParam();
  9323. const std::string spirv = R"(
  9324. OpCapability Shader
  9325. OpCapability UntypedPointersKHR
  9326. OpExtension "SPV_KHR_untyped_pointers"
  9327. OpExtension "SPV_KHR_storage_buffer_storage_class"
  9328. OpMemoryModel Logical GLSL450
  9329. OpEntryPoint GLCompute %main "main"
  9330. OpExecutionMode %main LocalSize 1 1 1
  9331. OpName %var "var"
  9332. OpDecorate %struct Block
  9333. OpMemberDecorate %struct 0 Offset 0
  9334. OpDecorate %var Binding 0
  9335. %void = OpTypeVoid
  9336. %int = OpTypeInt 32 0
  9337. %struct = OpTypeStruct %int
  9338. %ptr = OpTypeUntypedPointerKHR )" +
  9339. sc + R"(
  9340. %var = OpUntypedVariableKHR %ptr )" + sc + R"( %struct
  9341. %void_fn = OpTypeFunction %void
  9342. %main = OpFunction %void None %void_fn
  9343. %entry = OpLabel
  9344. %load = OpLoad %struct %var
  9345. OpReturn
  9346. OpFunctionEnd
  9347. )";
  9348. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9349. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9350. EXPECT_THAT(getDiagnosticString(),
  9351. HasSubstr(sc + " id '2' is missing DescriptorSet decoration"));
  9352. }
  9353. TEST_P(UntypedVariableSetAndBinding, MissingBinding) {
  9354. const auto sc = GetParam();
  9355. const std::string spirv = R"(
  9356. OpCapability Shader
  9357. OpCapability UntypedPointersKHR
  9358. OpExtension "SPV_KHR_untyped_pointers"
  9359. OpExtension "SPV_KHR_storage_buffer_storage_class"
  9360. OpMemoryModel Logical GLSL450
  9361. OpEntryPoint GLCompute %main "main"
  9362. OpExecutionMode %main LocalSize 1 1 1
  9363. OpName %var "var"
  9364. OpDecorate %struct Block
  9365. OpMemberDecorate %struct 0 Offset 0
  9366. OpDecorate %var DescriptorSet 0
  9367. %void = OpTypeVoid
  9368. %int = OpTypeInt 32 0
  9369. %struct = OpTypeStruct %int
  9370. %ptr = OpTypeUntypedPointerKHR )" +
  9371. sc + R"(
  9372. %var = OpUntypedVariableKHR %ptr )" + sc + R"( %struct
  9373. %void_fn = OpTypeFunction %void
  9374. %main = OpFunction %void None %void_fn
  9375. %entry = OpLabel
  9376. %load = OpLoad %struct %var
  9377. OpReturn
  9378. OpFunctionEnd
  9379. )";
  9380. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9381. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9382. EXPECT_THAT(getDiagnosticString(),
  9383. HasSubstr(sc + " id '2' is missing Binding decoration"));
  9384. }
  9385. INSTANTIATE_TEST_SUITE_P(ValidateUntypedVariableSetAndBinding,
  9386. UntypedVariableSetAndBinding,
  9387. Values("StorageBuffer", "Uniform"));
  9388. using UntypedPointerLayout =
  9389. spvtest::ValidateBase<std::tuple<std::string, std::string>>;
  9390. TEST_P(UntypedPointerLayout, BadOffset) {
  9391. const auto sc = std::get<0>(GetParam());
  9392. const auto op = std::get<1>(GetParam());
  9393. const std::string set = (sc == "StorageBuffer" || sc == "Uniform"
  9394. ? R"(OpDecorate %var DescriptorSet 0
  9395. OpDecorate %var Binding 0
  9396. )"
  9397. : R"()");
  9398. const std::string spirv = R"(
  9399. OpCapability Shader
  9400. OpCapability VariablePointers
  9401. OpCapability UntypedPointersKHR
  9402. OpCapability WorkgroupMemoryExplicitLayoutKHR
  9403. OpExtension "SPV_KHR_untyped_pointers"
  9404. OpExtension "SPV_KHR_variable_pointers"
  9405. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  9406. OpExtension "SPV_KHR_storage_buffer_storage_class"
  9407. OpMemoryModel Logical GLSL450
  9408. OpEntryPoint GLCompute %main "main" %var
  9409. OpExecutionMode %main LocalSize 1 1 1
  9410. OpName %var "var"
  9411. OpDecorate %struct Block
  9412. OpMemberDecorate %struct 0 Offset 0
  9413. OpMemberDecorate %struct 1 Offset 4
  9414. )" + set + R"(OpMemberDecorate %test_type 0 Offset 0
  9415. OpMemberDecorate %test_type 1 Offset 1
  9416. %void = OpTypeVoid
  9417. %int = OpTypeInt 32 0
  9418. %int_0 = OpConstant %int 0
  9419. %struct = OpTypeStruct %int %int
  9420. %test_type = OpTypeStruct %int %int
  9421. %test_val = OpConstantNull %test_type
  9422. %ptr = OpTypeUntypedPointerKHR )" +
  9423. sc + R"(
  9424. %var = OpUntypedVariableKHR %ptr )" + sc + R"( %struct
  9425. %void_fn = OpTypeFunction %void
  9426. %main = OpFunction %void None %void_fn
  9427. %entry = OpLabel
  9428. )" + op + R"(
  9429. OpReturn
  9430. OpFunctionEnd
  9431. )";
  9432. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  9433. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  9434. const bool read_only = sc == "Uniform" || sc == "PushConstant";
  9435. if (!read_only || op.find("OpStore") == std::string::npos) {
  9436. EXPECT_THAT(getDiagnosticString(),
  9437. HasSubstr("member 1 at offset 1 is not aligned to"));
  9438. }
  9439. }
  9440. TEST_P(UntypedPointerLayout, BadStride) {
  9441. const auto sc = std::get<0>(GetParam());
  9442. const auto op = std::get<1>(GetParam());
  9443. const std::string set = (sc == "StorageBuffer" || sc == "Uniform"
  9444. ? R"(OpDecorate %var DescriptorSet 0
  9445. OpDecorate %var Binding 0
  9446. )"
  9447. : R"()");
  9448. const std::string spirv = R"(
  9449. OpCapability Shader
  9450. OpCapability VariablePointers
  9451. OpCapability UntypedPointersKHR
  9452. OpCapability WorkgroupMemoryExplicitLayoutKHR
  9453. OpExtension "SPV_KHR_untyped_pointers"
  9454. OpExtension "SPV_KHR_variable_pointers"
  9455. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  9456. OpExtension "SPV_KHR_storage_buffer_storage_class"
  9457. OpMemoryModel Logical GLSL450
  9458. OpEntryPoint GLCompute %main "main" %var
  9459. OpExecutionMode %main LocalSize 1 1 1
  9460. OpName %var "var"
  9461. OpDecorate %struct Block
  9462. OpMemberDecorate %struct 0 Offset 0
  9463. OpMemberDecorate %struct 1 Offset 4
  9464. )" + set + R"(OpDecorate %test_type ArrayStride 4
  9465. %void = OpTypeVoid
  9466. %int = OpTypeInt 32 0
  9467. %int_0 = OpConstant %int 0
  9468. %int_4 = OpConstant %int 4
  9469. %int4 = OpTypeVector %int 4
  9470. %test_type = OpTypeArray %int4 %int_4
  9471. %test_val = OpConstantNull %test_type
  9472. %struct = OpTypeStruct %int %int
  9473. %ptr = OpTypeUntypedPointerKHR )" +
  9474. sc + R"(
  9475. %var = OpUntypedVariableKHR %ptr )" + sc + R"( %struct
  9476. %void_fn = OpTypeFunction %void
  9477. %main = OpFunction %void None %void_fn
  9478. %entry = OpLabel
  9479. )" + op + R"(
  9480. OpReturn
  9481. OpFunctionEnd
  9482. )";
  9483. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  9484. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  9485. const bool read_only = sc == "Uniform" || sc == "PushConstant";
  9486. if (!read_only || op.find("OpStore") == std::string::npos) {
  9487. EXPECT_THAT(
  9488. getDiagnosticString(),
  9489. HasSubstr("array with stride 4 not satisfying alignment to 16"));
  9490. }
  9491. }
  9492. INSTANTIATE_TEST_SUITE_P(
  9493. ValidateUntypedPointerLayout, UntypedPointerLayout,
  9494. Combine(Values("StorageBuffer", "Uniform", "PushConstant", "Workgroup"),
  9495. Values("%gep = OpUntypedAccessChainKHR %ptr %test_type %var %int_0",
  9496. "%gep = OpUntypedInBoundsAccessChainKHR %ptr %test_type "
  9497. "%var %int_0",
  9498. "%gep = OpUntypedPtrAccessChainKHR %ptr %test_type %var "
  9499. "%int_0 %int_0",
  9500. "%ld = OpLoad %test_type %var", "OpStore %var %test_val")));
  9501. TEST_F(ValidateDecorations, UntypedArrayLengthMissingOffset) {
  9502. const std::string spirv = R"(
  9503. OpCapability Shader
  9504. OpCapability UntypedPointersKHR
  9505. OpExtension "SPV_KHR_untyped_pointers"
  9506. OpMemoryModel Logical GLSL450
  9507. OpEntryPoint GLCompute %main "main"
  9508. OpExecutionMode %main LocalSize 1 1 1
  9509. OpDecorate %struct Block
  9510. OpDecorate %block Block
  9511. OpMemberDecorate %block 0 Offset 0
  9512. OpDecorate %array ArrayStride 4
  9513. OpDecorate %var DescriptorSet 0
  9514. OpDecorate %var Binding 0
  9515. %void = OpTypeVoid
  9516. %int = OpTypeInt 32 0
  9517. %array = OpTypeRuntimeArray %int
  9518. %struct = OpTypeStruct %array
  9519. %block = OpTypeStruct %array
  9520. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  9521. %var = OpUntypedVariableKHR %ptr StorageBuffer %block
  9522. %void_fn = OpTypeFunction %void
  9523. %main = OpFunction %void None %void_fn
  9524. %entry = OpLabel
  9525. %len = OpUntypedArrayLengthKHR %int %struct %var 0
  9526. OpReturn
  9527. OpFunctionEnd
  9528. )";
  9529. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  9530. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  9531. EXPECT_THAT(getDiagnosticString(),
  9532. HasSubstr("member 0 is missing an Offset decoration"));
  9533. }
  9534. TEST_F(ValidateDecorations, ComponentMultipleArrays) {
  9535. const std::string spirv = R"(
  9536. OpCapability Tessellation
  9537. %1 = OpExtInstImport "GLSL.std.450"
  9538. OpMemoryModel Logical GLSL450
  9539. OpEntryPoint TessellationEvaluation %main "main" %_ %FOO %FOO0
  9540. OpExecutionMode %main Triangles
  9541. OpExecutionMode %main SpacingEqual
  9542. OpExecutionMode %main VertexOrderCcw
  9543. OpSource GLSL 460
  9544. OpSourceExtension "GL_EXT_nonuniform_qualifier"
  9545. OpName %main "main"
  9546. OpName %gl_PerVertex "gl_PerVertex"
  9547. OpMemberName %gl_PerVertex 0 "gl_Position"
  9548. OpMemberName %gl_PerVertex 1 "gl_PointSize"
  9549. OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
  9550. OpMemberName %gl_PerVertex 3 "gl_CullDistance"
  9551. OpName %_ ""
  9552. OpName %FOO "FOO"
  9553. OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
  9554. OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
  9555. OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
  9556. OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
  9557. OpDecorate %gl_PerVertex Block
  9558. OpDecorate %FOO Component 2
  9559. OpDecorate %FOO Location 1
  9560. OpDecorate %FOO0 Location 4
  9561. OpDecorate %FOO0 Component 0
  9562. %void = OpTypeVoid
  9563. %3 = OpTypeFunction %void
  9564. %float = OpTypeFloat 32
  9565. %v4float = OpTypeVector %float 4
  9566. %uint = OpTypeInt 32 0
  9567. %uint_1 = OpConstant %uint 1
  9568. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  9569. %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
  9570. %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
  9571. %_ = OpVariable %_ptr_Output_gl_PerVertex Output
  9572. %int = OpTypeInt 32 1
  9573. %int_0 = OpConstant %int 0
  9574. %v2float = OpTypeVector %float 2
  9575. %uint_2 = OpConstant %uint 2
  9576. %_arr_v2float_uint_2 = OpTypeArray %v2float %uint_2
  9577. %uint_32 = OpConstant %uint 32
  9578. %_arr__arr_v2float_uint_2_uint_32 = OpTypeArray %_arr_v2float_uint_2 %uint_32
  9579. %_ptr_Input__arr__arr_v2float_uint_2_uint_32 = OpTypePointer Input %_arr__arr_v2float_uint_2_uint_32
  9580. %FOO = OpVariable %_ptr_Input__arr__arr_v2float_uint_2_uint_32 Input
  9581. %FOO0 = OpVariable %_ptr_Input__arr__arr_v2float_uint_2_uint_32 Input
  9582. %_ptr_Input_v2float = OpTypePointer Input %v2float
  9583. %int_1 = OpConstant %int 1
  9584. %uint_0 = OpConstant %uint 0
  9585. %_ptr_Output_float = OpTypePointer Output %float
  9586. %main = OpFunction %void None %3
  9587. %5 = OpLabel
  9588. %24 = OpAccessChain %_ptr_Input_v2float %FOO %int_0 %int_0
  9589. %25 = OpLoad %v2float %24
  9590. %27 = OpAccessChain %_ptr_Input_v2float %FOO0 %int_1 %int_1
  9591. %28 = OpLoad %v2float %27
  9592. %29 = OpFAdd %v2float %25 %28
  9593. %32 = OpAccessChain %_ptr_Output_float %_ %int_0 %uint_0
  9594. %33 = OpCompositeExtract %float %29 0
  9595. OpStore %32 %33
  9596. %34 = OpAccessChain %_ptr_Output_float %_ %int_0 %uint_1
  9597. %35 = OpCompositeExtract %float %29 1
  9598. OpStore %34 %35
  9599. OpReturn
  9600. OpFunctionEnd
  9601. )";
  9602. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9603. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9604. }
  9605. const std::string kNodeShaderPrelude = R"(
  9606. OpCapability Shader
  9607. OpCapability ShaderEnqueueAMDX
  9608. OpExtension "SPV_AMDX_shader_enqueue"
  9609. OpMemoryModel Logical GLSL450
  9610. OpEntryPoint GLCompute %main "main"
  9611. OpEntryPoint GLCompute %other "other"
  9612. )";
  9613. const std::string kNodeShaderPostlude = R"(
  9614. %uint = OpTypeInt 32 0
  9615. %uint_0 = OpConstant %uint 0
  9616. %uint_1 = OpConstant %uint 1
  9617. %node0 = OpConstantStringAMDX "node0"
  9618. %node1 = OpConstantStringAMDX "node1"
  9619. %node2 = OpConstantStringAMDX "node2"
  9620. %S = OpTypeStruct
  9621. %_payloadarr_S = OpTypeNodePayloadArrayAMDX %S
  9622. %_payloadarr_S_0 = OpTypeNodePayloadArrayAMDX %S
  9623. %bool = OpTypeBool
  9624. %true = OpConstantTrue %bool
  9625. %void = OpTypeVoid
  9626. %void_fn = OpTypeFunction %void
  9627. %main = OpFunction %void None %void_fn
  9628. %entry = OpLabel
  9629. OpReturn
  9630. OpFunctionEnd
  9631. %other = OpFunction %void None %void_fn
  9632. %entry0 = OpLabel
  9633. OpReturn
  9634. OpFunctionEnd
  9635. )";
  9636. TEST_F(ValidateDecorations, NodeShader) {
  9637. const std::string spirv = kNodeShaderPrelude + R"(
  9638. OpExecutionModeId %main ShaderIndexAMDX %uint_0
  9639. OpExecutionModeId %main IsApiEntryAMDX %true
  9640. OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
  9641. OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9642. OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
  9643. OpExecutionModeId %other ShaderIndexAMDX %uint_0
  9644. OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9645. OpDecorateId %_payloadarr_S PayloadNodeNameAMDX %node1
  9646. OpDecorateId %_payloadarr_S_0 PayloadNodeNameAMDX %node2
  9647. OpDecorateId %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
  9648. OpDecorateId %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
  9649. OpDecorateId %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
  9650. )" + kNodeShaderPostlude;
  9651. spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
  9652. CompileSuccessfully(spirv, env);
  9653. EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env));
  9654. }
  9655. TEST_F(ValidateDecorations, NodeShaderDecoratePayloadNodeName) {
  9656. const std::string spirv = kNodeShaderPrelude + R"(
  9657. OpExecutionModeId %main ShaderIndexAMDX %uint_0
  9658. OpExecutionModeId %main IsApiEntryAMDX %true
  9659. OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
  9660. OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9661. OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
  9662. OpExecutionModeId %other ShaderIndexAMDX %uint_0
  9663. OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9664. OpDecorate %_payloadarr_S PayloadNodeNameAMDX %node1
  9665. OpDecorate %_payloadarr_S_0 PayloadNodeNameAMDX %node2
  9666. OpDecorateId %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
  9667. OpDecorateId %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
  9668. OpDecorateId %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
  9669. )" + kNodeShaderPostlude;
  9670. spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
  9671. CompileSuccessfully(spirv, env);
  9672. EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env));
  9673. EXPECT_THAT(
  9674. getDiagnosticString(),
  9675. HasSubstr(
  9676. "Decorations taking ID parameters may not be used with OpDecorate"));
  9677. }
  9678. TEST_F(ValidateDecorations, NodeShaderDecoratePayloadNodeBaseIndex) {
  9679. const std::string spirv = kNodeShaderPrelude + R"(
  9680. OpExecutionModeId %main ShaderIndexAMDX %uint_0
  9681. OpExecutionModeId %main IsApiEntryAMDX %true
  9682. OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
  9683. OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9684. OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
  9685. OpExecutionModeId %other ShaderIndexAMDX %uint_0
  9686. OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9687. OpDecorateId %_payloadarr_S PayloadNodeNameAMDX %node1
  9688. OpDecorateId %_payloadarr_S_0 PayloadNodeNameAMDX %node2
  9689. OpDecorate %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
  9690. OpDecorateId %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
  9691. OpDecorateId %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
  9692. )" + kNodeShaderPostlude;
  9693. spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
  9694. CompileSuccessfully(spirv, env);
  9695. EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env));
  9696. EXPECT_THAT(
  9697. getDiagnosticString(),
  9698. HasSubstr(
  9699. "Decorations taking ID parameters may not be used with OpDecorate"));
  9700. }
  9701. TEST_F(ValidateDecorations, NodeShaderDecoratePayloadNodeArraySize) {
  9702. const std::string spirv = kNodeShaderPrelude + R"(
  9703. OpExecutionModeId %main ShaderIndexAMDX %uint_0
  9704. OpExecutionModeId %main IsApiEntryAMDX %true
  9705. OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
  9706. OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9707. OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
  9708. OpExecutionModeId %other ShaderIndexAMDX %uint_0
  9709. OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9710. OpDecorateId %_payloadarr_S PayloadNodeNameAMDX %node1
  9711. OpDecorateId %_payloadarr_S_0 PayloadNodeNameAMDX %node2
  9712. OpDecorateId %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
  9713. OpDecorate %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
  9714. OpDecorateId %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
  9715. )" + kNodeShaderPostlude;
  9716. spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
  9717. CompileSuccessfully(spirv, env);
  9718. EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env));
  9719. EXPECT_THAT(
  9720. getDiagnosticString(),
  9721. HasSubstr(
  9722. "Decorations taking ID parameters may not be used with OpDecorate"));
  9723. }
  9724. TEST_F(ValidateDecorations, NodeShaderDecorateNodeSharesPayloadLimitsWith) {
  9725. const std::string spirv = kNodeShaderPrelude + R"(
  9726. OpExecutionModeId %main ShaderIndexAMDX %uint_0
  9727. OpExecutionModeId %main IsApiEntryAMDX %true
  9728. OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
  9729. OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9730. OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
  9731. OpExecutionModeId %other ShaderIndexAMDX %uint_0
  9732. OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
  9733. OpDecorateId %_payloadarr_S PayloadNodeNameAMDX %node1
  9734. OpDecorateId %_payloadarr_S_0 PayloadNodeNameAMDX %node2
  9735. OpDecorateId %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
  9736. OpDecorateId %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
  9737. OpDecorate %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
  9738. )" + kNodeShaderPostlude;
  9739. spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
  9740. CompileSuccessfully(spirv, env);
  9741. EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env));
  9742. EXPECT_THAT(
  9743. getDiagnosticString(),
  9744. HasSubstr(
  9745. "Decorations taking ID parameters may not be used with OpDecorate"));
  9746. }
  9747. TEST_F(ValidateDecorations, BlockArrayWithStride) {
  9748. const std::string spirv = R"(
  9749. OpCapability Shader
  9750. OpCapability Linkage
  9751. OpMemoryModel Logical GLSL450
  9752. OpDecorate %struct Block
  9753. OpMemberDecorate %struct 0 Offset 0
  9754. OpDecorate %array ArrayStride 4
  9755. %int = OpTypeInt 32 0
  9756. %int_4 = OpConstant %int 4
  9757. %struct = OpTypeStruct %int
  9758. %array = OpTypeArray %struct %int_4
  9759. )";
  9760. CompileSuccessfully(spirv);
  9761. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  9762. EXPECT_THAT(getDiagnosticString(),
  9763. HasSubstr("Array containing a Block or BufferBlock must not be "
  9764. "decorated with ArrayStride"));
  9765. }
  9766. TEST_F(ValidateDecorations, BufferBlockRuntimeArrayWithStride) {
  9767. const std::string spirv = R"(
  9768. OpCapability Shader
  9769. OpCapability Linkage
  9770. OpMemoryModel Logical GLSL450
  9771. OpDecorate %struct BufferBlock
  9772. OpMemberDecorate %struct 0 Offset 0
  9773. OpDecorate %array ArrayStride 4
  9774. %int = OpTypeInt 32 0
  9775. %struct = OpTypeStruct %int
  9776. %array = OpTypeRuntimeArray %struct
  9777. )";
  9778. CompileSuccessfully(spirv);
  9779. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  9780. EXPECT_THAT(getDiagnosticString(),
  9781. HasSubstr("Array containing a Block or BufferBlock must not be "
  9782. "decorated with ArrayStride"));
  9783. }
  9784. TEST_F(ValidateDecorations, BlockArrayWithoutStride) {
  9785. const std::string spirv = R"(
  9786. OpCapability Shader
  9787. OpExtension "SPV_KHR_storage_buffer_storage_class"
  9788. OpMemoryModel Logical GLSL450
  9789. OpEntryPoint GLCompute %main "main"
  9790. OpExecutionMode %main LocalSize 1 1 1
  9791. OpDecorate %struct Block
  9792. OpMemberDecorate %struct 0 Offset 0
  9793. OpDecorate %var DescriptorSet 0
  9794. OpDecorate %var Binding 0
  9795. %int = OpTypeInt 32 0
  9796. %int_4 = OpConstant %int 4
  9797. %struct = OpTypeStruct %int
  9798. %array = OpTypeArray %struct %int_4
  9799. %ptr = OpTypePointer StorageBuffer %array
  9800. %var = OpVariable %ptr StorageBuffer
  9801. %void = OpTypeVoid
  9802. %void_fn = OpTypeFunction %void
  9803. %main = OpFunction %void None %void_fn
  9804. %entry = OpLabel
  9805. OpReturn
  9806. OpFunctionEnd
  9807. )";
  9808. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9809. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9810. }
  9811. TEST_F(ValidateDecorations, BlockArrayWithoutStrideUntypedAccessChain) {
  9812. const std::string spirv = R"(
  9813. OpCapability Shader
  9814. OpCapability UntypedPointersKHR
  9815. OpExtension "SPV_KHR_storage_buffer_storage_class"
  9816. OpExtension "SPV_KHR_untyped_pointers"
  9817. OpMemoryModel Logical GLSL450
  9818. OpEntryPoint GLCompute %main "main"
  9819. OpExecutionMode %main LocalSize 1 1 1
  9820. OpDecorate %struct Block
  9821. OpMemberDecorate %struct 0 Offset 0
  9822. OpDecorate %var DescriptorSet 0
  9823. OpDecorate %var Binding 0
  9824. %int = OpTypeInt 32 0
  9825. %int_4 = OpConstant %int 4
  9826. %struct = OpTypeStruct %int
  9827. %array = OpTypeArray %struct %int_4
  9828. %void = OpTypeVoid
  9829. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  9830. %var = OpUntypedVariableKHR %ptr StorageBuffer %array
  9831. %void_fn = OpTypeFunction %void
  9832. %main = OpFunction %void None %void_fn
  9833. %entry = OpLabel
  9834. %gep = OpUntypedAccessChainKHR %ptr %array %var
  9835. OpReturn
  9836. OpFunctionEnd
  9837. )";
  9838. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9839. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9840. }
  9841. TEST_F(ValidateDecorations, InvalidLayoutBlockFunctionPre1p4) {
  9842. const std::string spirv = R"(
  9843. OpCapability Shader
  9844. OpMemoryModel Logical GLSL450
  9845. OpEntryPoint GLCompute %main "main"
  9846. OpExecutionMode %main LocalSize 1 1 1
  9847. OpDecorate %block Block
  9848. %void = OpTypeVoid
  9849. %int = OpTypeInt 32 0
  9850. %block = OpTypeStruct %int
  9851. %ptr_function_block = OpTypePointer Function %block
  9852. %void_fn = OpTypeFunction %void
  9853. %main = OpFunction %void None %void_fn
  9854. %entry = OpLabel
  9855. %var = OpVariable %ptr_function_block Function
  9856. OpReturn
  9857. OpFunctionEnd
  9858. )";
  9859. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  9860. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  9861. }
  9862. TEST_F(ValidateDecorations, InvalidLayoutBlockFunctionPost1p4) {
  9863. const std::string spirv = R"(
  9864. OpCapability Shader
  9865. OpMemoryModel Logical GLSL450
  9866. OpEntryPoint GLCompute %main "main"
  9867. OpExecutionMode %main LocalSize 1 1 1
  9868. OpDecorate %block Block
  9869. %void = OpTypeVoid
  9870. %int = OpTypeInt 32 0
  9871. %block = OpTypeStruct %int
  9872. %ptr_function_block = OpTypePointer Function %block
  9873. %void_fn = OpTypeFunction %void
  9874. %main = OpFunction %void None %void_fn
  9875. %entry = OpLabel
  9876. %var = OpVariable %ptr_function_block Function
  9877. OpReturn
  9878. OpFunctionEnd
  9879. )";
  9880. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  9881. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  9882. EXPECT_THAT(
  9883. getDiagnosticString(),
  9884. HasSubstr("Invalid explicit layout decorations on type for operand"));
  9885. }
  9886. TEST_F(ValidateDecorations, InvalidLayoutOffsetPrivatePre1p4) {
  9887. const std::string spirv = R"(
  9888. OpCapability Shader
  9889. OpMemoryModel Logical GLSL450
  9890. OpEntryPoint GLCompute %main "main"
  9891. OpExecutionMode %main LocalSize 1 1 1
  9892. OpMemberDecorate %block 0 Offset 0
  9893. %void = OpTypeVoid
  9894. %int = OpTypeInt 32 0
  9895. %block = OpTypeStruct %int
  9896. %ptr_private_block = OpTypePointer Private %block
  9897. %void_fn = OpTypeFunction %void
  9898. %var = OpVariable %ptr_private_block Private
  9899. %main = OpFunction %void None %void_fn
  9900. %entry = OpLabel
  9901. OpReturn
  9902. OpFunctionEnd
  9903. )";
  9904. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9905. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9906. }
  9907. TEST_F(ValidateDecorations, InvalidLayoutOffsetPrivatePost1p4) {
  9908. const std::string spirv = R"(
  9909. OpCapability Shader
  9910. OpMemoryModel Logical GLSL450
  9911. OpEntryPoint GLCompute %main "main"
  9912. OpExecutionMode %main LocalSize 1 1 1
  9913. OpMemberDecorate %block 0 Offset 0
  9914. %void = OpTypeVoid
  9915. %int = OpTypeInt 32 0
  9916. %block = OpTypeStruct %int
  9917. %ptr_private_block = OpTypePointer Private %block
  9918. %void_fn = OpTypeFunction %void
  9919. %var = OpVariable %ptr_private_block Private
  9920. %main = OpFunction %void None %void_fn
  9921. %entry = OpLabel
  9922. OpReturn
  9923. OpFunctionEnd
  9924. )";
  9925. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  9926. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  9927. EXPECT_THAT(
  9928. getDiagnosticString(),
  9929. HasSubstr("Invalid explicit layout decorations on type for operand"));
  9930. }
  9931. TEST_F(ValidateDecorations, InvalidLayoutArrayStrideWorkgroupExplicitLayout) {
  9932. const std::string spirv = R"(
  9933. OpCapability Shader
  9934. OpCapability WorkgroupMemoryExplicitLayoutKHR
  9935. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  9936. OpMemoryModel Logical GLSL450
  9937. OpEntryPoint GLCompute %main "main"
  9938. OpExecutionMode %main LocalSize 1 1 1
  9939. OpDecorate %array ArrayStride 4
  9940. %void = OpTypeVoid
  9941. %int = OpTypeInt 32 0
  9942. %int_4 = OpConstant %int 4
  9943. %array = OpTypeArray %int %int_4
  9944. %ptr_wg_block = OpTypePointer Workgroup %array
  9945. %void_fn = OpTypeFunction %void
  9946. %var = OpVariable %ptr_wg_block Workgroup
  9947. %main = OpFunction %void None %void_fn
  9948. %entry = OpLabel
  9949. OpReturn
  9950. OpFunctionEnd
  9951. )";
  9952. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  9953. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  9954. }
  9955. TEST_F(ValidateDecorations, InvalidLayoutArrayStrideWorkgroup) {
  9956. const std::string spirv = R"(
  9957. OpCapability Shader
  9958. OpMemoryModel Logical GLSL450
  9959. OpEntryPoint GLCompute %main "main"
  9960. OpExecutionMode %main LocalSize 1 1 1
  9961. OpDecorate %array ArrayStride 4
  9962. %void = OpTypeVoid
  9963. %int = OpTypeInt 32 0
  9964. %int_4 = OpConstant %int 4
  9965. %array = OpTypeArray %int %int_4
  9966. %ptr_wg_block = OpTypePointer Workgroup %array
  9967. %void_fn = OpTypeFunction %void
  9968. %var = OpVariable %ptr_wg_block Workgroup
  9969. %main = OpFunction %void None %void_fn
  9970. %entry = OpLabel
  9971. OpReturn
  9972. OpFunctionEnd
  9973. )";
  9974. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  9975. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  9976. EXPECT_THAT(
  9977. getDiagnosticString(),
  9978. HasSubstr("Invalid explicit layout decorations on type for operand"));
  9979. }
  9980. TEST_F(ValidateDecorations, InvalidLayoutArrayStrideUniformConstant) {
  9981. const std::string spirv = R"(
  9982. OpCapability Shader
  9983. OpMemoryModel Logical GLSL450
  9984. OpEntryPoint GLCompute %main "main"
  9985. OpExecutionMode %main LocalSize 1 1 1
  9986. OpDecorate %array ArrayStride 4
  9987. OpDecorate %var DescriptorSet 0
  9988. OpDecorate %var Binding 0
  9989. %void = OpTypeVoid
  9990. %int = OpTypeInt 32 0
  9991. %int_4 = OpConstant %int 4
  9992. %sampler = OpTypeSampler
  9993. %array = OpTypeArray %sampler %int_4
  9994. %ptr_uc_block = OpTypePointer UniformConstant %array
  9995. %void_fn = OpTypeFunction %void
  9996. %var = OpVariable %ptr_uc_block UniformConstant
  9997. %main = OpFunction %void None %void_fn
  9998. %entry = OpLabel
  9999. OpReturn
  10000. OpFunctionEnd
  10001. )";
  10002. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  10003. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  10004. EXPECT_THAT(
  10005. getDiagnosticString(),
  10006. HasSubstr("Invalid explicit layout decorations on type for operand"));
  10007. }
  10008. TEST_F(ValidateDecorations, InvalidLayoutMatrixStrideFunctionPost1p4) {
  10009. const std::string spirv = R"(
  10010. OpCapability Shader
  10011. OpMemoryModel Logical GLSL450
  10012. OpEntryPoint GLCompute %main "main"
  10013. OpExecutionMode %main LocalSize 1 1 1
  10014. OpMemberDecorate %block 0 MatrixStride 16
  10015. %void = OpTypeVoid
  10016. %float = OpTypeFloat 32
  10017. %v4float = OpTypeVector %float 4
  10018. %mat4x4 = OpTypeMatrix %v4float 4
  10019. %block = OpTypeStruct %mat4x4
  10020. %ptr_function_block = OpTypePointer Function %block
  10021. %void_fn = OpTypeFunction %void
  10022. %main = OpFunction %void None %void_fn
  10023. %entry = OpLabel
  10024. %var = OpVariable %ptr_function_block Function
  10025. OpReturn
  10026. OpFunctionEnd
  10027. )";
  10028. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  10029. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  10030. EXPECT_THAT(
  10031. getDiagnosticString(),
  10032. HasSubstr("Invalid explicit layout decorations on type for operand"));
  10033. }
  10034. TEST_F(ValidateDecorations, InvalidLayoutNestedMatrixStrideFunctionPost1p4) {
  10035. const std::string spirv = R"(
  10036. OpCapability Shader
  10037. OpMemoryModel Logical GLSL450
  10038. OpEntryPoint GLCompute %main "main"
  10039. OpExecutionMode %main LocalSize 1 1 1
  10040. OpMemberDecorate %block 0 MatrixStride 16
  10041. %void = OpTypeVoid
  10042. %float = OpTypeFloat 32
  10043. %v4float = OpTypeVector %float 4
  10044. %mat4x4 = OpTypeMatrix %v4float 4
  10045. %block = OpTypeStruct %mat4x4
  10046. %block2 = OpTypeStruct %block
  10047. %int = OpTypeInt 32 0
  10048. %int_2 = OpConstant %int 2
  10049. %array = OpTypeArray %block2 %int_2
  10050. %ptr_function_array = OpTypePointer Function %array
  10051. %void_fn = OpTypeFunction %void
  10052. %main = OpFunction %void None %void_fn
  10053. %entry = OpLabel
  10054. %var = OpVariable %ptr_function_array Function
  10055. OpReturn
  10056. OpFunctionEnd
  10057. )";
  10058. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  10059. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  10060. EXPECT_THAT(
  10061. getDiagnosticString(),
  10062. HasSubstr("Invalid explicit layout decorations on type for operand"));
  10063. }
  10064. TEST_F(ValidateDecorations, InvalidLayoutBufferBlockWorkgroup) {
  10065. const std::string spirv = R"(
  10066. OpCapability Shader
  10067. OpMemoryModel Logical GLSL450
  10068. OpEntryPoint GLCompute %main "main"
  10069. OpExecutionMode %main LocalSize 1 1 1
  10070. OpDecorate %block BufferBlock
  10071. %void = OpTypeVoid
  10072. %int = OpTypeInt 32 0
  10073. %block = OpTypeStruct %int
  10074. %ptr_wg_block = OpTypePointer Workgroup %block
  10075. %void_fn = OpTypeFunction %void
  10076. %var = OpVariable %ptr_wg_block Workgroup
  10077. %main = OpFunction %void None %void_fn
  10078. %entry = OpLabel
  10079. OpReturn
  10080. OpFunctionEnd
  10081. )";
  10082. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  10083. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  10084. EXPECT_THAT(
  10085. getDiagnosticString(),
  10086. HasSubstr("Invalid explicit layout decorations on type for operand"));
  10087. }
  10088. TEST_F(ValidateDecorations, ExplicitLayoutOnPtrPhysicalStorageBuffer) {
  10089. const std::string spirv = R"(
  10090. OpCapability PhysicalStorageBufferAddresses
  10091. OpCapability Int64
  10092. OpCapability Shader
  10093. OpExtension "SPV_KHR_physical_storage_buffer"
  10094. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  10095. OpEntryPoint GLCompute %main "main"
  10096. OpExecutionMode %main LocalSize 1 1 1
  10097. OpDecorate %_ptr_PhysicalStorageBuffer_int ArrayStride 4
  10098. %void = OpTypeVoid
  10099. %void_fn = OpTypeFunction %void
  10100. %int = OpTypeInt 32 1
  10101. %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int ; ArrayStride 4
  10102. %Foo = OpTypeStruct %_ptr_PhysicalStorageBuffer_int
  10103. %_ptr_Function_Foo = OpTypePointer Function %Foo
  10104. %int_0 = OpConstant %int 0
  10105. %_ptr_Function__ptr_PhysicalStorageBuffer_int = OpTypePointer Function %_ptr_PhysicalStorageBuffer_int
  10106. %ulong = OpTypeInt 64 0
  10107. %ulong_0 = OpConstant %ulong 0
  10108. %main = OpFunction %void None %void_fn
  10109. %entry = OpLabel
  10110. %obj = OpVariable %_ptr_Function_Foo Function
  10111. %obj_member = OpAccessChain %_ptr_Function__ptr_PhysicalStorageBuffer_int %obj %int_0
  10112. %nullptr = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_int %ulong_0
  10113. OpStore %obj_member %nullptr
  10114. OpReturn
  10115. OpFunctionEnd
  10116. )";
  10117. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  10118. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  10119. }
  10120. TEST_F(ValidateDecorations, RuntimeArrayNotLargestOffsetInBlock) {
  10121. const std::string spirv = R"(
  10122. OpCapability Shader
  10123. OpExtension "SPV_KHR_storage_buffer_storage_class"
  10124. OpMemoryModel Logical GLSL450
  10125. OpEntryPoint GLCompute %main "main"
  10126. OpExecutionMode %main LocalSize 1 1 1
  10127. OpDecorate %var DescriptorSet 0
  10128. OpDecorate %var Binding 0
  10129. OpDecorate %block Block
  10130. OpMemberDecorate %block 0 Offset 16
  10131. OpMemberDecorate %block 1 Offset 0
  10132. %void = OpTypeVoid
  10133. %void_fn = OpTypeFunction %void
  10134. %int = OpTypeInt 32 0
  10135. %array = OpTypeRuntimeArray %int
  10136. %block = OpTypeStruct %int %array
  10137. %ptr = OpTypePointer StorageBuffer %block
  10138. %var = OpVariable %ptr StorageBuffer
  10139. %main = OpFunction %void None %void_fn
  10140. %entry = OpLabel
  10141. OpReturn
  10142. OpFunctionEnd
  10143. )";
  10144. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  10145. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  10146. EXPECT_THAT(getDiagnosticString(),
  10147. HasSubstr("has a runtime array at offset 0, but other members at "
  10148. "larger offsets"));
  10149. EXPECT_THAT(getDiagnosticString(),
  10150. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  10151. }
  10152. TEST_F(ValidateDecorations, RuntimeArrayNotLargestOffsetInBufferBlock) {
  10153. const std::string spirv = R"(
  10154. OpCapability Shader
  10155. OpMemoryModel Logical GLSL450
  10156. OpEntryPoint GLCompute %main "main"
  10157. OpExecutionMode %main LocalSize 1 1 1
  10158. OpDecorate %var DescriptorSet 0
  10159. OpDecorate %var Binding 0
  10160. OpDecorate %block BufferBlock
  10161. OpMemberDecorate %block 0 Offset 16
  10162. OpMemberDecorate %block 1 Offset 0
  10163. %void = OpTypeVoid
  10164. %void_fn = OpTypeFunction %void
  10165. %int = OpTypeInt 32 0
  10166. %array = OpTypeRuntimeArray %int
  10167. %block = OpTypeStruct %int %array
  10168. %ptr = OpTypePointer Uniform %block
  10169. %var = OpVariable %ptr Uniform
  10170. %main = OpFunction %void None %void_fn
  10171. %entry = OpLabel
  10172. OpReturn
  10173. OpFunctionEnd
  10174. )";
  10175. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  10176. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  10177. EXPECT_THAT(getDiagnosticString(),
  10178. HasSubstr("has a runtime array at offset 0, but other members at "
  10179. "larger offsets"));
  10180. EXPECT_THAT(getDiagnosticString(),
  10181. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  10182. }
  10183. } // namespace
  10184. } // namespace val
  10185. } // namespace spvtools