| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070 |
- // Copyright (c) 2017 Google Inc.
- // Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
- // reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- // Validation tests for decorations
- #include <string>
- #include <vector>
- #include "gmock/gmock.h"
- #include "source/val/decoration.h"
- #include "test/unit_spirv.h"
- #include "test/val/val_code_generator.h"
- #include "test/val/val_fixtures.h"
- namespace spvtools {
- namespace val {
- namespace {
- using ::testing::Combine;
- using ::testing::Eq;
- using ::testing::HasSubstr;
- using ::testing::Values;
- struct TestResult {
- TestResult(spv_result_t in_validation_result = SPV_SUCCESS,
- const std::string& in_error_str = "")
- : validation_result(in_validation_result), error_str(in_error_str) {}
- spv_result_t validation_result;
- const std::string error_str;
- };
- using ValidateDecorations = spvtest::ValidateBase<bool>;
- using ValidateDecorationString = spvtest::ValidateBase<std::string>;
- using ValidateVulkanCombineDecorationResult =
- spvtest::ValidateBase<std::tuple<const char*, const char*, TestResult>>;
- TEST_F(ValidateDecorations, ValidateOpDecorateRegistration) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %1 Location 4
- OpDecorate %1 Centroid
- %2 = OpTypeFloat 32
- %3 = OpTypePointer Output %2
- %1 = OpVariable %3 Output
- ; Since %1 is used first in Decoration, it gets id 1.
- )";
- const uint32_t id = 1;
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- // Must have 2 decorations.
- EXPECT_THAT(
- vstate_->id_decorations(id),
- Eq(std::set<Decoration>{Decoration(spv::Decoration::Location, {4}),
- Decoration(spv::Decoration::Centroid)}));
- }
- TEST_F(ValidateDecorations, ValidateOpMemberDecorateRegistration) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %_arr_double_uint_6 ArrayStride 4
- OpMemberDecorate %_struct_115 2 NonReadable
- OpMemberDecorate %_struct_115 2 Offset 2
- OpDecorate %_struct_115 BufferBlock
- %float = OpTypeFloat 32
- %uint = OpTypeInt 32 0
- %uint_6 = OpConstant %uint 6
- %_arr_double_uint_6 = OpTypeArray %float %uint_6
- %_struct_115 = OpTypeStruct %float %float %_arr_double_uint_6
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- // The array must have 1 decoration.
- const uint32_t arr_id = 1;
- EXPECT_THAT(
- vstate_->id_decorations(arr_id),
- Eq(std::set<Decoration>{Decoration(spv::Decoration::ArrayStride, {4})}));
- // The struct must have 3 decorations.
- const uint32_t struct_id = 2;
- EXPECT_THAT(
- vstate_->id_decorations(struct_id),
- Eq(std::set<Decoration>{Decoration(spv::Decoration::NonReadable, {}, 2),
- Decoration(spv::Decoration::Offset, {2}, 2),
- Decoration(spv::Decoration::BufferBlock)}));
- }
- TEST_F(ValidateDecorations, ValidateOpMemberDecorateOutOfBound) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "Main"
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %_struct_2 1 RelaxedPrecision
- %void = OpTypeVoid
- %4 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_struct_2 = OpTypeStruct %float
- %1 = OpFunction %void None %4
- %6 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Index 1 provided in OpMemberDecorate for struct <id> "
- "'2[%_struct_2]' is out of bounds. The structure has 1 "
- "members. Largest valid index is 0."));
- }
- TEST_F(ValidateDecorations, ValidateGroupDecorateRegistration) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %1 DescriptorSet 0
- OpDecorate %1 RelaxedPrecision
- OpDecorate %1 Restrict
- %1 = OpDecorationGroup
- OpGroupDecorate %1 %2 %3
- OpGroupDecorate %1 %4
- %float = OpTypeFloat 32
- %_runtimearr_float = OpTypeRuntimeArray %float
- %_struct_9 = OpTypeStruct %_runtimearr_float
- %_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
- %2 = OpVariable %_ptr_Uniform__struct_9 Uniform
- %_struct_10 = OpTypeStruct %_runtimearr_float
- %_ptr_Uniform__struct_10 = OpTypePointer Uniform %_struct_10
- %3 = OpVariable %_ptr_Uniform__struct_10 Uniform
- %_struct_11 = OpTypeStruct %_runtimearr_float
- %_ptr_Uniform__struct_11 = OpTypePointer Uniform %_struct_11
- %4 = OpVariable %_ptr_Uniform__struct_11 Uniform
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- // Decoration group has 3 decorations.
- auto expected_decorations =
- std::set<Decoration>{Decoration(spv::Decoration::DescriptorSet, {0}),
- Decoration(spv::Decoration::RelaxedPrecision),
- Decoration(spv::Decoration::Restrict)};
- // Decoration group is applied to id 1, 2, 3, and 4. Note that id 1 (which is
- // the decoration group id) also has all the decorations.
- EXPECT_THAT(vstate_->id_decorations(1), Eq(expected_decorations));
- EXPECT_THAT(vstate_->id_decorations(2), Eq(expected_decorations));
- EXPECT_THAT(vstate_->id_decorations(3), Eq(expected_decorations));
- EXPECT_THAT(vstate_->id_decorations(4), Eq(expected_decorations));
- }
- TEST_F(ValidateDecorations, ValidateGroupMemberDecorateRegistration) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %1 Offset 3
- %1 = OpDecorationGroup
- OpGroupMemberDecorate %1 %_struct_1 3 %_struct_2 3 %_struct_3 3
- %float = OpTypeFloat 32
- %_runtimearr = OpTypeRuntimeArray %float
- %_struct_1 = OpTypeStruct %float %float %float %_runtimearr
- %_struct_2 = OpTypeStruct %float %float %float %_runtimearr
- %_struct_3 = OpTypeStruct %float %float %float %_runtimearr
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- // Decoration group has 1 decoration.
- auto expected_decorations =
- std::set<Decoration>{Decoration(spv::Decoration::Offset, {3}, 3)};
- // Decoration group is applied to id 2, 3, and 4.
- EXPECT_THAT(vstate_->id_decorations(2), Eq(expected_decorations));
- EXPECT_THAT(vstate_->id_decorations(3), Eq(expected_decorations));
- EXPECT_THAT(vstate_->id_decorations(4), Eq(expected_decorations));
- }
- TEST_F(ValidateDecorations, LinkageImportUsedForInitializedVariableBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %target LinkageAttributes "link_ptr" Import
- %float = OpTypeFloat 32
- %_ptr_float = OpTypePointer Uniform %float
- %zero = OpConstantNull %float
- %target = OpVariable %_ptr_float Uniform %zero
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("A module-scope OpVariable with initialization value "
- "cannot be marked with the Import Linkage Type."));
- }
- TEST_F(ValidateDecorations, LinkageExportUsedForInitializedVariableGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %target LinkageAttributes "link_ptr" Export
- %float = OpTypeFloat 32
- %_ptr_float = OpTypePointer Uniform %float
- %zero = OpConstantNull %float
- %target = OpVariable %_ptr_float Uniform %zero
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, StructAllMembersHaveBuiltInDecorationsGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %_struct_1 Block
- OpMemberDecorate %_struct_1 0 BuiltIn Position
- OpMemberDecorate %_struct_1 1 BuiltIn Position
- OpMemberDecorate %_struct_1 2 BuiltIn Position
- OpMemberDecorate %_struct_1 3 BuiltIn Position
- %float = OpTypeFloat 32
- %_runtimearr = OpTypeRuntimeArray %float
- %_struct_1 = OpTypeStruct %float %float %float %_runtimearr
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, MixedBuiltInDecorationsBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %_struct_1 Block
- OpMemberDecorate %_struct_1 0 BuiltIn Position
- OpMemberDecorate %_struct_1 1 BuiltIn Position
- %float = OpTypeFloat 32
- %_runtimearr = OpTypeRuntimeArray %float
- %_struct_1 = OpTypeStruct %float %float %float %_runtimearr
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("When BuiltIn decoration is applied to a structure-type "
- "member, all members of that structure type must also be "
- "decorated with BuiltIn (No allowed mixing of built-in "
- "variables and non-built-in variables within a single "
- "structure). Structure id 1 does not meet this requirement."));
- }
- TEST_F(ValidateDecorations, StructContainsBuiltInStructBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %_struct_1 Block
- OpMemberDecorate %_struct_1 0 BuiltIn Position
- OpMemberDecorate %_struct_1 1 BuiltIn Position
- OpMemberDecorate %_struct_1 2 BuiltIn Position
- OpMemberDecorate %_struct_1 3 BuiltIn Position
- %float = OpTypeFloat 32
- %_runtimearr = OpTypeRuntimeArray %float
- %_struct_1 = OpTypeStruct %float %float %float %_runtimearr
- %_struct_2 = OpTypeStruct %_struct_1
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Structure <id> '1[%_struct_1]' contains members with "
- "BuiltIn decoration. Therefore this structure may not "
- "be contained as a member of another structure type. "
- "Structure <id> '4[%_struct_4]' contains structure <id> "
- "'1[%_struct_1]'."));
- }
- TEST_F(ValidateDecorations, StructContainsNonBuiltInStructGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %float = OpTypeFloat 32
- %_struct_1 = OpTypeStruct %float
- %_struct_2 = OpTypeStruct %_struct_1
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, MultipleBuiltInObjectsConsumedByOpEntryPointBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Geometry
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %in_1 %in_2
- OpExecutionMode %main InputPoints
- OpExecutionMode %main OutputPoints
- OpDecorate %struct_1 Block
- OpDecorate %struct_2 Block
- OpMemberDecorate %struct_1 0 BuiltIn InvocationId
- OpMemberDecorate %struct_2 0 BuiltIn Position
- %int = OpTypeInt 32 1
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct_1 = OpTypeStruct %int
- %struct_2 = OpTypeStruct %float
- %ptr_builtin_1 = OpTypePointer Input %struct_1
- %ptr_builtin_2 = OpTypePointer Input %struct_2
- %in_1 = OpVariable %ptr_builtin_1 Input
- %in_2 = OpVariable %ptr_builtin_2 Input
- %main = OpFunction %void None %func
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("There must be at most one object per Storage Class "
- "that can contain a structure type containing members "
- "decorated with BuiltIn, consumed per entry-point."));
- }
- TEST_F(ValidateDecorations,
- OneBuiltInObjectPerStorageClassConsumedByOpEntryPointGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Geometry
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %in_1 %out_1
- OpExecutionMode %main InputPoints
- OpExecutionMode %main OutputPoints
- OpDecorate %struct_1 Block
- OpDecorate %struct_2 Block
- OpMemberDecorate %struct_1 0 BuiltIn InvocationId
- OpMemberDecorate %struct_2 0 BuiltIn Position
- %int = OpTypeInt 32 1
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct_1 = OpTypeStruct %int
- %struct_2 = OpTypeStruct %float
- %ptr_builtin_1 = OpTypePointer Input %struct_1
- %ptr_builtin_2 = OpTypePointer Output %struct_2
- %in_1 = OpVariable %ptr_builtin_1 Input
- %out_1 = OpVariable %ptr_builtin_2 Output
- %main = OpFunction %void None %func
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, NoBuiltInObjectsConsumedByOpEntryPointGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Geometry
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %in_1 %out_1
- OpExecutionMode %main InputPoints
- OpExecutionMode %main OutputPoints
- %int = OpTypeInt 32 1
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct_1 = OpTypeStruct %int
- %struct_2 = OpTypeStruct %float
- %ptr_builtin_1 = OpTypePointer Input %struct_1
- %ptr_builtin_2 = OpTypePointer Output %struct_2
- %in_1 = OpVariable %ptr_builtin_1 Input
- %out_1 = OpVariable %ptr_builtin_2 Output
- %main = OpFunction %void None %func
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, EntryPointFunctionHasLinkageAttributeBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %main LinkageAttributes "import_main" Import
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %main = OpFunction %1 None %2
- %4 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("The LinkageAttributes Decoration (Linkage name: import_main) "
- "cannot be applied to function id 1 because it is targeted by "
- "an OpEntryPoint instruction."));
- }
- TEST_F(ValidateDecorations, FunctionDeclarationWithoutImportLinkageBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Function declaration (id 3) must have a LinkageAttributes "
- "decoration with the Import Linkage type."));
- }
- TEST_F(ValidateDecorations, FunctionDeclarationWithImportLinkageGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %main LinkageAttributes "link_fn" Import
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, FunctionDeclarationWithExportLinkageBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %main LinkageAttributes "link_fn" Export
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Function declaration (id 1) must have a LinkageAttributes "
- "decoration with the Import Linkage type."));
- }
- TEST_F(ValidateDecorations, FunctionDefinitionWithImportLinkageBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %main LinkageAttributes "link_fn" Import
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Function definition (id 1) may not be decorated with "
- "Import Linkage type."));
- }
- TEST_F(ValidateDecorations, FunctionDefinitionWithoutImportLinkageGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, BuiltinVariablesGoodVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %gl_FragCoord %_entryPointOutput
- OpExecutionMode %main OriginUpperLeft
- OpSource HLSL 500
- OpDecorate %gl_FragCoord BuiltIn FragCoord
- OpDecorate %_entryPointOutput Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %float_0 = OpConstant %float 0
- %14 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %_entryPointOutput = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpStore %_entryPointOutput %14
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- }
- TEST_F(ValidateDecorations, BuiltinVariablesWithLocationDecorationVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %gl_FragCoord %_entryPointOutput
- OpExecutionMode %main OriginUpperLeft
- OpSource HLSL 500
- OpDecorate %gl_FragCoord BuiltIn FragCoord
- OpDecorate %gl_FragCoord Location 0
- OpDecorate %_entryPointOutput Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %float_0 = OpConstant %float 0
- %14 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %_entryPointOutput = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpStore %_entryPointOutput %14
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Location-04915"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("A BuiltIn variable (id 2) cannot have any Location or "
- "Component decorations"));
- }
- TEST_F(ValidateDecorations, BuiltinVariablesWithComponentDecorationVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %gl_FragCoord %_entryPointOutput
- OpExecutionMode %main OriginUpperLeft
- OpSource HLSL 500
- OpDecorate %gl_FragCoord BuiltIn FragCoord
- OpDecorate %gl_FragCoord Component 0
- OpDecorate %_entryPointOutput Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %float_0 = OpConstant %float 0
- %14 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %_entryPointOutput = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpStore %_entryPointOutput %14
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Location-04915"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("A BuiltIn variable (id 2) cannot have any Location or "
- "Component decorations"));
- }
- TEST_F(ValidateDecorations, LocationDecorationOnNumericTypeBad) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %fragCoord Location 0
- OpDecorate %v4float Location 1
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %ptr_v4float = OpTypePointer Output %v4float
- %fragCoord = OpVariable %ptr_v4float Output
- %non_interface = OpVariable %ptr_v4float Output
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Location decoration on target <id> '3[%v4float]' must "
- "be a variable"));
- }
- TEST_F(ValidateDecorations, LocationDecorationOnStructBad) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %fragCoord Location 0
- OpDecorate %struct Location 1
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %v4float = OpTypeVector %float 4
- %ptr_v4float = OpTypePointer Output %v4float
- %fragCoord = OpVariable %ptr_v4float Output
- %non_interface = OpVariable %ptr_v4float Output
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Location decoration on target <id> '3[%_struct_3]' "
- "must be a variable"));
- }
- TEST_F(ValidateDecorations,
- LocationDecorationUnusedNonInterfaceVariableVulkan_Ignored) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %fragCoord Location 0
- OpDecorate %non_interface Location 1
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %ptr_v4float = OpTypePointer Output %v4float
- %fragCoord = OpVariable %ptr_v4float Output
- %non_interface = OpVariable %ptr_v4float Output
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- EXPECT_EQ(getDiagnosticString(), "");
- }
- TEST_F(ValidateDecorations,
- LocationDecorationNonInterfaceStructVulkan_Ignored) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %fragCoord Location 0
- OpMemberDecorate %block 0 Location 2
- OpMemberDecorate %block 0 Component 1
- OpDecorate %block Block
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %vec3 = OpTypeVector %float 3
- %outvar_ptr = OpTypePointer Output %vec3
- %fragCoord = OpVariable %outvar_ptr Output
- %block = OpTypeStruct %vec3
- %invar_ptr = OpTypePointer Input %block
- %non_interface = OpVariable %invar_ptr Input
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- EXPECT_EQ(getDiagnosticString(), "");
- }
- TEST_F(ValidateDecorations, LocationDecorationNonInterfaceStructVulkanGood) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord %interface
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %fragCoord Location 0
- OpMemberDecorate %block 0 Location 2
- OpMemberDecorate %block 0 Component 1
- OpDecorate %block Block
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %vec3 = OpTypeVector %float 3
- %outvar_ptr = OpTypePointer Output %vec3
- %fragCoord = OpVariable %outvar_ptr Output
- %block = OpTypeStruct %vec3
- %invar_ptr = OpTypePointer Input %block
- %interface = OpVariable %invar_ptr Input ;; this variable is unused. Ignore it
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- }
- TEST_F(ValidateDecorations, LocationDecorationVariableNonStructVulkanBad) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord %nonblock_var
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %fragCoord Location 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %ptr_v4float = OpTypePointer Output %v4float
- %fragCoord = OpVariable %ptr_v4float Output
- %nonblock_var = OpVariable %ptr_v4float Output
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Location-04916"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Variable must be decorated with a location"));
- }
- TEST_F(ValidateDecorations, LocationDecorationVariableStructNoBlockVulkanBad) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord %block_var
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %fragCoord Location 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %ptr_v4float = OpTypePointer Output %v4float
- %fragCoord = OpVariable %ptr_v4float Output
- %block = OpTypeStruct %v4float
- %block_ptr = OpTypePointer Output %block
- %block_var = OpVariable %block_ptr Output
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Location-04917"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Variable must be decorated with a location"));
- }
- TEST_F(ValidateDecorations, LocationDecorationVariableNoBlockVulkanGood) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord %block_var
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %fragCoord Location 0
- OpDecorate %block_var Location 1
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %ptr_v4float = OpTypePointer Output %v4float
- %fragCoord = OpVariable %ptr_v4float Output
- %block = OpTypeStruct %v4float
- %block_ptr = OpTypePointer Output %block
- %block_var = OpVariable %block_ptr Output
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, LocationDecorationVariableExtraMemeberVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord %block_var
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %fragCoord Location 0
- OpDecorate %block Block
- OpDecorate %block_var Location 1
- OpMemberDecorate %block 0 Location 1
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %ptr_v4float = OpTypePointer Output %v4float
- %fragCoord = OpVariable %ptr_v4float Output
- %block = OpTypeStruct %v4float
- %block_ptr = OpTypePointer Output %block
- %block_var = OpVariable %block_ptr Output
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Location-04918"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Members cannot be assigned a location"));
- }
- TEST_F(ValidateDecorations, LocationDecorationVariableMissingMemeberVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord %block_var
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %fragCoord Location 0
- OpDecorate %block Block
- OpMemberDecorate %block 0 Location 1
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %ptr_v4float = OpTypePointer Output %v4float
- %fragCoord = OpVariable %ptr_v4float Output
- %block = OpTypeStruct %v4float %v4float
- %block_ptr = OpTypePointer Output %block
- %block_var = OpVariable %block_ptr Output
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Location-04919"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Member index 1 is missing a location assignment"));
- }
- TEST_F(ValidateDecorations, LocationDecorationVariableOnlyMemeberVulkanGood) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %fragCoord %block_var
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %fragCoord Location 0
- OpDecorate %block Block
- OpMemberDecorate %block 0 Location 1
- OpMemberDecorate %block 1 Location 4
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %ptr_v4float = OpTypePointer Output %v4float
- %fragCoord = OpVariable %ptr_v4float Output
- %block = OpTypeStruct %v4float %v4float
- %block_ptr = OpTypePointer Output %block
- %block_var = OpVariable %block_ptr Output
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- // #version 440
- // #extension GL_EXT_nonuniform_qualifier : enable
- // layout(binding = 1) uniform sampler2D s2d[];
- // layout(location = 0) in nonuniformEXT int i;
- // void main()
- // {
- // vec4 v = texture(s2d[i], vec2(0.3));
- // }
- TEST_F(ValidateDecorations, RuntimeArrayOfDescriptorSetsIsAllowed) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpCapability ShaderNonUniformEXT
- OpCapability RuntimeDescriptorArrayEXT
- OpCapability SampledImageArrayNonUniformIndexingEXT
- OpExtension "SPV_EXT_descriptor_indexing"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %i
- OpSource GLSL 440
- OpSourceExtension "GL_EXT_nonuniform_qualifier"
- OpName %main "main"
- OpName %v "v"
- OpName %s2d "s2d"
- OpName %i "i"
- OpDecorate %s2d DescriptorSet 0
- OpDecorate %s2d Binding 1
- OpDecorate %i Location 0
- OpDecorate %i NonUniformEXT
- OpDecorate %18 NonUniformEXT
- OpDecorate %21 NonUniformEXT
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
- %11 = OpTypeSampledImage %10
- %_runtimearr_11 = OpTypeRuntimeArray %11
- %_ptr_Uniform__runtimearr_11 = OpTypePointer Uniform %_runtimearr_11
- %s2d = OpVariable %_ptr_Uniform__runtimearr_11 Uniform
- %int = OpTypeInt 32 1
- %_ptr_Input_int = OpTypePointer Input %int
- %i = OpVariable %_ptr_Input_int Input
- %_ptr_Uniform_11 = OpTypePointer Uniform %11
- %v2float = OpTypeVector %float 2
- %float_0_300000012 = OpConstant %float 0.300000012
- %24 = OpConstantComposite %v2float %float_0_300000012 %float_0_300000012
- %float_0 = OpConstant %float 0
- %main = OpFunction %void None %3
- %5 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %18 = OpLoad %int %i
- %20 = OpAccessChain %_ptr_Uniform_11 %s2d %18
- %21 = OpLoad %11 %20
- %26 = OpImageSampleExplicitLod %v4float %21 %24 Lod %float_0
- OpStore %v %26
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, BlockDecoratingArrayBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 1
- %int_3 = OpConstant %int 3
- %Output = OpTypeArray %float %int_3
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
- }
- TEST_F(ValidateDecorations, BlockDecoratingIntBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %Output = OpTypeInt 32 1
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
- }
- TEST_F(ValidateDecorations, BlockMissingOffsetBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %Output = OpTypeStruct %float
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("must be explicitly laid out with Offset decorations"));
- }
- TEST_F(ValidateDecorations, BufferBlockMissingOffsetBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output BufferBlock
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %Output = OpTypeStruct %float
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("must be explicitly laid out with Offset decorations"));
- }
- TEST_F(ValidateDecorations, BlockNestedStructMissingOffsetBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %v3float = OpTypeVector %float 3
- %int = OpTypeInt 32 1
- %S = OpTypeStruct %v3float %int
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("must be explicitly laid out with Offset decorations"));
- }
- TEST_F(ValidateDecorations, BufferBlockNestedStructMissingOffsetBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output BufferBlock
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %v3float = OpTypeVector %float 3
- %int = OpTypeInt 32 1
- %S = OpTypeStruct %v3float %int
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("must be explicitly laid out with Offset decorations"));
- }
- TEST_F(ValidateDecorations, BlockGLSLSharedBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output Block
- OpDecorate %Output GLSLShared
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %Output = OpTypeStruct %float
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "'GLSLShared' is not valid for the Vulkan execution environment"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
- }
- TEST_F(ValidateDecorations, BufferBlockGLSLSharedBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output BufferBlock
- OpDecorate %Output GLSLShared
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %Output = OpTypeStruct %float
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "'GLSLShared' is not valid for the Vulkan execution environment"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
- }
- TEST_F(ValidateDecorations, BlockNestedStructGLSLSharedBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpDecorate %S GLSLShared
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %int = OpTypeInt 32 1
- %S = OpTypeStruct %int
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "'GLSLShared' is not valid for the Vulkan execution environment"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
- }
- TEST_F(ValidateDecorations, BufferBlockNestedStructGLSLSharedBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpDecorate %S GLSLShared
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output BufferBlock
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %int = OpTypeInt 32 1
- %S = OpTypeStruct %int
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "'GLSLShared' is not valid for the Vulkan execution environment"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
- }
- TEST_F(ValidateDecorations, BlockGLSLPackedBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output Block
- OpDecorate %Output GLSLPacked
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %Output = OpTypeStruct %float
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "'GLSLPacked' is not valid for the Vulkan execution environment"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
- }
- TEST_F(ValidateDecorations, BufferBlockGLSLPackedBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output BufferBlock
- OpDecorate %Output GLSLPacked
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %Output = OpTypeStruct %float
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "'GLSLPacked' is not valid for the Vulkan execution environment"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
- }
- TEST_F(ValidateDecorations, BlockNestedStructGLSLPackedBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpDecorate %S GLSLPacked
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %int = OpTypeInt 32 1
- %S = OpTypeStruct %int
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "'GLSLPacked' is not valid for the Vulkan execution environment"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
- }
- TEST_F(ValidateDecorations, BufferBlockNestedStructGLSLPackedBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpDecorate %S GLSLPacked
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output BufferBlock
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %int = OpTypeInt 32 1
- %S = OpTypeStruct %int
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "'GLSLPacked' is not valid for the Vulkan execution environment"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]"));
- }
- TEST_F(ValidateDecorations, BlockMissingArrayStrideBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output Block
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 1
- %int_3 = OpConstant %int 3
- %array = OpTypeArray %float %int_3
- %Output = OpTypeStruct %array
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with ArrayStride decorations"));
- }
- TEST_F(ValidateDecorations, BufferBlockMissingArrayStrideBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output BufferBlock
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 1
- %int_3 = OpConstant %int 3
- %array = OpTypeArray %float %int_3
- %Output = OpTypeStruct %array
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with ArrayStride decorations"));
- }
- TEST_F(ValidateDecorations, BlockNestedStructMissingArrayStrideBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %int = OpTypeInt 32 1
- %int_3 = OpConstant %int 3
- %array = OpTypeArray %float %int_3
- %S = OpTypeStruct %array
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with ArrayStride decorations"));
- }
- TEST_F(ValidateDecorations, BufferBlockNestedStructMissingArrayStrideBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output BufferBlock
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %int = OpTypeInt 32 1
- %int_3 = OpConstant %int 3
- %array = OpTypeArray %float %int_3
- %S = OpTypeStruct %array
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with ArrayStride decorations"));
- }
- TEST_F(ValidateDecorations, BlockMissingMatrixStrideBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output Block
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %matrix = OpTypeMatrix %v3float 4
- %Output = OpTypeStruct %matrix
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with MatrixStride decorations"));
- }
- TEST_F(ValidateDecorations, BufferBlockMissingMatrixStrideBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output BufferBlock
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %matrix = OpTypeMatrix %v3float 4
- %Output = OpTypeStruct %matrix
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with MatrixStride decorations"));
- }
- TEST_F(ValidateDecorations, BlockMissingMatrixStrideArrayBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output Block
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %matrix = OpTypeMatrix %v3float 4
- %int = OpTypeInt 32 1
- %int_3 = OpConstant %int 3
- %array = OpTypeArray %matrix %int_3
- %Output = OpTypeStruct %matrix
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with MatrixStride decorations"));
- }
- TEST_F(ValidateDecorations, BufferBlockMissingMatrixStrideArrayBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %Output BufferBlock
- OpMemberDecorate %Output 0 Offset 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %matrix = OpTypeMatrix %v3float 4
- %int = OpTypeInt 32 1
- %int_3 = OpConstant %int 3
- %array = OpTypeArray %matrix %int_3
- %Output = OpTypeStruct %matrix
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with MatrixStride decorations"));
- }
- TEST_F(ValidateDecorations, BlockNestedStructMissingMatrixStrideBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %v4float = OpTypeVector %float 4
- %matrix = OpTypeMatrix %v3float 4
- %S = OpTypeStruct %matrix
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with MatrixStride decorations"));
- }
- TEST_F(ValidateDecorations, BufferBlockNestedStructMissingMatrixStrideBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 16
- OpMemberDecorate %Output 2 Offset 32
- OpDecorate %Output BufferBlock
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %v4float = OpTypeVector %float 4
- %matrix = OpTypeMatrix %v3float 4
- %S = OpTypeStruct %matrix
- %Output = OpTypeStruct %float %v4float %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with MatrixStride decorations"));
- }
- TEST_F(ValidateDecorations, BlockStandardUniformBufferLayout) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %F 0 Offset 0
- OpMemberDecorate %F 1 Offset 8
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 48
- OpMemberDecorate %O 0 Offset 0
- OpMemberDecorate %O 1 Offset 16
- OpMemberDecorate %O 2 Offset 32
- OpMemberDecorate %O 3 Offset 64
- OpMemberDecorate %O 4 ColMajor
- OpMemberDecorate %O 4 Offset 80
- OpMemberDecorate %O 4 MatrixStride 16
- OpDecorate %_arr_O_uint_2 ArrayStride 176
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 8
- OpMemberDecorate %Output 2 Offset 16
- OpMemberDecorate %Output 3 Offset 32
- OpMemberDecorate %Output 4 Offset 48
- OpMemberDecorate %Output 5 Offset 64
- OpMemberDecorate %Output 6 ColMajor
- OpMemberDecorate %Output 6 Offset 96
- OpMemberDecorate %Output 6 MatrixStride 16
- OpMemberDecorate %Output 7 Offset 128
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v3float = OpTypeVector %float 3
- %int = OpTypeInt 32 1
- %uint = OpTypeInt 32 0
- %v2uint = OpTypeVector %uint 2
- %F = OpTypeStruct %int %v2uint
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %mat2v3float = OpTypeMatrix %v3float 2
- %v3uint = OpTypeVector %uint 3
- %mat3v3float = OpTypeMatrix %v3float 3
- %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
- %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
- %_arr_O_uint_2 = OpTypeArray %O %uint_2
- %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, BlockLayoutPermitsTightVec3ScalarPackingGood) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 12
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %v3float %float
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, BlockCantAppearWithinABlockBad) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1587
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 16
- OpMemberDecorate %S2 0 Offset 0
- OpMemberDecorate %S2 1 Offset 12
- OpDecorate %S Block
- OpDecorate %S2 Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %S2 = OpTypeStruct %float %float
- %S = OpTypeStruct %float %S2
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("rules: A Block or BufferBlock cannot be nested within "
- "another Block or BufferBlock."));
- }
- TEST_F(ValidateDecorations, BufferblockCantAppearWithinABufferblockBad) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1587
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 16
- OpMemberDecorate %S2 0 Offset 0
- OpMemberDecorate %S2 1 Offset 16
- OpMemberDecorate %S3 0 Offset 0
- OpMemberDecorate %S3 1 Offset 12
- OpDecorate %S BufferBlock
- OpDecorate %S3 BufferBlock
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %S3 = OpTypeStruct %float %float
- %S2 = OpTypeStruct %float %S3
- %S = OpTypeStruct %float %S2
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("rules: A Block or BufferBlock cannot be nested within "
- "another Block or BufferBlock."));
- }
- TEST_F(ValidateDecorations, BufferblockCantAppearWithinABlockBad) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1587
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 16
- OpMemberDecorate %S2 0 Offset 0
- OpMemberDecorate %S2 1 Offset 16
- OpMemberDecorate %S3 0 Offset 0
- OpMemberDecorate %S3 1 Offset 12
- OpDecorate %S Block
- OpDecorate %S3 BufferBlock
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %S3 = OpTypeStruct %float %float
- %S2 = OpTypeStruct %float %S3
- %S = OpTypeStruct %float %S2
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("rules: A Block or BufferBlock cannot be nested within "
- "another Block or BufferBlock."));
- }
- TEST_F(ValidateDecorations, BlockCantAppearWithinABufferblockBad) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1587
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 16
- OpMemberDecorate %S2 0 Offset 0
- OpMemberDecorate %S2 1 Offset 16
- OpMemberDecorate %S3 0 Offset 0
- OpMemberDecorate %S3 1 Offset 16
- OpMemberDecorate %S4 0 Offset 0
- OpMemberDecorate %S4 1 Offset 12
- OpDecorate %S BufferBlock
- OpDecorate %S4 Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %S4 = OpTypeStruct %float %float
- %S3 = OpTypeStruct %float %S4
- %S2 = OpTypeStruct %float %S3
- %S = OpTypeStruct %float %S2
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("rules: A Block or BufferBlock cannot be nested within "
- "another Block or BufferBlock."));
- }
- TEST_F(ValidateDecorations, BlockCannotAppearWithinBlockArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpMemberDecorate %outer 0 Offset 0
- OpMemberDecorate %outer 1 Offset 4
- OpMemberDecorate %outer 2 Offset 20
- OpDecorate %outer Block
- OpMemberDecorate %inner 0 Offset 0
- OpDecorate %inner Block
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %inner = OpTypeStruct %int
- %array = OpTypeArray %inner %int_4
- %outer = OpTypeStruct %int %array %int
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("rules: A Block or BufferBlock cannot be nested within "
- "another Block or BufferBlock."));
- }
- TEST_F(ValidateDecorations, BlockCannotAppearWithinBlockMultiArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpMemberDecorate %outer 0 Offset 0
- OpMemberDecorate %outer 1 Offset 4
- OpDecorate %outer Block
- OpMemberDecorate %inner 0 Offset 0
- OpDecorate %inner Block
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %inner = OpTypeStruct %int
- %array1 = OpTypeArray %inner %int_4
- %array2 = OpTypeArray %array1 %int_4
- %outer = OpTypeStruct %int %array2
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("rules: A Block or BufferBlock cannot be nested within "
- "another Block or BufferBlock."));
- }
- TEST_F(ValidateDecorations, BlockLayoutForbidsTightScalarVec3PackingBad) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %float %v3float
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Structure id 2 decorated as Block for variable in Uniform "
- "storage class must follow standard uniform buffer layout "
- "rules: member 1 at offset 4 is not aligned to 16"));
- }
- TEST_F(ValidateDecorations,
- BlockLayoutPermitsTightScalarVec3PackingWithRelaxedLayoutGood) {
- // Same as previous test, but with explicit option to relax block layout.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %float %v3float
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations,
- BlockLayoutPermitsTightScalarVec3PackingBadOffsetWithRelaxedLayoutBad) {
- // Same as previous test, but with the vector not aligned to its scalar
- // element. Use offset 5 instead of a multiple of 4.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 5
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %float %v3float
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 2 decorated as Block for variable in Uniform storage "
- "class must follow relaxed uniform buffer layout rules: member 1 at "
- "offset 5 is not aligned to scalar element size 4"));
- }
- TEST_F(ValidateDecorations,
- BlockLayoutPermitsTightScalarVec3PackingWithVulkan1_1Good) {
- // Same as previous test, but with Vulkan 1.1. Vulkan 1.1 included
- // VK_KHR_relaxed_block_layout in core.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %float %v3float
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations,
- BlockLayoutPermitsTightScalarVec3PackingWithScalarLayoutGood) {
- // Same as previous test, but with scalar block layout.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %float %v3float
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations,
- BlockLayoutPermitsScalarAlignedArrayWithScalarLayoutGood) {
- // The array at offset 4 is ok with scalar block layout.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- OpDecorate %arr_float ArrayStride 4
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %uint_3 = OpConstant %uint 3
- %float = OpTypeFloat 32
- %arr_float = OpTypeArray %float %uint_3
- %S = OpTypeStruct %float %arr_float
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations,
- BlockLayoutPermitsScalarAlignedArrayOfVec3WithScalarLayoutGood) {
- // The array at offset 4 is ok with scalar block layout, even though
- // its elements are vec3.
- // This is the same as the previous case, but the array elements are vec3
- // instead of float.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- OpDecorate %arr_vec3 ArrayStride 12
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %uint_3 = OpConstant %uint 3
- %float = OpTypeFloat 32
- %vec3 = OpTypeVector %float 3
- %arr_vec3 = OpTypeArray %vec3 %uint_3
- %S = OpTypeStruct %float %arr_vec3
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations,
- BlockLayoutPermitsScalarAlignedStructWithScalarLayoutGood) {
- // Scalar block layout permits the struct at offset 4, even though
- // it contains a vector with base alignment 8 and scalar alignment 4.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpMemberDecorate %st 0 Offset 0
- OpMemberDecorate %st 1 Offset 8
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %vec2 = OpTypeVector %float 2
- %st = OpTypeStruct %vec2 %float
- %S = OpTypeStruct %float %st
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(
- ValidateDecorations,
- BlockLayoutPermitsFieldsInBaseAlignmentPaddingAtEndOfStructWithScalarLayoutGood) {
- // Scalar block layout permits fields in what would normally be the padding at
- // the end of a struct.
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Float64
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %st 0 Offset 0
- OpMemberDecorate %st 1 Offset 8
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 12
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %double = OpTypeFloat 64
- %st = OpTypeStruct %double %float
- %S = OpTypeStruct %st %float
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(
- ValidateDecorations,
- BlockLayoutPermitsStraddlingVectorWithScalarLayoutOverrideRelaxBlockLayoutGood) {
- // Same as previous, but set relaxed block layout first. Scalar layout always
- // wins.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %vec4 = OpTypeVector %float 4
- %S = OpTypeStruct %float %vec4
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
- spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(
- ValidateDecorations,
- BlockLayoutPermitsStraddlingVectorWithRelaxedLayoutOverridenByScalarBlockLayoutGood) {
- // Same as previous, but set scalar block layout first. Scalar layout always
- // wins.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %vec4 = OpTypeVector %float 4
- %S = OpTypeStruct %float %vec4
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetScalarBlockLayout(getValidatorOptions(), true);
- spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, BufferBlock16bitStandardStorageBufferLayout) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability StorageUniform16
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %f32arr ArrayStride 4
- OpDecorate %f16arr ArrayStride 2
- OpMemberDecorate %SSBO32 0 Offset 0
- OpMemberDecorate %SSBO16 0 Offset 0
- OpDecorate %SSBO32 BufferBlock
- OpDecorate %SSBO16 BufferBlock
- %void = OpTypeVoid
- %voidf = OpTypeFunction %void
- %u32 = OpTypeInt 32 0
- %i32 = OpTypeInt 32 1
- %f32 = OpTypeFloat 32
- %uvec3 = OpTypeVector %u32 3
- %c_i32_32 = OpConstant %i32 32
- %c_i32_128 = OpConstant %i32 128
- %f32arr = OpTypeArray %f32 %c_i32_128
- %f16 = OpTypeFloat 16
- %f16arr = OpTypeArray %f16 %c_i32_128
- %SSBO32 = OpTypeStruct %f32arr
- %SSBO16 = OpTypeStruct %f16arr
- %_ptr_Uniform_SSBO32 = OpTypePointer Uniform %SSBO32
- %varSSBO32 = OpVariable %_ptr_Uniform_SSBO32 Uniform
- %_ptr_Uniform_SSBO16 = OpTypePointer Uniform %SSBO16
- %varSSBO16 = OpVariable %_ptr_Uniform_SSBO16 Uniform
- %main = OpFunction %void None %voidf
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, BlockArrayExtendedAlignmentGood) {
- // For uniform buffer, Array base alignment is 16, and ArrayStride
- // must be a multiple of 16.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 16
- OpDecorate %S Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %S = OpTypeStruct %v2float %_arr_float_uint_2
- %_ptr_PushConstant_S = OpTypePointer PushConstant %S
- %u = OpVariable %_ptr_PushConstant_S PushConstant
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, BlockArrayBaseAlignmentBad) {
- // For uniform buffer, Array base alignment is 16.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 8
- OpDecorate %S Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %S = OpTypeStruct %v2float %_arr_float_uint_2
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %u = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 3 decorated as Block for variable in Uniform "
- "storage class must follow standard uniform buffer layout rules: "
- "member 1 at offset 8 is not aligned to 16"));
- }
- TEST_F(ValidateDecorations, BlockArrayBaseAlignmentWithRelaxedLayoutStillBad) {
- // For uniform buffer, Array base alignment is 16, and ArrayStride
- // must be a multiple of 16. This case uses relaxed block layout. Relaxed
- // layout only relaxes rules for vector alignment, not array alignment.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpDecorate %u DescriptorSet 0
- OpDecorate %u Binding 0
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 8
- OpDecorate %S Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %S = OpTypeStruct %v2float %_arr_float_uint_2
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %u = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- spvValidatorOptionsSetRelaxBlockLayout(getValidatorOptions(), true);
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 4 decorated as Block for variable in Uniform "
- "storage class must follow standard uniform buffer layout rules: "
- "member 1 at offset 8 is not aligned to 16"));
- }
- TEST_F(ValidateDecorations, BlockArrayBaseAlignmentWithVulkan1_1StillBad) {
- // Same as previous test, but with Vulkan 1.1, which includes
- // VK_KHR_relaxed_block_layout in core.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpDecorate %u DescriptorSet 0
- OpDecorate %u Binding 0
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 8
- OpDecorate %S Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %S = OpTypeStruct %v2float %_arr_float_uint_2
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %u = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 4 decorated as Block for variable in Uniform "
- "storage class must follow relaxed uniform buffer layout rules: "
- "member 1 at offset 8 is not aligned to 16"));
- }
- TEST_F(ValidateDecorations,
- BlockArrayBaseAlignmentWithBlockStandardLayoutGood) {
- // Same as previous test, but with VK_KHR_uniform_buffer_standard_layout
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpDecorate %u DescriptorSet 0
- OpDecorate %u Binding 0
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 8
- OpDecorate %S Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %S = OpTypeStruct %v2float %_arr_float_uint_2
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %u = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetUniformBufferStandardLayout(getValidatorOptions(),
- true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, VulkanBufferBlockOnStorageBufferBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct BufferBlock
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr StorageBuffer
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("In Vulkan, BufferBlock is disallowed on variables in "
- "the StorageBuffer storage class"));
- }
- TEST_F(ValidateDecorations, PushConstantArrayBaseAlignmentGood) {
- // Tests https://github.com/KhronosGroup/SPIRV-Tools/issues/1664
- // From GLSL vertex shader:
- // #version 450
- // layout(push_constant) uniform S { vec2 v; float arr[2]; } u;
- // void main() { }
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpDecorate %_arr_float_uint_2 ArrayStride 4
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 8
- OpDecorate %S Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %S = OpTypeStruct %v2float %_arr_float_uint_2
- %_ptr_PushConstant_S = OpTypePointer PushConstant %S
- %u = OpVariable %_ptr_PushConstant_S PushConstant
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, PushConstantArrayBadAlignmentBad) {
- // Like the previous test, but with offset 7 instead of 8.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpDecorate %_arr_float_uint_2 ArrayStride 4
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 7
- OpDecorate %S Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %S = OpTypeStruct %v2float %_arr_float_uint_2
- %_ptr_PushConstant_S = OpTypePointer PushConstant %S
- %u = OpVariable %_ptr_PushConstant_S PushConstant
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 3 decorated as Block for variable in PushConstant "
- "storage class must follow standard storage buffer layout rules: "
- "member 1 at offset 7 is not aligned to 4"));
- }
- TEST_F(ValidateDecorations,
- PushConstantLayoutPermitsTightVec3ScalarPackingGood) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 12
- OpDecorate %S Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %v3float %float
- %_ptr_PushConstant_S = OpTypePointer PushConstant %S
- %B = OpVariable %_ptr_PushConstant_S PushConstant
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations,
- PushConstantLayoutForbidsTightScalarVec3PackingBad) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %float %v3float
- %_ptr_Uniform_S = OpTypePointer PushConstant %S
- %B = OpVariable %_ptr_Uniform_S PushConstant
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 2 decorated as Block for variable in PushConstant "
- "storage class must follow standard storage buffer layout "
- "rules: member 1 at offset 4 is not aligned to 16"));
- }
- TEST_F(ValidateDecorations, PushConstantMissingBlockGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer PushConstant %struct
- %pc = OpVariable %ptr PushConstant
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, VulkanPushConstantMissingBlockBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer PushConstant %struct
- %pc = OpVariable %ptr PushConstant
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("PushConstant id '2' is missing Block decoration.\n"
- "From Vulkan spec:\n"
- "Such variables must be identified with a Block "
- "decoration"));
- }
- TEST_F(ValidateDecorations, MultiplePushConstantsSingleEntryPointGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer PushConstant %struct
- %ptr_float = OpTypePointer PushConstant %float
- %pc1 = OpVariable %ptr PushConstant
- %pc2 = OpVariable %ptr PushConstant
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- %2 = OpAccessChain %ptr_float %pc1 %int_0
- %3 = OpLoad %float %2
- %4 = OpAccessChain %ptr_float %pc2 %int_0
- %5 = OpLoad %float %4
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations,
- VulkanMultiplePushConstantsDifferentEntryPointGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "func1"
- OpEntryPoint Fragment %2 "func2"
- OpExecutionMode %2 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer PushConstant %struct
- %ptr_float = OpTypePointer PushConstant %float
- %pc1 = OpVariable %ptr PushConstant
- %pc2 = OpVariable %ptr PushConstant
- %1 = OpFunction %void None %voidfn
- %label1 = OpLabel
- %3 = OpAccessChain %ptr_float %pc1 %int_0
- %4 = OpLoad %float %3
- OpReturn
- OpFunctionEnd
- %2 = OpFunction %void None %voidfn
- %label2 = OpLabel
- %5 = OpAccessChain %ptr_float %pc2 %int_0
- %6 = OpLoad %float %5
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations,
- VulkanMultiplePushConstantsUnusedSingleEntryPointGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer PushConstant %struct
- %ptr_float = OpTypePointer PushConstant %float
- %pc1 = OpVariable %ptr PushConstant
- %pc2 = OpVariable %ptr PushConstant
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, VulkanMultiplePushConstantsSingleEntryPointBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer PushConstant %struct
- %ptr_float = OpTypePointer PushConstant %float
- %pc1 = OpVariable %ptr PushConstant
- %pc2 = OpVariable %ptr PushConstant
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- %2 = OpAccessChain %ptr_float %pc1 %int_0
- %3 = OpLoad %float %2
- %4 = OpAccessChain %ptr_float %pc2 %int_0
- %5 = OpLoad %float %4
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-06674"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Entry point id '1' uses more than one PushConstant interface.\n"
- "From Vulkan spec:\n"
- "There must be no more than one push constant block "
- "statically used per shader entry point."));
- }
- TEST_F(ValidateDecorations,
- VulkanMultiplePushConstantsDifferentEntryPointSubFunctionGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "func1"
- OpEntryPoint Fragment %2 "func2"
- OpExecutionMode %2 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer PushConstant %struct
- %ptr_float = OpTypePointer PushConstant %float
- %pc1 = OpVariable %ptr PushConstant
- %pc2 = OpVariable %ptr PushConstant
- %sub1 = OpFunction %void None %voidfn
- %label_sub1 = OpLabel
- %3 = OpAccessChain %ptr_float %pc1 %int_0
- %4 = OpLoad %float %3
- OpReturn
- OpFunctionEnd
- %sub2 = OpFunction %void None %voidfn
- %label_sub2 = OpLabel
- %5 = OpAccessChain %ptr_float %pc2 %int_0
- %6 = OpLoad %float %5
- OpReturn
- OpFunctionEnd
- %1 = OpFunction %void None %voidfn
- %label1 = OpLabel
- %call1 = OpFunctionCall %void %sub1
- OpReturn
- OpFunctionEnd
- %2 = OpFunction %void None %voidfn
- %label2 = OpLabel
- %call2 = OpFunctionCall %void %sub2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations,
- VulkanMultiplePushConstantsSingleEntryPointSubFunctionBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer PushConstant %struct
- %ptr_float = OpTypePointer PushConstant %float
- %pc1 = OpVariable %ptr PushConstant
- %pc2 = OpVariable %ptr PushConstant
- %sub1 = OpFunction %void None %voidfn
- %label_sub1 = OpLabel
- %3 = OpAccessChain %ptr_float %pc1 %int_0
- %4 = OpLoad %float %3
- OpReturn
- OpFunctionEnd
- %sub2 = OpFunction %void None %voidfn
- %label_sub2 = OpLabel
- %5 = OpAccessChain %ptr_float %pc2 %int_0
- %6 = OpLoad %float %5
- OpReturn
- OpFunctionEnd
- %1 = OpFunction %void None %voidfn
- %label1 = OpLabel
- %call1 = OpFunctionCall %void %sub1
- %call2 = OpFunctionCall %void %sub2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-06674"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Entry point id '1' uses more than one PushConstant interface.\n"
- "From Vulkan spec:\n"
- "There must be no more than one push constant block "
- "statically used per shader entry point."));
- }
- TEST_F(ValidateDecorations,
- VulkanMultiplePushConstantsSingleEntryPointInterfaceBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %func1 "func1" %pc1 %pc2
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer PushConstant %struct
- %ptr_float = OpTypePointer PushConstant %float
- %pc1 = OpVariable %ptr PushConstant
- %pc2 = OpVariable %ptr PushConstant
- %func1 = OpFunction %void None %voidfn
- %label1 = OpLabel
- %access1 = OpAccessChain %ptr_float %pc1 %int_0
- %load1 = OpLoad %float %access1
- OpReturn
- OpFunctionEnd
- %func2 = OpFunction %void None %voidfn
- %label2 = OpLabel
- %access2 = OpAccessChain %ptr_float %pc2 %int_0
- %load2 = OpLoad %float %access2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpVariable-06673"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Entry-point has more than one variable with the "
- "PushConstant storage class in the interface"));
- }
- TEST_F(ValidateDecorations, VulkanUniformMissingDescriptorSetBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer Uniform %struct
- %ptr_float = OpTypePointer Uniform %float
- %var = OpVariable %ptr Uniform
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- %2 = OpAccessChain %ptr_float %var %int_0
- %3 = OpLoad %float %2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Uniform id '3' is missing DescriptorSet decoration.\n"
- "From Vulkan spec:\n"
- "These variables must have DescriptorSet and Binding "
- "decorations specified"));
- }
- TEST_F(ValidateDecorations, VulkanUniformMissingBindingBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %var DescriptorSet 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer Uniform %struct
- %ptr_float = OpTypePointer Uniform %float
- %var = OpVariable %ptr Uniform
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- %2 = OpAccessChain %ptr_float %var %int_0
- %3 = OpLoad %float %2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Uniform id '3' is missing Binding decoration.\n"
- "From Vulkan spec:\n"
- "These variables must have DescriptorSet and Binding "
- "decorations specified"));
- }
- TEST_F(ValidateDecorations, VulkanUniformConstantMissingDescriptorSetBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %sampler = OpTypeSampler
- %ptr = OpTypePointer UniformConstant %sampler
- %var = OpVariable %ptr UniformConstant
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- %2 = OpLoad %sampler %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("UniformConstant id '2' is missing DescriptorSet decoration.\n"
- "From Vulkan spec:\n"
- "These variables must have DescriptorSet and Binding "
- "decorations specified"));
- }
- TEST_F(ValidateDecorations, VulkanUniformConstantMissingBindingBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %var DescriptorSet 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %sampler = OpTypeSampler
- %ptr = OpTypePointer UniformConstant %sampler
- %var = OpVariable %ptr UniformConstant
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- %2 = OpLoad %sampler %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("UniformConstant id '2' is missing Binding decoration.\n"
- "From Vulkan spec:\n"
- "These variables must have DescriptorSet and Binding "
- "decorations specified"));
- }
- TEST_F(ValidateDecorations, VulkanStorageBufferMissingDescriptorSetBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr StorageBuffer
- %ptr_float = OpTypePointer StorageBuffer %float
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- %2 = OpAccessChain %ptr_float %var %int_0
- %3 = OpLoad %float %2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("StorageBuffer id '3' is missing DescriptorSet decoration.\n"
- "From Vulkan spec:\n"
- "These variables must have DescriptorSet and Binding "
- "decorations specified"));
- }
- TEST_F(ValidateDecorations, VulkanStorageBufferMissingBindingBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpDecorate %var DescriptorSet 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr StorageBuffer
- %ptr_float = OpTypePointer StorageBuffer %float
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- %2 = OpAccessChain %ptr_float %var %int_0
- %3 = OpLoad %float %2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("StorageBuffer id '3' is missing Binding decoration.\n"
- "From Vulkan spec:\n"
- "These variables must have DescriptorSet and Binding "
- "decorations specified"));
- }
- TEST_F(ValidateDecorations,
- VulkanStorageBufferMissingDescriptorSetSubFunctionBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr StorageBuffer
- %ptr_float = OpTypePointer StorageBuffer %float
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- %call = OpFunctionCall %void %2
- OpReturn
- OpFunctionEnd
- %2 = OpFunction %void None %voidfn
- %label2 = OpLabel
- %3 = OpAccessChain %ptr_float %var %int_0
- %4 = OpLoad %float %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("StorageBuffer id '3' is missing DescriptorSet decoration.\n"
- "From Vulkan spec:\n"
- "These variables must have DescriptorSet and Binding "
- "decorations specified"));
- }
- TEST_F(ValidateDecorations,
- VulkanStorageBufferMissingDescriptorAndBindingUnusedGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr StorageBuffer
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
- }
- TEST_F(ValidateDecorations, UniformMissingDescriptorSetGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer Uniform %struct
- %var = OpVariable %ptr Uniform
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, UniformMissingBindingGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %var DescriptorSet 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer Uniform %struct
- %var = OpVariable %ptr Uniform
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, UniformConstantMissingDescriptorSetGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %sampler = OpTypeSampler
- %ptr = OpTypePointer UniformConstant %sampler
- %var = OpVariable %ptr UniformConstant
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, UniformConstantMissingBindingGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %var DescriptorSet 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %sampler = OpTypeSampler
- %ptr = OpTypePointer UniformConstant %sampler
- %var = OpVariable %ptr UniformConstant
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, StorageBufferMissingDescriptorSetGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct BufferBlock
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr StorageBuffer
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, StorageBufferMissingBindingGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct BufferBlock
- OpDecorate %var DescriptorSet 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %ptr = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr StorageBuffer
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, StorageBufferStorageClassArrayBaseAlignmentGood) {
- // Spot check buffer rules when using StorageBuffer storage class with Block
- // decoration.
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpDecorate %_arr_float_uint_2 ArrayStride 4
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 8
- OpDecorate %S Block
- OpDecorate %u DescriptorSet 0
- OpDecorate %u Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %S = OpTypeStruct %v2float %_arr_float_uint_2
- %_ptr_Uniform_S = OpTypePointer StorageBuffer %S
- %u = OpVariable %_ptr_Uniform_S StorageBuffer
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, StorageBufferStorageClassArrayBadAlignmentBad) {
- // Like the previous test, but with offset 7.
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpDecorate %_arr_float_uint_2 ArrayStride 4
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 7
- OpDecorate %S Block
- OpDecorate %u DescriptorSet 0
- OpDecorate %u Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %S = OpTypeStruct %v2float %_arr_float_uint_2
- %_ptr_Uniform_S = OpTypePointer StorageBuffer %S
- %u = OpVariable %_ptr_Uniform_S StorageBuffer
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 3 decorated as Block for variable in StorageBuffer "
- "storage class must follow standard storage buffer layout rules: "
- "member 1 at offset 7 is not aligned to 4"));
- }
- TEST_F(ValidateDecorations, BufferBlockStandardStorageBufferLayout) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %F 0 Offset 0
- OpMemberDecorate %F 1 Offset 8
- OpDecorate %_arr_float_uint_2 ArrayStride 4
- OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 48
- OpMemberDecorate %O 0 Offset 0
- OpMemberDecorate %O 1 Offset 16
- OpMemberDecorate %O 2 Offset 24
- OpMemberDecorate %O 3 Offset 32
- OpMemberDecorate %O 4 ColMajor
- OpMemberDecorate %O 4 Offset 48
- OpMemberDecorate %O 4 MatrixStride 16
- OpDecorate %_arr_O_uint_2 ArrayStride 144
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 8
- OpMemberDecorate %Output 2 Offset 16
- OpMemberDecorate %Output 3 Offset 32
- OpMemberDecorate %Output 4 Offset 48
- OpMemberDecorate %Output 5 Offset 52
- OpMemberDecorate %Output 6 ColMajor
- OpMemberDecorate %Output 6 Offset 64
- OpMemberDecorate %Output 6 MatrixStride 16
- OpMemberDecorate %Output 7 Offset 96
- OpDecorate %Output BufferBlock
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v3float = OpTypeVector %float 3
- %int = OpTypeInt 32 1
- %uint = OpTypeInt 32 0
- %v2uint = OpTypeVector %uint 2
- %F = OpTypeStruct %int %v2uint
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %mat2v3float = OpTypeMatrix %v3float 2
- %v3uint = OpTypeVector %uint 3
- %mat3v3float = OpTypeMatrix %v3float 3
- %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
- %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
- %_arr_O_uint_2 = OpTypeArray %O %uint_2
- %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations,
- StorageBufferLayoutPermitsTightVec3ScalarPackingGood) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 12
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %v3float %float
- %_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
- %B = OpVariable %_ptr_StorageBuffer_S StorageBuffer
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations,
- StorageBufferLayoutForbidsTightScalarVec3PackingBad) {
- // See https://github.com/KhronosGroup/SPIRV-Tools/issues/1666
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %float %v3float
- %_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
- %B = OpVariable %_ptr_StorageBuffer_S StorageBuffer
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 2 decorated as Block for variable in StorageBuffer "
- "storage class must follow standard storage buffer layout "
- "rules: member 1 at offset 4 is not aligned to 16"));
- }
- TEST_F(ValidateDecorations,
- BlockStandardUniformBufferLayoutIncorrectOffset0Bad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %F 0 Offset 0
- OpMemberDecorate %F 1 Offset 8
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 48
- OpMemberDecorate %O 0 Offset 0
- OpMemberDecorate %O 1 Offset 16
- OpMemberDecorate %O 2 Offset 24
- OpMemberDecorate %O 3 Offset 33
- OpMemberDecorate %O 4 ColMajor
- OpMemberDecorate %O 4 Offset 80
- OpMemberDecorate %O 4 MatrixStride 16
- OpDecorate %_arr_O_uint_2 ArrayStride 176
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 8
- OpMemberDecorate %Output 2 Offset 16
- OpMemberDecorate %Output 3 Offset 32
- OpMemberDecorate %Output 4 Offset 48
- OpMemberDecorate %Output 5 Offset 64
- OpMemberDecorate %Output 6 ColMajor
- OpMemberDecorate %Output 6 Offset 96
- OpMemberDecorate %Output 6 MatrixStride 16
- OpMemberDecorate %Output 7 Offset 128
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v3float = OpTypeVector %float 3
- %int = OpTypeInt 32 1
- %uint = OpTypeInt 32 0
- %v2uint = OpTypeVector %uint 2
- %F = OpTypeStruct %int %v2uint
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %mat2v3float = OpTypeMatrix %v3float 2
- %v3uint = OpTypeVector %uint 3
- %mat3v3float = OpTypeMatrix %v3float 3
- %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
- %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
- %_arr_O_uint_2 = OpTypeArray %O %uint_2
- %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Structure id 6 decorated as Block for variable in Uniform "
- "storage class must follow standard uniform buffer layout "
- "rules: member 2 at offset 152 is not aligned to 16"));
- }
- TEST_F(ValidateDecorations,
- BlockStandardUniformBufferLayoutIncorrectOffset1Bad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %F 0 Offset 0
- OpMemberDecorate %F 1 Offset 8
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 48
- OpMemberDecorate %O 0 Offset 0
- OpMemberDecorate %O 1 Offset 16
- OpMemberDecorate %O 2 Offset 32
- OpMemberDecorate %O 3 Offset 64
- OpMemberDecorate %O 4 ColMajor
- OpMemberDecorate %O 4 Offset 80
- OpMemberDecorate %O 4 MatrixStride 16
- OpDecorate %_arr_O_uint_2 ArrayStride 176
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 8
- OpMemberDecorate %Output 2 Offset 16
- OpMemberDecorate %Output 3 Offset 32
- OpMemberDecorate %Output 4 Offset 48
- OpMemberDecorate %Output 5 Offset 71
- OpMemberDecorate %Output 6 ColMajor
- OpMemberDecorate %Output 6 Offset 96
- OpMemberDecorate %Output 6 MatrixStride 16
- OpMemberDecorate %Output 7 Offset 128
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v3float = OpTypeVector %float 3
- %int = OpTypeInt 32 1
- %uint = OpTypeInt 32 0
- %v2uint = OpTypeVector %uint 2
- %F = OpTypeStruct %int %v2uint
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %mat2v3float = OpTypeMatrix %v3float 2
- %v3uint = OpTypeVector %uint 3
- %mat3v3float = OpTypeMatrix %v3float 3
- %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
- %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
- %_arr_O_uint_2 = OpTypeArray %O %uint_2
- %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Structure id 8 decorated as Block for variable in Uniform "
- "storage class must follow standard uniform buffer layout "
- "rules: member 5 at offset 71 is not aligned to 16"));
- }
- TEST_F(ValidateDecorations, BlockUniformBufferLayoutIncorrectArrayStrideBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %F 0 Offset 0
- OpMemberDecorate %F 1 Offset 8
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpDecorate %_arr_mat3v3float_uint_2 ArrayStride 49
- OpMemberDecorate %O 0 Offset 0
- OpMemberDecorate %O 1 Offset 16
- OpMemberDecorate %O 2 Offset 32
- OpMemberDecorate %O 3 Offset 64
- OpMemberDecorate %O 4 ColMajor
- OpMemberDecorate %O 4 Offset 80
- OpMemberDecorate %O 4 MatrixStride 16
- OpDecorate %_arr_O_uint_2 ArrayStride 176
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 8
- OpMemberDecorate %Output 2 Offset 16
- OpMemberDecorate %Output 3 Offset 32
- OpMemberDecorate %Output 4 Offset 48
- OpMemberDecorate %Output 5 Offset 64
- OpMemberDecorate %Output 6 ColMajor
- OpMemberDecorate %Output 6 Offset 96
- OpMemberDecorate %Output 6 MatrixStride 16
- OpMemberDecorate %Output 7 Offset 128
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v3float = OpTypeVector %float 3
- %int = OpTypeInt 32 1
- %uint = OpTypeInt 32 0
- %v2uint = OpTypeVector %uint 2
- %F = OpTypeStruct %int %v2uint
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %mat2v3float = OpTypeMatrix %v3float 2
- %v3uint = OpTypeVector %uint 3
- %mat3v3float = OpTypeMatrix %v3float 3
- %_arr_mat3v3float_uint_2 = OpTypeArray %mat3v3float %uint_2
- %O = OpTypeStruct %v3uint %v2float %_arr_float_uint_2 %v2float %_arr_mat3v3float_uint_2
- %_arr_O_uint_2 = OpTypeArray %O %uint_2
- %Output = OpTypeStruct %float %v2float %v3float %F %float %_arr_float_uint_2 %mat2v3float %_arr_O_uint_2
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 6 decorated as Block for variable in Uniform storage "
- "class must follow standard uniform buffer layout rules: member 4 "
- "contains "
- "an array with stride 49 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations,
- BufferBlockStandardStorageBufferLayoutImproperStraddleBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 8
- OpDecorate %Output BufferBlock
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %Output = OpTypeStruct %float %v3float
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Structure id 3 decorated as BufferBlock for variable in "
- "Uniform storage class must follow standard storage buffer "
- "layout rules: member 1 at offset 8 is not aligned to 16"));
- }
- TEST_F(ValidateDecorations,
- BlockUniformBufferLayoutOffsetInsideArrayPaddingBad) {
- // In this case the 2nd member fits entirely within the padding.
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpDecorate %_arr_float_uint_2 ArrayStride 16
- OpMemberDecorate %Output 0 Offset 0
- OpMemberDecorate %Output 1 Offset 20
- OpDecorate %Output Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %uint = OpTypeInt 32 0
- %v2uint = OpTypeVector %uint 2
- %uint_2 = OpConstant %uint 2
- %_arr_float_uint_2 = OpTypeArray %float %uint_2
- %Output = OpTypeStruct %_arr_float_uint_2 %float
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 4 decorated as Block for variable in Uniform storage "
- "class must follow standard uniform buffer layout rules: member 1 at "
- "offset 20 overlaps previous member ending at offset 31"));
- }
- TEST_F(ValidateDecorations,
- BlockUniformBufferLayoutOffsetInsideStructPaddingBad) {
- // In this case the 2nd member fits entirely within the padding.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %1 "main"
- OpExecutionMode %1 LocalSize 1 1 1
- OpMemberDecorate %_struct_6 0 Offset 0
- OpMemberDecorate %_struct_2 0 Offset 0
- OpMemberDecorate %_struct_2 1 Offset 4
- OpDecorate %_struct_2 Block
- %void = OpTypeVoid
- %4 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_struct_6 = OpTypeStruct %float
- %_struct_2 = OpTypeStruct %_struct_6 %float
- %_ptr_Uniform__struct_2 = OpTypePointer Uniform %_struct_2
- %8 = OpVariable %_ptr_Uniform__struct_2 Uniform
- %1 = OpFunction %void None %4
- %9 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 3 decorated as Block for variable in Uniform storage "
- "class must follow standard uniform buffer layout rules: member 1 at "
- "offset 4 overlaps previous member ending at offset 15"));
- }
- TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderGoodUniversal1_0) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %Outer 0 Offset 4
- OpMemberDecorate %Outer 1 Offset 0
- OpDecorate %Outer Block
- OpDecorate %O DescriptorSet 0
- OpDecorate %O Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %Outer = OpTypeStruct %uint %uint
- %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
- %O = OpVariable %_ptr_Uniform_Outer Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_0));
- }
- TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderGoodOpenGL4_5) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %Outer 0 Offset 4
- OpMemberDecorate %Outer 1 Offset 0
- OpDecorate %Outer Block
- OpDecorate %O DescriptorSet 0
- OpDecorate %O Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %Outer = OpTypeStruct %uint %uint
- %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
- %O = OpVariable %_ptr_Uniform_Outer Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_OPENGL_4_5));
- }
- TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderGoodVulkan1_1) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %Outer 0 Offset 4
- OpMemberDecorate %Outer 1 Offset 0
- OpDecorate %Outer Block
- OpDecorate %O DescriptorSet 0
- OpDecorate %O Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %Outer = OpTypeStruct %uint %uint
- %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
- %O = OpVariable %_ptr_Uniform_Outer Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1))
- << getDiagnosticString();
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, BlockLayoutOffsetOverlapBad) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %Outer 0 Offset 0
- OpMemberDecorate %Outer 1 Offset 16
- OpMemberDecorate %Inner 0 Offset 0
- OpMemberDecorate %Inner 1 Offset 16
- OpDecorate %Outer Block
- OpDecorate %O DescriptorSet 0
- OpDecorate %O Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %Inner = OpTypeStruct %uint %uint
- %Outer = OpTypeStruct %Inner %uint
- %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
- %O = OpVariable %_ptr_Uniform_Outer Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 3 decorated as Block for variable in Uniform storage "
- "class must follow standard uniform buffer layout rules: member 1 at "
- "offset 16 overlaps previous member ending at offset 31"));
- }
- TEST_F(ValidateDecorations, BufferBlockEmptyStruct) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %Output 0 Offset 0
- OpDecorate %Output BufferBlock
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %S = OpTypeStruct
- %Output = OpTypeStruct %S
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, RowMajorMatrixTightPackingGood) {
- // Row major matrix rule:
- // A row-major matrix of C columns has a base alignment equal to
- // the base alignment of a vector of C matrix components.
- // Note: The "matrix component" is the scalar element type.
- // The matrix has 3 columns and 2 rows (C=3, R=2).
- // So the base alignment of b is the same as a vector of 3 floats, which is 16
- // bytes. The matrix consists of two of these, and therefore occupies 2 x 16
- // bytes, or 32 bytes.
- //
- // So the offsets can be:
- // a -> 0
- // b -> 16
- // c -> 48
- // d -> 60 ; d fits at bytes 12-15 after offset of c. Tight (vec3;float)
- // packing
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpSource GLSL 450
- OpMemberDecorate %_struct_2 0 Offset 0
- OpMemberDecorate %_struct_2 1 RowMajor
- OpMemberDecorate %_struct_2 1 Offset 16
- OpMemberDecorate %_struct_2 1 MatrixStride 16
- OpMemberDecorate %_struct_2 2 Offset 48
- OpMemberDecorate %_struct_2 3 Offset 60
- OpDecorate %_struct_2 Block
- OpDecorate %3 DescriptorSet 0
- OpDecorate %3 Binding 0
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %v2float = OpTypeVector %float 2
- %mat3v2float = OpTypeMatrix %v2float 3
- %v3float = OpTypeVector %float 3
- %_struct_2 = OpTypeStruct %v4float %mat3v2float %v3float %float
- %_ptr_Uniform__struct_2 = OpTypePointer Uniform %_struct_2
- %3 = OpVariable %_ptr_Uniform__struct_2 Uniform
- %1 = OpFunction %void None %5
- %12 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState())
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, ArrayArrayRowMajorMatrixTightPackingGood) {
- // Like the previous case, but we have an array of arrays of matrices.
- // The RowMajor decoration goes on the struct member (surprisingly).
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpSource GLSL 450
- OpMemberDecorate %_struct_2 0 Offset 0
- OpMemberDecorate %_struct_2 1 RowMajor
- OpMemberDecorate %_struct_2 1 Offset 16
- OpMemberDecorate %_struct_2 1 MatrixStride 16
- OpMemberDecorate %_struct_2 2 Offset 80
- OpMemberDecorate %_struct_2 3 Offset 92
- OpDecorate %arr_mat ArrayStride 32
- OpDecorate %arr_arr_mat ArrayStride 32
- OpDecorate %_struct_2 Block
- OpDecorate %3 DescriptorSet 0
- OpDecorate %3 Binding 0
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %v2float = OpTypeVector %float 2
- %mat3v2float = OpTypeMatrix %v2float 3
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %arr_mat = OpTypeArray %mat3v2float %uint_1
- %arr_arr_mat = OpTypeArray %arr_mat %uint_2
- %v3float = OpTypeVector %float 3
- %_struct_2 = OpTypeStruct %v4float %arr_arr_mat %v3float %float
- %_ptr_Uniform__struct_2 = OpTypePointer Uniform %_struct_2
- %3 = OpVariable %_ptr_Uniform__struct_2 Uniform
- %1 = OpFunction %void None %5
- %12 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, ArrayArrayRowMajorMatrixNextMemberOverlapsBad) {
- // Like the previous case, but the offset of member 2 overlaps the matrix.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpSource GLSL 450
- OpMemberDecorate %_struct_2 0 Offset 0
- OpMemberDecorate %_struct_2 1 RowMajor
- OpMemberDecorate %_struct_2 1 Offset 16
- OpMemberDecorate %_struct_2 1 MatrixStride 16
- OpMemberDecorate %_struct_2 2 Offset 64
- OpMemberDecorate %_struct_2 3 Offset 92
- OpDecorate %arr_mat ArrayStride 32
- OpDecorate %arr_arr_mat ArrayStride 32
- OpDecorate %_struct_2 Block
- OpDecorate %3 DescriptorSet 0
- OpDecorate %3 Binding 0
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %v2float = OpTypeVector %float 2
- %mat3v2float = OpTypeMatrix %v2float 3
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %arr_mat = OpTypeArray %mat3v2float %uint_1
- %arr_arr_mat = OpTypeArray %arr_mat %uint_2
- %v3float = OpTypeVector %float 3
- %_struct_2 = OpTypeStruct %v4float %arr_arr_mat %v3float %float
- %_ptr_Uniform__struct_2 = OpTypePointer Uniform %_struct_2
- %3 = OpVariable %_ptr_Uniform__struct_2 Uniform
- %1 = OpFunction %void None %5
- %12 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 2 decorated as Block for variable in Uniform storage "
- "class must follow standard uniform buffer layout rules: member 2 at "
- "offset 64 overlaps previous member ending at offset 79"));
- }
- TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackGood) {
- // Original GLSL
- // #version 450
- // layout (set=0,binding=0) buffer S {
- // uvec3 arr[2][2]; // first 3 elements are 16 bytes, last is 12
- // uint i; // Can't have offset 60 = 3x16 + 12
- // } B;
- // void main() {}
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
- OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
- OpMemberDecorate %_struct_4 0 Offset 0
- OpMemberDecorate %_struct_4 1 Offset 64
- OpDecorate %_struct_4 BufferBlock
- OpDecorate %5 DescriptorSet 0
- OpDecorate %5 Binding 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %v3uint = OpTypeVector %uint 3
- %uint_2 = OpConstant %uint 2
- %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
- %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
- %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
- %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
- %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
- %1 = OpFunction %void None %7
- %12 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackGoodScalar) {
- // Original GLSL
- // #version 450
- // layout (set=0,binding=0) buffer S {
- // uvec3 arr[2][2]; // first 3 elements are 16 bytes, last is 12
- // uint i; // Can have offset 60 = 3x16 + 12
- // } B;
- // void main() {}
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
- OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
- OpMemberDecorate %_struct_4 0 Offset 0
- OpMemberDecorate %_struct_4 1 Offset 60
- OpDecorate %_struct_4 BufferBlock
- OpDecorate %5 DescriptorSet 0
- OpDecorate %5 Binding 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %v3uint = OpTypeVector %uint 3
- %uint_2 = OpConstant %uint 2
- %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
- %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
- %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
- %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
- %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
- %1 = OpFunction %void None %7
- %12 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- options_->scalar_block_layout = true;
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackBad) {
- // Like previous but, the offset of the second member is too small.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
- OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
- OpMemberDecorate %_struct_4 0 Offset 0
- OpMemberDecorate %_struct_4 1 Offset 60
- OpDecorate %_struct_4 BufferBlock
- OpDecorate %5 DescriptorSet 0
- OpDecorate %5 Binding 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %v3uint = OpTypeVector %uint 3
- %uint_2 = OpConstant %uint 2
- %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
- %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
- %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
- %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
- %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
- %1 = OpFunction %void None %7
- %12 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Structure id 4 decorated as BufferBlock for variable "
- "in Uniform storage class must follow standard storage "
- "buffer layout rules: member 1 at offset 60 overlaps "
- "previous member ending at offset 63"));
- }
- TEST_F(ValidateDecorations, UniformBufferArraySizeCalculationPackGood) {
- // Like the corresponding buffer block case, but the array padding must
- // count for the last element as well, and so the offset of the second
- // member must be at least 64.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
- OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
- OpMemberDecorate %_struct_4 0 Offset 0
- OpMemberDecorate %_struct_4 1 Offset 64
- OpDecorate %_struct_4 Block
- OpDecorate %5 DescriptorSet 0
- OpDecorate %5 Binding 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %v3uint = OpTypeVector %uint 3
- %uint_2 = OpConstant %uint 2
- %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
- %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
- %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
- %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
- %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
- %1 = OpFunction %void None %7
- %12 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, UniformBufferArraySizeCalculationPackBad) {
- // Like previous but, the offset of the second member is too small.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpDecorate %_arr_v3uint_uint_2 ArrayStride 16
- OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32
- OpMemberDecorate %_struct_4 0 Offset 0
- OpMemberDecorate %_struct_4 1 Offset 60
- OpDecorate %_struct_4 Block
- OpDecorate %5 DescriptorSet 0
- OpDecorate %5 Binding 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %v3uint = OpTypeVector %uint 3
- %uint_2 = OpConstant %uint 2
- %_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2
- %_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2
- %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint
- %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
- %5 = OpVariable %_ptr_Uniform__struct_4 Uniform
- %1 = OpFunction %void None %7
- %12 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 4 decorated as Block for variable in Uniform storage "
- "class must follow standard uniform buffer layout rules: member 1 at "
- "offset 60 overlaps previous member ending at offset 63"));
- }
- TEST_F(ValidateDecorations, LayoutNotCheckedWhenSkipBlockLayout) {
- // Checks that block layout is not verified in skipping block layout mode.
- // Even for obviously wrong layout.
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 3 ; wrong alignment
- OpMemberDecorate %S 1 Offset 3 ; same offset as before!
- OpDecorate %S Block
- OpDecorate %B DescriptorSet 0
- OpDecorate %B Binding 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %float %v3float
- %_ptr_Uniform_S = OpTypePointer Uniform %S
- %B = OpVariable %_ptr_Uniform_S Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- spvValidatorOptionsSetSkipBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, EntryPointVariableWrongStorageClass) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "func" %var
- OpExecutionMode %1 OriginUpperLeft
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %ptr_int_Workgroup = OpTypePointer Workgroup %int
- %var = OpVariable %ptr_int_Workgroup Workgroup
- %func_ty = OpTypeFunction %void
- %1 = OpFunction %void None %func_ty
- %2 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint interfaces must be OpVariables with "
- "Storage Class of Input(1) or Output(3). Found Storage "
- "Class 4 for Entry Point id 1."));
- }
- TEST_F(ValidateDecorations, VulkanMemoryModelNonCoherent) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical VulkanKHR
- OpDecorate %1 Coherent
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer StorageBuffer %2
- %1 = OpVariable %3 StorageBuffer
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Coherent decoration targeting '1[%1]' is "
- "banned when using the Vulkan memory model."));
- }
- TEST_F(ValidateDecorations, VulkanMemoryModelNoCoherentMember) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- OpMemberDecorate %1 0 Coherent
- %2 = OpTypeInt 32 0
- %1 = OpTypeStruct %2 %2
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Coherent decoration targeting '1[%_struct_1]' (member index 0) "
- "is banned when using the Vulkan memory model."));
- }
- TEST_F(ValidateDecorations, VulkanMemoryModelNoVolatile) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical VulkanKHR
- OpDecorate %1 Volatile
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer StorageBuffer %2
- %1 = OpVariable %3 StorageBuffer
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Volatile decoration targeting '1[%1]' is banned when "
- "using the Vulkan memory model."));
- }
- TEST_F(ValidateDecorations, VulkanMemoryModelNoVolatileMember) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- OpMemberDecorate %1 1 Volatile
- %2 = OpTypeInt 32 0
- %1 = OpTypeStruct %2 %2
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Volatile decoration targeting '1[%_struct_1]' (member "
- "index 1) is banned when using the Vulkan memory "
- "model."));
- }
- TEST_F(ValidateDecorations, FPRoundingModeGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability StorageBuffer16BitAccess
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %_ FPRoundingMode RTE
- %half = OpTypeFloat 16
- %float = OpTypeFloat 32
- %float_1_25 = OpConstant %float 1.25
- %half_ptr = OpTypePointer StorageBuffer %half
- %half_ptr_var = OpVariable %half_ptr StorageBuffer
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %main_entry = OpLabel
- %_ = OpFConvert %half %float_1_25
- OpStore %half_ptr_var %_
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, FPRoundingModeVectorGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability StorageBuffer16BitAccess
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %_ FPRoundingMode RTE
- %half = OpTypeFloat 16
- %float = OpTypeFloat 32
- %v2half = OpTypeVector %half 2
- %v2float = OpTypeVector %float 2
- %float_1_25 = OpConstant %float 1.25
- %floats = OpConstantComposite %v2float %float_1_25 %float_1_25
- %halfs_ptr = OpTypePointer StorageBuffer %v2half
- %halfs_ptr_var = OpVariable %halfs_ptr StorageBuffer
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %main_entry = OpLabel
- %_ = OpFConvert %v2half %floats
- OpStore %halfs_ptr_var %_
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, FPRoundingModeNotOpFConvert) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability StorageBuffer16BitAccess
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %_ FPRoundingMode RTE
- %short = OpTypeInt 16 1
- %int = OpTypeInt 32 1
- %int_17 = OpConstant %int 17
- %short_ptr = OpTypePointer StorageBuffer %short
- %short_ptr_var = OpVariable %short_ptr StorageBuffer
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %main_entry = OpLabel
- %_ = OpSConvert %short %int_17
- OpStore %short_ptr_var %_
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("FPRoundingMode decoration can be applied only to a "
- "width-only conversion instruction for floating-point "
- "object."));
- }
- TEST_F(ValidateDecorations, FPRoundingModeNoOpStoreGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability StorageBuffer16BitAccess
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %_ FPRoundingMode RTE
- %half = OpTypeFloat 16
- %float = OpTypeFloat 32
- %float_1_25 = OpConstant %float 1.25
- %half_ptr = OpTypePointer StorageBuffer %half
- %half_ptr_var = OpVariable %half_ptr StorageBuffer
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %main_entry = OpLabel
- %_ = OpFConvert %half %float_1_25
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, FPRoundingModeFConvert64to16Good) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability StorageBuffer16BitAccess
- OpCapability Float64
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %_ FPRoundingMode RTE
- %half = OpTypeFloat 16
- %double = OpTypeFloat 64
- %double_1_25 = OpConstant %double 1.25
- %half_ptr = OpTypePointer StorageBuffer %half
- %half_ptr_var = OpVariable %half_ptr StorageBuffer
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %main_entry = OpLabel
- %_ = OpFConvert %half %double_1_25
- OpStore %half_ptr_var %_
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, FPRoundingModeNotStoreInFloat16) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability StorageBuffer16BitAccess
- OpCapability Float64
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %_ FPRoundingMode RTE
- %float = OpTypeFloat 32
- %double = OpTypeFloat 64
- %double_1_25 = OpConstant %double 1.25
- %float_ptr = OpTypePointer StorageBuffer %float
- %float_ptr_var = OpVariable %float_ptr StorageBuffer
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %main_entry = OpLabel
- %_ = OpFConvert %float %double_1_25
- OpStore %float_ptr_var %_
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("FPRoundingMode decoration can be applied only to the "
- "Object operand of an OpStore storing through a "
- "pointer to a 16-bit floating-point scalar or vector object."));
- }
- TEST_F(ValidateDecorations, FPRoundingModeMultipleOpStoreGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability StorageBuffer16BitAccess
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %_ FPRoundingMode RTE
- %half = OpTypeFloat 16
- %float = OpTypeFloat 32
- %float_1_25 = OpConstant %float 1.25
- %half_ptr = OpTypePointer StorageBuffer %half
- %half_ptr_var_0 = OpVariable %half_ptr StorageBuffer
- %half_ptr_var_1 = OpVariable %half_ptr StorageBuffer
- %half_ptr_var_2 = OpVariable %half_ptr StorageBuffer
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %main_entry = OpLabel
- %_ = OpFConvert %half %float_1_25
- OpStore %half_ptr_var_0 %_
- OpStore %half_ptr_var_1 %_
- OpStore %half_ptr_var_2 %_
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, FPRoundingModeMultipleUsesBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability StorageBuffer16BitAccess
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %_ FPRoundingMode RTE
- %half = OpTypeFloat 16
- %float = OpTypeFloat 32
- %float_1_25 = OpConstant %float 1.25
- %half_ptr = OpTypePointer StorageBuffer %half
- %half_ptr_var_0 = OpVariable %half_ptr StorageBuffer
- %half_ptr_var_1 = OpVariable %half_ptr StorageBuffer
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %main_entry = OpLabel
- %_ = OpFConvert %half %float_1_25
- OpStore %half_ptr_var_0 %_
- %result = OpFAdd %half %_ %_
- OpStore %half_ptr_var_1 %_
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("FPRoundingMode decoration can be applied only to the "
- "Object operand of an OpStore."));
- }
- TEST_F(ValidateDecorations, VulkanFPRoundingModeGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability StorageBuffer16BitAccess
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %ssbo 0 Offset 0
- OpDecorate %ssbo Block
- OpDecorate %_ DescriptorSet 0
- OpDecorate %_ Binding 0
- OpDecorate %17 FPRoundingMode RTE
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_1 = OpConstant %float 1
- %half = OpTypeFloat 16
- %ssbo = OpTypeStruct %half
- %_ptr_StorageBuffer_ssbo = OpTypePointer StorageBuffer %ssbo
- %_ = OpVariable %_ptr_StorageBuffer_ssbo StorageBuffer
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
- %main = OpFunction %void None %3
- %5 = OpLabel
- %b = OpVariable %_ptr_Function_float Function
- OpStore %b %float_1
- %16 = OpLoad %float %b
- %17 = OpFConvert %half %16
- %19 = OpAccessChain %_ptr_StorageBuffer_half %_ %int_0
- OpStore %19 %17
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
- }
- TEST_F(ValidateDecorations, VulkanFPRoundingModeBadMode) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability StorageBuffer16BitAccess
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %ssbo 0 Offset 0
- OpDecorate %ssbo Block
- OpDecorate %_ DescriptorSet 0
- OpDecorate %_ Binding 0
- OpDecorate %17 FPRoundingMode RTP
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_1 = OpConstant %float 1
- %half = OpTypeFloat 16
- %ssbo = OpTypeStruct %half
- %_ptr_StorageBuffer_ssbo = OpTypePointer StorageBuffer %ssbo
- %_ = OpVariable %_ptr_StorageBuffer_ssbo StorageBuffer
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
- %main = OpFunction %void None %3
- %5 = OpLabel
- %b = OpVariable %_ptr_Function_float Function
- OpStore %b %float_1
- %16 = OpLoad %float %b
- %17 = OpFConvert %half %16
- %19 = OpAccessChain %_ptr_StorageBuffer_half %_ %int_0
- OpStore %19 %17
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-FPRoundingMode-04675"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("In Vulkan, the FPRoundingMode mode must only by RTE or RTZ."));
- }
- TEST_F(ValidateDecorations, GroupDecorateTargetsDecorationGroup) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %1 = OpDecorationGroup
- OpGroupDecorate %1 %1
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpGroupDecorate may not target OpDecorationGroup <id> "
- "'1[%1]'"));
- }
- TEST_F(ValidateDecorations, GroupDecorateTargetsDecorationGroup2) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %1 = OpDecorationGroup
- OpGroupDecorate %1 %2 %1
- %2 = OpTypeVoid
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpGroupDecorate may not target OpDecorationGroup <id> "
- "'1[%1]'"));
- }
- TEST_F(ValidateDecorations, RecurseThroughRuntimeArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %outer Block
- OpMemberDecorate %inner 0 Offset 0
- OpMemberDecorate %inner 1 Offset 1
- OpDecorate %runtime ArrayStride 16
- OpMemberDecorate %outer 0 Offset 0
- %int = OpTypeInt 32 0
- %inner = OpTypeStruct %int %int
- %runtime = OpTypeRuntimeArray %inner
- %outer = OpTypeStruct %runtime
- %outer_ptr = OpTypePointer StorageBuffer %outer
- %var = OpVariable %outer_ptr StorageBuffer
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 3 decorated as Block for variable in StorageBuffer "
- "storage class must follow standard storage buffer layout "
- "rules: member 1 at offset 1 is not aligned to 4"));
- }
- TEST_F(ValidateDecorations, VulkanStructWithoutDecorationWithRuntimeArray) {
- std::string str = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %func "func"
- OpExecutionMode %func OriginUpperLeft
- OpDecorate %array_t ArrayStride 4
- OpMemberDecorate %struct_t 0 Offset 0
- OpMemberDecorate %struct_t 1 Offset 4
- %uint_t = OpTypeInt 32 0
- %array_t = OpTypeRuntimeArray %uint_t
- %struct_t = OpTypeStruct %uint_t %array_t
- %struct_ptr = OpTypePointer StorageBuffer %struct_t
- %2 = OpVariable %struct_ptr StorageBuffer
- %void = OpTypeVoid
- %func_t = OpTypeFunction %void
- %func = OpFunction %void None %func_t
- %1 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(str.c_str(), SPV_ENV_VULKAN_1_1);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Vulkan, OpTypeStruct containing an OpTypeRuntimeArray "
- "must be decorated with Block or BufferBlock."));
- }
- TEST_F(ValidateDecorations, EmptyStructAtNonZeroOffsetGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 1 Offset 16
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %empty = OpTypeStruct
- %struct = OpTypeStruct %float %empty
- %ptr_struct_ubo = OpTypePointer Uniform %struct
- %var = OpVariable %ptr_struct_ubo Uniform
- %voidfn = OpTypeFunction %void
- %main = OpFunction %void None %voidfn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Uniform and UniformId decorations
- TEST_F(ValidateDecorations, UniformDecorationGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical Simple
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %int0 Uniform
- OpDecorate %var Uniform
- OpDecorate %val Uniform
- %void = OpTypeVoid
- %int = OpTypeInt 32 1
- %int0 = OpConstantNull %int
- %intptr = OpTypePointer Private %int
- %var = OpVariable %intptr Private
- %fn = OpTypeFunction %void
- %main = OpFunction %void None %fn
- %entry = OpLabel
- %val = OpLoad %int %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- // Returns SPIR-V assembly for a shader that uses a given decoration
- // instruction.
- std::string ShaderWithUniformLikeDecoration(const std::string& inst) {
- return std::string(R"(
- OpCapability Shader
- OpMemoryModel Logical Simple
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpName %subgroupscope "subgroupscope"
- OpName %call "call"
- OpName %myfunc "myfunc"
- OpName %int0 "int0"
- OpName %float0 "float0"
- OpName %fn "fn"
- )") + inst +
- R"(
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 1
- %int0 = OpConstantNull %int
- %int_99 = OpConstant %int 99
- %subgroupscope = OpConstant %int 3
- %float0 = OpConstantNull %float
- %fn = OpTypeFunction %void
- %myfunc = OpFunction %void None %fn
- %myfuncentry = OpLabel
- OpReturn
- OpFunctionEnd
- %main = OpFunction %void None %fn
- %entry = OpLabel
- %call = OpFunctionCall %void %myfunc
- OpReturn
- OpFunctionEnd
- )";
- }
- TEST_F(ValidateDecorations, UniformIdDecorationWithScopeIdV13Bad) {
- const std::string spirv = ShaderWithUniformLikeDecoration(
- "OpDecorateId %int0 UniformId %subgroupscope");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_WRONG_VERSION,
- ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("requires SPIR-V version 1.4 or later\n"
- " OpDecorateId %int0 UniformId %subgroupscope"))
- << spirv;
- }
- TEST_F(ValidateDecorations, UniformIdDecorationWithScopeIdV13BadTargetV14) {
- const std::string spirv = ShaderWithUniformLikeDecoration(
- "OpDecorateId %int0 UniformId %subgroupscope");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_WRONG_VERSION,
- ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("requires SPIR-V version 1.4 or later"));
- }
- TEST_F(ValidateDecorations, UniformIdDecorationWithScopeIdV14Good) {
- const std::string spirv = ShaderWithUniformLikeDecoration(
- "OpDecorateId %int0 UniformId %subgroupscope");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, UniformDecorationTargetsTypeBad) {
- const std::string spirv =
- ShaderWithUniformLikeDecoration("OpDecorate %fn Uniform");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Uniform decoration applied to a non-object"));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("%fn = OpTypeFunction %void"));
- }
- TEST_F(ValidateDecorations, UniformIdDecorationTargetsTypeBad) {
- const std::string spirv = ShaderWithUniformLikeDecoration(
- "OpDecorateId %fn UniformId %subgroupscope");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("UniformId decoration applied to a non-object"));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("%fn = OpTypeFunction %void"));
- }
- TEST_F(ValidateDecorations, UniformDecorationTargetsVoidValueBad) {
- const std::string spirv =
- ShaderWithUniformLikeDecoration("OpDecorate %call Uniform");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Uniform decoration applied to a value with void type\n"
- " %call = OpFunctionCall %void %myfunc"));
- }
- TEST_F(ValidateDecorations, UniformIdDecorationTargetsVoidValueBad) {
- const std::string spirv = ShaderWithUniformLikeDecoration(
- "OpDecorateId %call UniformId %subgroupscope");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4))
- << spirv;
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("UniformId decoration applied to a value with void type\n"
- " %call = OpFunctionCall %void %myfunc"));
- }
- TEST_F(ValidateDecorations,
- UniformDecorationWithScopeIdV14IdIsFloatValueIsBad) {
- const std::string spirv =
- ShaderWithUniformLikeDecoration("OpDecorateId %int0 UniformId %float0");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA,
- ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ConstantNull: expected scope to be a 32-bit int"));
- }
- TEST_F(ValidateDecorations,
- UniformDecorationWithScopeIdV14IdIsInvalidIntValueBad) {
- const std::string spirv =
- ShaderWithUniformLikeDecoration("OpDecorateId %int0 UniformId %int_99");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA,
- ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Invalid scope value:\n %int_99 = OpConstant %int 99\n"));
- }
- TEST_F(ValidateDecorations, UniformDecorationWithScopeIdV14VulkanEnv) {
- const std::string spirv =
- ShaderWithUniformLikeDecoration("OpDecorateId %int0 UniformId %int0");
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1_SPIRV_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA,
- ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-None-04636"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(": in Vulkan environment Execution Scope is limited to "
- "Workgroup and Subgroup"));
- }
- TEST_F(ValidateDecorations, UniformDecorationWithWrongInstructionBad) {
- const std::string spirv =
- ShaderWithUniformLikeDecoration("OpDecorateId %int0 Uniform");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_2);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_2));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Decorations that don't take ID parameters may not be "
- "used with OpDecorateId\n"
- " OpDecorateId %int0 Uniform"));
- }
- TEST_F(ValidateDecorations, UniformIdDecorationWithWrongInstructionBad) {
- const std::string spirv = ShaderWithUniformLikeDecoration(
- "OpDecorate %int0 UniformId %subgroupscope");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Decorations taking ID parameters may not be used with OpDecorateId\n"
- " OpDecorate %int0 UniformId %subgroupscope"));
- }
- TEST_F(ValidateDecorations, MultipleOffsetDecorationsOnSameID) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID '2', member '0' decorated with Offset multiple "
- "times is not allowed."));
- }
- TEST_F(ValidateDecorations, MultipleArrayStrideDecorationsOnSameID) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %array ArrayStride 4
- OpDecorate %array ArrayStride 4
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %uint = OpTypeInt 32 0
- %uint_4 = OpConstant %uint 4
- %array = OpTypeArray %float %uint_4
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID '2' decorated with ArrayStride multiple "
- "times is not allowed."));
- }
- TEST_F(ValidateDecorations, MultipleMatrixStrideDecorationsOnSameID) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 0 ColMajor
- OpMemberDecorate %struct 0 MatrixStride 16
- OpMemberDecorate %struct 0 MatrixStride 16
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %fvec4 = OpTypeVector %float 4
- %fmat4 = OpTypeMatrix %fvec4 4
- %struct = OpTypeStruct %fmat4
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID '2', member '0' decorated with MatrixStride "
- "multiple times is not allowed."));
- }
- TEST_F(ValidateDecorations, MultipleRowMajorDecorationsOnSameID) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 0 MatrixStride 16
- OpMemberDecorate %struct 0 RowMajor
- OpMemberDecorate %struct 0 RowMajor
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %fvec4 = OpTypeVector %float 4
- %fmat4 = OpTypeMatrix %fvec4 4
- %struct = OpTypeStruct %fmat4
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID '2', member '0' decorated with RowMajor multiple "
- "times is not allowed."));
- }
- TEST_F(ValidateDecorations, MultipleColMajorDecorationsOnSameID) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 0 MatrixStride 16
- OpMemberDecorate %struct 0 ColMajor
- OpMemberDecorate %struct 0 ColMajor
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %fvec4 = OpTypeVector %float 4
- %fmat4 = OpTypeMatrix %fvec4 4
- %struct = OpTypeStruct %fmat4
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID '2', member '0' decorated with ColMajor multiple "
- "times is not allowed."));
- }
- TEST_F(ValidateDecorations, RowMajorAndColMajorDecorationsOnSameID) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 0 MatrixStride 16
- OpMemberDecorate %struct 0 ColMajor
- OpMemberDecorate %struct 0 RowMajor
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %fvec4 = OpTypeVector %float 4
- %fmat4 = OpTypeMatrix %fvec4 4
- %struct = OpTypeStruct %fmat4
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID '2', member '0' decorated with both RowMajor and "
- "ColMajor is not allowed."));
- }
- TEST_F(ValidateDecorations, BlockAndBufferBlockDecorationsOnSameID) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- OpDecorate %struct Block
- OpDecorate %struct BufferBlock
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 0 MatrixStride 16
- OpMemberDecorate %struct 0 RowMajor
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %fvec4 = OpTypeVector %float 4
- %fmat4 = OpTypeMatrix %fvec4 4
- %struct = OpTypeStruct %fmat4
- %1 = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "ID '2' decorated with both BufferBlock and Block is not allowed."));
- }
- std::string MakeIntegerShader(
- const std::string& decoration, const std::string& inst,
- const std::string& extension =
- "OpExtension \"SPV_KHR_no_integer_wrap_decoration\"") {
- return R"(
- OpCapability Shader
- OpCapability Linkage
- )" + extension +
- R"(
- %glsl = OpExtInstImport "GLSL.std.450"
- %opencl = OpExtInstImport "OpenCL.std"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpName %entry "entry"
- )" + decoration +
- R"(
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %zero = OpConstantNull %int
- %float = OpTypeFloat 32
- %float0 = OpConstantNull %float
- %main = OpFunction %void None %voidfn
- %entry = OpLabel
- )" + inst +
- R"(
- OpReturn
- OpFunctionEnd)";
- }
- // NoSignedWrap
- TEST_F(ValidateDecorations, NoSignedWrapOnTypeBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %void NoSignedWrap", "");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("NoSignedWrap decoration may not be applied to TypeVoid"));
- }
- TEST_F(ValidateDecorations, NoSignedWrapOnLabelBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %entry NoSignedWrap", "");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NoSignedWrap decoration may not be applied to Label"));
- }
- TEST_F(ValidateDecorations, NoSignedWrapRequiresExtensionBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpIAdd %int %zero %zero", "");
- CompileSuccessfully(spirv);
- EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("requires one of these extensions: "
- "SPV_KHR_no_integer_wrap_decoration"));
- }
- TEST_F(ValidateDecorations, NoSignedWrapRequiresExtensionV13Bad) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpIAdd %int %zero %zero", "");
- CompileSuccessfully(spirv);
- EXPECT_NE(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("requires one of these extensions: "
- "SPV_KHR_no_integer_wrap_decoration"));
- }
- TEST_F(ValidateDecorations, NoSignedWrapOkInSPV14Good) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpIAdd %int %zero %zero", "");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoSignedWrapIAddGood) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpIAdd %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoSignedWrapISubGood) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpISub %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoSignedWrapIMulGood) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpIMul %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoSignedWrapShiftLeftLogicalGood) {
- std::string spirv =
- MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpShiftLeftLogical %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoSignedWrapSNegateGood) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpSNegate %int %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoSignedWrapSRemBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpSRem %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NoSignedWrap decoration may not be applied to SRem"));
- }
- TEST_F(ValidateDecorations, NoSignedWrapFAddBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpFAdd %float %float0 %float0");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NoSignedWrap decoration may not be applied to FAdd"));
- }
- TEST_F(ValidateDecorations, NoSignedWrapExtInstOpenCLGood) {
- std::string spirv =
- MakeIntegerShader("OpDecorate %val NoSignedWrap",
- "%val = OpExtInst %int %opencl s_abs %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoSignedWrapExtInstGLSLGood) {
- std::string spirv = MakeIntegerShader(
- "OpDecorate %val NoSignedWrap", "%val = OpExtInst %int %glsl SAbs %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- // TODO(dneto): For NoSignedWrap and NoUnsignedWrap, permit
- // "OpExtInst for instruction numbers specified in the extended
- // instruction-set specifications as accepting this decoration."
- // NoUnignedWrap
- TEST_F(ValidateDecorations, NoUnsignedWrapOnTypeBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %void NoUnsignedWrap", "");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("NoUnsignedWrap decoration may not be applied to TypeVoid"));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapOnLabelBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %entry NoUnsignedWrap", "");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("NoUnsignedWrap decoration may not be applied to Label"));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapRequiresExtensionBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpIAdd %int %zero %zero", "");
- CompileSuccessfully(spirv);
- EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("requires one of these extensions: "
- "SPV_KHR_no_integer_wrap_decoration"));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapRequiresExtensionV13Bad) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpIAdd %int %zero %zero", "");
- CompileSuccessfully(spirv);
- EXPECT_NE(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("requires one of these extensions: "
- "SPV_KHR_no_integer_wrap_decoration"));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapOkInSPV14Good) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpIAdd %int %zero %zero", "");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapIAddGood) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpIAdd %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapISubGood) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpISub %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapIMulGood) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpIMul %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapShiftLeftLogicalGood) {
- std::string spirv =
- MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpShiftLeftLogical %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapSNegateGood) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpSNegate %int %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapSRemBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpSRem %int %zero %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("NoUnsignedWrap decoration may not be applied to SRem"));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapFAddBad) {
- std::string spirv = MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpFAdd %float %float0 %float0");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("NoUnsignedWrap decoration may not be applied to FAdd"));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapExtInstOpenCLGood) {
- std::string spirv =
- MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpExtInst %int %opencl s_abs %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NoUnsignedWrapExtInstGLSLGood) {
- std::string spirv =
- MakeIntegerShader("OpDecorate %val NoUnsignedWrap",
- "%val = OpExtInst %int %glsl SAbs %zero");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, AliasedandRestrictBad) {
- const std::string body = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 430
- OpMemberDecorate %Output 0 Offset 0
- OpDecorate %Output BufferBlock
- OpDecorate %dataOutput Restrict
- OpDecorate %dataOutput Aliased
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %Output = OpTypeStruct %float
- %_ptr_Uniform_Output = OpTypePointer Uniform %Output
- %dataOutput = OpVariable %_ptr_Uniform_Output Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str());
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("decorated with both Aliased and Restrict is not allowed"));
- }
- // TODO(dneto): For NoUnsignedWrap and NoUnsignedWrap, permit
- // "OpExtInst for instruction numbers specified in the extended
- // instruction-set specifications as accepting this decoration."
- TEST_F(ValidateDecorations, PSBAliasedRestrictPointerSuccess) {
- const std::string body = R"(
- OpCapability PhysicalStorageBufferAddresses
- OpCapability Int64
- OpCapability Shader
- OpExtension "SPV_EXT_physical_storage_buffer"
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %val1 RestrictPointer
- %uint64 = OpTypeInt 64 0
- %ptr = OpTypePointer PhysicalStorageBuffer %uint64
- %pptr_f = OpTypePointer Function %ptr
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %main = OpFunction %void None %voidfn
- %entry = OpLabel
- %val1 = OpVariable %pptr_f Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str());
- ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateDecorations, PSBAliasedRestrictPointerBoth) {
- const std::string body = R"(
- OpCapability PhysicalStorageBufferAddresses
- OpCapability Int64
- OpCapability Shader
- OpExtension "SPV_EXT_physical_storage_buffer"
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %val1 RestrictPointer
- OpDecorate %val1 AliasedPointer
- %uint64 = OpTypeInt 64 0
- %ptr = OpTypePointer PhysicalStorageBuffer %uint64
- %pptr_f = OpTypePointer Function %ptr
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %main = OpFunction %void None %voidfn
- %entry = OpLabel
- %val1 = OpVariable %pptr_f Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str());
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("decorated with both AliasedPointer and "
- "RestrictPointer is not allowed"));
- }
- TEST_F(ValidateDecorations, PSBAliasedRestrictFunctionParamSuccess) {
- const std::string body = R"(
- OpCapability PhysicalStorageBufferAddresses
- OpCapability Int64
- OpCapability Shader
- OpExtension "SPV_EXT_physical_storage_buffer"
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %fparam Restrict
- %uint64 = OpTypeInt 64 0
- %ptr = OpTypePointer PhysicalStorageBuffer %uint64
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %fnptr = OpTypeFunction %void %ptr
- %main = OpFunction %void None %voidfn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- %fn = OpFunction %void None %fnptr
- %fparam = OpFunctionParameter %ptr
- %lab = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str());
- ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateDecorations, PSBAliasedRestrictFunctionParamBoth) {
- const std::string body = R"(
- OpCapability PhysicalStorageBufferAddresses
- OpCapability Int64
- OpCapability Shader
- OpExtension "SPV_EXT_physical_storage_buffer"
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %fparam Restrict
- OpDecorate %fparam Aliased
- %uint64 = OpTypeInt 64 0
- %ptr = OpTypePointer PhysicalStorageBuffer %uint64
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %fnptr = OpTypeFunction %void %ptr
- %main = OpFunction %void None %voidfn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- %fn = OpFunction %void None %fnptr
- %fparam = OpFunctionParameter %ptr
- %lab = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str());
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("decorated with both Aliased and Restrict is not allowed"));
- }
- TEST_F(ValidateDecorations, PSBFPRoundingModeSuccess) {
- std::string spirv = R"(
- OpCapability PhysicalStorageBufferAddresses
- OpCapability Shader
- OpCapability Linkage
- OpCapability StorageBuffer16BitAccess
- OpExtension "SPV_EXT_physical_storage_buffer"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_16bit_storage"
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %_ FPRoundingMode RTE
- OpDecorate %half_ptr_var AliasedPointer
- %half = OpTypeFloat 16
- %float = OpTypeFloat 32
- %float_1_25 = OpConstant %float 1.25
- %half_ptr = OpTypePointer PhysicalStorageBuffer %half
- %half_pptr_f = OpTypePointer Function %half_ptr
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %main = OpFunction %void None %func
- %main_entry = OpLabel
- %half_ptr_var = OpVariable %half_pptr_f Function
- %val1 = OpLoad %half_ptr %half_ptr_var
- %_ = OpFConvert %half %float_1_25
- OpStore %val1 %_ Aligned 2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, InvalidStraddle) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %inner_struct 0 Offset 0
- OpMemberDecorate %inner_struct 1 Offset 4
- OpDecorate %outer_struct Block
- OpMemberDecorate %outer_struct 0 Offset 0
- OpMemberDecorate %outer_struct 1 Offset 8
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %float2 = OpTypeVector %float 2
- %inner_struct = OpTypeStruct %float %float2
- %outer_struct = OpTypeStruct %float2 %inner_struct
- %ptr_ssbo_outer = OpTypePointer StorageBuffer %outer_struct
- %var = OpVariable %ptr_ssbo_outer StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Structure id 2 decorated as Block for variable in "
- "StorageBuffer storage class must follow relaxed "
- "storage buffer layout rules: member 1 is an "
- "improperly straddling vector at offset 12"));
- }
- TEST_F(ValidateDecorations, DescriptorArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 1 Offset 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %float2 = OpTypeVector %float 2
- %struct = OpTypeStruct %float %float2
- %struct_array = OpTypeArray %struct %int_2
- %ptr_ssbo_array = OpTypePointer StorageBuffer %struct_array
- %var = OpVariable %ptr_ssbo_array StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Structure id 2 decorated as Block for variable in "
- "StorageBuffer storage class must follow standard "
- "storage buffer layout rules: member 1 at offset 1 is "
- "not aligned to 8"));
- }
- TEST_F(ValidateDecorations, DescriptorRuntimeArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability RuntimeDescriptorArrayEXT
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_EXT_descriptor_indexing"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 1 Offset 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %float2 = OpTypeVector %float 2
- %struct = OpTypeStruct %float %float2
- %struct_array = OpTypeRuntimeArray %struct
- %ptr_ssbo_array = OpTypePointer StorageBuffer %struct_array
- %var = OpVariable %ptr_ssbo_array StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Structure id 2 decorated as Block for variable in "
- "StorageBuffer storage class must follow standard "
- "storage buffer layout rules: member 1 at offset 1 is "
- "not aligned to 8"));
- }
- TEST_F(ValidateDecorations, MultiDimensionalArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %array_4 ArrayStride 4
- OpDecorate %array_3 ArrayStride 48
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_3 = OpConstant %int 3
- %int_4 = OpConstant %int 4
- %array_4 = OpTypeArray %int %int_4
- %array_3 = OpTypeArray %array_4 %int_3
- %struct = OpTypeStruct %array_3
- %ptr_struct = OpTypePointer Uniform %struct
- %var = OpVariable %ptr_struct Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Structure id 2 decorated as Block for variable in "
- "Uniform storage class must follow standard uniform "
- "buffer layout rules: member 0 contains an array with "
- "stride 4 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations, ImproperStraddleInArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %array ArrayStride 24
- OpMemberDecorate %inner 0 Offset 0
- OpMemberDecorate %inner 1 Offset 4
- OpMemberDecorate %inner 2 Offset 12
- OpMemberDecorate %inner 3 Offset 16
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %int2 = OpTypeVector %int 2
- %inner = OpTypeStruct %int %int2 %int %int
- %array = OpTypeArray %inner %int_2
- %struct = OpTypeStruct %array
- %ptr_struct = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr_struct StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Structure id 4 decorated as Block for variable in "
- "StorageBuffer storage class must follow relaxed "
- "storage buffer layout rules: member 1 is an "
- "improperly straddling vector at offset 28"));
- }
- TEST_F(ValidateDecorations, LargeArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %array ArrayStride 24
- OpMemberDecorate %inner 0 Offset 0
- OpMemberDecorate %inner 1 Offset 8
- OpMemberDecorate %inner 2 Offset 16
- OpMemberDecorate %inner 3 Offset 20
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_2000000 = OpConstant %int 2000000
- %int2 = OpTypeVector %int 2
- %inner = OpTypeStruct %int %int2 %int %int
- %array = OpTypeArray %inner %int_2000000
- %struct = OpTypeStruct %array
- %ptr_struct = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr_struct StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- }
- // NonWritable
- // Returns a SPIR-V shader module with variables in various storage classes,
- // parameterizable by which ID should be decorated as NonWritable.
- std::string ShaderWithNonWritableTarget(const std::string& target,
- bool member_decorate = false) {
- const std::string decoration_inst =
- std::string(member_decorate ? "OpMemberDecorate " : "OpDecorate ") +
- target + (member_decorate ? " 0" : "");
- return std::string(R"(
- OpCapability Shader
- OpCapability RuntimeDescriptorArrayEXT
- OpExtension "SPV_EXT_descriptor_indexing"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpName %label "label"
- OpName %param_f "param_f"
- OpName %param_p "param_p"
- OpName %_ptr_imstor "_ptr_imstor"
- OpName %_ptr_imsam "_ptr_imsam"
- OpName %var_wg "var_wg"
- OpName %var_imsam "var_imsam"
- OpName %var_priv "var_priv"
- OpName %var_func "var_func"
- OpName %simple_struct "simple_struct"
- OpDecorate %struct_b Block
- OpDecorate %struct_b_rtarr Block
- OpMemberDecorate %struct_b 0 Offset 0
- OpMemberDecorate %struct_b_rtarr 0 Offset 0
- OpDecorate %rtarr ArrayStride 4
- )") + decoration_inst +
- R"( NonWritable
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %struct_b = OpTypeStruct %float
- %rtarr = OpTypeRuntimeArray %float
- %struct_b_rtarr = OpTypeStruct %rtarr
- %simple_struct = OpTypeStruct %float
- ; storage image
- %imstor = OpTypeImage %float 2D 0 0 0 2 R32f
- ; sampled image
- %imsam = OpTypeImage %float 2D 0 0 0 1 R32f
- %array_imstor = OpTypeArray %imstor %int_2
- %rta_imstor = OpTypeRuntimeArray %imstor
- %_ptr_Uniform_stb = OpTypePointer Uniform %struct_b
- %_ptr_StorageBuffer_stb = OpTypePointer StorageBuffer %struct_b
- %_ptr_StorageBuffer_stb_rtarr = OpTypePointer StorageBuffer %struct_b_rtarr
- %_ptr_Workgroup = OpTypePointer Workgroup %float
- %_ptr_Private = OpTypePointer Private %float
- %_ptr_Function = OpTypePointer Function %float
- %_ptr_imstor = OpTypePointer UniformConstant %imstor
- %_ptr_imsam = OpTypePointer UniformConstant %imsam
- %_ptr_array_imstor = OpTypePointer UniformConstant %array_imstor
- %_ptr_rta_imstor = OpTypePointer UniformConstant %rta_imstor
- %extra_fn = OpTypeFunction %void %float %_ptr_Private %_ptr_imstor
- %var_ubo = OpVariable %_ptr_Uniform_stb Uniform
- %var_ssbo_sb = OpVariable %_ptr_StorageBuffer_stb StorageBuffer
- %var_ssbo_sb_rtarr = OpVariable %_ptr_StorageBuffer_stb_rtarr StorageBuffer
- %var_wg = OpVariable %_ptr_Workgroup Workgroup
- %var_priv = OpVariable %_ptr_Private Private
- %var_imstor = OpVariable %_ptr_imstor UniformConstant
- %var_imsam = OpVariable %_ptr_imsam UniformConstant
- %var_array_imstor = OpVariable %_ptr_array_imstor UniformConstant
- %var_rta_imstor = OpVariable %_ptr_rta_imstor UniformConstant
- %helper = OpFunction %void None %extra_fn
- %param_f = OpFunctionParameter %float
- %param_p = OpFunctionParameter %_ptr_Private
- %param_pimstor = OpFunctionParameter %_ptr_imstor
- %helper_label = OpLabel
- %helper_func_var = OpVariable %_ptr_Function Function
- OpReturn
- OpFunctionEnd
- %main = OpFunction %void None %void_fn
- %label = OpLabel
- %var_func = OpVariable %_ptr_Function Function
- OpReturn
- OpFunctionEnd
- )";
- }
- TEST_F(ValidateDecorations, NonWritableLabelTargetBad) {
- std::string spirv = ShaderWithNonWritableTarget("%label");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("must be a memory object declaration"));
- }
- TEST_F(ValidateDecorations, NonWritableTypeTargetBad) {
- std::string spirv = ShaderWithNonWritableTarget("%void");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("must be a memory object declaration"));
- }
- TEST_F(ValidateDecorations, NonWritableValueTargetBad) {
- std::string spirv = ShaderWithNonWritableTarget("%float_0");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("must be a memory object declaration"));
- }
- TEST_F(ValidateDecorations, NonWritableValueParamBad) {
- std::string spirv = ShaderWithNonWritableTarget("%param_f");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a pointer type"));
- }
- TEST_F(ValidateDecorations, NonWritablePointerParamButWrongTypeBad) {
- std::string spirv = ShaderWithNonWritableTarget("%param_p");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, or storage "
- "buffer\n %param_p = OpFunctionParameter %_ptr_Private_float"));
- }
- TEST_F(ValidateDecorations, NonWritablePointerParamStorageImageGood) {
- std::string spirv = ShaderWithNonWritableTarget("%param_pimstor");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NonWritableVarStorageImageGood) {
- std::string spirv = ShaderWithNonWritableTarget("%var_imstor");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NonWritableVarSampledImageBad) {
- std::string spirv = ShaderWithNonWritableTarget("%var_imsam");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, or storage "
- "buffer\n %var_imsam"));
- }
- TEST_F(ValidateDecorations, NonWritableVarUboGood) {
- std::string spirv = ShaderWithNonWritableTarget("%var_ubo");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NonWritableVarSsboInUniformGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpDecorate %struct_bb BufferBlock
- OpMemberDecorate %struct_bb 0 Offset 0
- OpDecorate %var_ssbo_u NonWritable
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct_bb = OpTypeStruct %float
- %_ptr_Uniform_stbb = OpTypePointer Uniform %struct_bb
- %var_ssbo_u = OpVariable %_ptr_Uniform_stbb Uniform
- %main = OpFunction %void None %void_fn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NonWritableVarSsboInStorageBufferGood) {
- std::string spirv = ShaderWithNonWritableTarget("%var_ssbo_sb");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NonWritableMemberOfSsboInStorageBufferGood) {
- std::string spirv = ShaderWithNonWritableTarget("%struct_b_rtarr", true);
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NonWritableMemberOfStructGood) {
- std::string spirv = ShaderWithNonWritableTarget("%simple_struct", true);
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateDecorations, NonWritableVarWorkgroupBad) {
- std::string spirv = ShaderWithNonWritableTarget("%var_wg");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, or storage "
- "buffer\n %var_wg"));
- }
- TEST_F(ValidateDecorations, NonWritableVarWorkgroupV14Bad) {
- std::string spirv = ShaderWithNonWritableTarget("%var_wg");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, storage "
- "buffer, or variable in Private or Function storage "
- "class\n %var_wg"));
- }
- TEST_F(ValidateDecorations, NonWritableVarPrivateBad) {
- std::string spirv = ShaderWithNonWritableTarget("%var_priv");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, or storage "
- "buffer\n %var_priv"));
- }
- TEST_F(ValidateDecorations, NonWritableVarPrivateV13Bad) {
- std::string spirv = ShaderWithNonWritableTarget("%var_priv");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, or storage "
- "buffer\n %var_priv"));
- }
- TEST_F(ValidateDecorations, NonWritableVarPrivateV14Good) {
- std::string spirv = ShaderWithNonWritableTarget("%var_priv");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NonWritableVarPrivateV13TargetV14Bad) {
- std::string spirv = ShaderWithNonWritableTarget("%var_priv");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, or storage "
- "buffer\n %var_priv"));
- }
- TEST_F(ValidateDecorations, NonWritableVarFunctionBad) {
- std::string spirv = ShaderWithNonWritableTarget("%var_func");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, or storage "
- "buffer\n %var_func"));
- }
- TEST_F(ValidateDecorations, NonWritableArrayGood) {
- std::string spirv = ShaderWithNonWritableTarget("%var_array_imstor");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateDecorations, NonWritableRuntimeArrayGood) {
- std::string spirv = ShaderWithNonWritableTarget("%var_rta_imstor");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateVulkanCombineDecorationResult, Decorate) {
- const char* const decoration = std::get<0>(GetParam());
- const char* const vuid = std::get<1>(GetParam());
- const TestResult& test_result = std::get<2>(GetParam());
- CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
- generator.before_types_ = "OpDecorate %u32 ";
- generator.before_types_ += decoration;
- generator.before_types_ += "\n";
- EntryPoint entry_point;
- entry_point.name = "main";
- entry_point.execution_model = "Vertex";
- generator.entry_points_.push_back(std::move(entry_point));
- CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
- ASSERT_EQ(test_result.validation_result,
- ValidateInstructions(SPV_ENV_VULKAN_1_0));
- if (!test_result.error_str.empty()) {
- EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
- }
- if (vuid) {
- EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
- }
- }
- INSTANTIATE_TEST_SUITE_P(
- DecorationAllowListFailure, ValidateVulkanCombineDecorationResult,
- Combine(Values("GLSLShared", "GLSLPacked"),
- Values("VUID-StandaloneSpirv-GLSLShared-04669"),
- Values(TestResult(
- SPV_ERROR_INVALID_ID,
- "is not valid for the Vulkan execution environment."))));
- TEST_F(ValidateDecorations, NonWritableVarFunctionV13Bad) {
- std::string spirv = ShaderWithNonWritableTarget("%var_func");
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, or storage "
- "buffer\n %var_func"));
- }
- TEST_F(ValidateDecorations, NonWritableVarFunctionV14Good) {
- std::string spirv = ShaderWithNonWritableTarget("%var_func");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, NonWritableVarFunctionV13TargetV14Bad) {
- std::string spirv = ShaderWithNonWritableTarget("%var_func");
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of NonWritable decoration is invalid: must "
- "point to a storage image, uniform block, or storage "
- "buffer\n %var_func"));
- }
- TEST_F(ValidateDecorations, BufferBlockV13ValV14Good) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %1 BufferBlock
- %1 = OpTypeStruct
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- }
- TEST_F(ValidateDecorations, BufferBlockV14Bad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %1 BufferBlock
- %1 = OpTypeStruct
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_WRONG_VERSION,
- ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("2nd operand of Decorate: operand BufferBlock(3) "
- "requires SPIR-V version 1.3 or earlier"));
- }
- // Component
- TEST_F(ValidateDecorations, ComponentDecorationBadTarget) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpDecorate %t Component 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %t = OpTypeVector %float 2
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("must be a memory object declaration"));
- }
- TEST_F(ValidateDecorations, ComponentDecorationBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpDecorate %v Component 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %t = OpTypeVector %float 2
- %ptr_private = OpTypePointer Private %t
- %v = OpVariable %ptr_private Private
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target of Component decoration is invalid: must "
- "point to a Storage Class of Input(1) or Output(3)"));
- }
- TEST_F(ValidateDecorations, ComponentDecorationBadTypeVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Matrix
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpDecorate %v Component 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %vtype = OpTypeVector %float 4
- %t = OpTypeMatrix %vtype 4
- %ptr_input = OpTypePointer Input %t
- %v = OpVariable %ptr_input Input
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-10583"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Component decoration specified for type"));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a scalar or vector"));
- }
- std::string ShaderWithComponentDecoration(const std::string& type,
- const std::string& decoration) {
- return R"(
- OpCapability Shader
- OpCapability Int64
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %entryPointOutput
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %entryPointOutput Location 0
- OpDecorate %entryPointOutput )" +
- decoration + R"(
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %v4float = OpTypeVector %float 4
- %uint = OpTypeInt 32 0
- %uint64 = OpTypeInt 64 0
- %v2uint64 = OpTypeVector %uint64 2
- %v3uint64 = OpTypeVector %uint64 3
- %uint_2 = OpConstant %uint 2
- %arr_v3float_uint_2 = OpTypeArray %v3float %uint_2
- %float_0 = OpConstant %float 0
- %_ptr_Output_type = OpTypePointer Output %)" + type + R"(
- %entryPointOutput = OpVariable %_ptr_Output_type Output
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- }
- TEST_F(ValidateDecorations, ComponentDecorationIntGood0Vulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("uint", "Component 0");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, ComponentDecorationIntGood1Vulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("uint", "Component 1");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, ComponentDecorationIntGood2Vulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("uint", "Component 2");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, ComponentDecorationIntGood3Vulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("uint", "Component 3");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, ComponentDecorationIntBad4Vulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("uint", "Component 4");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-04920"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Component decoration value must not be greater than 3"));
- }
- TEST_F(ValidateDecorations, ComponentDecorationVector3GoodVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("v3float", "Component 1");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, ComponentDecorationVector4GoodVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("v4float", "Component 0");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, ComponentDecorationVector4Bad1Vulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("v4float", "Component 1");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-04921"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Sequence of components starting with 1 "
- "and ending with 4 gets larger than 3"));
- }
- TEST_F(ValidateDecorations, ComponentDecorationVector4Bad3Vulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("v4float", "Component 3");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-04921"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Sequence of components starting with 3 "
- "and ending with 6 gets larger than 3"));
- }
- TEST_F(ValidateDecorations, ComponentDecorationArrayGoodVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv =
- ShaderWithComponentDecoration("arr_v3float_uint_2", "Component 1");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, ComponentDecorationArrayBadVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv =
- ShaderWithComponentDecoration("arr_v3float_uint_2", "Component 2");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-04921"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Sequence of components starting with 2 "
- "and ending with 4 gets larger than 3"));
- }
- TEST_F(ValidateDecorations, ComponentDecoration64ScalarGoodVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("uint64", "Component 0");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- }
- TEST_F(ValidateDecorations, ComponentDecoration64Scalar1BadVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("uint64", "Component 1");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-04923"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Component decoration value must not be 1 or 3 for "
- "64-bit data types"));
- }
- TEST_F(ValidateDecorations, ComponentDecoration64Scalar2GoodVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("uint64", "Component 2");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- }
- TEST_F(ValidateDecorations, ComponentDecoration64Scalar3BadVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("uint64", "Component 3");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-04923"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Component decoration value must not be 1 or 3 for "
- "64-bit data types"));
- }
- TEST_F(ValidateDecorations, ComponentDecoration64Vec0GoodVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 0");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- }
- TEST_F(ValidateDecorations, ComponentDecoration64Vec1BadVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 1");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-04923"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Component decoration value must not be 1 or 3 for "
- "64-bit data types"));
- }
- TEST_F(ValidateDecorations, ComponentDecoration64Vec2BadVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 2");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-04922"));
- HasSubstr(
- "Sequence of components starting with 2 "
- "and ending with 6 gets larger than 3");
- }
- TEST_F(ValidateDecorations, ComponentDecoration64VecWideBadVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = ShaderWithComponentDecoration("v3uint64", "Component 0");
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-07703"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Component decoration only allowed on 64-bit scalar "
- "and 2-component vector"));
- }
- TEST_F(ValidateDecorations, ComponentDecorationBlockGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main" %9 %12
- OpExecutionMode %4 OriginUpperLeft
- OpDecorate %9 Location 0
- OpMemberDecorate %block 0 Location 2
- OpMemberDecorate %block 0 Component 1
- OpDecorate %block Block
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %float = OpTypeFloat 32
- %vec3 = OpTypeVector %float 3
- %8 = OpTypePointer Output %vec3
- %9 = OpVariable %8 Output
- %block = OpTypeStruct %vec3
- %11 = OpTypePointer Input %block
- %12 = OpVariable %11 Input
- %int = OpTypeInt 32 1
- %14 = OpConstant %int 0
- %15 = OpTypePointer Input %vec3
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %16 = OpAccessChain %15 %12 %14
- %17 = OpLoad %vec3 %16
- OpStore %9 %17
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(), Eq(""));
- }
- TEST_F(ValidateDecorations, ComponentDecorationBlockBadVulkan) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main" %9 %12
- OpExecutionMode %4 OriginUpperLeft
- OpDecorate %9 Location 0
- OpMemberDecorate %block 0 Location 2
- OpMemberDecorate %block 0 Component 2
- OpDecorate %block Block
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %float = OpTypeFloat 32
- %vec3 = OpTypeVector %float 3
- %8 = OpTypePointer Output %vec3
- %9 = OpVariable %8 Output
- %block = OpTypeStruct %vec3
- %11 = OpTypePointer Input %block
- %12 = OpVariable %11 Input
- %int = OpTypeInt 32 1
- %14 = OpConstant %int 0
- %15 = OpTypePointer Input %vec3
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %16 = OpAccessChain %15 %12 %14
- %17 = OpLoad %vec3 %16
- OpStore %9 %17
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Component-04921"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Sequence of components starting with 2 "
- "and ending with 4 gets larger than 3"));
- }
- TEST_F(ValidateDecorations, ComponentDecorationFunctionParameter) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpDecorate %param_f Component 0
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %struct_b = OpTypeStruct %float
- %extra_fn = OpTypeFunction %void %float
- %helper = OpFunction %void None %extra_fn
- %param_f = OpFunctionParameter %float
- %helper_label = OpLabel
- OpReturn
- OpFunctionEnd
- %main = OpFunction %void None %void_fn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a pointer type"));
- }
- TEST_F(ValidateDecorations, VulkanStorageBufferBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %struct = OpTypeStruct %uint
- %ptr_ssbo = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr_ssbo StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, VulkanStorageBufferMissingBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %struct = OpTypeStruct %uint
- %ptr_ssbo = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr_ssbo StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("From Vulkan spec:\nSuch variables "
- "must be identified with a Block decoration"));
- }
- TEST_F(ValidateDecorations, VulkanStorageBufferArrayMissingBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %uint_4 = OpConstant %uint 4
- %struct = OpTypeStruct %uint
- %array = OpTypeArray %struct %uint_4
- %ptr_ssbo = OpTypePointer StorageBuffer %array
- %var = OpVariable %ptr_ssbo StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("From Vulkan spec:\nSuch variables "
- "must be identified with a Block decoration"));
- }
- TEST_F(ValidateDecorations, VulkanStorageBufferRuntimeArrayMissingBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability RuntimeDescriptorArrayEXT
- OpExtension "SPV_EXT_descriptor_indexing"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %struct = OpTypeStruct %uint
- %array = OpTypeRuntimeArray %struct
- %ptr_ssbo = OpTypePointer StorageBuffer %array
- %var = OpVariable %ptr_ssbo StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("From Vulkan spec:\nSuch variables "
- "must be identified with a Block decoration"));
- }
- TEST_F(ValidateDecorations, VulkanUniformBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %struct = OpTypeStruct %uint
- %ptr_ubo = OpTypePointer Uniform %struct
- %var = OpVariable %ptr_ubo Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, VulkanUniformBufferBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct BufferBlock
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %struct = OpTypeStruct %uint
- %ptr_ubo = OpTypePointer Uniform %struct
- %var = OpVariable %ptr_ubo Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, VulkanUniformMissingBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %struct = OpTypeStruct %uint
- %ptr_ubo = OpTypePointer Uniform %struct
- %var = OpVariable %ptr_ubo Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Uniform-06676"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("From Vulkan spec:\nSuch variables must be "
- "identified with a Block or BufferBlock decoration"));
- }
- TEST_F(ValidateDecorations, VulkanUniformArrayMissingBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %uint_4 = OpConstant %uint 4
- %struct = OpTypeStruct %uint
- %array = OpTypeArray %struct %uint_4
- %ptr_ubo = OpTypePointer Uniform %array
- %var = OpVariable %ptr_ubo Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Uniform-06676"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("From Vulkan spec:\nSuch variables must be "
- "identified with a Block or BufferBlock decoration"));
- }
- TEST_F(ValidateDecorations, VulkanUniformRuntimeArrayMissingBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability RuntimeDescriptorArrayEXT
- OpExtension "SPV_EXT_descriptor_indexing"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %struct = OpTypeStruct %uint
- %array = OpTypeRuntimeArray %struct
- %ptr_ubo = OpTypePointer Uniform %array
- %var = OpVariable %ptr_ubo Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Uniform-06676"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("From Vulkan spec:\nSuch variables must be "
- "identified with a Block or BufferBlock decoration"));
- }
- TEST_F(ValidateDecorations, VulkanArrayStrideZero) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %array ArrayStride 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %array = OpTypeArray %int %int_4
- %struct = OpTypeStruct %array
- %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr_ssbo_struct StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("contains an array with stride 0"));
- }
- TEST_F(ValidateDecorations, VulkanArrayStrideTooSmall) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %inner ArrayStride 4
- OpDecorate %outer ArrayStride 4
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %inner = OpTypeArray %int %int_4
- %outer = OpTypeArray %inner %int_4
- %struct = OpTypeStruct %outer
- %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
- %var = OpVariable %ptr_ssbo_struct StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "contains an array with stride 4, but with an element size of 16"));
- }
- TEST_F(ValidateDecorations, FunctionsWithOpGroupDecorate) {
- std::string spirv = R"(
- OpCapability Addresses
- OpCapability Linkage
- OpCapability Kernel
- OpCapability Int8
- %1 = OpExtInstImport "OpenCL.std"
- OpMemoryModel Physical32 OpenCL
- OpName %foo "foo"
- OpName %entry "entry"
- OpName %bar "bar"
- OpName %entry_0 "entry"
- OpName %k "k"
- OpName %entry_1 "entry"
- OpName %b "b"
- OpDecorate %28 FuncParamAttr Zext
- %28 = OpDecorationGroup
- OpDecorate %k LinkageAttributes "k" Export
- OpDecorate %foo LinkageAttributes "foo" Export
- OpDecorate %bar LinkageAttributes "bar" Export
- OpDecorate %b Alignment 1
- OpGroupDecorate %28 %foo %bar
- %uchar = OpTypeInt 8 0
- %bool = OpTypeBool
- %3 = OpTypeFunction %bool
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %_ptr_Function_uchar = OpTypePointer Function %uchar
- %true = OpConstantTrue %bool
- %foo = OpFunction %bool DontInline %3
- %entry = OpLabel
- OpReturnValue %true
- OpFunctionEnd
- %bar = OpFunction %bool DontInline %3
- %entry_0 = OpLabel
- OpReturnValue %true
- OpFunctionEnd
- %k = OpFunction %void DontInline %10
- %entry_1 = OpLabel
- %b = OpVariable %_ptr_Function_uchar Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateDecorations, LocationVariableGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %in_var Location 0
- %float = OpTypeFloat 32
- %ptr_input_float = OpTypePointer Input %float
- %in_var = OpVariable %ptr_input_float Input
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateDecorations, LocationStructMemberGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpMemberDecorate %struct 0 Location 0
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateDecorations, LocationStructBad) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %struct Location 0
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
- }
- TEST_F(ValidateDecorations, LocationFloatBad) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %float Location 0
- %float = OpTypeFloat 32
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
- }
- TEST_F(ValidateDecorations, WorkgroupSingleBlockVariable) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 8 1 1
- OpMemberDecorate %first 0 Offset 0
- OpDecorate %first Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %first = OpTypeStruct %int
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %main = OpFunction %void None %3
- %5 = OpLabel
- %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
- OpStore %13 %int_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- }
- TEST_F(ValidateDecorations, WorkgroupBlockVariableRequiresV14) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 8 1 1
- OpMemberDecorate %first 0 Offset 0
- OpDecorate %first Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %first = OpTypeStruct %int
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %main = OpFunction %void None %3
- %5 = OpLabel
- %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
- OpStore %13 %int_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_WRONG_VERSION,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("requires SPIR-V version 1.4 or later"));
- }
- TEST_F(ValidateDecorations, WorkgroupSingleNonBlockVariable) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %a
- OpExecutionMode %main LocalSize 8 1 1
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %a = OpVariable %_ptr_Workgroup_int Workgroup
- %int_2 = OpConstant %int 2
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpStore %a %int_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- }
- TEST_F(ValidateDecorations, WorkgroupMultiBlockVariable) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_ %__0
- OpExecutionMode %main LocalSize 8 1 1
- OpMemberDecorate %first 0 Offset 0
- OpDecorate %first Block
- OpMemberDecorate %second 0 Offset 0
- OpDecorate %second Block
- OpDecorate %_ Aliased
- OpDecorate %__0 Aliased
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %first = OpTypeStruct %int
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %second = OpTypeStruct %int
- %_ptr_Workgroup_second = OpTypePointer Workgroup %second
- %__0 = OpVariable %_ptr_Workgroup_second Workgroup
- %int_3 = OpConstant %int 3
- %main = OpFunction %void None %3
- %5 = OpLabel
- %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
- OpStore %13 %int_2
- %18 = OpAccessChain %_ptr_Workgroup_int %__0 %int_0
- OpStore %18 %int_3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- }
- TEST_F(ValidateDecorations, WorkgroupBlockVariableWith8BitType) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Int8
- OpCapability WorkgroupMemoryExplicitLayout8BitAccessKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 2 1 1
- OpMemberDecorate %first 0 Offset 0
- OpDecorate %first Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %char = OpTypeInt 8 1
- %first = OpTypeStruct %char
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %char_2 = OpConstant %char 2
- %_ptr_Workgroup_char = OpTypePointer Workgroup %char
- %main = OpFunction %void None %3
- %5 = OpLabel
- %14 = OpAccessChain %_ptr_Workgroup_char %_ %int_0
- OpStore %14 %char_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- }
- TEST_F(ValidateDecorations, WorkgroupMultiNonBlockVariable) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %a %b
- OpExecutionMode %main LocalSize 8 1 1
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %a = OpVariable %_ptr_Workgroup_int Workgroup
- %int_2 = OpConstant %int 2
- %b = OpVariable %_ptr_Workgroup_int Workgroup
- %int_3 = OpConstant %int 3
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpStore %a %int_2
- OpStore %b %int_3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- }
- TEST_F(ValidateDecorations, WorkgroupBlockVariableWith16BitType) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Float16
- OpCapability Int16
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpCapability WorkgroupMemoryExplicitLayout16BitAccessKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 2 1 1
- OpMemberDecorate %first 0 Offset 0
- OpMemberDecorate %first 1 Offset 2
- OpDecorate %first Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %short = OpTypeInt 16 1
- %half = OpTypeFloat 16
- %first = OpTypeStruct %short %half
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %short_3 = OpConstant %short 3
- %_ptr_Workgroup_short = OpTypePointer Workgroup %short
- %int_1 = OpConstant %int 1
- %half_0x1_898p_3 = OpConstant %half 0x1.898p+3
- %_ptr_Workgroup_half = OpTypePointer Workgroup %half
- %main = OpFunction %void None %3
- %5 = OpLabel
- %15 = OpAccessChain %_ptr_Workgroup_short %_ %int_0
- OpStore %15 %short_3
- %19 = OpAccessChain %_ptr_Workgroup_half %_ %int_1
- OpStore %19 %half_0x1_898p_3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- }
- TEST_F(ValidateDecorations, WorkgroupBlockVariableScalarLayout) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %B
- OpSource GLSL 450
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 4
- OpMemberDecorate %S 2 Offset 16
- OpMemberDecorate %S 3 Offset 28
- OpDecorate %S Block
- OpDecorate %B Aliased
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %S = OpTypeStruct %float %v3float %v3float %v3float
- %_ptr_Workgroup_S = OpTypePointer Workgroup %S
- %B = OpVariable %_ptr_Workgroup_S Workgroup
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- spvValidatorOptionsSetWorkgroupScalarBlockLayout(getValidatorOptions(), true);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4))
- << getDiagnosticString();
- }
- TEST_F(ValidateDecorations, WorkgroupMixBlockAndNonBlockBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_ %b
- OpExecutionMode %main LocalSize 8 1 1
- OpMemberDecorate %first 0 Offset 0
- OpDecorate %first Block
- OpDecorate %_ Aliased
- OpDecorate %b Aliased
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %first = OpTypeStruct %int
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %b = OpVariable %_ptr_Workgroup_int Workgroup
- %int_3 = OpConstant %int 3
- %main = OpFunction %void None %3
- %5 = OpLabel
- %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
- OpStore %13 %int_2
- OpStore %b %int_3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("either all or none of the Workgroup Storage Class variables "
- "in the entry point interface must point to struct types "
- "decorated with Block"));
- }
- TEST_F(ValidateDecorations, WorkgroupMultiBlockVariableMissingAliased) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_ %__0
- OpExecutionMode %main LocalSize 8 1 1
- OpMemberDecorate %first 0 Offset 0
- OpDecorate %first Block
- OpMemberDecorate %second 0 Offset 0
- OpDecorate %second Block
- OpDecorate %_ Aliased
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %first = OpTypeStruct %int
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %second = OpTypeStruct %int
- %_ptr_Workgroup_second = OpTypePointer Workgroup %second
- %__0 = OpVariable %_ptr_Workgroup_second Workgroup
- %int_3 = OpConstant %int 3
- %main = OpFunction %void None %3
- %5 = OpLabel
- %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
- OpStore %13 %int_2
- %18 = OpAccessChain %_ptr_Workgroup_int %__0 %int_0
- OpStore %18 %int_3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("more than one Workgroup Storage Class variable in the "
- "entry point interface point to a type decorated with Block, "
- "all of them must be decorated with Aliased"));
- }
- TEST_F(ValidateDecorations, WorkgroupSingleBlockVariableNotAStruct) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 8 1 1
- OpDecorate %first Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %int_3 = OpConstant %int 3
- %first = OpTypeArray %int %int_3
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %main = OpFunction %void None %3
- %5 = OpLabel
- %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
- OpStore %13 %int_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
- }
- TEST_F(ValidateDecorations, WorkgroupSingleBlockVariableMissingLayout) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 8 1 1
- OpDecorate %first Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %first = OpTypeStruct %int
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %main = OpFunction %void None %3
- %5 = OpLabel
- %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
- OpStore %13 %int_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Block must be explicitly laid out with Offset decorations"));
- }
- TEST_F(ValidateDecorations, WorkgroupSingleBlockVariableBadLayout) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 8 1 1
- OpMemberDecorate %first 0 Offset 1
- OpDecorate %first Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %first = OpTypeStruct %int
- %_ptr_Workgroup_first = OpTypePointer Workgroup %first
- %_ = OpVariable %_ptr_Workgroup_first Workgroup
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %_ptr_Workgroup_int = OpTypePointer Workgroup %int
- %main = OpFunction %void None %3
- %5 = OpLabel
- %13 = OpAccessChain %_ptr_Workgroup_int %_ %int_0
- OpStore %13 %int_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Block for variable in Workgroup storage class must follow "
- "relaxed storage buffer layout rules: "
- "member 0 at offset 1 is not aligned to 4"));
- }
- TEST_F(ValidateDecorations, WorkgroupBlockNoCapability) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 1 Offset 4
- OpDecorate %struct Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %struct = OpTypeStruct %int %int
- %ptr_workgroup = OpTypePointer Workgroup %struct
- %_ = OpVariable %ptr_workgroup Workgroup
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Workgroup Storage Class variables can't be decorated with Block "
- "unless declaring the WorkgroupMemoryExplicitLayoutKHR capability"));
- }
- TEST_F(ValidateDecorations, BadMatrixStrideUniform) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 3
- OpMemberDecorate %block 0 ColMajor
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %float4 = OpTypeVector %float 4
- %matrix4x4 = OpTypeMatrix %float4 4
- %block = OpTypeStruct %matrix4x4
- %block_ptr = OpTypePointer Uniform %block
- %var = OpVariable %block_ptr Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 2 decorated as Block for variable in Uniform storage "
- "class must follow standard uniform buffer layout rules: member 0 is "
- "a matrix with stride 3 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations, BadMatrixStrideStorageBuffer) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 3
- OpMemberDecorate %block 0 ColMajor
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %float4 = OpTypeVector %float 4
- %matrix4x4 = OpTypeMatrix %float4 4
- %block = OpTypeStruct %matrix4x4
- %block_ptr = OpTypePointer StorageBuffer %block
- %var = OpVariable %block_ptr StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 2 decorated as Block for variable in StorageBuffer "
- "storage class must follow standard storage buffer layout rules: "
- "member 0 is a matrix with stride 3 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations, BadMatrixStridePushConstant) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 3
- OpMemberDecorate %block 0 ColMajor
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %float4 = OpTypeVector %float 4
- %matrix4x4 = OpTypeMatrix %float4 4
- %block = OpTypeStruct %matrix4x4
- %block_ptr = OpTypePointer PushConstant %block
- %var = OpVariable %block_ptr PushConstant
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 2 decorated as Block for variable in PushConstant "
- "storage class must follow standard storage buffer layout rules: "
- "member 0 is a matrix with stride 3 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations, BadMatrixStrideStorageBufferScalarLayout) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 3
- OpMemberDecorate %block 0 RowMajor
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %float4 = OpTypeVector %float 4
- %matrix4x4 = OpTypeMatrix %float4 4
- %block = OpTypeStruct %matrix4x4
- %block_ptr = OpTypePointer StorageBuffer %block
- %var = OpVariable %block_ptr StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- options_->scalar_block_layout = true;
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Structure id 2 decorated as Block for variable in StorageBuffer "
- "storage class must follow scalar storage buffer layout rules: "
- "member 0 is a matrix with stride 3 not satisfying alignment to 4"));
- }
- TEST_F(ValidateDecorations, MissingOffsetStructNestedInArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %array ArrayStride 4
- OpDecorate %outer Block
- OpMemberDecorate %outer 0 Offset 0
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %inner = OpTypeStruct %int
- %array = OpTypeArray %inner %int_4
- %outer = OpTypeStruct %array
- %ptr_ssbo_outer = OpTypePointer StorageBuffer %outer
- %var = OpVariable %ptr_ssbo_outer StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Structure id 3 decorated as Block must be explicitly "
- "laid out with Offset decorations"));
- }
- TEST_F(ValidateDecorations, AllOnesOffset) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %outer Block
- OpMemberDecorate %outer 0 Offset 0
- OpMemberDecorate %struct 0 Offset 4294967295
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %struct = OpTypeStruct %int
- %outer = OpTypeStruct %struct
- %ptr = OpTypePointer Uniform %outer
- %var = OpVariable %ptr Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("decorated as Block must be explicitly laid out with "
- "Offset decorations"));
- }
- TEST_F(ValidateDecorations, PerVertexVulkanGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability FragmentBarycentricKHR
- OpExtension "SPV_KHR_fragment_shader_barycentric"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %vertexIDs
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %vertexIDs Location 0
- OpDecorate %vertexIDs PerVertexKHR
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %float = OpTypeFloat 32
- %uint = OpTypeInt 32 0
- %ptrFloat = OpTypePointer Input %float
- %uint_3 = OpConstant %uint 3
- %floatArray = OpTypeArray %float %uint_3
- %ptrFloatArray = OpTypePointer Input %floatArray
- %vertexIDs = OpVariable %ptrFloatArray Input
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %main = OpFunction %void None %func
- %label = OpLabel
- %access = OpAccessChain %ptrFloat %vertexIDs %int_0
- %load = OpLoad %float %access
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, PerVertexVulkanOutput) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability FragmentBarycentricKHR
- OpExtension "SPV_KHR_fragment_shader_barycentric"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %vertexIDs
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %vertexIDs Location 0
- OpDecorate %vertexIDs PerVertexKHR
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %float = OpTypeFloat 32
- %uint = OpTypeInt 32 0
- %ptrFloat = OpTypePointer Output %float
- %uint_3 = OpConstant %uint 3
- %floatArray = OpTypeArray %float %uint_3
- %ptrFloatArray = OpTypePointer Output %floatArray
- %vertexIDs = OpVariable %ptrFloatArray Output
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %main = OpFunction %void None %func
- %label = OpLabel
- %access = OpAccessChain %ptrFloat %vertexIDs %int_0
- %load = OpLoad %float %access
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-PerVertexKHR-06777"));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("storage class must be Input"));
- }
- TEST_F(ValidateDecorations, PerVertexVulkanNonFragment) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability FragmentBarycentricKHR
- OpExtension "SPV_KHR_fragment_shader_barycentric"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %vertexIDs
- OpDecorate %vertexIDs Location 0
- OpDecorate %vertexIDs PerVertexKHR
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %float = OpTypeFloat 32
- %uint = OpTypeInt 32 0
- %ptrFloat = OpTypePointer Input %float
- %uint_3 = OpConstant %uint 3
- %floatArray = OpTypeArray %float %uint_3
- %ptrFloatArray = OpTypePointer Input %floatArray
- %vertexIDs = OpVariable %ptrFloatArray Input
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %main = OpFunction %void None %func
- %label = OpLabel
- %access = OpAccessChain %ptrFloat %vertexIDs %int_0
- %load = OpLoad %float %access
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-PerVertexKHR-06777"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "PerVertexKHR can only be applied to Fragment Execution Models"));
- }
- TEST_F(ValidateDecorations, PerVertexVulkanNonArray) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability FragmentBarycentricKHR
- OpExtension "SPV_KHR_fragment_shader_barycentric"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %vertexIDs
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %vertexIDs Location 0
- OpDecorate %vertexIDs PerVertexKHR
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %float = OpTypeFloat 32
- %ptrFloat = OpTypePointer Input %float
- %vertexIDs = OpVariable %ptrFloat Input
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %main = OpFunction %void None %func
- %label = OpLabel
- %load = OpLoad %float %vertexIDs
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Input-06778"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("PerVertexKHR must be declared as arrays"));
- }
- TEST_F(ValidateDecorations, RelaxedPrecisionDecorationOnNumericTypeBad) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %float RelaxedPrecision
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("RelaxPrecision decoration cannot be applied to a type"));
- }
- TEST_F(ValidateDecorations, RelaxedPrecisionDecorationOnStructMember) {
- const spv_target_env env = SPV_ENV_VULKAN_1_0;
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpMemberDecorate %struct 0 RelaxedPrecision
- %void = OpTypeVoid
- %voidfn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float
- %main = OpFunction %void None %voidfn
- %label = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, env);
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env));
- }
- TEST_F(ValidateDecorations, VulkanFlatMultipleInterfaceGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Geometry
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %layer %gl_Layer
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %layer Location 0
- OpDecorate %gl_Layer Flat
- OpDecorate %gl_Layer BuiltIn Layer
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Output_int = OpTypePointer Output %int
- %layer = OpVariable %_ptr_Output_int Output
- %_ptr_Input_int = OpTypePointer Input %int
- %gl_Layer = OpVariable %_ptr_Input_int Input
- %main = OpFunction %void None %3
- %5 = OpLabel
- %11 = OpLoad %int %gl_Layer
- OpStore %layer %11
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, VulkanFlatMultipleInterfaceBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Geometry
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %layer %gl_Layer
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %layer Location 0
- OpDecorate %gl_Layer BuiltIn Layer
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Output_int = OpTypePointer Output %int
- %layer = OpVariable %_ptr_Output_int Output
- %_ptr_Input_int = OpTypePointer Input %int
- %gl_Layer = OpVariable %_ptr_Input_int Input
- %main = OpFunction %void None %3
- %5 = OpLabel
- %11 = OpLoad %int %gl_Layer
- OpStore %layer %11
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Flat-04744"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Fragment OpEntryPoint operand 4 with Input interfaces with integer "
- "or float type must have a Flat decoration for Entry Point id 2."));
- }
- TEST_F(ValidateDecorations, VulkanNoFlatFloat32) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %in
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %in Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %_ptr_Input_float = OpTypePointer Input %float
- %in = OpVariable %_ptr_Input_float Input
- %main = OpFunction %void None %3
- %5 = OpLabel
- %b = OpVariable %_ptr_Function_float Function
- %11 = OpLoad %float %in
- OpStore %b %11
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, VulkanNoFlatFloat64) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Float64
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %in
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %in Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %double = OpTypeFloat 64
- %_ptr_Function_double = OpTypePointer Function %double
- %_ptr_Input_double = OpTypePointer Input %double
- %in = OpVariable %_ptr_Input_double Input
- %main = OpFunction %void None %3
- %5 = OpLabel
- %b = OpVariable %_ptr_Function_double Function
- %11 = OpLoad %double %in
- OpStore %b %11
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Flat-04744"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Fragment OpEntryPoint operand 3 with Input interfaces with integer "
- "or float type must have a Flat decoration for Entry Point id 2."));
- }
- TEST_F(ValidateDecorations, VulkanNoFlatVectorFloat64) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Float64
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %in
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %in Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %double = OpTypeFloat 64
- %v2double = OpTypeVector %double 2
- %_ptr_Function_v2double = OpTypePointer Function %v2double
- %_ptr_Input_v2double = OpTypePointer Input %v2double
- %in = OpVariable %_ptr_Input_v2double Input
- %main = OpFunction %void None %3
- %5 = OpLabel
- %b = OpVariable %_ptr_Function_v2double Function
- %11 = OpLoad %v2double %in
- OpStore %b %11
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, VulkanNoFlatIntVector) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %in
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %in Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %v2int = OpTypeVector %int 2
- %_ptr_Function_v2int = OpTypePointer Function %v2int
- %_ptr_Input_v2int = OpTypePointer Input %v2int
- %in = OpVariable %_ptr_Input_v2int Input
- %main = OpFunction %void None %3
- %5 = OpLabel
- %b = OpVariable %_ptr_Function_v2int Function
- %12 = OpLoad %v2int %in
- OpStore %b %12
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Flat-04744"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Fragment OpEntryPoint operand 3 with Input interfaces with integer "
- "or float type must have a Flat decoration for Entry Point id 2."));
- }
- TEST_P(ValidateDecorationString, VulkanOutputInvalidInterface) {
- const std::string decoration = GetParam();
- std::stringstream ss;
- ss << R"(
- OpCapability Shader
- OpCapability SampleRateShading
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %out
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpDecorate %out )"
- << decoration << R"(
- OpDecorate %out Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Output_int = OpTypePointer Output %int
- %out = OpVariable %_ptr_Output_int Output
- %int_1 = OpConstant %int 1
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpStore %out %int_1
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(ss.str(), SPV_ENV_VULKAN_1_0);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Flat-06201"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("decorated variable must not be used in fragment execution "
- "model as an Output storage class for Entry Point id 2."));
- }
- TEST_P(ValidateDecorationString, VulkanVertexInputInvalidInterface) {
- const std::string decoration = GetParam();
- std::stringstream ss;
- ss << R"(
- OpCapability Shader
- OpCapability SampleRateShading
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %out %in
- OpSource GLSL 450
- OpDecorate %in )"
- << decoration << R"(
- OpDecorate %out Location 0
- OpDecorate %in Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Output_int = OpTypePointer Output %int
- %out = OpVariable %_ptr_Output_int Output
- %_ptr_Input_int = OpTypePointer Input %int
- %in = OpVariable %_ptr_Input_int Input
- %main = OpFunction %void None %3
- %5 = OpLabel
- %11 = OpLoad %int %in
- OpStore %out %11
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(ss.str(), SPV_ENV_VULKAN_1_0);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Flat-06202"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("decorated variable must not be used in vertex execution model "
- "as an Input storage class for Entry Point id 2."));
- }
- INSTANTIATE_TEST_SUITE_P(FragmentInputInterface, ValidateDecorationString,
- ::testing::Values("Flat", "NoPerspective", "Sample",
- "Centroid"));
- TEST_F(ValidateDecorations, NVBindlessSamplerArrayInBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability BindlessTextureNV
- OpExtension "SPV_NV_bindless_texture"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpSamplerImageAddressingModeNV 64
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %UBO "UBO"
- OpMemberName %UBO 0 "uboSampler"
- OpName %_ ""
- OpDecorate %array ArrayStride 16
- OpMemberDecorate %UBO 0 Offset 0
- OpDecorate %UBO Block
- OpDecorate %_ DescriptorSet 0
- OpDecorate %_ Binding 2
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
- %8 = OpTypeSampledImage %7
- %uint = OpTypeInt 32 0
- %uint_3 = OpConstant %uint 3
- %array = OpTypeArray %8 %uint_3
- %UBO = OpTypeStruct %array
- %pointer = OpTypePointer Uniform %UBO
- %_ = OpVariable %pointer Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateDecorations, Std140ColMajorMat2x2) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 ColMajor
- OpMemberDecorate %block 0 MatrixStride 8
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float2 = OpTypeVector %float 2
- %matrix = OpTypeMatrix %float2 2
- %block = OpTypeStruct %matrix
- %ptr_block = OpTypePointer Uniform %block
- %var = OpVariable %ptr_block Uniform
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "member 0 is a matrix with stride 8 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations, Std140RowMajorMat2x2) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 RowMajor
- OpMemberDecorate %block 0 MatrixStride 8
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float2 = OpTypeVector %float 2
- %matrix = OpTypeMatrix %float2 2
- %block = OpTypeStruct %matrix
- %ptr_block = OpTypePointer Uniform %block
- %var = OpVariable %ptr_block Uniform
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "member 0 is a matrix with stride 8 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations, Std140ColMajorMat4x2) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 ColMajor
- OpMemberDecorate %block 0 MatrixStride 8
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float2 = OpTypeVector %float 2
- %matrix = OpTypeMatrix %float2 4
- %block = OpTypeStruct %matrix
- %ptr_block = OpTypePointer Uniform %block
- %var = OpVariable %ptr_block Uniform
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "member 0 is a matrix with stride 8 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations, Std140ColMajorMat2x3) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 ColMajor
- OpMemberDecorate %block 0 MatrixStride 12
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float3 = OpTypeVector %float 3
- %matrix = OpTypeMatrix %float3 2
- %block = OpTypeStruct %matrix
- %ptr_block = OpTypePointer Uniform %block
- %var = OpVariable %ptr_block Uniform
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("member 0 is a matrix with stride 12 not satisfying "
- "alignment to 16"));
- }
- TEST_F(ValidateDecorations, MatrixMissingMajornessUniform) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 16
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float2 = OpTypeVector %float 2
- %matrix = OpTypeMatrix %float2 2
- %block = OpTypeStruct %matrix
- %ptr_block = OpTypePointer Uniform %block
- %var = OpVariable %ptr_block Uniform
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "must be explicitly laid out with RowMajor or ColMajor decorations"));
- }
- TEST_F(ValidateDecorations, MatrixMissingMajornessStorageBuffer) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 16
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float2 = OpTypeVector %float 2
- %matrix = OpTypeMatrix %float2 2
- %block = OpTypeStruct %matrix
- %ptr_block = OpTypePointer StorageBuffer %block
- %var = OpVariable %ptr_block StorageBuffer
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "must be explicitly laid out with RowMajor or ColMajor decorations"));
- }
- TEST_F(ValidateDecorations, MatrixMissingMajornessPushConstant) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 16
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float2 = OpTypeVector %float 2
- %matrix = OpTypeMatrix %float2 2
- %block = OpTypeStruct %matrix
- %ptr_block = OpTypePointer PushConstant %block
- %var = OpVariable %ptr_block PushConstant
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "must be explicitly laid out with RowMajor or ColMajor decorations"));
- }
- TEST_F(ValidateDecorations, StructWithRowAndColMajor) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 16
- OpMemberDecorate %block 0 ColMajor
- OpMemberDecorate %block 1 Offset 32
- OpMemberDecorate %block 1 MatrixStride 16
- OpMemberDecorate %block 1 RowMajor
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float2 = OpTypeVector %float 2
- %matrix = OpTypeMatrix %float2 2
- %block = OpTypeStruct %matrix %matrix
- %ptr_block = OpTypePointer PushConstant %block
- %var = OpVariable %ptr_block PushConstant
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, PhysicalStorageBufferWithOffset) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Int64
- OpCapability PhysicalStorageBufferAddresses
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint GLCompute %main "main" %pc
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %pc_block Block
- OpMemberDecorate %pc_block 0 Offset 0
- OpMemberDecorate %pssbo_struct 0 Offset 0
- %void = OpTypeVoid
- %long = OpTypeInt 64 0
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %pc_block = OpTypeStruct %long
- %pc_block_ptr = OpTypePointer PushConstant %pc_block
- %pc_long_ptr = OpTypePointer PushConstant %long
- %pc = OpVariable %pc_block_ptr PushConstant
- %pssbo_struct = OpTypeStruct %float
- %pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %pc_gep = OpAccessChain %pc_long_ptr %pc %int_0
- %addr = OpLoad %long %pc_gep
- %ptr = OpConvertUToPtr %pssbo_ptr %addr
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
- }
- TEST_F(ValidateDecorations, UntypedVariableDuplicateInterface) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %var %var
- OpName %var "var"
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %struct = OpTypeStruct %int
- %ptr = OpTypeUntypedPointerKHR Workgroup
- %var = OpUntypedVariableKHR %ptr Workgroup %struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Non-unique OpEntryPoint interface '2[%var]' is disallowed"));
- }
- TEST_F(ValidateDecorations, PhysicalStorageBufferMissingOffset) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Int64
- OpCapability PhysicalStorageBufferAddresses
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint GLCompute %main "main" %pc
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %pc_block Block
- OpMemberDecorate %pc_block 0 Offset 0
- %void = OpTypeVoid
- %long = OpTypeInt 64 0
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %pc_block = OpTypeStruct %long
- %pc_block_ptr = OpTypePointer PushConstant %pc_block
- %pc_long_ptr = OpTypePointer PushConstant %long
- %pc = OpVariable %pc_block_ptr PushConstant
- %pssbo_struct = OpTypeStruct %float
- %pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %pc_gep = OpAccessChain %pc_long_ptr %pc %int_0
- %addr = OpLoad %long %pc_gep
- %ptr = OpConvertUToPtr %pssbo_ptr %addr
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("decorated as Block for variable in PhysicalStorageBuffer "
- "storage class must follow relaxed storage buffer layout "
- "rules: member 0 is missing an Offset decoration"));
- }
- TEST_F(ValidateDecorations, PhysicalStorageBufferMissingArrayStride) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Int64
- OpCapability PhysicalStorageBufferAddresses
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint GLCompute %main "main" %pc
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %pc_block Block
- OpMemberDecorate %pc_block 0 Offset 0
- %void = OpTypeVoid
- %long = OpTypeInt 64 0
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %int_4 = OpConstant %int 4
- %pc_block = OpTypeStruct %long
- %pc_block_ptr = OpTypePointer PushConstant %pc_block
- %pc_long_ptr = OpTypePointer PushConstant %long
- %pc = OpVariable %pc_block_ptr PushConstant
- %pssbo_array = OpTypeArray %float %int_4
- %pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_array
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %pc_gep = OpAccessChain %pc_long_ptr %pc %int_0
- %addr = OpLoad %long %pc_gep
- %ptr = OpConvertUToPtr %pssbo_ptr %addr
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "decorated as Block for variable in PhysicalStorageBuffer storage "
- "class must follow relaxed storage buffer layout rules: member 0 "
- "contains an array with stride 0, but with an element size of 4"));
- }
- TEST_F(ValidateDecorations, MatrixArrayMissingMajorness) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 16
- OpDecorate %array ArrayStride 32
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %vec = OpTypeVector %float 2
- %mat = OpTypeMatrix %vec 2
- %array = OpTypeArray %mat %int_2
- %block = OpTypeStruct %array
- %ptr = OpTypePointer Uniform %block
- %var = OpVariable %ptr Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "must be explicitly laid out with RowMajor or ColMajor decorations"));
- }
- TEST_F(ValidateDecorations, MatrixArrayMissingStride) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 ColMajor
- OpDecorate %array ArrayStride 32
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %vec = OpTypeVector %float 2
- %mat = OpTypeMatrix %vec 2
- %array = OpTypeArray %mat %int_2
- %block = OpTypeStruct %array
- %ptr = OpTypePointer Uniform %block
- %var = OpVariable %ptr Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with MatrixStride decorations"));
- }
- TEST_F(ValidateDecorations, MatrixArrayBadStride) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 ColMajor
- OpMemberDecorate %block 0 MatrixStride 8
- OpDecorate %array ArrayStride 32
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %vec = OpTypeVector %float 2
- %mat = OpTypeMatrix %vec 2
- %array = OpTypeArray %mat %int_2
- %block = OpTypeStruct %array
- %ptr = OpTypePointer Uniform %block
- %var = OpVariable %ptr Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("is a matrix with stride 8 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations, MatrixArrayArrayMissingMajorness) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 MatrixStride 16
- OpDecorate %array ArrayStride 32
- OpDecorate %rta ArrayStride 64
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %vec = OpTypeVector %float 2
- %mat = OpTypeMatrix %vec 2
- %array = OpTypeArray %mat %int_2
- %rta = OpTypeRuntimeArray %array
- %block = OpTypeStruct %rta
- %ptr = OpTypePointer StorageBuffer %block
- %var = OpVariable %ptr StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "must be explicitly laid out with RowMajor or ColMajor decorations"));
- }
- TEST_F(ValidateDecorations, MatrixArrayArrayMissingStride) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 ColMajor
- OpDecorate %array ArrayStride 32
- OpDecorate %rta ArrayStride 64
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %vec = OpTypeVector %float 2
- %mat = OpTypeMatrix %vec 2
- %array = OpTypeArray %mat %int_2
- %rta = OpTypeRuntimeArray %array
- %block = OpTypeStruct %rta
- %ptr = OpTypePointer StorageBuffer %block
- %var = OpVariable %ptr StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("must be explicitly laid out with MatrixStride decorations"));
- }
- TEST_F(ValidateDecorations, MatrixArrayArrayBadStride) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpMemberDecorate %block 0 ColMajor
- OpMemberDecorate %block 0 MatrixStride 8
- OpDecorate %array ArrayStride 32
- OpDecorate %a ArrayStride 64
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %vec = OpTypeVector %float 2
- %mat = OpTypeMatrix %vec 2
- %array = OpTypeArray %mat %int_2
- %a = OpTypeArray %array %int_2
- %block = OpTypeStruct %a
- %ptr = OpTypePointer Uniform %block
- %var = OpVariable %ptr Uniform
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("is a matrix with stride 8 not satisfying alignment to 16"));
- }
- TEST_F(ValidateDecorations, MultipleBuiltinsInputVertex) {
- const std::string body = R"(
- OpCapability Shader
- OpCapability DrawParameters
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %_ %gl_BaseInstance1 %gl_BaseInstance2
- OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
- OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
- OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
- OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
- OpDecorate %gl_PerVertex Block
- OpDecorate %gl_BaseInstance1 BuiltIn BaseInstance
- OpDecorate %gl_BaseInstance2 BuiltIn BaseInstance
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
- %_arr_float_uint_1 = OpTypeArray %float %uint_1
- %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
- %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
- %_ = OpVariable %_ptr_Output_gl_PerVertex Output
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %float_0 = OpConstant %float 0
- %17 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %_ptr_Input_int = OpTypePointer Input %int
- %gl_BaseInstance1 = OpVariable %_ptr_Input_int Input
- %gl_BaseInstance2 = OpVariable %_ptr_Input_int Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %main = OpFunction %void None %3
- %5 = OpLabel
- %20 = OpLoad %int %gl_BaseInstance1
- %21 = OpConvertSToF %float %20
- %22 = OpVectorTimesScalar %v4float %17 %21
- %24 = OpAccessChain %_ptr_Output_v4float %_ %int_0
- OpStore %24 %22
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint contains duplicate input variables with "
- "BaseInstance builtin"));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09658"));
- }
- TEST_F(ValidateDecorations, MultipleBuiltinsInputMesh) {
- const std::string body = R"(
- OpCapability DrawParameters
- OpCapability MeshShadingEXT
- OpExtension "SPV_EXT_mesh_shader"
- OpMemoryModel Logical GLSL450
- OpEntryPoint MeshEXT %main "main" %gl_DrawID_1 %gl_DrawID_2
- OpExecutionMode %main LocalSize 1 1 1
- OpExecutionMode %main OutputVertices 32
- OpExecutionMode %main OutputPrimitivesEXT 32
- OpExecutionMode %main OutputTrianglesEXT
- OpDecorate %gl_DrawID_1 BuiltIn DrawIndex
- OpDecorate %gl_DrawID_2 BuiltIn DrawIndex
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Input_int = OpTypePointer Input %int
- %gl_DrawID_1 = OpVariable %_ptr_Input_int Input
- %gl_DrawID_2 = OpVariable %_ptr_Input_int Input
- %uint = OpTypeInt 32 0
- %main = OpFunction %void None %3
- %5 = OpLabel
- %9 = OpLoad %int %gl_DrawID_1
- %11 = OpBitcast %uint %9
- %12 = OpLoad %int %gl_DrawID_2
- %13 = OpBitcast %uint %12
- OpSetMeshOutputsEXT %11 %13
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint contains duplicate input variables with "
- "DrawIndex builtin"));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09658"));
- }
- TEST_F(ValidateDecorations, MultipleBuiltinsInputCompute) {
- const std::string body = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %_ %gl_WorkGroupID_1 %gl_WorkGroupID_2
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %Buffers 0 Offset 0
- OpDecorate %Buffers Block
- OpDecorate %_ DescriptorSet 0
- OpDecorate %_ Binding 0
- OpDecorate %gl_WorkGroupID_1 BuiltIn WorkgroupId
- OpDecorate %gl_WorkGroupID_2 BuiltIn WorkgroupId
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %v3uint = OpTypeVector %uint 3
- %Buffers = OpTypeStruct %v3uint
- %_ptr_StorageBuffer_Buffers = OpTypePointer StorageBuffer %Buffers
- %_ = OpVariable %_ptr_StorageBuffer_Buffers StorageBuffer
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %_ptr_Input_v3uint = OpTypePointer Input %v3uint
- %gl_WorkGroupID_1 = OpVariable %_ptr_Input_v3uint Input
- %gl_WorkGroupID_2 = OpVariable %_ptr_Input_v3uint Input
- %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
- %main = OpFunction %void None %3
- %5 = OpLabel
- %15 = OpLoad %v3uint %gl_WorkGroupID_1
- %16 = OpLoad %v3uint %gl_WorkGroupID_2
- %17 = OpIAdd %v3uint %15 %16
- %19 = OpAccessChain %_ptr_StorageBuffer_v3uint %_ %int_0
- OpStore %19 %17
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint contains duplicate input variables with "
- "WorkgroupId builtin"));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09658"));
- }
- TEST_F(ValidateDecorations, MultipleBuiltinsOutputFragment) {
- const std::string body = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %gl_FragDepth_1 %gl_FragDepth_2
- OpExecutionMode %main OriginUpperLeft
- OpExecutionMode %main DepthReplacing
- OpDecorate %gl_FragDepth_1 BuiltIn FragDepth
- OpDecorate %gl_FragDepth_2 BuiltIn FragDepth
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Output_float = OpTypePointer Output %float
- %gl_FragDepth_1 = OpVariable %_ptr_Output_float Output
- %gl_FragDepth_2 = OpVariable %_ptr_Output_float Output
- %float_1 = OpConstant %float 1
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpStore %gl_FragDepth_1 %float_1
- %10 = OpLoad %float %gl_FragDepth_1
- %11 = OpFAdd %float %10 %float_1
- OpStore %gl_FragDepth_2 %11
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint contains duplicate output variables with "
- "FragDepth builtin"));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09659"));
- }
- TEST_F(ValidateDecorations, MultipleBuiltinsRayTmaxKHR) {
- const std::string body = R"(
- OpCapability RayTracingKHR
- OpExtension "SPV_KHR_ray_tracing"
- OpMemoryModel Logical GLSL450
- OpEntryPoint AnyHitKHR %main "main" %gl_RayTmaxEXT %gl_HitTEXT %incomingPayload
- OpDecorate %gl_RayTmaxEXT BuiltIn RayTmaxKHR
- OpDecorate %gl_HitTEXT BuiltIn RayTmaxKHR
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %_ptr_Input_float = OpTypePointer Input %float
- %gl_RayTmaxEXT = OpVariable %_ptr_Input_float Input
- %gl_HitTEXT = OpVariable %_ptr_Input_float Input
- %v4float = OpTypeVector %float 4
- %_ptr_IncomingRayPayloadKHR_v4float = OpTypePointer IncomingRayPayloadKHR %v4float
- %incomingPayload = OpVariable %_ptr_IncomingRayPayloadKHR_v4float IncomingRayPayloadKHR
- %main = OpFunction %void None %3
- %5 = OpLabel
- %a = OpVariable %_ptr_Function_float Function
- %b = OpVariable %_ptr_Function_float Function
- %11 = OpLoad %float %gl_RayTmaxEXT
- OpStore %a %11
- %14 = OpLoad %float %gl_HitTEXT
- OpStore %b %14
- %18 = OpLoad %float %a
- %19 = OpLoad %float %b
- %22 = OpCompositeConstruct %v4float %18 %18 %19 %19
- OpStore %incomingPayload %22
- OpTerminateRayKHR
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "OpEntryPoint contains duplicate input variables with RayTmax"));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09658"));
- }
- TEST_F(ValidateDecorations, MultipleBuiltinsBlock) {
- const std::string body = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %var
- OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
- OpMemberDecorate %gl_PerVertex 1 BuiltIn Position
- OpDecorate %gl_PerVertex Block
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %gl_PerVertex = OpTypeStruct %v4float %v4float
- %_ptr_gl_PerVertex = OpTypePointer Output %gl_PerVertex
- %var = OpVariable %_ptr_gl_PerVertex Output
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %int_1 = OpConstant %int 1
- %float_0 = OpConstant %float 0
- %17 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %ptr_vec4 = OpTypePointer Output %v4float
- %main = OpFunction %void None %3
- %5 = OpLabel
- %19 = OpAccessChain %ptr_vec4 %var %int_0
- OpStore %19 %17
- %22 = OpAccessChain %ptr_vec4 %var %int_1
- OpStore %22 %17
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_0);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "OpEntryPoint contains duplicate output variables with Position"));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09659"));
- }
- TEST_F(ValidateDecorations, MultipleBuiltinsBlockMixed) {
- const std::string body = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %var %position
- OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
- OpDecorate %gl_PerVertex Block
- OpDecorate %position BuiltIn Position
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %gl_PerVertex = OpTypeStruct %v4float
- %_ptr_gl_PerVertex = OpTypePointer Output %gl_PerVertex
- %var = OpVariable %_ptr_gl_PerVertex Output
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %int_1 = OpConstant %int 1
- %float_0 = OpConstant %float 0
- %17 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %ptr_vec4 = OpTypePointer Output %v4float
- %position = OpVariable %ptr_vec4 Output
- %main = OpFunction %void None %3
- %5 = OpLabel
- %19 = OpAccessChain %ptr_vec4 %var %int_0
- OpStore %19 %17
- OpStore %position %17
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_0);
- ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "OpEntryPoint contains duplicate output variables with Position"));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-09659"));
- }
- TEST_F(ValidateDecorations, UntypedVariableWorkgroupRequiresStruct) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %var
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %ptr = OpTypeUntypedPointerKHR Workgroup
- %var = OpUntypedVariableKHR %ptr Workgroup %int
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Untyped workgroup variables in shaders must be block "
- "decorated structs"));
- }
- TEST_F(ValidateDecorations, UntypedVariableWorkgroupRequiresBlockStruct) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %var
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %struct = OpTypeStruct %int
- %ptr = OpTypeUntypedPointerKHR Workgroup
- %var = OpUntypedVariableKHR %ptr Workgroup %struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Untyped workgroup variables in shaders must be block "
- "decorated"));
- }
- TEST_F(ValidateDecorations, UntypedVariableStorageBufferMissingBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpName %struct "struct"
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %struct = OpTypeStruct %int
- %ptr = OpTypeUntypedPointerKHR StorageBuffer
- %var = OpUntypedVariableKHR %ptr StorageBuffer %struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("StorageBuffer id '2' is missing Block decoration"));
- }
- TEST_F(ValidateDecorations, UntypedVariableUniformMissingBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpName %struct "struct"
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %struct = OpTypeStruct %int
- %ptr = OpTypeUntypedPointerKHR Uniform
- %var = OpUntypedVariableKHR %ptr Uniform %struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Uniform id '2' is missing Block or BufferBlock decoration"));
- }
- TEST_F(ValidateDecorations, UntypedVariablePushConstantMissingBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpName %struct "struct"
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %struct = OpTypeStruct %int
- %ptr = OpTypeUntypedPointerKHR PushConstant
- %var = OpUntypedVariableKHR %ptr PushConstant %struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("PushConstant id '2' is missing Block decoration"));
- }
- using UntypedVariableSetAndBinding = spvtest::ValidateBase<std::string>;
- TEST_P(UntypedVariableSetAndBinding, MissingSet) {
- const auto sc = GetParam();
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpName %var "var"
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %struct = OpTypeStruct %int
- %ptr = OpTypeUntypedPointerKHR )" +
- sc + R"(
- %var = OpUntypedVariableKHR %ptr )" + sc + R"( %struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %load = OpLoad %struct %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(sc + " id '2' is missing DescriptorSet decoration"));
- }
- TEST_P(UntypedVariableSetAndBinding, MissingBinding) {
- const auto sc = GetParam();
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpName %var "var"
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %var DescriptorSet 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %struct = OpTypeStruct %int
- %ptr = OpTypeUntypedPointerKHR )" +
- sc + R"(
- %var = OpUntypedVariableKHR %ptr )" + sc + R"( %struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %load = OpLoad %struct %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(sc + " id '2' is missing Binding decoration"));
- }
- INSTANTIATE_TEST_SUITE_P(ValidateUntypedVariableSetAndBinding,
- UntypedVariableSetAndBinding,
- Values("StorageBuffer", "Uniform"));
- using UntypedPointerLayout =
- spvtest::ValidateBase<std::tuple<std::string, std::string>>;
- TEST_P(UntypedPointerLayout, BadOffset) {
- const auto sc = std::get<0>(GetParam());
- const auto op = std::get<1>(GetParam());
- const std::string set = (sc == "StorageBuffer" || sc == "Uniform"
- ? R"(OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- )"
- : R"()");
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability VariablePointers
- OpCapability UntypedPointersKHR
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %var
- OpExecutionMode %main LocalSize 1 1 1
- OpName %var "var"
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 1 Offset 4
- )" + set + R"(OpMemberDecorate %test_type 0 Offset 0
- OpMemberDecorate %test_type 1 Offset 1
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %struct = OpTypeStruct %int %int
- %test_type = OpTypeStruct %int %int
- %test_val = OpConstantNull %test_type
- %ptr = OpTypeUntypedPointerKHR )" +
- sc + R"(
- %var = OpUntypedVariableKHR %ptr )" + sc + R"( %struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- )" + op + R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- const bool read_only = sc == "Uniform" || sc == "PushConstant";
- if (!read_only || op.find("OpStore") == std::string::npos) {
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("member 1 at offset 1 is not aligned to"));
- }
- }
- TEST_P(UntypedPointerLayout, BadStride) {
- const auto sc = std::get<0>(GetParam());
- const auto op = std::get<1>(GetParam());
- const std::string set = (sc == "StorageBuffer" || sc == "Uniform"
- ? R"(OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- )"
- : R"()");
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability VariablePointers
- OpCapability UntypedPointersKHR
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpExtension "SPV_KHR_variable_pointers"
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %var
- OpExecutionMode %main LocalSize 1 1 1
- OpName %var "var"
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpMemberDecorate %struct 1 Offset 4
- )" + set + R"(OpDecorate %test_type ArrayStride 4
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_0 = OpConstant %int 0
- %int_4 = OpConstant %int 4
- %int4 = OpTypeVector %int 4
- %test_type = OpTypeArray %int4 %int_4
- %test_val = OpConstantNull %test_type
- %struct = OpTypeStruct %int %int
- %ptr = OpTypeUntypedPointerKHR )" +
- sc + R"(
- %var = OpUntypedVariableKHR %ptr )" + sc + R"( %struct
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- )" + op + R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- const bool read_only = sc == "Uniform" || sc == "PushConstant";
- if (!read_only || op.find("OpStore") == std::string::npos) {
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("array with stride 4 not satisfying alignment to 16"));
- }
- }
- INSTANTIATE_TEST_SUITE_P(
- ValidateUntypedPointerLayout, UntypedPointerLayout,
- Combine(Values("StorageBuffer", "Uniform", "PushConstant", "Workgroup"),
- Values("%gep = OpUntypedAccessChainKHR %ptr %test_type %var %int_0",
- "%gep = OpUntypedInBoundsAccessChainKHR %ptr %test_type "
- "%var %int_0",
- "%gep = OpUntypedPtrAccessChainKHR %ptr %test_type %var "
- "%int_0 %int_0",
- "%ld = OpLoad %test_type %var", "OpStore %var %test_val")));
- TEST_F(ValidateDecorations, UntypedArrayLengthMissingOffset) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 0
- OpDecorate %array ArrayStride 4
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %array = OpTypeRuntimeArray %int
- %struct = OpTypeStruct %array
- %block = OpTypeStruct %array
- %ptr = OpTypeUntypedPointerKHR StorageBuffer
- %var = OpUntypedVariableKHR %ptr StorageBuffer %block
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %len = OpUntypedArrayLengthKHR %int %struct %var 0
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("member 0 is missing an Offset decoration"));
- }
- TEST_F(ValidateDecorations, ComponentMultipleArrays) {
- const std::string spirv = R"(
- OpCapability Tessellation
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint TessellationEvaluation %main "main" %_ %FOO %FOO0
- OpExecutionMode %main Triangles
- OpExecutionMode %main SpacingEqual
- OpExecutionMode %main VertexOrderCcw
- OpSource GLSL 460
- OpSourceExtension "GL_EXT_nonuniform_qualifier"
- OpName %main "main"
- OpName %gl_PerVertex "gl_PerVertex"
- OpMemberName %gl_PerVertex 0 "gl_Position"
- OpMemberName %gl_PerVertex 1 "gl_PointSize"
- OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
- OpMemberName %gl_PerVertex 3 "gl_CullDistance"
- OpName %_ ""
- OpName %FOO "FOO"
- OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
- OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
- OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
- OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
- OpDecorate %gl_PerVertex Block
- OpDecorate %FOO Component 2
- OpDecorate %FOO Location 1
- OpDecorate %FOO0 Location 4
- OpDecorate %FOO0 Component 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
- %_arr_float_uint_1 = OpTypeArray %float %uint_1
- %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
- %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
- %_ = OpVariable %_ptr_Output_gl_PerVertex Output
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %v2float = OpTypeVector %float 2
- %uint_2 = OpConstant %uint 2
- %_arr_v2float_uint_2 = OpTypeArray %v2float %uint_2
- %uint_32 = OpConstant %uint 32
- %_arr__arr_v2float_uint_2_uint_32 = OpTypeArray %_arr_v2float_uint_2 %uint_32
- %_ptr_Input__arr__arr_v2float_uint_2_uint_32 = OpTypePointer Input %_arr__arr_v2float_uint_2_uint_32
- %FOO = OpVariable %_ptr_Input__arr__arr_v2float_uint_2_uint_32 Input
- %FOO0 = OpVariable %_ptr_Input__arr__arr_v2float_uint_2_uint_32 Input
- %_ptr_Input_v2float = OpTypePointer Input %v2float
- %int_1 = OpConstant %int 1
- %uint_0 = OpConstant %uint 0
- %_ptr_Output_float = OpTypePointer Output %float
- %main = OpFunction %void None %3
- %5 = OpLabel
- %24 = OpAccessChain %_ptr_Input_v2float %FOO %int_0 %int_0
- %25 = OpLoad %v2float %24
- %27 = OpAccessChain %_ptr_Input_v2float %FOO0 %int_1 %int_1
- %28 = OpLoad %v2float %27
- %29 = OpFAdd %v2float %25 %28
- %32 = OpAccessChain %_ptr_Output_float %_ %int_0 %uint_0
- %33 = OpCompositeExtract %float %29 0
- OpStore %32 %33
- %34 = OpAccessChain %_ptr_Output_float %_ %int_0 %uint_1
- %35 = OpCompositeExtract %float %29 1
- OpStore %34 %35
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- }
- const std::string kNodeShaderPrelude = R"(
- OpCapability Shader
- OpCapability ShaderEnqueueAMDX
- OpExtension "SPV_AMDX_shader_enqueue"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpEntryPoint GLCompute %other "other"
- )";
- const std::string kNodeShaderPostlude = R"(
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %node0 = OpConstantStringAMDX "node0"
- %node1 = OpConstantStringAMDX "node1"
- %node2 = OpConstantStringAMDX "node2"
- %S = OpTypeStruct
- %_payloadarr_S = OpTypeNodePayloadArrayAMDX %S
- %_payloadarr_S_0 = OpTypeNodePayloadArrayAMDX %S
- %bool = OpTypeBool
- %true = OpConstantTrue %bool
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- %other = OpFunction %void None %void_fn
- %entry0 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- TEST_F(ValidateDecorations, NodeShader) {
- const std::string spirv = kNodeShaderPrelude + R"(
- OpExecutionModeId %main ShaderIndexAMDX %uint_0
- OpExecutionModeId %main IsApiEntryAMDX %true
- OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
- OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
- OpExecutionModeId %other ShaderIndexAMDX %uint_0
- OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpDecorateId %_payloadarr_S PayloadNodeNameAMDX %node1
- OpDecorateId %_payloadarr_S_0 PayloadNodeNameAMDX %node2
- OpDecorateId %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
- OpDecorateId %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
- OpDecorateId %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
- )" + kNodeShaderPostlude;
- spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
- CompileSuccessfully(spirv, env);
- EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env));
- }
- TEST_F(ValidateDecorations, NodeShaderDecoratePayloadNodeName) {
- const std::string spirv = kNodeShaderPrelude + R"(
- OpExecutionModeId %main ShaderIndexAMDX %uint_0
- OpExecutionModeId %main IsApiEntryAMDX %true
- OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
- OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
- OpExecutionModeId %other ShaderIndexAMDX %uint_0
- OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpDecorate %_payloadarr_S PayloadNodeNameAMDX %node1
- OpDecorate %_payloadarr_S_0 PayloadNodeNameAMDX %node2
- OpDecorateId %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
- OpDecorateId %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
- OpDecorateId %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
- )" + kNodeShaderPostlude;
- spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
- CompileSuccessfully(spirv, env);
- EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Decorations taking ID parameters may not be used with OpDecorate"));
- }
- TEST_F(ValidateDecorations, NodeShaderDecoratePayloadNodeBaseIndex) {
- const std::string spirv = kNodeShaderPrelude + R"(
- OpExecutionModeId %main ShaderIndexAMDX %uint_0
- OpExecutionModeId %main IsApiEntryAMDX %true
- OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
- OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
- OpExecutionModeId %other ShaderIndexAMDX %uint_0
- OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpDecorateId %_payloadarr_S PayloadNodeNameAMDX %node1
- OpDecorateId %_payloadarr_S_0 PayloadNodeNameAMDX %node2
- OpDecorate %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
- OpDecorateId %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
- OpDecorateId %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
- )" + kNodeShaderPostlude;
- spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
- CompileSuccessfully(spirv, env);
- EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Decorations taking ID parameters may not be used with OpDecorate"));
- }
- TEST_F(ValidateDecorations, NodeShaderDecoratePayloadNodeArraySize) {
- const std::string spirv = kNodeShaderPrelude + R"(
- OpExecutionModeId %main ShaderIndexAMDX %uint_0
- OpExecutionModeId %main IsApiEntryAMDX %true
- OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
- OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
- OpExecutionModeId %other ShaderIndexAMDX %uint_0
- OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpDecorateId %_payloadarr_S PayloadNodeNameAMDX %node1
- OpDecorateId %_payloadarr_S_0 PayloadNodeNameAMDX %node2
- OpDecorateId %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
- OpDecorate %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
- OpDecorateId %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
- )" + kNodeShaderPostlude;
- spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
- CompileSuccessfully(spirv, env);
- EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Decorations taking ID parameters may not be used with OpDecorate"));
- }
- TEST_F(ValidateDecorations, NodeShaderDecorateNodeSharesPayloadLimitsWith) {
- const std::string spirv = kNodeShaderPrelude + R"(
- OpExecutionModeId %main ShaderIndexAMDX %uint_0
- OpExecutionModeId %main IsApiEntryAMDX %true
- OpExecutionModeId %main MaxNodeRecursionAMDX %uint_1
- OpExecutionModeId %main MaxNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpExecutionModeId %main SharesInputWithAMDX %node0 %uint_0
- OpExecutionModeId %other ShaderIndexAMDX %uint_0
- OpExecutionModeId %other StaticNumWorkgroupsAMDX %uint_1 %uint_1 %uint_1
- OpDecorateId %_payloadarr_S PayloadNodeNameAMDX %node1
- OpDecorateId %_payloadarr_S_0 PayloadNodeNameAMDX %node2
- OpDecorateId %_payloadarr_S PayloadNodeBaseIndexAMDX %uint_0
- OpDecorateId %_payloadarr_S PayloadNodeArraySizeAMDX %uint_1
- OpDecorate %_payloadarr_S NodeSharesPayloadLimitsWithAMDX %_payloadarr_S_0
- )" + kNodeShaderPostlude;
- spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
- CompileSuccessfully(spirv, env);
- EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Decorations taking ID parameters may not be used with OpDecorate"));
- }
- TEST_F(ValidateDecorations, BlockArrayWithStride) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %array ArrayStride 4
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %struct = OpTypeStruct %int
- %array = OpTypeArray %struct %int_4
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Array containing a Block or BufferBlock must not be "
- "decorated with ArrayStride"));
- }
- TEST_F(ValidateDecorations, BufferBlockRuntimeArrayWithStride) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpDecorate %struct BufferBlock
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %array ArrayStride 4
- %int = OpTypeInt 32 0
- %struct = OpTypeStruct %int
- %array = OpTypeRuntimeArray %struct
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Array containing a Block or BufferBlock must not be "
- "decorated with ArrayStride"));
- }
- TEST_F(ValidateDecorations, BlockArrayWithoutStride) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %struct = OpTypeStruct %int
- %array = OpTypeArray %struct %int_4
- %ptr = OpTypePointer StorageBuffer %array
- %var = OpVariable %ptr StorageBuffer
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, BlockArrayWithoutStrideUntypedAccessChain) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %struct Block
- OpMemberDecorate %struct 0 Offset 0
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %struct = OpTypeStruct %int
- %array = OpTypeArray %struct %int_4
- %void = OpTypeVoid
- %ptr = OpTypeUntypedPointerKHR StorageBuffer
- %var = OpUntypedVariableKHR %ptr StorageBuffer %array
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %gep = OpUntypedAccessChainKHR %ptr %array %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, InvalidLayoutBlockFunctionPre1p4) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %int
- %ptr_function_block = OpTypePointer Function %block
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %var = OpVariable %ptr_function_block Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- }
- TEST_F(ValidateDecorations, InvalidLayoutBlockFunctionPost1p4) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block Block
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %int
- %ptr_function_block = OpTypePointer Function %block
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %var = OpVariable %ptr_function_block Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Invalid explicit layout decorations on type for operand"));
- }
- TEST_F(ValidateDecorations, InvalidLayoutOffsetPrivatePre1p4) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %block 0 Offset 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %int
- %ptr_private_block = OpTypePointer Private %block
- %void_fn = OpTypeFunction %void
- %var = OpVariable %ptr_private_block Private
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- }
- TEST_F(ValidateDecorations, InvalidLayoutOffsetPrivatePost1p4) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %block 0 Offset 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %int
- %ptr_private_block = OpTypePointer Private %block
- %void_fn = OpTypeFunction %void
- %var = OpVariable %ptr_private_block Private
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Invalid explicit layout decorations on type for operand"));
- }
- TEST_F(ValidateDecorations, InvalidLayoutArrayStrideWorkgroupExplicitLayout) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %array ArrayStride 4
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %array = OpTypeArray %int %int_4
- %ptr_wg_block = OpTypePointer Workgroup %array
- %void_fn = OpTypeFunction %void
- %var = OpVariable %ptr_wg_block Workgroup
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
- }
- TEST_F(ValidateDecorations, InvalidLayoutArrayStrideWorkgroup) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %array ArrayStride 4
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %array = OpTypeArray %int %int_4
- %ptr_wg_block = OpTypePointer Workgroup %array
- %void_fn = OpTypeFunction %void
- %var = OpVariable %ptr_wg_block Workgroup
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Invalid explicit layout decorations on type for operand"));
- }
- TEST_F(ValidateDecorations, InvalidLayoutArrayStrideUniformConstant) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %array ArrayStride 4
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int_4 = OpConstant %int 4
- %sampler = OpTypeSampler
- %array = OpTypeArray %sampler %int_4
- %ptr_uc_block = OpTypePointer UniformConstant %array
- %void_fn = OpTypeFunction %void
- %var = OpVariable %ptr_uc_block UniformConstant
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Invalid explicit layout decorations on type for operand"));
- }
- TEST_F(ValidateDecorations, InvalidLayoutMatrixStrideFunctionPost1p4) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %block 0 MatrixStride 16
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %mat4x4 = OpTypeMatrix %v4float 4
- %block = OpTypeStruct %mat4x4
- %ptr_function_block = OpTypePointer Function %block
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %var = OpVariable %ptr_function_block Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Invalid explicit layout decorations on type for operand"));
- }
- TEST_F(ValidateDecorations, InvalidLayoutNestedMatrixStrideFunctionPost1p4) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpMemberDecorate %block 0 MatrixStride 16
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %mat4x4 = OpTypeMatrix %v4float 4
- %block = OpTypeStruct %mat4x4
- %block2 = OpTypeStruct %block
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %array = OpTypeArray %block2 %int_2
- %ptr_function_array = OpTypePointer Function %array
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %var = OpVariable %ptr_function_array Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Invalid explicit layout decorations on type for operand"));
- }
- TEST_F(ValidateDecorations, InvalidLayoutBufferBlockWorkgroup) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %block BufferBlock
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %int
- %ptr_wg_block = OpTypePointer Workgroup %block
- %void_fn = OpTypeFunction %void
- %var = OpVariable %ptr_wg_block Workgroup
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Invalid explicit layout decorations on type for operand"));
- }
- TEST_F(ValidateDecorations, ExplicitLayoutOnPtrPhysicalStorageBuffer) {
- const std::string spirv = R"(
- OpCapability PhysicalStorageBufferAddresses
- OpCapability Int64
- OpCapability Shader
- OpExtension "SPV_KHR_physical_storage_buffer"
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %_ptr_PhysicalStorageBuffer_int ArrayStride 4
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int ; ArrayStride 4
- %Foo = OpTypeStruct %_ptr_PhysicalStorageBuffer_int
- %_ptr_Function_Foo = OpTypePointer Function %Foo
- %int_0 = OpConstant %int 0
- %_ptr_Function__ptr_PhysicalStorageBuffer_int = OpTypePointer Function %_ptr_PhysicalStorageBuffer_int
- %ulong = OpTypeInt 64 0
- %ulong_0 = OpConstant %ulong 0
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- %obj = OpVariable %_ptr_Function_Foo Function
- %obj_member = OpAccessChain %_ptr_Function__ptr_PhysicalStorageBuffer_int %obj %int_0
- %nullptr = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_int %ulong_0
- OpStore %obj_member %nullptr
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
- }
- TEST_F(ValidateDecorations, RuntimeArrayNotLargestOffsetInBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %block Block
- OpMemberDecorate %block 0 Offset 16
- OpMemberDecorate %block 1 Offset 0
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %array = OpTypeRuntimeArray %int
- %block = OpTypeStruct %int %array
- %ptr = OpTypePointer StorageBuffer %block
- %var = OpVariable %ptr StorageBuffer
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("has a runtime array at offset 0, but other members at "
- "larger offsets"));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
- }
- TEST_F(ValidateDecorations, RuntimeArrayNotLargestOffsetInBufferBlock) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpDecorate %var DescriptorSet 0
- OpDecorate %var Binding 0
- OpDecorate %block BufferBlock
- OpMemberDecorate %block 0 Offset 16
- OpMemberDecorate %block 1 Offset 0
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %array = OpTypeRuntimeArray %int
- %block = OpTypeStruct %int %array
- %ptr = OpTypePointer Uniform %block
- %var = OpVariable %ptr Uniform
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("has a runtime array at offset 0, but other members at "
- "larger offsets"));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
- }
- } // namespace
- } // namespace val
- } // namespace spvtools
|