| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573 |
- // Copyright (c) 2015-2016 The Khronos Group Inc.
- //
- // 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.
- #include <sstream>
- #include <string>
- #include <vector>
- #include "gmock/gmock.h"
- #include "test/test_fixture.h"
- #include "test/unit_spirv.h"
- #include "test/val/val_fixtures.h"
- // NOTE: The tests in this file are ONLY testing ID usage, there for the input
- // SPIR-V does not follow the logical layout rules from the spec in all cases in
- // order to makes the tests smaller. Validation of the whole module is handled
- // in stages, ID validation is only one of these stages. All validation stages
- // are stand alone.
- namespace spvtools {
- namespace val {
- namespace {
- using spvtest::ScopedContext;
- using ::testing::HasSubstr;
- using ::testing::ValuesIn;
- using ValidateIdWithMessage = spvtest::ValidateBase<bool>;
- std::string kOpCapabilitySetupWithoutVector16 = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability Int8
- OpCapability Int16
- OpCapability Int64
- OpCapability Float64
- OpCapability LiteralSampler
- OpCapability Pipes
- OpCapability DeviceEnqueue
- )";
- std::string kOpCapabilitySetup = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability Int8
- OpCapability Int16
- OpCapability Int64
- OpCapability Float64
- OpCapability LiteralSampler
- OpCapability Pipes
- OpCapability DeviceEnqueue
- OpCapability Vector16
- )";
- std::string kOpVariablePtrSetUp = R"(
- OpCapability VariablePointers
- OpExtension "SPV_KHR_variable_pointers"
- )";
- std::string kGLSL450MemoryModel =
- kOpCapabilitySetup + kOpVariablePtrSetUp + R"(
- OpMemoryModel Logical GLSL450
- )";
- std::string kGLSL450MemoryModelWithoutVector16 =
- kOpCapabilitySetupWithoutVector16 + kOpVariablePtrSetUp + R"(
- OpMemoryModel Logical GLSL450
- )";
- std::string kNoKernelGLSL450MemoryModel = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability Int8
- OpCapability Int16
- OpCapability Int64
- OpCapability Float64
- OpMemoryModel Logical GLSL450
- )";
- std::string kOpenCLMemoryModel32 = R"(
- OpCapability Addresses
- OpCapability Linkage
- OpCapability Kernel
- %1 = OpExtInstImport "OpenCL.std"
- OpMemoryModel Physical32 OpenCL
- )";
- std::string kOpenCLMemoryModel64 = R"(
- OpCapability Addresses
- OpCapability Linkage
- OpCapability Kernel
- OpCapability Int64
- %1 = OpExtInstImport "OpenCL.std"
- OpMemoryModel Physical64 OpenCL
- )";
- std::string sampledImageSetup = R"(
- %void = OpTypeVoid
- %typeFuncVoid = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %image_type = OpTypeImage %float 2D 0 0 0 1 Unknown
- %_ptr_UniformConstant_img = OpTypePointer UniformConstant %image_type
- %tex = OpVariable %_ptr_UniformConstant_img UniformConstant
- %sampler_type = OpTypeSampler
- %_ptr_UniformConstant_sam = OpTypePointer UniformConstant %sampler_type
- %s = OpVariable %_ptr_UniformConstant_sam UniformConstant
- %sampled_image_type = OpTypeSampledImage %image_type
- %v2float = OpTypeVector %float 2
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %const_vec_1_1 = OpConstantComposite %v2float %float_1 %float_1
- %const_vec_2_2 = OpConstantComposite %v2float %float_2 %float_2
- %bool_type = OpTypeBool
- %spec_true = OpSpecConstantTrue %bool_type
- %main = OpFunction %void None %typeFuncVoid
- %label_1 = OpLabel
- %image_inst = OpLoad %image_type %tex
- %sampler_inst = OpLoad %sampler_type %s
- )";
- std::string BranchConditionalSetup = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- ; type definitions
- %bool = OpTypeBool
- %uint = OpTypeInt 32 0
- %int = OpTypeInt 32 1
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- ; constants
- %true = OpConstantTrue %bool
- %i0 = OpConstant %int 0
- %i1 = OpConstant %int 1
- %f0 = OpConstant %float 0
- %f1 = OpConstant %float 1
- ; main function header
- %void = OpTypeVoid
- %voidfunc = OpTypeFunction %void
- %main = OpFunction %void None %voidfunc
- %lmain = OpLabel
- )";
- std::string BranchConditionalTail = R"(
- %target_t = OpLabel
- OpNop
- OpBranch %end
- %target_f = OpLabel
- OpNop
- OpBranch %end
- %end = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- // TODO: OpUndef
- TEST_F(ValidateIdWithMessage, OpName) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpName %2 "name"
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer UniformConstant %1
- %3 = OpVariable %2 UniformConstant)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpMemberNameGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberName %2 0 "foo"
- %1 = OpTypeInt 32 0
- %2 = OpTypeStruct %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpMemberNameTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberName %1 0 "foo"
- %1 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpMemberName Type <id> '1[%uint]' is not a struct type."));
- }
- TEST_F(ValidateIdWithMessage, OpMemberNameMemberBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberName %1 1 "foo"
- %2 = OpTypeInt 32 0
- %1 = OpTypeStruct %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpMemberName Member <id> '1[%_struct_1]' index is larger "
- "than Type <id> '1[%_struct_1]'s member count."));
- }
- TEST_F(ValidateIdWithMessage, OpLineGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpString "/path/to/source.file"
- OpLine %1 0 0
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Input %2
- %4 = OpVariable %3 Input)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpLineFileBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- OpLine %1 0 0
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpLine Target <id> '1[%uint]' is not an OpString."));
- }
- TEST_F(ValidateIdWithMessage, OpDecorateGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %2 GLSLShared
- %1 = OpTypeInt 64 0
- %2 = OpTypeStruct %1 %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpDecorateBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 GLSLShared)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("forward referenced IDs have not been defined"));
- }
- TEST_F(ValidateIdWithMessage, OpMemberDecorateGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %2 0 RelaxedPrecision
- %1 = OpTypeInt 32 0
- %2 = OpTypeStruct %1 %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpMemberDecorateBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 RelaxedPrecision
- %1 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpMemberDecorate Structure type <id> '1[%uint]' is "
- "not a struct type."));
- }
- TEST_F(ValidateIdWithMessage, OpMemberDecorateMemberBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 3 RelaxedPrecision
- %int = OpTypeInt 32 0
- %1 = OpTypeStruct %int %int)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Index 3 provided in OpMemberDecorate for struct <id> "
- "1[%_struct_1] is out of bounds. The structure has 2 "
- "members. Largest valid index is 1."));
- }
- TEST_F(ValidateIdWithMessage, OpGroupDecorateGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpDecorationGroup
- OpDecorate %1 RelaxedPrecision
- OpDecorate %1 GLSLShared
- OpGroupDecorate %1 %3 %4
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 42
- %4 = OpConstant %2 23)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpDecorationGroupBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpDecorationGroup
- OpDecorate %1 RelaxedPrecision
- OpDecorate %1 GLSLShared
- OpMemberDecorate %1 0 Constant
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Result id of OpDecorationGroup can only "
- "be targeted by OpName, OpGroupDecorate, "
- "OpDecorate, OpDecorateId, and OpGroupMemberDecorate"));
- }
- TEST_F(ValidateIdWithMessage, OpGroupDecorateDecorationGroupBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpGroupDecorate %1 %2 %3
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 42)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpGroupDecorate Decoration group <id> '1[%1]' is not "
- "a decoration group."));
- }
- TEST_F(ValidateIdWithMessage, OpGroupDecorateTargetBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpDecorationGroup
- OpDecorate %1 RelaxedPrecision
- OpDecorate %1 GLSLShared
- OpGroupDecorate %1 %3
- %2 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("forward referenced IDs have not been defined"));
- }
- TEST_F(ValidateIdWithMessage, OpGroupMemberDecorateDecorationGroupBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpGroupMemberDecorate %1 %2 0
- %2 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpGroupMemberDecorate Decoration group <id> '1[%1]' "
- "is not a decoration group."));
- }
- TEST_F(ValidateIdWithMessage, OpGroupMemberDecorateIdNotStructBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpDecorationGroup
- OpGroupMemberDecorate %1 %2 0
- %2 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpGroupMemberDecorate Structure type <id> '2[%uint]' "
- "is not a struct type."));
- }
- TEST_F(ValidateIdWithMessage, OpGroupMemberDecorateIndexOutOfBoundBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 Offset 0
- %1 = OpDecorationGroup
- OpGroupMemberDecorate %1 %struct 3
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float %float %float
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Index 3 provided in OpGroupMemberDecorate for struct "
- "<id> 2[%_struct_2] is out of bounds. The structure "
- "has 3 members. Largest valid index is 2."));
- }
- // TODO: OpExtInst
- TEST_F(ValidateIdWithMessage, OpEntryPointGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %3 ""
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpEntryPointFunctionBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %1 ""
- %1 = OpTypeVoid)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint Entry Point <id> '1[%void]' is not a "
- "function."));
- }
- TEST_F(ValidateIdWithMessage, OpEntryPointParameterCountBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %1 ""
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2 %2
- %1 = OpFunction %2 None %3
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint Entry Point <id> '1[%1]'s function "
- "parameter count is not zero"));
- }
- TEST_F(ValidateIdWithMessage, OpEntryPointReturnTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %1 ""
- %2 = OpTypeInt 32 0
- %ret = OpConstant %2 0
- %3 = OpTypeFunction %2
- %1 = OpFunction %2 None %3
- %4 = OpLabel
- OpReturnValue %ret
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint Entry Point <id> '1[%1]'s function "
- "return type is not void."));
- }
- TEST_F(ValidateIdWithMessage, OpEntryPointParameterCountBadInVulkan) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %1 ""
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2 %2
- %1 = OpFunction %2 None %3
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-None-04633"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint Entry Point <id> '1[%1]'s function "
- "parameter count is not zero"));
- }
- TEST_F(ValidateIdWithMessage, OpEntryPointReturnTypeBadInVulkan) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %1 ""
- %2 = OpTypeInt 32 0
- %ret = OpConstant %2 0
- %3 = OpTypeFunction %2
- %1 = OpFunction %2 None %3
- %4 = OpLabel
- OpReturnValue %ret
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-None-04633"));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpEntryPoint Entry Point <id> '1[%1]'s function "
- "return type is not void."));
- }
- TEST_F(ValidateIdWithMessage, OpEntryPointInterfaceIsNotVariableTypeBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Geometry
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %ptr_builtin_1
- OpExecutionMode %main InputPoints
- OpExecutionMode %main OutputPoints
- OpMemberDecorate %struct_1 0 BuiltIn InvocationId
- %int = OpTypeInt 32 1
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %struct_1 = OpTypeStruct %int
- %ptr_builtin_1 = OpTypePointer Input %struct_1
- %main = OpFunction %void None %func
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Interfaces passed to OpEntryPoint must be of type "
- "OpTypeVariable. Found OpTypePointer."));
- }
- TEST_F(ValidateIdWithMessage, OpEntryPointInterfaceStorageClassBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Geometry
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %in_1
- OpExecutionMode %main InputPoints
- OpExecutionMode %main OutputPoints
- OpMemberDecorate %struct_1 0 BuiltIn InvocationId
- %int = OpTypeInt 32 1
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %struct_1 = OpTypeStruct %int
- %ptr_builtin_1 = OpTypePointer Uniform %struct_1
- %in_1 = OpVariable %ptr_builtin_1 Uniform
- %main = OpFunction %void None %func
- %5 = 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 2 for Entry Point id 1."));
- }
- TEST_F(ValidateIdWithMessage, OpExecutionModeGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %3 ""
- OpExecutionMode %3 LocalSize 1 1 1
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpExecutionModeEntryPointMissing) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpExecutionMode %3 LocalSize 1 1 1
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpExecutionMode Entry Point <id> '1[%1]' is not the "
- "Entry Point operand of an OpEntryPoint."));
- }
- TEST_F(ValidateIdWithMessage, OpExecutionModeEntryPointBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %3 "" %a
- OpExecutionMode %a LocalSize 1 1 1
- %void = OpTypeVoid
- %ptr = OpTypePointer Input %void
- %a = OpVariable %ptr Input
- %2 = OpTypeFunction %void
- %3 = OpFunction %void None %2
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpExecutionMode Entry Point <id> '2[%2]' is not the "
- "Entry Point operand of an OpEntryPoint."));
- }
- TEST_F(ValidateIdWithMessage, OpTypeVectorFloat) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeVectorInt) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeVector %1 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeVectorUInt) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 64 0
- %2 = OpTypeVector %1 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeVectorBool) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpTypeVector %1 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeVectorComponentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypePointer UniformConstant %1
- %3 = OpTypeVector %2 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpTypeVector Component Type <id> "
- "'2[%_ptr_UniformConstant_float]' is not a scalar type."));
- }
- TEST_F(ValidateIdWithMessage, OpTypeVectorColumnCountLessThanTwoBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Illegal number of components (1) for TypeVector\n %v1float = "
- "OpTypeVector %float 1\n"));
- }
- TEST_F(ValidateIdWithMessage, OpTypeVectorColumnCountGreaterThanFourBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Illegal number of components (5) for TypeVector\n %v5float = "
- "OpTypeVector %float 5\n"));
- }
- TEST_F(ValidateIdWithMessage, OpTypeVectorColumnCountEightWithoutVector16Bad) {
- std::string spirv = kGLSL450MemoryModelWithoutVector16 + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Having 8 components for TypeVector requires the Vector16 "
- "capability\n %v8float = OpTypeVector %float 8\n"));
- }
- TEST_F(ValidateIdWithMessage,
- OpTypeVectorColumnCountSixteenWithoutVector16Bad) {
- std::string spirv = kGLSL450MemoryModelWithoutVector16 + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 16)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Having 16 components for TypeVector requires the Vector16 "
- "capability\n %v16float = OpTypeVector %float 16\n"));
- }
- TEST_F(ValidateIdWithMessage, OpTypeVectorColumnCountOfEightWithVector16Good) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage,
- OpTypeVectorColumnCountOfSixteenWithVector16Good) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 16)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeMatrixGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 2
- %3 = OpTypeMatrix %2 3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeMatrixColumnTypeNonVectorBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeMatrix %1 3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("olumns in a matrix must be of type vector.\n %mat3float = "
- "OpTypeMatrix %float 3\n"));
- }
- TEST_F(ValidateIdWithMessage, OpTypeMatrixVectorTypeNonFloatBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 16 0
- %2 = OpTypeVector %1 2
- %3 = OpTypeMatrix %2 2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Matrix types can only be parameterized with floating-point "
- "types.\n %mat2v2ushort = OpTypeMatrix %v2ushort 2\n"));
- }
- TEST_F(ValidateIdWithMessage, OpTypeMatrixColumnCountLessThanTwoBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 2
- %3 = OpTypeMatrix %2 1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Matrix types can only be parameterized as having only 2, 3, "
- "or 4 columns.\n %mat1v2float = OpTypeMatrix %v2float 1\n"));
- }
- TEST_F(ValidateIdWithMessage, OpTypeMatrixColumnCountGreaterThanFourBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 2
- %3 = OpTypeMatrix %2 8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Matrix types can only be parameterized as having only 2, 3, "
- "or 4 columns.\n %mat8v2float = OpTypeMatrix %v2float 8\n"));
- }
- TEST_F(ValidateIdWithMessage, OpTypeSamplerGood) {
- // In Rev31, OpTypeSampler takes no arguments.
- std::string spirv = kGLSL450MemoryModel + R"(
- %s = OpTypeSampler)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeArrayGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 1
- %3 = OpTypeArray %1 %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeArrayElementTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 1
- %3 = OpTypeArray %2 %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpTypeArray Element Type <id> '2[%uint_1]' is not a "
- "type."));
- }
- // Signed or unsigned.
- enum Signed { kSigned, kUnsigned };
- // Creates an assembly module declaring OpTypeArray with the given length.
- std::string MakeArrayLength(const std::string& len, Signed isSigned, int width,
- int max_int_width = 64,
- bool use_vulkan_memory_model = false) {
- std::ostringstream ss;
- ss << R"(
- OpCapability Shader
- )";
- if (use_vulkan_memory_model) {
- ss << " OpCapability VulkanMemoryModel\n";
- }
- if (width == 16) {
- ss << " OpCapability Int16\n";
- }
- if (max_int_width > 32) {
- ss << "\n OpCapability Int64\n";
- }
- if (use_vulkan_memory_model) {
- ss << " OpExtension \"SPV_KHR_vulkan_memory_model\"\n";
- ss << "OpMemoryModel Logical Vulkan\n";
- } else {
- ss << "OpMemoryModel Logical GLSL450\n";
- }
- ss << "OpEntryPoint GLCompute %main \"main\"\n";
- ss << "OpExecutionMode %main LocalSize 1 1 1\n";
- ss << " %t = OpTypeInt " << width << (isSigned == kSigned ? " 1" : " 0");
- ss << " %l = OpConstant %t " << len;
- ss << " %a = OpTypeArray %t %l";
- ss << " %void = OpTypeVoid \n"
- " %voidfn = OpTypeFunction %void \n"
- " %main = OpFunction %void None %voidfn \n"
- " %entry = OpLabel\n"
- " OpReturn\n"
- " OpFunctionEnd\n";
- return ss.str();
- }
- // Tests OpTypeArray. Parameter is the width (in bits) of the array-length's
- // type.
- class OpTypeArrayLengthTest
- : public spvtest::TextToBinaryTestBase<::testing::TestWithParam<int>> {
- protected:
- OpTypeArrayLengthTest()
- : env_(SPV_ENV_UNIVERSAL_1_0),
- position_(spv_position_t{0, 0, 0}),
- diagnostic_(spvDiagnosticCreate(&position_, "")) {}
- ~OpTypeArrayLengthTest() { spvDiagnosticDestroy(diagnostic_); }
- // Runs spvValidate() on v, printing any errors via spvDiagnosticPrint().
- spv_result_t Val(const SpirvVector& v, const std::string& expected_err = "") {
- spv_const_binary_t cbinary{v.data(), v.size()};
- spvDiagnosticDestroy(diagnostic_);
- diagnostic_ = nullptr;
- const auto status =
- spvValidate(ScopedContext(env_).context, &cbinary, &diagnostic_);
- if (status != SPV_SUCCESS) {
- spvDiagnosticPrint(diagnostic_);
- EXPECT_THAT(std::string(diagnostic_->error),
- testing::ContainsRegex(expected_err));
- }
- return status;
- }
- protected:
- spv_target_env env_;
- private:
- spv_position_t position_; // For creating diagnostic_.
- spv_diagnostic diagnostic_;
- };
- TEST_P(OpTypeArrayLengthTest, LengthPositiveSmall) {
- const int width = GetParam();
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("1", kSigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("1", kUnsigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("2", kSigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("2", kUnsigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("55", kSigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("55", kUnsigned, width))));
- const std::string fpad(width / 4 - 1, 'F');
- EXPECT_EQ(
- SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("0x7" + fpad, kSigned, width))))
- << MakeArrayLength("0x7" + fpad, kSigned, width);
- }
- TEST_P(OpTypeArrayLengthTest, LengthZero) {
- const int width = GetParam();
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("0", kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("0", kUnsigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- }
- TEST_P(OpTypeArrayLengthTest, LengthNegative) {
- const int width = GetParam();
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("-1", kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("-2", kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("-123", kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- const std::string neg_max = "0x8" + std::string(width / 4 - 1, '0');
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength(neg_max, kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- }
- // Returns the string form of an integer of the form 0x80....0 of the
- // given bit width.
- std::string big_num_ending_0(int bit_width) {
- return "0x8" + std::string(bit_width / 4 - 1, '0');
- }
- // Returns the string form of an integer of the form 0x80..001 of the
- // given bit width.
- std::string big_num_ending_1(int bit_width) {
- return "0x8" + std::string(bit_width / 4 - 2, '0') + "1";
- }
- TEST_P(OpTypeArrayLengthTest, LengthPositiveHugeEnding0InVulkan) {
- env_ = SPV_ENV_VULKAN_1_0;
- const int width = GetParam();
- for (int max_int_width : {32, 64}) {
- if (width > max_int_width) {
- // Not valid to even make the OpConstant in this case.
- continue;
- }
- const auto module = CompileSuccessfully(MakeArrayLength(
- big_num_ending_0(width), kUnsigned, width, max_int_width));
- EXPECT_EQ(SPV_SUCCESS, Val(module));
- }
- }
- TEST_P(OpTypeArrayLengthTest, LengthPositiveHugeEnding1InVulkan) {
- env_ = SPV_ENV_VULKAN_1_0;
- const int width = GetParam();
- for (int max_int_width : {32, 64}) {
- if (width > max_int_width) {
- // Not valid to even make the OpConstant in this case.
- continue;
- }
- const auto module = CompileSuccessfully(MakeArrayLength(
- big_num_ending_1(width), kUnsigned, width, max_int_width));
- EXPECT_EQ(SPV_SUCCESS, Val(module));
- }
- }
- // The only valid widths for integers are 8, 16, 32, and 64.
- // Since the Int8 capability requires the Kernel capability, and the Kernel
- // capability prohibits usage of signed integers, we can skip 8-bit integers
- // here since the purpose of these tests is to check the validity of
- // OpTypeArray, not OpTypeInt.
- INSTANTIATE_TEST_SUITE_P(Widths, OpTypeArrayLengthTest,
- ValuesIn(std::vector<int>{16, 32, 64}));
- TEST_F(ValidateIdWithMessage, OpTypeArrayLengthNull) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %i32 = OpTypeInt 32 0
- %len = OpConstantNull %i32
- %ary = OpTypeArray %i32 %len)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "OpTypeArray Length <id> '2[%2]' default value must be at least 1."));
- }
- TEST_F(ValidateIdWithMessage, OpTypeArrayLengthSpecConst) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %i32 = OpTypeInt 32 0
- %len = OpSpecConstant %i32 2
- %ary = OpTypeArray %i32 %len)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeArrayLengthSpecConstOp) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %i32 = OpTypeInt 32 0
- %c1 = OpConstant %i32 1
- %c2 = OpConstant %i32 2
- %len = OpSpecConstantOp %i32 IAdd %c1 %c2
- %ary = OpTypeArray %i32 %len)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeRuntimeArrayGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeRuntimeArray %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeRuntimeArrayBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 0
- %3 = OpTypeRuntimeArray %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpTypeRuntimeArray Element Type <id> '2[%uint_0]' is not a "
- "type."));
- }
- // TODO: Object of this type can only be created with OpVariable using the
- // Unifrom Storage Class
- TEST_F(ValidateIdWithMessage, OpTypeStructGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeFloat 64
- %3 = OpTypePointer Input %1
- %4 = OpTypeStruct %1 %2 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeStructMemberTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeFloat 64
- %3 = OpConstant %2 0.0
- %4 = OpTypeStruct %1 %2 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpTypeStruct Member Type <id> '3[%double_0]' is not "
- "a type."));
- }
- TEST_F(ValidateIdWithMessage, OpTypeStructOpaqueTypeBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- %1 = OpTypeSampler
- %2 = OpTypeStruct %1
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpTypeStruct must not contain an opaque type"));
- }
- TEST_F(ValidateIdWithMessage, OpTypePointerGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Input %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypePointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 0
- %3 = OpTypePointer Input %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpTypePointer Type <id> '2[%uint_0]' is not a "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpTypeFunctionGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpTypeFunctionReturnTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 0
- %3 = OpTypeFunction %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpTypeFunction Return Type <id> '2[%uint_0]' is not "
- "a type."));
- }
- TEST_F(ValidateIdWithMessage, OpTypeFunctionParameterBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 0
- %4 = OpTypeFunction %1 %2 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpTypeFunction Parameter Type <id> '3[%uint_0]' is not a "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpTypeFunctionParameterTypeVoidBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %4 = OpTypeFunction %1 %2 %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpTypeFunction Parameter Type <id> '1[%void]' cannot "
- "be OpTypeVoid."));
- }
- TEST_F(ValidateIdWithMessage, OpTypePipeGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 16
- %3 = OpTypePipe ReadOnly)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantTrueGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantTrueBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpConstantTrue Result Type <id> '1[%void]' is not a boolean "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantFalseGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantFalseBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpConstantFalse %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpConstantFalse Result Type <id> '1[%void]' is not a boolean "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpConstant !1 !0)";
- // The expected failure code is implementation dependent (currently
- // INVALID_BINARY because the binary parser catches these cases) and may
- // change over time, but this must always fail.
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpConstant %1 3.14
- %4 = OpConstantComposite %2 %3 %3 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorWithUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpConstant %1 3.14
- %9 = OpUndef %1
- %4 = OpConstantComposite %2 %3 %3 %3 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpConstant %1 3.14
- %4 = OpConstantComposite %1 %3 %3 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpConstantComposite Result Type <id> '1[%float]' is not a "
- "composite type."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %4 = OpTypeInt 32 0
- %3 = OpConstant %1 3.14
- %5 = OpConstant %4 42 ; bad type for constant value
- %6 = OpConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpConstantComposite Constituent <id> '5[%uint_42]'s type "
- "does not match Result Type <id> '2[%v4float]'s vector "
- "element type."));
- }
- TEST_F(ValidateIdWithMessage,
- OpConstantCompositeVectorConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %4 = OpTypeInt 32 0
- %3 = OpConstant %1 3.14
- %5 = OpUndef %4 ; bad type for undef value
- %6 = OpConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpConstantComposite Constituent <id> '5[%5]'s type does not "
- "match Result Type <id> '2[%v4float]'s vector element type."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpConstantComposite %2 %4 %5 %5 %5
- %7 = OpConstantComposite %2 %5 %4 %5 %5
- %8 = OpConstantComposite %2 %5 %5 %4 %5
- %9 = OpConstantComposite %2 %5 %5 %5 %4
- %10 = OpConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpConstantComposite %2 %4 %5 %5 %5
- %7 = OpConstantComposite %2 %5 %4 %5 %5
- %8 = OpConstantComposite %2 %5 %5 %4 %5
- %9 = OpUndef %2
- %10 = OpConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %11 = OpTypeVector %1 3
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpConstantComposite %2 %4 %5 %5 %5
- %7 = OpConstantComposite %2 %5 %4 %5 %5
- %8 = OpConstantComposite %2 %5 %5 %4 %5
- %9 = OpConstantComposite %11 %5 %5 %5
- %10 = OpConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpConstantComposite Constituent <id> '10[%10]' vector "
- "component count does not match Result Type <id> "
- "'4[%mat4v4float]'s vector component count."));
- }
- TEST_F(ValidateIdWithMessage,
- OpConstantCompositeMatrixConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %11 = OpTypeVector %1 3
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpConstantComposite %2 %4 %5 %5 %5
- %7 = OpConstantComposite %2 %5 %4 %5 %5
- %8 = OpConstantComposite %2 %5 %5 %4 %5
- %9 = OpUndef %11
- %10 = OpConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpConstantComposite Constituent <id> '10[%10]' vector "
- "component count does not match Result Type <id> "
- "'4[%mat4v4float]'s vector component count."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpConstantComposite %3 %2 %2 %2 %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayWithUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %9 = OpUndef %1
- %3 = OpTypeArray %1 %2
- %4 = OpConstantComposite %3 %2 %2 %2 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpConstantComposite %3 %2 %2 %2 %1)"; // Uses a type as operand
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 1[%uint] cannot be a "
- "type"));
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstConstituentBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpTypePointer Uniform %1
- %5 = OpVariable %4 Uniform
- %6 = OpConstantComposite %3 %2 %2 %2 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpConstantComposite Constituent <id> '5[%5]' is not a "
- "constant or undef."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %5 = OpTypeFloat 32
- %6 = OpConstant %5 3.14 ; bad type for const value
- %4 = OpConstantComposite %3 %2 %2 %2 %6)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpConstantComposite Constituent <id> "
- "'5[%float_3_1400001]'s type does not match Result "
- "Type <id> '3[%_arr_uint_uint_4]'s array element "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %5 = OpTypeFloat 32
- %6 = OpUndef %5 ; bad type for undef
- %4 = OpConstantComposite %3 %2 %2 %2 %6)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpConstantComposite Constituent <id> "
- "'5[%5]'s type does not match Result "
- "Type <id> '3[%_arr_uint_uint_4]'s array element "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeStructGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpConstant %2 4300000000
- %6 = OpConstantComposite %3 %4 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeStructUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpUndef %2
- %6 = OpConstantComposite %3 %4 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeStructMemberTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpConstant %2 4300000000
- %6 = OpConstantComposite %3 %4 %5 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpConstantComposite Constituent <id> "
- "'5[%ulong_4300000000]' type does not match the "
- "Result Type <id> '3[%_struct_3]'s member type."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantCompositeStructMemberUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpUndef %2
- %6 = OpConstantComposite %3 %4 %5 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpConstantComposite Constituent <id> '5[%5]' type "
- "does not match the Result Type <id> '3[%_struct_3]'s "
- "member type."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantSamplerGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %float = OpTypeFloat 32
- %samplerType = OpTypeSampler
- %3 = OpConstantSampler %samplerType ClampToEdge 0 Nearest)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantSamplerResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpConstantSampler %1 Clamp 0 Nearest)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "OpConstantSampler Result Type <id> '1[%float]' is not a sampler "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantNullGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpConstantNull %1
- %3 = OpTypeInt 32 0
- %4 = OpConstantNull %3
- %5 = OpTypeFloat 32
- %6 = OpConstantNull %5
- %7 = OpTypePointer UniformConstant %3
- %8 = OpConstantNull %7
- %9 = OpTypeEvent
- %10 = OpConstantNull %9
- %11 = OpTypeDeviceEvent
- %12 = OpConstantNull %11
- %13 = OpTypeReserveId
- %14 = OpConstantNull %13
- %15 = OpTypeQueue
- %16 = OpConstantNull %15
- %17 = OpTypeVector %5 2
- %18 = OpConstantNull %17
- %19 = OpTypeMatrix %17 2
- %20 = OpConstantNull %19
- %25 = OpConstant %3 8
- %21 = OpTypeArray %3 %25
- %22 = OpConstantNull %21
- %23 = OpTypeStruct %3 %5 %1
- %24 = OpConstantNull %23
- %26 = OpTypeArray %17 %25
- %27 = OpConstantNull %26
- %28 = OpTypeStruct %7 %26 %26 %1
- %29 = OpConstantNull %28
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpConstantNullBasicBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpConstantNull %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpConstantNull Result Type <id> '1[%void]' cannot have a null "
- "value."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantNullArrayBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %2 = OpTypeInt 32 0
- %3 = OpTypeSampler
- %4 = OpConstant %2 4
- %5 = OpTypeArray %3 %4
- %6 = OpConstantNull %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "OpConstantNull Result Type <id> '4[%_arr_2_uint_4]' cannot have a "
- "null value."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantNullStructBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %2 = OpTypeSampler
- %3 = OpTypeStruct %2 %2
- %4 = OpConstantNull %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpConstantNull Result Type <id> '2[%_struct_2]' "
- "cannot have a null value."));
- }
- TEST_F(ValidateIdWithMessage, OpConstantNullRuntimeArrayBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %bool = OpTypeBool
- %array = OpTypeRuntimeArray %bool
- %null = OpConstantNull %array)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "OpConstantNull Result Type <id> '2[%_runtimearr_bool]' cannot have "
- "a null value."));
- }
- TEST_F(ValidateIdWithMessage, OpSpecConstantTrueGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpSpecConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpSpecConstantTrueBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpSpecConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantTrue Result Type <id> '1[%void]' is not "
- "a boolean type"));
- }
- TEST_F(ValidateIdWithMessage, OpSpecConstantFalseGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpSpecConstantFalse %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpSpecConstantFalseBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpSpecConstantFalse %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpSpecConstantFalse Result Type <id> '1[%void]' is not "
- "a boolean type"));
- }
- TEST_F(ValidateIdWithMessage, OpSpecConstantGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpSpecConstant %1 42)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpSpecConstantBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpSpecConstant !1 !4)";
- // The expected failure code is implementation dependent (currently
- // INVALID_BINARY because the binary parser catches these cases) and may
- // change over time, but this must always fail.
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Type Id 1 is not a scalar numeric type"));
- }
- // Valid: SpecConstantComposite specializes to a vector.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpSpecConstant %1 3.14
- %4 = OpConstant %1 3.14
- %5 = OpSpecConstantComposite %2 %3 %3 %4 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Valid: Vector of floats and Undefs.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorWithUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpSpecConstant %1 3.14
- %5 = OpConstant %1 3.14
- %9 = OpUndef %1
- %4 = OpSpecConstantComposite %2 %3 %5 %3 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: result type is float.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpSpecConstant %1 3.14
- %4 = OpSpecConstantComposite %1 %3 %3 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a composite type"));
- }
- // Invalid: Vector contains a mix of Int and Float.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %4 = OpTypeInt 32 0
- %3 = OpSpecConstant %1 3.14
- %5 = OpConstant %4 42 ; bad type for constant value
- %6 = OpSpecConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> "
- "'5[%uint_42]'s type does not match Result Type <id> "
- "'2[%v4float]'s vector element type."));
- }
- // Invalid: Constituent is not a constant
- TEST_F(ValidateIdWithMessage,
- OpSpecConstantCompositeVectorConstituentNotConstantBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeInt 32 0
- %4 = OpSpecConstant %1 3.14
- %5 = OpTypePointer Uniform %1
- %6 = OpVariable %5 Uniform
- %7 = OpSpecConstantComposite %2 %6 %4 %4 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '6[%6]' is "
- "not a constant or undef."));
- }
- // Invalid: Vector contains a mix of Undef-int and Float.
- TEST_F(ValidateIdWithMessage,
- OpSpecConstantCompositeVectorConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %4 = OpTypeInt 32 0
- %3 = OpSpecConstant %1 3.14
- %5 = OpUndef %4 ; bad type for undef value
- %6 = OpSpecConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]'s "
- "type does not match Result Type <id> '2[%v4float]'s "
- "vector element type."));
- }
- // Invalid: Vector expects 3 components, but 4 specified.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorNumComponentsBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 3
- %3 = OpConstant %1 3.14
- %5 = OpSpecConstant %1 4.0
- %6 = OpSpecConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> count does "
- "not match Result Type <id> '2[%v3float]'s vector "
- "component count."));
- }
- // Valid: 4x4 matrix of floats
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpSpecConstant %1 0.0
- %6 = OpSpecConstantComposite %2 %4 %5 %5 %5
- %7 = OpSpecConstantComposite %2 %5 %4 %5 %5
- %8 = OpSpecConstantComposite %2 %5 %5 %4 %5
- %9 = OpSpecConstantComposite %2 %5 %5 %5 %4
- %10 = OpSpecConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Valid: Matrix in which one column is Undef
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpSpecConstant %1 0.0
- %6 = OpSpecConstantComposite %2 %4 %5 %5 %5
- %7 = OpSpecConstantComposite %2 %5 %4 %5 %5
- %8 = OpSpecConstantComposite %2 %5 %5 %4 %5
- %9 = OpUndef %2
- %10 = OpSpecConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Matrix in which the sizes of column vectors are not equal.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeVector %1 3
- %4 = OpTypeMatrix %2 4
- %5 = OpSpecConstant %1 1.0
- %6 = OpConstant %1 0.0
- %7 = OpSpecConstantComposite %2 %5 %6 %6 %6
- %8 = OpSpecConstantComposite %2 %6 %5 %6 %6
- %9 = OpSpecConstantComposite %2 %6 %6 %5 %6
- %10 = OpSpecConstantComposite %3 %6 %6 %6
- %11 = OpSpecConstantComposite %4 %7 %8 %9 %10)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '10[%10]' "
- "vector component count does not match Result Type "
- "<id> '4[%mat4v4float]'s vector component count."));
- }
- // Invalid: Matrix type expects 4 columns but only 3 specified.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixNumColsBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpSpecConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpSpecConstantComposite %2 %4 %5 %5 %5
- %7 = OpSpecConstantComposite %2 %5 %4 %5 %5
- %8 = OpSpecConstantComposite %2 %5 %5 %4 %5
- %10 = OpSpecConstantComposite %3 %6 %7 %8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> count does "
- "not match Result Type <id> '3[%mat4v4float]'s matrix column "
- "count."));
- }
- // Invalid: Composite contains a non-const/undef component
- TEST_F(ValidateIdWithMessage,
- OpSpecConstantCompositeMatrixConstituentNotConstBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpConstant %1 0.0
- %3 = OpTypeVector %1 4
- %4 = OpTypeMatrix %3 4
- %5 = OpSpecConstantComposite %3 %2 %2 %2 %2
- %6 = OpTypePointer Uniform %1
- %7 = OpVariable %6 Uniform
- %8 = OpSpecConstantComposite %4 %5 %5 %5 %7)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '7[%7]' is "
- "not a constant or undef."));
- }
- // Invalid: Composite contains a column that is *not* a vector (it's an array)
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixColTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeInt 32 0
- %3 = OpSpecConstant %2 4
- %4 = OpConstant %1 0.0
- %5 = OpTypeVector %1 4
- %6 = OpTypeArray %2 %3
- %7 = OpTypeMatrix %5 4
- %8 = OpSpecConstantComposite %6 %3 %3 %3 %3
- %9 = OpSpecConstantComposite %5 %4 %4 %4 %4
- %10 = OpSpecConstantComposite %7 %9 %9 %9 %8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '8[%8]' type "
- "does not match Result Type <id> '7[%mat4v4float]'s "
- "matrix column type."));
- }
- // Invalid: Matrix with an Undef column of the wrong size.
- TEST_F(ValidateIdWithMessage,
- OpSpecConstantCompositeMatrixConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeVector %1 3
- %4 = OpTypeMatrix %2 4
- %5 = OpSpecConstant %1 1.0
- %6 = OpSpecConstant %1 0.0
- %7 = OpSpecConstantComposite %2 %5 %6 %6 %6
- %8 = OpSpecConstantComposite %2 %6 %5 %6 %6
- %9 = OpSpecConstantComposite %2 %6 %6 %5 %6
- %10 = OpUndef %3
- %11 = OpSpecConstantComposite %4 %7 %8 %9 %10)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '10[%10]' "
- "vector component count does not match Result Type "
- "<id> '4[%mat4v4float]'s vector component count."));
- }
- // Invalid: Matrix in which some columns are Int and some are Float.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixColumnTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeFloat 32
- %3 = OpTypeVector %1 2
- %4 = OpTypeVector %2 2
- %5 = OpTypeMatrix %4 2
- %6 = OpSpecConstant %1 42
- %7 = OpConstant %2 3.14
- %8 = OpSpecConstantComposite %3 %6 %6
- %9 = OpSpecConstantComposite %4 %7 %7
- %10 = OpSpecConstantComposite %5 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '8[%8]' "
- "component type does not match Result Type <id> "
- "'5[%mat2v2float]'s matrix column component type."));
- }
- // Valid: Array of integers
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpSpecConstant %1 4
- %5 = OpConstant %1 5
- %3 = OpTypeArray %1 %2
- %6 = OpTypeArray %1 %5
- %4 = OpSpecConstantComposite %3 %2 %2 %2 %2
- %7 = OpSpecConstantComposite %3 %5 %5 %5 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Expecting an array of 4 components, but 3 specified.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayNumComponentsBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpSpecConstantComposite %3 %2 %2 %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent count does not "
- "match Result Type <id> '3[%_arr_uint_uint_4]'s array "
- "length."));
- }
- // Valid: Array of Integers and Undef-int
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayWithUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpSpecConstant %1 4
- %9 = OpUndef %1
- %3 = OpTypeArray %1 %2
- %4 = OpSpecConstantComposite %3 %2 %2 %2 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Array uses a type as operand.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayConstConstituentBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpTypePointer Uniform %1
- %5 = OpVariable %4 Uniform
- %6 = OpSpecConstantComposite %3 %2 %2 %2 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]' is "
- "not a constant or undef."));
- }
- // Invalid: Array has a mix of Int and Float components.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpTypeFloat 32
- %5 = OpSpecConstant %4 3.14 ; bad type for const value
- %6 = OpSpecConstantComposite %3 %2 %2 %2 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]'s "
- "type does not match Result Type <id> "
- "'3[%_arr_uint_uint_4]'s array element type."));
- }
- // Invalid: Array has a mix of Int and Undef-float.
- TEST_F(ValidateIdWithMessage,
- OpSpecConstantCompositeArrayConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpSpecConstant %1 4
- %3 = OpTypeArray %1 %2
- %5 = OpTypeFloat 32
- %6 = OpUndef %5 ; bad type for undef
- %4 = OpSpecConstantComposite %3 %2 %2 %2 %6)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]'s "
- "type does not match Result Type <id> "
- "'3[%_arr_uint_2]'s array element type."));
- }
- // Valid: Struct of {Int32,Int32,Int64}.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpSpecConstant %2 4300000000
- %6 = OpSpecConstantComposite %3 %4 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: missing one int32 struct member.
- TEST_F(ValidateIdWithMessage,
- OpSpecConstantCompositeStructMissingComponentBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %3 = OpTypeStruct %1 %1 %1
- %4 = OpConstant %1 42
- %5 = OpSpecConstant %1 430
- %6 = OpSpecConstantComposite %3 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> "
- "'2[%_struct_2]' count does not match Result Type "
- "<id> '2[%_struct_2]'s struct member count."));
- }
- // Valid: Struct uses Undef-int64.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpSpecConstant %1 42
- %5 = OpUndef %2
- %6 = OpSpecConstantComposite %3 %4 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Composite contains non-const/undef component.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructNonConstBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpSpecConstant %1 42
- %5 = OpUndef %2
- %6 = OpTypePointer Uniform %1
- %7 = OpVariable %6 Uniform
- %8 = OpSpecConstantComposite %3 %4 %7 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '7[%7]' is "
- "not a constant or undef."));
- }
- // Invalid: Struct component type does not match expected specialization type.
- // Second component was expected to be Int32, but got Int64.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructMemberTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpSpecConstant %2 4300000000
- %6 = OpSpecConstantComposite %3 %4 %5 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]' type "
- "does not match the Result Type <id> '3[%_struct_3]'s "
- "member type."));
- }
- // Invalid: Undef-int64 used when Int32 was expected.
- TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructMemberUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpSpecConstant %1 42
- %5 = OpUndef %2
- %6 = OpSpecConstantComposite %3 %4 %5 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]' type "
- "does not match the Result Type <id> '3[%_struct_3]'s "
- "member type."));
- }
- // TODO: OpSpecConstantOp
- TEST_F(ValidateIdWithMessage, OpVariableGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Input %1
- %3 = OpVariable %2 Input)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVariableInitializerConstantGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Input %1
- %3 = OpConstant %1 42
- %4 = OpVariable %2 Input %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVariableInitializerGlobalVariableGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Uniform %1
- %3 = OpVariable %2 Uniform
- %4 = OpTypePointer Private %2 ; pointer to pointer
- %5 = OpVariable %4 Private %3
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // TODO: Positive test OpVariable with OpConstantNull of OpTypePointer
- TEST_F(ValidateIdWithMessage, OpVariableResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpVariable %1 Input)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpVariable Result Type <id> '1[%uint]' is not a pointer "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpVariableInitializerIsTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Input %1
- %3 = OpVariable %2 Input %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 2[%_ptr_Input_uint] "
- "cannot be a type"));
- }
- TEST_F(ValidateIdWithMessage, OpVariableInitializerIsFunctionVarBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ptrint = OpTypePointer Function %int
- %ptrptrint = OpTypePointer Function %ptrint
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %var = OpVariable %ptrint Function
- %varinit = OpVariable %ptrptrint Function %var ; Can't initialize function variable.
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpVariable Initializer <id> '8[%8]' is not a constant "
- "or module-scope variable"));
- }
- TEST_F(ValidateIdWithMessage, OpVariableInitializerIsModuleVarGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ptrint = OpTypePointer Uniform %int
- %mvar = OpVariable %ptrint Uniform
- %ptrptrint = OpTypePointer Function %ptrint
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %goodvar = OpVariable %ptrptrint Function %mvar ; This is ok
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVariableContainsBoolBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %bool = OpTypeBool
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %bool %int
- %_ptr_Uniform_block = OpTypePointer Uniform %block
- %var = OpVariable %_ptr_Uniform_block Uniform
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %block %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("If OpTypeBool is stored in conjunction with OpVariable"
- ", it can only be used with non-externally visible "
- "shader Storage Classes: Workgroup, CrossWorkgroup, "
- "Private, and Function"));
- }
- TEST_F(ValidateIdWithMessage, OpVariableContainsBoolPointerGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %bool = OpTypeBool
- %boolptr = OpTypePointer Uniform %bool
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %boolptr %int
- %_ptr_Uniform_block = OpTypePointer Uniform %block
- %var = OpVariable %_ptr_Uniform_block Uniform
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %block %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVariableContainsBuiltinBoolGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %input 0 BuiltIn FrontFacing
- %bool = OpTypeBool
- %input = OpTypeStruct %bool
- %_ptr_input = OpTypePointer Input %input
- %var = OpVariable %_ptr_input Input
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %input %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVariableContainsRayPayloadBoolGood) {
- std::string spirv = R"(
- OpCapability RayTracingNV
- OpCapability Shader
- OpCapability Linkage
- OpExtension "SPV_NV_ray_tracing"
- OpMemoryModel Logical GLSL450
- %bool = OpTypeBool
- %PerRayData = OpTypeStruct %bool
- %_ptr_PerRayData = OpTypePointer RayPayloadNV %PerRayData
- %var = OpVariable %_ptr_PerRayData RayPayloadNV
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %PerRayData %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVariablePointerNoVariablePointersBad) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
- %voidfn = OpTypeFunction %void
- %func = OpFunction %void None %voidfn
- %entry = OpLabel
- %var = OpVariable %_ptr_function_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "In Logical addressing, variables may not allocate a pointer type"));
- }
- TEST_F(ValidateIdWithMessage,
- OpVariablePointerNoVariablePointersRelaxedLogicalGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
- %voidfn = OpTypeFunction %void
- %func = OpFunction %void None %voidfn
- %entry = OpLabel
- %var = OpVariable %_ptr_function_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- auto options = getValidatorOptions();
- options->relax_logical_pointer = true;
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpFunctionWithNonMemoryObject) {
- // DXC generates code that looks like when given something like:
- // T t;
- // t.s.fn_1();
- // This needs to be accepted before legalization takes place, so we
- // will include it with the relaxed logical pointer.
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpSource HLSL 600
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %_struct_5 = OpTypeStruct
- %_struct_6 = OpTypeStruct %_struct_5
- %_ptr_Function__struct_6 = OpTypePointer Function %_struct_6
- %_ptr_Function__struct_5 = OpTypePointer Function %_struct_5
- %23 = OpTypeFunction %void %_ptr_Function__struct_5
- %1 = OpFunction %void None %9
- %10 = OpLabel
- %11 = OpVariable %_ptr_Function__struct_6 Function
- %20 = OpAccessChain %_ptr_Function__struct_5 %11 %int_0
- %21 = OpFunctionCall %void %12 %20
- OpReturn
- OpFunctionEnd
- %12 = OpFunction %void None %23
- %13 = OpFunctionParameter %_ptr_Function__struct_5
- %14 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- auto options = getValidatorOptions();
- options->relax_logical_pointer = true;
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage,
- OpVariablePointerVariablePointersStorageBufferGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VariablePointersStorageBuffer
- OpExtension "SPV_KHR_variable_pointers"
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
- %voidfn = OpTypeFunction %void
- %func = OpFunction %void None %voidfn
- %entry = OpLabel
- %var = OpVariable %_ptr_function_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVariablePointerVariablePointersGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VariablePointers
- OpExtension "SPV_KHR_variable_pointers"
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
- %voidfn = OpTypeFunction %void
- %func = OpFunction %void None %voidfn
- %entry = OpLabel
- %var = OpVariable %_ptr_function_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVariablePointerVariablePointersBad) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability VariablePointers
- OpExtension "SPV_KHR_variable_pointers"
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_uniform_ptr = OpTypePointer Uniform %_ptr_workgroup_int
- %var = OpVariable %_ptr_uniform_ptr Uniform
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("In Logical addressing with variable pointers, "
- "variables that allocate pointers must be in Function "
- "or Private storage classes"));
- }
- TEST_F(ValidateIdWithMessage, OpLoadGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %1
- %5 = OpVariable %3 UniformConstant
- %6 = OpFunction %1 None %4
- %7 = OpLabel
- %8 = OpLoad %2 %5
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // TODO: Add tests that exercise VariablePointersStorageBuffer instead of
- // VariablePointers.
- void createVariablePointerSpirvProgram(std::ostringstream* spirv,
- std::string result_strategy,
- bool use_varptr_cap,
- bool add_helper_function) {
- *spirv << "OpCapability Shader ";
- if (use_varptr_cap) {
- *spirv << "OpCapability VariablePointers ";
- *spirv << "OpExtension \"SPV_KHR_variable_pointers\" ";
- }
- *spirv << "OpExtension \"SPV_KHR_storage_buffer_storage_class\" ";
- *spirv << R"(
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- %void = OpTypeVoid
- %voidf = OpTypeFunction %void
- %bool = OpTypeBool
- %i32 = OpTypeInt 32 1
- %f32 = OpTypeFloat 32
- %f32ptr = OpTypePointer StorageBuffer %f32
- %i = OpConstant %i32 1
- %zero = OpConstant %i32 0
- %float_1 = OpConstant %f32 1.0
- %ptr1 = OpVariable %f32ptr StorageBuffer
- %ptr2 = OpVariable %f32ptr StorageBuffer
- )";
- if (add_helper_function) {
- *spirv << R"(
- ; ////////////////////////////////////////////////////////////
- ;;;; Function that returns a pointer
- ; ////////////////////////////////////////////////////////////
- %selector_func_type = OpTypeFunction %f32ptr %bool %f32ptr %f32ptr
- %choose_input_func = OpFunction %f32ptr None %selector_func_type
- %is_neg_param = OpFunctionParameter %bool
- %first_ptr_param = OpFunctionParameter %f32ptr
- %second_ptr_param = OpFunctionParameter %f32ptr
- %selector_func_begin = OpLabel
- %result_ptr = OpSelect %f32ptr %is_neg_param %first_ptr_param %second_ptr_param
- OpReturnValue %result_ptr
- OpFunctionEnd
- )";
- }
- *spirv << R"(
- %main = OpFunction %void None %voidf
- %label = OpLabel
- )";
- *spirv << result_strategy;
- *spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- }
- // With the VariablePointer Capability, OpLoad should allow loading a
- // VaiablePointer. In this test the variable pointer is obtained by an OpSelect
- TEST_F(ValidateIdWithMessage, OpLoadVarPtrOpSelectGood) {
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
- %result = OpLoad %f32 %varptr
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- true /* Add VariablePointers Capability? */,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Without the VariablePointers Capability, OpLoad will not allow loading
- // through a variable pointer.
- // Disabled since using OpSelect with pointers without VariablePointers will
- // fail LogicalsPass.
- TEST_F(ValidateIdWithMessage, DISABLED_OpLoadVarPtrOpSelectBad) {
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
- %result = OpLoad %f32 %varptr
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- false /* Add VariablePointers Capability?*/,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a logical pointer."));
- }
- // With the VariablePointer Capability, OpLoad should allow loading a
- // VaiablePointer. In this test the variable pointer is obtained by an OpPhi
- TEST_F(ValidateIdWithMessage, OpLoadVarPtrOpPhiGood) {
- std::string result_strategy = R"(
- %is_neg = OpSLessThan %bool %i %zero
- OpSelectionMerge %end_label None
- OpBranchConditional %is_neg %take_ptr_1 %take_ptr_2
- %take_ptr_1 = OpLabel
- OpBranch %end_label
- %take_ptr_2 = OpLabel
- OpBranch %end_label
- %end_label = OpLabel
- %varptr = OpPhi %f32ptr %ptr1 %take_ptr_1 %ptr2 %take_ptr_2
- %result = OpLoad %f32 %varptr
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- true /* Add VariablePointers Capability?*/,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Without the VariablePointers Capability, OpPhi can have a pointer result
- // type.
- TEST_F(ValidateIdWithMessage, OpPhiBad) {
- std::string result_strategy = R"(
- %is_neg = OpSLessThan %bool %i %zero
- OpSelectionMerge %end_label None
- OpBranchConditional %is_neg %take_ptr_1 %take_ptr_2
- %take_ptr_1 = OpLabel
- OpBranch %end_label
- %take_ptr_2 = OpLabel
- OpBranch %end_label
- %end_label = OpLabel
- %varptr = OpPhi %f32ptr %ptr1 %take_ptr_1 %ptr2 %take_ptr_2
- %result = OpLoad %f32 %varptr
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- false /* Add VariablePointers Capability?*/,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Using pointers with OpPhi requires capability "
- "VariablePointers or VariablePointersStorageBuffer"));
- }
- // With the VariablePointer Capability, OpLoad should allow loading through a
- // VaiablePointer. In this test the variable pointer is obtained from an
- // OpFunctionCall (return value from a function)
- TEST_F(ValidateIdWithMessage, OpLoadVarPtrOpFunctionCallGood) {
- std::ostringstream spirv;
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpFunctionCall %f32ptr %choose_input_func %isneg %ptr1 %ptr2
- %result = OpLoad %f32 %varptr
- )";
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- true /* Add VariablePointers Capability?*/,
- true /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpLoadResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %1
- %5 = OpVariable %3 UniformConstant
- %6 = OpFunction %1 None %4
- %7 = OpLabel
- %8 = OpLoad %3 %5
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpLoad Result Type <id> "
- "'3[%_ptr_UniformConstant_uint]' does not match "
- "Pointer <id> '5[%5]'s type."));
- }
- TEST_F(ValidateIdWithMessage, OpLoadPointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %1
- %5 = OpFunction %1 None %4
- %6 = OpLabel
- %7 = OpLoad %2 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- // Prove that SSA checks trigger for a bad Id value.
- // The next test case show the not-a-logical-pointer case.
- EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 8[%8] has not been "
- "defined"));
- }
- // Disabled as bitcasting type to object is now not valid.
- TEST_F(ValidateIdWithMessage, DISABLED_OpLoadLogicalPointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFloat 32
- %4 = OpTypePointer UniformConstant %2
- %5 = OpTypePointer UniformConstant %3
- %6 = OpTypeFunction %1
- %7 = OpFunction %1 None %6
- %8 = OpLabel
- %9 = OpBitcast %5 %4 ; Not valid in logical addressing
- %10 = OpLoad %3 %9 ; Should trigger message
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- // Once we start checking bitcasts, we might catch that
- // as the error first, instead of catching it here.
- // I don't know if it's possible to generate a bad case
- // if/when the validator is complete.
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpLoad Pointer <id> '9' is not a logical pointer."));
- }
- TEST_F(ValidateIdWithMessage, OpStoreGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- OpStore %6 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpStorePointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42
- %6 = OpVariable %3 UniformConstant
- %7 = OpConstant %2 0
- %8 = OpFunction %1 None %4
- %9 = OpLabel
- OpStore %7 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpStore Pointer <id> '7[%uint_0]' is not a logical "
- "pointer."));
- }
- // Disabled as bitcasting type to object is now not valid.
- TEST_F(ValidateIdWithMessage, DISABLED_OpStoreLogicalPointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFloat 32
- %4 = OpTypePointer UniformConstant %2
- %5 = OpTypePointer UniformConstant %3
- %6 = OpTypeFunction %1
- %7 = OpConstantNull %5
- %8 = OpFunction %1 None %6
- %9 = OpLabel
- %10 = OpBitcast %5 %4 ; Not valid in logical addressing
- %11 = OpStore %10 %7 ; Should trigger message
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpStore Pointer <id> '10' is not a logical pointer."));
- }
- // Without the VariablePointer Capability, OpStore should may not store
- // through a variable pointer.
- // Disabled since using OpSelect with pointers without VariablePointers will
- // fail LogicalsPass.
- TEST_F(ValidateIdWithMessage, DISABLED_OpStoreVarPtrBad) {
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
- OpStore %varptr %float_1
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(
- &spirv, result_strategy, false /* Add VariablePointers Capability? */,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a logical pointer."));
- }
- // With the VariablePointer Capability, OpStore should allow storing through a
- // variable pointer.
- TEST_F(ValidateIdWithMessage, OpStoreVarPtrGood) {
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
- OpStore %varptr %float_1
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- true /* Add VariablePointers Capability? */,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpStoreObjectGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- %9 = OpFunctionCall %1 %10
- OpStore %6 %9
- OpReturn
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpStore Object <id> '9[%9]'s type is void."));
- }
- TEST_F(ValidateIdWithMessage, OpStoreTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %9 = OpTypeFloat 32
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %9 3.14
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- OpStore %6 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpStore Pointer <id> '7[%7]'s type does not match "
- "Object <id> '6[%float_3_1400001]'s type."));
- }
- // The next series of test check test a relaxation of the rules for stores to
- // structs. The first test checks that we get a failure when the option is not
- // set to relax the rule.
- // TODO: Add tests for layout compatible arrays and matricies when the validator
- // relaxes the rules for them as well. Also need test to check for layout
- // decorations specific to those types.
- TEST_F(ValidateIdWithMessage, OpStoreTypeBadStruct) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 4
- %3 = OpTypeVoid
- %4 = OpTypeFloat 32
- %1 = OpTypeStruct %4 %4
- %5 = OpTypePointer Uniform %1
- %2 = OpTypeStruct %4 %4
- %6 = OpTypeFunction %3
- %7 = OpConstant %4 3.14
- %8 = OpVariable %5 Uniform
- %9 = OpFunction %3 None %6
- %10 = OpLabel
- %11 = OpCompositeConstruct %2 %7 %7
- OpStore %8 %11
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpStore Pointer <id> '8[%8]'s type does not match "
- "Object <id> '11[%11]'s type."));
- }
- // Same code as the last test. The difference is that we relax the rule.
- // Because the structs %3 and %5 are defined the same way.
- TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedStruct) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 4
- %3 = OpTypeVoid
- %4 = OpTypeFloat 32
- %1 = OpTypeStruct %4 %4
- %5 = OpTypePointer Uniform %1
- %2 = OpTypeStruct %4 %4
- %6 = OpTypeFunction %3
- %7 = OpConstant %4 3.14
- %8 = OpVariable %5 Uniform
- %9 = OpFunction %3 None %6
- %10 = OpLabel
- %11 = OpCompositeConstruct %2 %7 %7
- OpStore %8 %11
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Same code as the last test excect for an extra decoration on one of the
- // members. With the relaxed rules, the code is still valid.
- TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedStructWithExtraDecoration) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %1 0 RelaxedPrecision
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 4
- %3 = OpTypeVoid
- %4 = OpTypeFloat 32
- %1 = OpTypeStruct %4 %4
- %5 = OpTypePointer Uniform %1
- %2 = OpTypeStruct %4 %4
- %6 = OpTypeFunction %3
- %7 = OpConstant %4 3.14
- %8 = OpVariable %5 Uniform
- %9 = OpFunction %3 None %6
- %10 = OpLabel
- %11 = OpCompositeConstruct %2 %7 %7
- OpStore %8 %11
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // This test check that we recursively traverse the struct to check if they are
- // interchangable.
- TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedNestedStruct) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 8
- OpMemberDecorate %3 0 Offset 0
- OpMemberDecorate %3 1 Offset 4
- OpMemberDecorate %4 0 Offset 0
- OpMemberDecorate %4 1 Offset 8
- %5 = OpTypeVoid
- %6 = OpTypeInt 32 0
- %7 = OpTypeFloat 32
- %1 = OpTypeStruct %7 %6
- %2 = OpTypeStruct %1 %1
- %8 = OpTypePointer Uniform %2
- %3 = OpTypeStruct %7 %6
- %4 = OpTypeStruct %3 %3
- %9 = OpTypeFunction %5
- %10 = OpConstant %6 7
- %11 = OpConstant %7 3.14
- %12 = OpConstantComposite %3 %11 %10
- %13 = OpVariable %8 Uniform
- %14 = OpFunction %5 None %9
- %15 = OpLabel
- %16 = OpCompositeConstruct %4 %12 %12
- OpStore %13 %16
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // This test check that the even with the relaxed rules an error is identified
- // if the members of the struct are in a different order.
- TEST_F(ValidateIdWithMessage, OpStoreTypeBadRelaxedStruct1) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 8
- OpMemberDecorate %3 0 Offset 0
- OpMemberDecorate %3 1 Offset 4
- OpMemberDecorate %4 0 Offset 0
- OpMemberDecorate %4 1 Offset 8
- %5 = OpTypeVoid
- %6 = OpTypeInt 32 0
- %7 = OpTypeFloat 32
- %1 = OpTypeStruct %6 %7
- %2 = OpTypeStruct %1 %1
- %8 = OpTypePointer Uniform %2
- %3 = OpTypeStruct %7 %6
- %4 = OpTypeStruct %3 %3
- %9 = OpTypeFunction %5
- %10 = OpConstant %6 7
- %11 = OpConstant %7 3.14
- %12 = OpConstantComposite %3 %11 %10
- %13 = OpVariable %8 Uniform
- %14 = OpFunction %5 None %9
- %15 = OpLabel
- %16 = OpCompositeConstruct %4 %12 %12
- OpStore %13 %16
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpStore Pointer <id> '13[%13]'s layout does not match Object "
- "<id> '16[%16]'s layout."));
- }
- // This test check that the even with the relaxed rules an error is identified
- // if the members of the struct are at different offsets.
- TEST_F(ValidateIdWithMessage, OpStoreTypeBadRelaxedStruct2) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 4
- OpMemberDecorate %1 1 Offset 0
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 8
- OpMemberDecorate %3 0 Offset 0
- OpMemberDecorate %3 1 Offset 4
- OpMemberDecorate %4 0 Offset 0
- OpMemberDecorate %4 1 Offset 8
- %5 = OpTypeVoid
- %6 = OpTypeInt 32 0
- %7 = OpTypeFloat 32
- %1 = OpTypeStruct %7 %6
- %2 = OpTypeStruct %1 %1
- %8 = OpTypePointer Uniform %2
- %3 = OpTypeStruct %7 %6
- %4 = OpTypeStruct %3 %3
- %9 = OpTypeFunction %5
- %10 = OpConstant %6 7
- %11 = OpConstant %7 3.14
- %12 = OpConstantComposite %3 %11 %10
- %13 = OpVariable %8 Uniform
- %14 = OpFunction %5 None %9
- %15 = OpLabel
- %16 = OpCompositeConstruct %4 %12 %12
- OpStore %13 %16
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpStore Pointer <id> '13[%13]'s layout does not match Object "
- "<id> '16[%16]'s layout."));
- }
- TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedLogicalPointerReturnPointer) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %1 = OpTypeInt 32 1
- %2 = OpTypePointer Function %1
- %3 = OpTypeFunction %2 %2
- %4 = OpFunction %2 None %3
- %5 = OpFunctionParameter %2
- %6 = OpLabel
- OpReturnValue %5
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxLogicalPointer(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedLogicalPointerAllocPointer) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 1
- %3 = OpTypeFunction %1 ; void(void)
- %4 = OpTypePointer Uniform %2 ; int*
- %5 = OpTypePointer Private %4 ; int** (Private)
- %6 = OpTypePointer Function %4 ; int** (Function)
- %7 = OpVariable %5 Private
- %8 = OpFunction %1 None %3
- %9 = OpLabel
- %10 = OpVariable %6 Function
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxLogicalPointer(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpStoreVoid) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- %9 = OpFunctionCall %1 %7
- OpStore %6 %9
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpStore Object <id> '8[%8]'s type is void."));
- }
- TEST_F(ValidateIdWithMessage, OpStoreLabel) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- OpStore %6 %8
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Operand 7[%7] requires a type"));
- }
- // TODO: enable when this bug is fixed:
- // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=15404
- TEST_F(ValidateIdWithMessage, DISABLED_OpStoreFunction) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %2
- %5 = OpConstant %2 123
- %6 = OpVariable %3 UniformConstant
- %7 = OpFunction %2 None %4
- %8 = OpLabel
- OpStore %6 %7
- OpReturnValue %5
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpStoreBuiltin) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 450
- OpName %main "main"
- OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
- OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
- %int = OpTypeInt 32 1
- %uint = OpTypeInt 32 0
- %v3uint = OpTypeVector %uint 3
- %_ptr_Input_v3uint = OpTypePointer Input %v3uint
- %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
- %zero = OpConstant %uint 0
- %v3uint_000 = OpConstantComposite %v3uint %zero %zero %zero
- %void = OpTypeVoid
- %voidfunc = OpTypeFunction %void
- %main = OpFunction %void None %voidfunc
- %lmain = OpLabel
- OpStore %gl_GlobalInvocationID %v3uint_000
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("storage class is read-only"));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemoryGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpConstant %2 42
- %5 = OpVariable %3 UniformConstant %4
- %6 = OpTypePointer Function %2
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %6 Function
- OpCopyMemory %10 %5 None
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemoryNonPointerTarget) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1 %2 %3
- %5 = OpFunction %1 None %4
- %6 = OpFunctionParameter %2
- %7 = OpFunctionParameter %3
- %8 = OpLabel
- OpCopyMemory %6 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target operand <id> '6[%6]' is not a pointer."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemoryNonPointerSource) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1 %2 %3
- %5 = OpFunction %1 None %4
- %6 = OpFunctionParameter %2
- %7 = OpFunctionParameter %3
- %8 = OpLabel
- OpCopyMemory %7 %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Source operand <id> '6[%6]' is not a pointer."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemoryBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpConstant %2 42
- %5 = OpVariable %3 UniformConstant %4
- %11 = OpTypeFloat 32
- %6 = OpTypePointer Function %11
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %6 Function
- OpCopyMemory %10 %5 None
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target <id> '5[%5]'s type does not match "
- "Source <id> '2[%uint]'s type."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemoryVoidTarget) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %1
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFunction %1 %3 %4
- %6 = OpFunction %1 None %5
- %7 = OpFunctionParameter %3
- %8 = OpFunctionParameter %4
- %9 = OpLabel
- OpCopyMemory %7 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target operand <id> '7[%7]' cannot be a void "
- "pointer."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemoryVoidSource) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %1
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFunction %1 %3 %4
- %6 = OpFunction %1 None %5
- %7 = OpFunctionParameter %3
- %8 = OpFunctionParameter %4
- %9 = OpLabel
- OpCopyMemory %8 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Source operand <id> '7[%7]' cannot be a void "
- "pointer."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpVariable %3 UniformConstant %5
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %4 Function
- OpCopyMemorySized %10 %6 %5 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedTargetBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpVariable %3 UniformConstant %5
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- OpCopyMemorySized %5 %5 %5 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Target operand <id> '5[%uint_4]' is not a pointer."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSourceBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpTypeFunction %1
- %7 = OpFunction %1 None %6
- %8 = OpLabel
- %9 = OpVariable %4 Function
- OpCopyMemorySized %9 %5 %5 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Source operand <id> '5[%uint_4]' is not a pointer."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpVariable %3 UniformConstant %5
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %4 Function
- OpCopyMemorySized %10 %6 %6 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Size operand <id> '6[%6]' must be a scalar integer type."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpVariable %3 UniformConstant %5
- %7 = OpTypeFunction %1
- %11 = OpTypeFloat 32
- %12 = OpConstant %11 1.0
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %4 Function
- OpCopyMemorySized %10 %6 %12 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Size operand <id> '9[%float_1]' must be a scalar integer "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantNull) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstantNull %2
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Size operand <id> '3[%3]' cannot be a constant "
- "zero."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantZero) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 0
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Size operand <id> '3[%uint_0]' cannot be a constant "
- "zero."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantZero64) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 64 0
- %3 = OpConstant %2 0
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Size operand <id> '3[%ulong_0]' cannot be a constant "
- "zero."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantNegative) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 1
- %3 = OpConstant %2 -1
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Size operand <id> '3[%int_n1]' cannot have the sign bit set "
- "to 1."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantNegative64) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 64 1
- %3 = OpConstant %2 -1
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Size operand <id> '3[%long_n1]' cannot have the sign bit set "
- "to 1."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeUnsignedNegative) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 2147483648
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeUnsignedNegative64) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 64 0
- %3 = OpConstant %2 9223372036854775808
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- const char kDeeplyNestedStructureSetup[] = R"(
- %void = OpTypeVoid
- %void_f = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %mat4x3 = OpTypeMatrix %v3float 4
- %_ptr_Private_mat4x3 = OpTypePointer Private %mat4x3
- %_ptr_Private_float = OpTypePointer Private %float
- %my_matrix = OpVariable %_ptr_Private_mat4x3 Private
- %my_float_var = OpVariable %_ptr_Private_float Private
- %_ptr_Function_float = OpTypePointer Function %float
- %int_0 = OpConstant %int 0
- %int_1 = OpConstant %int 1
- %int_2 = OpConstant %int 2
- %int_3 = OpConstant %int 3
- %int_5 = OpConstant %int 5
- ; Making the following nested structures.
- ;
- ; struct S {
- ; bool b;
- ; vec4 v[5];
- ; int i;
- ; mat4x3 m[5];
- ; }
- ; uniform blockName {
- ; S s;
- ; bool cond;
- ; RunTimeArray arr;
- ; }
- %f32arr = OpTypeRuntimeArray %float
- %v4float = OpTypeVector %float 4
- %array5_mat4x3 = OpTypeArray %mat4x3 %int_5
- %array5_vec4 = OpTypeArray %v4float %int_5
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_ptr_Function_vec4 = OpTypePointer Function %v4float
- %_ptr_Uniform_vec4 = OpTypePointer Uniform %v4float
- %struct_s = OpTypeStruct %int %array5_vec4 %int %array5_mat4x3
- %struct_blockName = OpTypeStruct %struct_s %int %f32arr
- %_ptr_Uniform_blockName = OpTypePointer Uniform %struct_blockName
- %_ptr_Uniform_struct_s = OpTypePointer Uniform %struct_s
- %_ptr_Uniform_array5_mat4x3 = OpTypePointer Uniform %array5_mat4x3
- %_ptr_Uniform_mat4x3 = OpTypePointer Uniform %mat4x3
- %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
- %blockName_var = OpVariable %_ptr_Uniform_blockName Uniform
- %spec_int = OpSpecConstant %int 2
- %float_0 = OpConstant %float 0
- %func = OpFunction %void None %void_f
- %my_label = OpLabel
- )";
- // In what follows, Access Chain Instruction refers to one of the following:
- // OpAccessChain, OpInBoundsAccessChain, OpPtrAccessChain, and
- // OpInBoundsPtrAccessChain
- using AccessChainInstructionTest = spvtest::ValidateBase<std::string>;
- // Determines whether the access chain instruction requires the 'element id'
- // argument.
- bool AccessChainRequiresElemId(const std::string& instr) {
- return (instr == "OpPtrAccessChain" || instr == "OpInBoundsPtrAccessChain");
- }
- // Valid: Access a float in a matrix using an access chain instruction.
- TEST_P(AccessChainInstructionTest, AccessChainGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup +
- "%float_entry = " + instr +
- R"( %_ptr_Private_float %my_matrix )" + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid. The result type of an access chain instruction must be a pointer.
- TEST_P(AccessChainInstructionTest, AccessChainResultTypeBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %float_entry = )" +
- instr +
- R"( %float %my_matrix )" + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = "The Result Type of " + instr +
- " <id> '36[%36]' must be "
- "OpTypePointer. Found OpTypeFloat.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid. The base type of an access chain instruction must be a pointer.
- TEST_P(AccessChainInstructionTest, AccessChainBaseTypeVoidBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %float_entry = )" +
- instr + " %_ptr_Private_float %void " + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 1[%void] cannot be a "
- "type"));
- }
- // Invalid. The base type of an access chain instruction must be a pointer.
- TEST_P(AccessChainInstructionTest, AccessChainBaseTypeNonPtrVariableBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %_ptr_Private_float )" +
- elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Operand 8[%_ptr_Private_float] cannot be a type"));
- }
- // Invalid: The storage class of Base and Result do not match.
- TEST_P(AccessChainInstructionTest,
- AccessChainResultAndBaseStorageClassDoesntMatchBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Function_float %my_matrix )" + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err =
- "The result pointer storage class and base pointer storage class in " +
- instr + " do not match.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid. The base type of an access chain instruction must point to a
- // composite object.
- TEST_P(AccessChainInstructionTest,
- AccessChainBasePtrNotPointingToCompositeBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %my_float_var )" + elem +
- R"(%int_0
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " reached non-composite type while "
- "indexes still remain to be traversed.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Valid. No Indexes were passed to the access chain instruction. The Result
- // Type is the same as the Base type.
- TEST_P(AccessChainInstructionTest, AccessChainNoIndexesGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %my_float_var )" + elem +
- R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid. No Indexes were passed to the access chain instruction, but the
- // Result Type is different from the Base type.
- TEST_P(AccessChainInstructionTest, AccessChainNoIndexesBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_mat4x3 %my_float_var )" + elem +
- R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("result type (OpTypeMatrix) does not match the type that "
- "results from indexing into the base <id> (OpTypeFloat)."));
- }
- // Valid: 255 indexes passed to the access chain instruction. Limit is 255.
- TEST_P(AccessChainInstructionTest, AccessChainTooManyIndexesGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
- int depth = 255;
- std::string header = kGLSL450MemoryModel + kDeeplyNestedStructureSetup;
- header.erase(header.find("%func"));
- std::ostringstream spirv;
- spirv << header << "\n";
- // Build nested structures. Struct 'i' contains struct 'i-1'
- spirv << "%s_depth_1 = OpTypeStruct %float\n";
- for (int i = 2; i <= depth; ++i) {
- spirv << "%s_depth_" << i << " = OpTypeStruct %s_depth_" << i - 1 << "\n";
- }
- // Define Pointer and Variable to use for the AccessChain instruction.
- spirv << "%_ptr_Uniform_deep_struct = OpTypePointer Uniform %s_depth_"
- << depth << "\n";
- spirv << "%deep_var = OpVariable %_ptr_Uniform_deep_struct Uniform\n";
- // Function Start
- spirv << R"(
- %func = OpFunction %void None %void_f
- %my_label = OpLabel
- )";
- // AccessChain with 'n' indexes (n = depth)
- spirv << "%entry = " << instr << " %_ptr_Uniform_float %deep_var" << elem;
- for (int i = 0; i < depth; ++i) {
- spirv << " %int_0";
- }
- // Function end
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: 256 indexes passed to the access chain instruction. Limit is 255.
- TEST_P(AccessChainInstructionTest, AccessChainTooManyIndexesBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
- std::ostringstream spirv;
- spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup;
- spirv << "%entry = " << instr << " %_ptr_Private_float %my_matrix" << elem;
- for (int i = 0; i < 256; ++i) {
- spirv << " %int_0";
- }
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = "The number of indexes in " + instr +
- " may not exceed 255. Found 256 indexes.";
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Valid: 10 indexes passed to the access chain instruction. (Custom limit: 10)
- TEST_P(AccessChainInstructionTest, CustomizedAccessChainTooManyIndexesGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
- int depth = 10;
- std::string header = kGLSL450MemoryModel + kDeeplyNestedStructureSetup;
- header.erase(header.find("%func"));
- std::ostringstream spirv;
- spirv << header << "\n";
- // Build nested structures. Struct 'i' contains struct 'i-1'
- spirv << "%s_depth_1 = OpTypeStruct %float\n";
- for (int i = 2; i <= depth; ++i) {
- spirv << "%s_depth_" << i << " = OpTypeStruct %s_depth_" << i - 1 << "\n";
- }
- // Define Pointer and Variable to use for the AccessChain instruction.
- spirv << "%_ptr_Uniform_deep_struct = OpTypePointer Uniform %s_depth_"
- << depth << "\n";
- spirv << "%deep_var = OpVariable %_ptr_Uniform_deep_struct Uniform\n";
- // Function Start
- spirv << R"(
- %func = OpFunction %void None %void_f
- %my_label = OpLabel
- )";
- // AccessChain with 'n' indexes (n = depth)
- spirv << "%entry = " << instr << " %_ptr_Uniform_float %deep_var" << elem;
- for (int i = 0; i < depth; ++i) {
- spirv << " %int_0";
- }
- // Function end
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- spvValidatorOptionsSetUniversalLimit(
- options_, spv_validator_limit_max_access_chain_indexes, 10u);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: 11 indexes passed to the access chain instruction. Custom Limit:10
- TEST_P(AccessChainInstructionTest, CustomizedAccessChainTooManyIndexesBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
- std::ostringstream spirv;
- spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup;
- spirv << "%entry = " << instr << " %_ptr_Private_float %my_matrix" << elem;
- for (int i = 0; i < 11; ++i) {
- spirv << " %int_0";
- }
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = "The number of indexes in " + instr +
- " may not exceed 10. Found 11 indexes.";
- spvValidatorOptionsSetUniversalLimit(
- options_, spv_validator_limit_max_access_chain_indexes, 10u);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: Index passed to the access chain instruction is float (must be
- // integer).
- TEST_P(AccessChainInstructionTest, AccessChainUndefinedIndexBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %my_matrix )" + elem +
- R"(%float_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err =
- "Indexes passed to " + instr + " must be of type integer.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: The index argument that indexes into a struct must be of type
- // OpConstant.
- TEST_P(AccessChainInstructionTest, AccessChainStructIndexNotConstantBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %f = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_0 %spec_int %int_2
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err =
- "The <id> passed to " + instr +
- " to index into a structure must be an OpConstant.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: Indexing up to a vec4 granularity, but result type expected float.
- TEST_P(AccessChainInstructionTest,
- AccessChainStructResultTypeDoesntMatchIndexedTypeBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_0 %int_1 %int_2
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " result type (OpTypeFloat) does not match "
- "the type that results from indexing into "
- "the base <id> (OpTypeVector).";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: Reach non-composite type (bool) when unused indexes remain.
- TEST_P(AccessChainInstructionTest, AccessChainStructTooManyIndexesBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_0 %int_2 %int_2
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " reached non-composite type while "
- "indexes still remain to be traversed.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: Trying to find index 3 of the struct that has only 3 members.
- TEST_P(AccessChainInstructionTest, AccessChainStructIndexOutOfBoundBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_3 %int_2 %int_2
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = "Index is out of bounds: " + instr +
- " can not find index 3 into the structure "
- "<id> '25[%_struct_25]'. This structure "
- "has 3 members. Largest valid index is 2.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Valid: Tests that we can index into Struct, Array, Matrix, and Vector!
- TEST_P(AccessChainInstructionTest, AccessChainIndexIntoAllTypesGood) {
- // indexes that we are passing are: 0, 3, 1, 2, 0
- // 0 will select the struct_s within the base struct (blockName)
- // 3 will select the Array that contains 5 matrices
- // 1 will select the Matrix that is at index 1 of the array
- // 2 will select the column (which is a vector) within the matrix at index 2
- // 0 will select the element at the index 0 of the vector. (which is a float).
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::ostringstream spirv;
- spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup << std::endl;
- spirv << "%ss = " << instr << " %_ptr_Uniform_struct_s %blockName_var "
- << elem << "%int_0" << std::endl;
- spirv << "%sa = " << instr << " %_ptr_Uniform_array5_mat4x3 %blockName_var "
- << elem << "%int_0 %int_3" << std::endl;
- spirv << "%sm = " << instr << " %_ptr_Uniform_mat4x3 %blockName_var " << elem
- << "%int_0 %int_3 %int_1" << std::endl;
- spirv << "%sc = " << instr << " %_ptr_Uniform_v3float %blockName_var " << elem
- << "%int_0 %int_3 %int_1 %int_2" << std::endl;
- spirv << "%entry = " << instr << " %_ptr_Uniform_float %blockName_var "
- << elem << "%int_0 %int_3 %int_1 %int_2 %int_0" << std::endl;
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Valid: Access an element of OpTypeRuntimeArray.
- TEST_P(AccessChainInstructionTest, AccessChainIndexIntoRuntimeArrayGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %runtime_arr_entry = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_2 %int_0
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Unused index when accessing OpTypeRuntimeArray.
- TEST_P(AccessChainInstructionTest, AccessChainIndexIntoRuntimeArrayBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %runtime_arr_entry = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_2 %int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err =
- instr +
- " reached non-composite type while indexes still remain to be traversed.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: Reached scalar type before arguments to the access chain instruction
- // finished.
- TEST_P(AccessChainInstructionTest, AccessChainMatrixMoreArgsThanNeededBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %my_matrix )" + elem +
- R"(%int_0 %int_1 %int_0
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " reached non-composite type while "
- "indexes still remain to be traversed.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: The result type and the type indexed into do not match.
- TEST_P(AccessChainInstructionTest,
- AccessChainResultTypeDoesntMatchIndexedTypeBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_mat4x3 %my_matrix )" + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " result type (OpTypeMatrix) does not match "
- "the type that results from indexing into "
- "the base <id> (OpTypeFloat).";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Run tests for Access Chain Instructions.
- INSTANTIATE_TEST_SUITE_P(
- CheckAccessChainInstructions, AccessChainInstructionTest,
- ::testing::Values("OpAccessChain", "OpInBoundsAccessChain",
- "OpPtrAccessChain", "OpInBoundsPtrAccessChain"));
- // TODO: OpArrayLength
- // TODO: OpImagePointer
- // TODO: OpGenericPtrMemSemantics
- TEST_F(ValidateIdWithMessage, OpFunctionGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1 %2 %2
- %4 = OpFunction %1 None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpFunctionResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 42
- %4 = OpTypeFunction %1 %2 %2
- %5 = OpFunction %2 None %4
- %6 = OpLabel
- OpReturnValue %3
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpFunction Result Type <id> '2[%uint]' does not "
- "match the Function Type's return type <id> "
- "'1[%void]'."));
- }
- TEST_F(ValidateIdWithMessage, OpReturnValueTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeFloat 32
- %3 = OpConstant %2 0
- %4 = OpTypeFunction %1
- %5 = OpFunction %1 None %4
- %6 = OpLabel
- OpReturnValue %3
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpReturnValue Value <id> '3[%float_0]'s type does "
- "not match OpFunction's return type."));
- }
- TEST_F(ValidateIdWithMessage, OpFunctionFunctionTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %4 = OpFunction %1 None %2
- %5 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpFunction Function Type <id> '2[%uint]' is not a function "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpFunctionUseBad) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- OpReturnValue %3
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Invalid use of function result id 3[%3]."));
- }
- TEST_F(ValidateIdWithMessage, OpFunctionParameterGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1 %2
- %4 = OpFunction %1 None %3
- %5 = OpFunctionParameter %2
- %6 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpFunctionParameterMultipleGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1 %2 %2
- %4 = OpFunction %1 None %3
- %5 = OpFunctionParameter %2
- %6 = OpFunctionParameter %2
- %7 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpFunctionParameterResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1 %2
- %4 = OpFunction %1 None %3
- %5 = OpFunctionParameter %1
- %6 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpFunctionParameter Result Type <id> '1[%void]' does not "
- "match the OpTypeFunction parameter type of the same index."));
- }
- TEST_F(ValidateIdWithMessage, OpFunctionCallGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42 ;21
- %6 = OpFunction %2 None %3
- %7 = OpFunctionParameter %2
- %8 = OpLabel
- OpReturnValue %7
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- %12 = OpFunctionCall %2 %6 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpFunctionCallResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42 ;21
- %6 = OpFunction %2 None %3
- %7 = OpFunctionParameter %2
- %8 = OpLabel
- %9 = OpIAdd %2 %7 %7
- OpReturnValue %9
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- %12 = OpFunctionCall %1 %6 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpFunctionCall Result Type <id> '1[%void]'s type "
- "does not match Function <id> '2[%uint]'s return "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpFunctionCallFunctionBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42 ;21
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- %12 = OpFunctionCall %2 %5 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpFunctionCall Function <id> '5[%uint_42]' is not a "
- "function."));
- }
- TEST_F(ValidateIdWithMessage, OpFunctionCallArgumentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42
- %13 = OpTypeFloat 32
- %14 = OpConstant %13 3.14
- %6 = OpFunction %2 None %3
- %7 = OpFunctionParameter %2
- %8 = OpLabel
- %9 = OpIAdd %2 %7 %7
- OpReturnValue %9
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- %12 = OpFunctionCall %2 %6 %14
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpFunctionCall Argument <id> '7[%float_3_1400001]'s "
- "type does not match Function <id> '2[%uint]'s "
- "parameter type."));
- }
- // Valid: OpSampledImage result <id> is used in the same block by
- // OpImageSampleImplictLod
- TEST_F(ValidateIdWithMessage, OpSampledImageGood) {
- std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
- %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
- %si_lod = OpImageSampleImplicitLod %v4float %smpld_img %const_vec_1_1
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: OpSampledImage result <id> is defined in one block and used in a
- // different block.
- TEST_F(ValidateIdWithMessage, OpSampledImageUsedInDifferentBlockBad) {
- std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
- %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
- OpBranch %label_2
- %label_2 = OpLabel
- %si_lod = OpImageSampleImplicitLod %v4float %smpld_img %const_vec_1_1
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("All OpSampledImage instructions must be in the same block in "
- "which their Result <id> are consumed. OpSampledImage Result "
- "Type <id> '23[%23]' has a consumer in a different basic "
- "block. The consumer instruction <id> is '25[%25]'."));
- }
- // Invalid: OpSampledImage result <id> is used by OpSelect
- // Note: According to the Spec, OpSelect parameters must be either a scalar or a
- // vector. Therefore, OpTypeSampledImage is an illegal parameter for OpSelect.
- // However, the OpSelect validation does not catch this today. Therefore, it is
- // caught by the OpSampledImage validation. If the OpSelect validation code is
- // updated, the error message for this test may change.
- //
- // Disabled since OpSelect catches this now.
- TEST_F(ValidateIdWithMessage, DISABLED_OpSampledImageUsedInOpSelectBad) {
- std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
- %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
- %select_img = OpSelect %sampled_image_type %spec_true %smpld_img %smpld_img
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Result <id> from OpSampledImage instruction must not "
- "appear as operands of OpSelect. Found result <id> "
- "'23' as an operand of <id> '24'."));
- }
- TEST_F(ValidateIdWithMessage, OpCopyObjectSampledImageGood) {
- std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
- %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
- %smpld_img2 = OpCopyObject %sampled_image_type %smpld_img
- %image_inst2 = OpCopyObject %image_type %image_inst
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Valid: Get a float in a matrix using CompositeExtract.
- // Valid: Insert float into a matrix using CompositeInsert.
- TEST_F(ValidateIdWithMessage, CompositeExtractInsertGood) {
- std::ostringstream spirv;
- spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup << std::endl;
- spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl;
- spirv << "%float_entry = OpCompositeExtract %float %matrix 0 1" << std::endl;
- // To test CompositeInsert, insert the object back in after extraction.
- spirv << "%new_composite = OpCompositeInsert %mat4x3 %float_entry %matrix 0 1"
- << std::endl;
- spirv << R"(OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- #if 0
- TEST_F(ValidateIdWithMessage, OpFunctionCallArgumentCountBar) {
- const char *spirv = R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42 ;21
- %6 = OpFunction %2 None %3
- %7 = OpFunctionParameter %2
- %8 = OpLabel
- %9 = OpLoad %2 %7
- OpReturnValue %9
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- OpReturn
- %12 = OpFunctionCall %2 %6 %5
- OpFunctionEnd)";
- CHECK(spirv, SPV_ERROR_INVALID_ID);
- }
- #endif
- // TODO: The many things that changed with how images are used.
- // TODO: OpTextureSample
- // TODO: OpTextureSampleDref
- // TODO: OpTextureSampleLod
- // TODO: OpTextureSampleProj
- // TODO: OpTextureSampleGrad
- // TODO: OpTextureSampleOffset
- // TODO: OpTextureSampleProjLod
- // TODO: OpTextureSampleProjGrad
- // TODO: OpTextureSampleLodOffset
- // TODO: OpTextureSampleProjOffset
- // TODO: OpTextureSampleGradOffset
- // TODO: OpTextureSampleProjLodOffset
- // TODO: OpTextureSampleProjGradOffset
- // TODO: OpTextureFetchTexelLod
- // TODO: OpTextureFetchTexelOffset
- // TODO: OpTextureFetchSample
- // TODO: OpTextureFetchTexel
- // TODO: OpTextureGather
- // TODO: OpTextureGatherOffset
- // TODO: OpTextureGatherOffsets
- // TODO: OpTextureQuerySizeLod
- // TODO: OpTextureQuerySize
- // TODO: OpTextureQueryLevels
- // TODO: OpTextureQuerySamples
- // TODO: OpConvertUToF
- // TODO: OpConvertFToS
- // TODO: OpConvertSToF
- // TODO: OpConvertUToF
- // TODO: OpUConvert
- // TODO: OpSConvert
- // TODO: OpFConvert
- // TODO: OpConvertPtrToU
- // TODO: OpConvertUToPtr
- // TODO: OpPtrCastToGeneric
- // TODO: OpGenericCastToPtr
- // TODO: OpBitcast
- // TODO: OpGenericCastToPtrExplicit
- // TODO: OpSatConvertSToU
- // TODO: OpSatConvertUToS
- // TODO: OpVectorExtractDynamic
- // TODO: OpVectorInsertDynamic
- TEST_F(ValidateIdWithMessage, OpVectorShuffleIntGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec3 = OpTypeVector %int 3
- %ivec4 = OpTypeVector %int 4
- %ptr_ivec3 = OpTypePointer Function %ivec3
- %undef = OpUndef %ivec4
- %int_42 = OpConstant %int 42
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
- %2 = OpTypeFunction %ivec3
- %3 = OpFunction %ivec3 None %2
- %4 = OpLabel
- %var = OpVariable %ptr_ivec3 Function %1
- %5 = OpLoad %ivec3 %var
- %6 = OpVectorShuffle %ivec3 %5 %undef 2 1 0
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVectorShuffleFloatGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %float = OpTypeFloat 32
- %vec2 = OpTypeVector %float 2
- %vec3 = OpTypeVector %float 3
- %vec4 = OpTypeVector %float 4
- %ptr_vec2 = OpTypePointer Function %vec2
- %ptr_vec3 = OpTypePointer Function %vec3
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %vec2 %float_2 %float_1
- %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
- %3 = OpTypeFunction %vec4
- %4 = OpFunction %vec4 None %3
- %5 = OpLabel
- %var = OpVariable %ptr_vec2 Function %1
- %var2 = OpVariable %ptr_vec3 Function %2
- %6 = OpLoad %vec2 %var
- %7 = OpLoad %vec3 %var2
- %8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0xffffffff
- OpReturnValue %8
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpVectorShuffleScalarResultType) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %float = OpTypeFloat 32
- %vec2 = OpTypeVector %float 2
- %ptr_vec2 = OpTypePointer Function %vec2
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %vec2 %float_2 %float_1
- %2 = OpTypeFunction %float
- %3 = OpFunction %float None %2
- %4 = OpLabel
- %var = OpVariable %ptr_vec2 Function %1
- %5 = OpLoad %vec2 %var
- %6 = OpVectorShuffle %float %5 %5 0
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Result Type of OpVectorShuffle must be OpTypeVector."));
- }
- TEST_F(ValidateIdWithMessage, OpVectorShuffleComponentCount) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec3 = OpTypeVector %int 3
- %ptr_ivec3 = OpTypePointer Function %ivec3
- %int_42 = OpConstant %int 42
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
- %2 = OpTypeFunction %ivec3
- %3 = OpFunction %ivec3 None %2
- %4 = OpLabel
- %var = OpVariable %ptr_ivec3 Function %1
- %5 = OpLoad %ivec3 %var
- %6 = OpVectorShuffle %ivec3 %5 %5 0 1
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpVectorShuffle component literals count does not match "
- "Result Type <id> '2[%v3uint]'s vector component count."));
- }
- TEST_F(ValidateIdWithMessage, OpVectorShuffleVector1Type) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec2 = OpTypeVector %int 2
- %ptr_int = OpTypePointer Function %int
- %undef = OpUndef %ivec2
- %int_42 = OpConstant %int 42
- %2 = OpTypeFunction %ivec2
- %3 = OpFunction %ivec2 None %2
- %4 = OpLabel
- %var = OpVariable %ptr_int Function %int_42
- %5 = OpLoad %int %var
- %6 = OpVectorShuffle %ivec2 %5 %undef 0 0
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("The type of Vector 1 must be OpTypeVector."));
- }
- TEST_F(ValidateIdWithMessage, OpVectorShuffleVector2Type) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec2 = OpTypeVector %int 2
- %ptr_ivec2 = OpTypePointer Function %ivec2
- %undef = OpUndef %int
- %int_42 = OpConstant %int 42
- %1 = OpConstantComposite %ivec2 %int_42 %int_42
- %2 = OpTypeFunction %ivec2
- %3 = OpFunction %ivec2 None %2
- %4 = OpLabel
- %var = OpVariable %ptr_ivec2 Function %1
- %5 = OpLoad %ivec2 %var
- %6 = OpVectorShuffle %ivec2 %5 %undef 0 1
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("The type of Vector 2 must be OpTypeVector."));
- }
- TEST_F(ValidateIdWithMessage, OpVectorShuffleVector1ComponentType) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec3 = OpTypeVector %int 3
- %ptr_ivec3 = OpTypePointer Function %ivec3
- %int_42 = OpConstant %int 42
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %float = OpTypeFloat 32
- %vec3 = OpTypeVector %float 3
- %vec4 = OpTypeVector %float 4
- %ptr_vec3 = OpTypePointer Function %vec3
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
- %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
- %3 = OpTypeFunction %vec4
- %4 = OpFunction %vec4 None %3
- %5 = OpLabel
- %var = OpVariable %ptr_ivec3 Function %1
- %var2 = OpVariable %ptr_vec3 Function %2
- %6 = OpLoad %ivec3 %var
- %7 = OpLoad %vec3 %var2
- %8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0
- OpReturnValue %8
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("The Component Type of Vector 1 must be the same as "
- "ResultType."));
- }
- TEST_F(ValidateIdWithMessage, OpVectorShuffleVector2ComponentType) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec3 = OpTypeVector %int 3
- %ptr_ivec3 = OpTypePointer Function %ivec3
- %int_42 = OpConstant %int 42
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %float = OpTypeFloat 32
- %vec3 = OpTypeVector %float 3
- %vec4 = OpTypeVector %float 4
- %ptr_vec3 = OpTypePointer Function %vec3
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
- %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
- %3 = OpTypeFunction %vec4
- %4 = OpFunction %vec4 None %3
- %5 = OpLabel
- %var = OpVariable %ptr_ivec3 Function %1
- %var2 = OpVariable %ptr_vec3 Function %2
- %6 = OpLoad %vec3 %var2
- %7 = OpLoad %ivec3 %var
- %8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0
- OpReturnValue %8
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("The Component Type of Vector 2 must be the same as "
- "ResultType."));
- }
- TEST_F(ValidateIdWithMessage, OpVectorShuffleLiterals) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %float = OpTypeFloat 32
- %vec2 = OpTypeVector %float 2
- %vec3 = OpTypeVector %float 3
- %vec4 = OpTypeVector %float 4
- %ptr_vec2 = OpTypePointer Function %vec2
- %ptr_vec3 = OpTypePointer Function %vec3
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %vec2 %float_2 %float_1
- %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
- %3 = OpTypeFunction %vec4
- %4 = OpFunction %vec4 None %3
- %5 = OpLabel
- %var = OpVariable %ptr_vec2 Function %1
- %var2 = OpVariable %ptr_vec3 Function %2
- %6 = OpLoad %vec2 %var
- %7 = OpLoad %vec3 %var2
- %8 = OpVectorShuffle %vec4 %6 %7 0 8 2 6
- OpReturnValue %8
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Component index 8 is out of bounds for combined (Vector1 + Vector2) "
- "size of 5."));
- }
- // TODO: OpCompositeConstruct
- // TODO: OpCompositeExtract
- // TODO: OpCompositeInsert
- // TODO: OpCopyObject
- // TODO: OpTranspose
- // TODO: OpSNegate
- // TODO: OpFNegate
- // TODO: OpNot
- // TODO: OpIAdd
- // TODO: OpFAdd
- // TODO: OpISub
- // TODO: OpFSub
- // TODO: OpIMul
- // TODO: OpFMul
- // TODO: OpUDiv
- // TODO: OpSDiv
- // TODO: OpFDiv
- // TODO: OpUMod
- // TODO: OpSRem
- // TODO: OpSMod
- // TODO: OpFRem
- // TODO: OpFMod
- // TODO: OpVectorTimesScalar
- // TODO: OpMatrixTimesScalar
- // TODO: OpVectorTimesMatrix
- // TODO: OpMatrixTimesVector
- // TODO: OpMatrixTimesMatrix
- // TODO: OpOuterProduct
- // TODO: OpDot
- // TODO: OpShiftRightLogical
- // TODO: OpShiftRightArithmetic
- // TODO: OpShiftLeftLogical
- // TODO: OpBitwiseOr
- // TODO: OpBitwiseXor
- // TODO: OpBitwiseAnd
- // TODO: OpAny
- // TODO: OpAll
- // TODO: OpIsNan
- // TODO: OpIsInf
- // TODO: OpIsFinite
- // TODO: OpIsNormal
- // TODO: OpSignBitSet
- // TODO: OpLessOrGreater
- // TODO: OpOrdered
- // TODO: OpUnordered
- // TODO: OpLogicalOr
- // TODO: OpLogicalXor
- // TODO: OpLogicalAnd
- // TODO: OpSelect
- // TODO: OpIEqual
- // TODO: OpFOrdEqual
- // TODO: OpFUnordEqual
- // TODO: OpINotEqual
- // TODO: OpFOrdNotEqual
- // TODO: OpFUnordNotEqual
- // TODO: OpULessThan
- // TODO: OpSLessThan
- // TODO: OpFOrdLessThan
- // TODO: OpFUnordLessThan
- // TODO: OpUGreaterThan
- // TODO: OpSGreaterThan
- // TODO: OpFOrdGreaterThan
- // TODO: OpFUnordGreaterThan
- // TODO: OpULessThanEqual
- // TODO: OpSLessThanEqual
- // TODO: OpFOrdLessThanEqual
- // TODO: OpFUnordLessThanEqual
- // TODO: OpUGreaterThanEqual
- // TODO: OpSGreaterThanEqual
- // TODO: OpFOrdGreaterThanEqual
- // TODO: OpFUnordGreaterThanEqual
- // TODO: OpDPdx
- // TODO: OpDPdy
- // TODO: OpFWidth
- // TODO: OpDPdxFine
- // TODO: OpDPdyFine
- // TODO: OpFwidthFine
- // TODO: OpDPdxCoarse
- // TODO: OpDPdyCoarse
- // TODO: OpFwidthCoarse
- // TODO: OpLoopMerge
- // TODO: OpSelectionMerge
- // TODO: OpBranch
- TEST_F(ValidateIdWithMessage, OpPhiNotAType) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %9 = OpPhi %3 %3 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 3[%true] is not a type "
- "id"));
- }
- TEST_F(ValidateIdWithMessage, OpPhiSamePredecessor) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranchConditional %3 %8 %8
- %8 = OpLabel
- %9 = OpPhi %2 %3 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpPhiOddArgumentNumber) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %9 = OpPhi %2 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpPhi does not have an equal number of incoming "
- "values and basic blocks."));
- }
- TEST_F(ValidateIdWithMessage, OpPhiTooFewPredecessors) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %9 = OpPhi %2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpPhi's number of incoming blocks (0) does not match "
- "block's predecessor count (1)."));
- }
- TEST_F(ValidateIdWithMessage, OpPhiTooManyPredecessors) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranch %8
- %9 = OpLabel
- OpReturn
- %8 = OpLabel
- %10 = OpPhi %2 %3 %7 %3 %9
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpPhi's number of incoming blocks (2) does not match "
- "block's predecessor count (1)."));
- }
- TEST_F(ValidateIdWithMessage, OpPhiMismatchedTypes) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeInt 32 0
- %6 = OpConstant %5 0
- %7 = OpTypeFunction %4
- %8 = OpFunction %4 None %7
- %9 = OpLabel
- OpBranchConditional %3 %10 %11
- %11 = OpLabel
- OpBranch %10
- %10 = OpLabel
- %12 = OpPhi %2 %3 %9 %6 %11
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpPhi's result type <id> 2[%bool] does not match "
- "incoming value <id> 6[%uint_0] type <id> "
- "5[%uint]."));
- }
- TEST_F(ValidateIdWithMessage, OpPhiPredecessorNotABlock) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranchConditional %3 %8 %9
- %9 = OpLabel
- OpBranch %11
- %11 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %10 = OpPhi %2 %3 %7 %3 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpPhi's incoming basic block <id> 3[%true] is not an "
- "OpLabel."));
- }
- TEST_F(ValidateIdWithMessage, OpPhiNotAPredecessor) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranchConditional %3 %8 %9
- %9 = OpLabel
- OpBranch %11
- %11 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %10 = OpPhi %2 %3 %7 %3 %9
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpPhi's incoming basic block <id> 9[%9] is not a "
- "predecessor of <id> 8[%8]."));
- }
- TEST_F(ValidateIdWithMessage, OpBranchConditionalGood) {
- std::string spirv = BranchConditionalSetup + R"(
- %branch_cond = OpINotEqual %bool %i0 %i1
- OpSelectionMerge %end None
- OpBranchConditional %branch_cond %target_t %target_f
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateIdWithMessage, OpBranchConditionalWithWeightsGood) {
- std::string spirv = BranchConditionalSetup + R"(
- %branch_cond = OpINotEqual %bool %i0 %i1
- OpSelectionMerge %end None
- OpBranchConditional %branch_cond %target_t %target_f 1 1
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateIdWithMessage, OpBranchConditional_CondIsScalarInt) {
- std::string spirv = BranchConditionalSetup + R"(
- OpSelectionMerge %end None
- OpBranchConditional %i0 %target_t %target_f
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Condition operand for OpBranchConditional must be of boolean type"));
- }
- TEST_F(ValidateIdWithMessage, OpBranchConditional_TrueTargetIsNotLabel) {
- std::string spirv = BranchConditionalSetup + R"(
- OpSelectionMerge %end None
- OpBranchConditional %true %i0 %target_f
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("The 'True Label' operand for OpBranchConditional must "
- "be the ID of an OpLabel instruction"));
- }
- TEST_F(ValidateIdWithMessage, OpBranchConditional_FalseTargetIsNotLabel) {
- std::string spirv = BranchConditionalSetup + R"(
- OpSelectionMerge %end None
- OpBranchConditional %true %target_t %i0
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("The 'False Label' operand for OpBranchConditional "
- "must be the ID of an OpLabel instruction"));
- }
- TEST_F(ValidateIdWithMessage, OpBranchConditional_NotEnoughWeights) {
- std::string spirv = BranchConditionalSetup + R"(
- %branch_cond = OpINotEqual %bool %i0 %i1
- OpSelectionMerge %end None
- OpBranchConditional %branch_cond %target_t %target_f 1
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpBranchConditional requires either 3 or 5 parameters"));
- }
- TEST_F(ValidateIdWithMessage, OpBranchConditional_TooManyWeights) {
- std::string spirv = BranchConditionalSetup + R"(
- %branch_cond = OpINotEqual %bool %i0 %i1
- OpSelectionMerge %end None
- OpBranchConditional %branch_cond %target_t %target_f 1 2 3
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpBranchConditional requires either 3 or 5 parameters"));
- }
- TEST_F(ValidateIdWithMessage, OpBranchConditional_ConditionIsAType) {
- std::string spirv = BranchConditionalSetup + R"(
- OpBranchConditional %bool %target_t %target_f
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 3[%bool] cannot be a "
- "type"));
- }
- // TODO: OpSwitch
- TEST_F(ValidateIdWithMessage, OpReturnValueConstantGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %4 = OpConstant %2 42
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- OpReturnValue %4
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpReturnValueVariableGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0 ;10
- %3 = OpTypeFunction %2
- %8 = OpTypePointer Function %2 ;18
- %4 = OpConstant %2 42 ;22
- %5 = OpFunction %2 None %3 ;27
- %6 = OpLabel ;29
- %7 = OpVariable %8 Function %4 ;34
- %9 = OpLoad %2 %7
- OpReturnValue %9 ;36
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpReturnValueExpressionGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %4 = OpConstant %2 42
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- %7 = OpIAdd %2 %4 %4
- OpReturnValue %7
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpReturnValueIsType) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- OpReturnValue %1
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 1[%void] cannot be a "
- "type"));
- }
- TEST_F(ValidateIdWithMessage, OpReturnValueIsLabel) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Operand 5[%5] requires a type"));
- }
- TEST_F(ValidateIdWithMessage, OpReturnValueIsVoid) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1
- %5 = OpFunction %1 None %3
- %6 = OpLabel
- %7 = OpFunctionCall %1 %5
- OpReturnValue %7
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpReturnValue value's type <id> '1[%void]' is missing or "
- "void."));
- }
- TEST_F(ValidateIdWithMessage, OpReturnValueIsVariableInPhysical) {
- // It's valid to return a pointer in a physical addressing model.
- std::string spirv = kOpCapabilitySetup + R"(
- OpMemoryModel Physical32 OpenCL
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Function %2
- %4 = OpTypeFunction %3
- %5 = OpFunction %3 None %4
- %6 = OpLabel
- %7 = OpVariable %3 Function
- OpReturnValue %7
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpReturnValueIsVariableInLogical) {
- // It's invalid to return a pointer in a physical addressing model.
- std::string spirv = kOpCapabilitySetup + R"(
- OpMemoryModel Logical GLSL450
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Function %2
- %4 = OpTypeFunction %3
- %5 = OpFunction %3 None %4
- %6 = OpLabel
- %7 = OpVariable %3 Function
- OpReturnValue %7
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpReturnValue value's type <id> "
- "'3[%_ptr_Function_uint]' is a pointer, which is "
- "invalid in the Logical addressing model."));
- }
- // With the VariablePointer Capability, the return value of a function is
- // allowed to be a pointer.
- TEST_F(ValidateIdWithMessage, OpReturnValueVarPtrGood) {
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv,
- "" /* Instructions to add to "main" */,
- true /* Add VariablePointers Capability?*/,
- true /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Without the VariablePointer Capability, the return value of a function is
- // *not* allowed to be a pointer.
- // Disabled since using OpSelect with pointers without VariablePointers will
- // fail LogicalsPass.
- TEST_F(ValidateIdWithMessage, DISABLED_OpReturnValueVarPtrBad) {
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv,
- "" /* Instructions to add to "main" */,
- false /* Add VariablePointers Capability?*/,
- true /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpReturnValue value's type <id> '7' is a pointer, "
- "which is invalid in the Logical addressing model."));
- }
- // TODO: enable when this bug is fixed:
- // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=15404
- TEST_F(ValidateIdWithMessage, DISABLED_OpReturnValueIsFunction) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- OpReturnValue %5
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, UndefinedTypeId) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %s = OpTypeStruct %i32
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Operand 2[%2] requires a previous definition"));
- }
- TEST_F(ValidateIdWithMessage, UndefinedIdScope) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %u32 = OpTypeInt 32 0
- %memsem = OpConstant %u32 0
- %void = OpTypeVoid
- %void_f = OpTypeFunction %void
- %f = OpFunction %void None %void_f
- %l = OpLabel
- OpMemoryBarrier %undef %memsem
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 7[%7] has not been "
- "defined"));
- }
- TEST_F(ValidateIdWithMessage, UndefinedIdMemSem) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %u32 = OpTypeInt 32 0
- %scope = OpConstant %u32 0
- %void = OpTypeVoid
- %void_f = OpTypeFunction %void
- %f = OpFunction %void None %void_f
- %l = OpLabel
- OpMemoryBarrier %scope %undef
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 7[%7] has not been "
- "defined"));
- }
- TEST_F(ValidateIdWithMessage,
- KernelOpEntryPointAndOpInBoundsPtrAccessChainGood) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- OpEntryPoint Kernel %2 "simple_kernel"
- OpSource OpenCL_C 200000
- OpDecorate %3 BuiltIn GlobalInvocationId
- OpDecorate %3 Constant
- OpDecorate %4 FuncParamAttr NoCapture
- OpDecorate %3 LinkageAttributes "__spirv_GlobalInvocationId" Import
- %5 = OpTypeInt 32 0
- %6 = OpTypeVector %5 3
- %7 = OpTypePointer UniformConstant %6
- %3 = OpVariable %7 UniformConstant
- %8 = OpTypeVoid
- %9 = OpTypeStruct %5
- %10 = OpTypePointer CrossWorkgroup %9
- %11 = OpTypeFunction %8 %10
- %12 = OpConstant %5 0
- %13 = OpTypePointer CrossWorkgroup %5
- %14 = OpConstant %5 42
- %2 = OpFunction %8 None %11
- %4 = OpFunctionParameter %10
- %15 = OpLabel
- %16 = OpLoad %6 %3 Aligned 0
- %17 = OpCompositeExtract %5 %16 0
- %18 = OpInBoundsPtrAccessChain %13 %4 %17 %12
- OpStore %18 %14 Aligned 4
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpPtrAccessChainGood) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- OpEntryPoint Kernel %2 "another_kernel"
- OpSource OpenCL_C 200000
- OpDecorate %3 BuiltIn GlobalInvocationId
- OpDecorate %3 Constant
- OpDecorate %4 FuncParamAttr NoCapture
- OpDecorate %3 LinkageAttributes "__spirv_GlobalInvocationId" Import
- %5 = OpTypeInt 64 0
- %6 = OpTypeVector %5 3
- %7 = OpTypePointer UniformConstant %6
- %3 = OpVariable %7 UniformConstant
- %8 = OpTypeVoid
- %9 = OpTypeInt 32 0
- %10 = OpTypeStruct %9
- %11 = OpTypePointer CrossWorkgroup %10
- %12 = OpTypeFunction %8 %11
- %13 = OpConstant %5 4294967295
- %14 = OpConstant %9 0
- %15 = OpTypePointer CrossWorkgroup %9
- %16 = OpConstant %9 42
- %2 = OpFunction %8 None %12
- %4 = OpFunctionParameter %11
- %17 = OpLabel
- %18 = OpLoad %6 %3 Aligned 0
- %19 = OpCompositeExtract %5 %18 0
- %20 = OpBitwiseAnd %5 %19 %13
- %21 = OpPtrAccessChain %15 %4 %20 %14
- OpStore %21 %16 Aligned 4
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, StgBufOpPtrAccessChainGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VariablePointersStorageBuffer
- OpExtension "SPV_KHR_variable_pointers"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %3 ""
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %int_4 = OpConstant %int 4
- %struct = OpTypeStruct %int
- %array = OpTypeArray %struct %int_4
- %ptr = OpTypePointer StorageBuffer %array
- %var = OpVariable %ptr StorageBuffer
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- %5 = OpPtrAccessChain %ptr %var %int_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpLoadBitcastPointerGood) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- %2 = OpTypeVoid
- %3 = OpTypeInt 32 0
- %4 = OpTypeFloat 32
- %5 = OpTypePointer UniformConstant %3
- %6 = OpTypePointer UniformConstant %4
- %7 = OpVariable %5 UniformConstant
- %8 = OpTypeFunction %2
- %9 = OpFunction %2 None %8
- %10 = OpLabel
- %11 = OpBitcast %6 %7
- %12 = OpLoad %4 %11
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpLoadBitcastNonPointerBad) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- %2 = OpTypeVoid
- %3 = OpTypeInt 32 0
- %4 = OpTypeFloat 32
- %5 = OpTypePointer UniformConstant %3
- %6 = OpTypeFunction %2
- %7 = OpVariable %5 UniformConstant
- %8 = OpFunction %2 None %6
- %9 = OpLabel
- %10 = OpLoad %3 %7
- %11 = OpBitcast %4 %10
- %12 = OpLoad %3 %11
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpLoad type for pointer <id> '11[%11]' is not a pointer "
- "type."));
- }
- TEST_F(ValidateIdWithMessage, OpStoreBitcastPointerGood) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- %2 = OpTypeVoid
- %3 = OpTypeInt 32 0
- %4 = OpTypeFloat 32
- %5 = OpTypePointer Function %3
- %6 = OpTypePointer Function %4
- %7 = OpTypeFunction %2
- %8 = OpConstant %3 42
- %9 = OpFunction %2 None %7
- %10 = OpLabel
- %11 = OpVariable %6 Function
- %12 = OpBitcast %5 %11
- OpStore %12 %8
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_F(ValidateIdWithMessage, OpStoreBitcastNonPointerBad) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- %2 = OpTypeVoid
- %3 = OpTypeInt 32 0
- %4 = OpTypeFloat 32
- %5 = OpTypePointer Function %4
- %6 = OpTypeFunction %2
- %7 = OpConstant %4 42
- %8 = OpFunction %2 None %6
- %9 = OpLabel
- %10 = OpVariable %5 Function
- %11 = OpBitcast %3 %7
- OpStore %11 %7
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("OpStore type for pointer <id> '11[%11]' is not a pointer "
- "type."));
- }
- // Result <id> resulting from an instruction within a function may not be used
- // outside that function.
- TEST_F(ValidateIdWithMessage, ResultIdUsedOutsideOfFunctionBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeInt 32 0
- %4 = OpTypePointer Function %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- %7 = OpVariable %4 Function
- OpReturn
- OpFunctionEnd
- %8 = OpFunction %1 None %2
- %9 = OpLabel
- %10 = OpLoad %3 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "ID 7[%7] defined in block 6[%6] does not dominate its use in block "
- "9[%9]"));
- }
- TEST_F(ValidateIdWithMessage, SpecIdTargetNotSpecializationConstant) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 SpecId 200
- %void = OpTypeVoid
- %2 = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %1 = OpConstant %int 3
- %main = OpFunction %void None %2
- %4 = OpLabel
- OpReturnValue %1
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpDecorate SpecId decoration target <id> "
- "'1[%uint_3]' is not a scalar specialization "
- "constant."));
- }
- TEST_F(ValidateIdWithMessage, SpecIdTargetOpSpecConstantOpBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 SpecId 200
- %void = OpTypeVoid
- %2 = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %3 = OpConstant %int 1
- %4 = OpConstant %int 2
- %1 = OpSpecConstantOp %int IAdd %3 %4
- %main = OpFunction %void None %2
- %6 = OpLabel
- OpReturnValue %3
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpDecorate SpecId decoration target <id> '1[%1]' is "
- "not a scalar specialization constant."));
- }
- TEST_F(ValidateIdWithMessage, SpecIdTargetOpSpecConstantCompositeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 SpecId 200
- %void = OpTypeVoid
- %2 = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %3 = OpConstant %int 1
- %1 = OpSpecConstantComposite %int
- %main = OpFunction %void None %2
- %4 = OpLabel
- OpReturnValue %3
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpDecorate SpecId decoration target <id> '1[%1]' is "
- "not a scalar specialization constant."));
- }
- TEST_F(ValidateIdWithMessage, SpecIdTargetGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %3 SpecId 200
- OpDecorate %4 SpecId 201
- OpDecorate %5 SpecId 202
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %int = OpTypeInt 32 0
- %bool = OpTypeBool
- %3 = OpSpecConstant %int 3
- %4 = OpSpecConstantTrue %bool
- %5 = OpSpecConstantFalse %bool
- %main = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_F(ValidateIdWithMessage, CorrectErrorForShuffle) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %uint = OpTypeInt 32 0
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %v2float = OpTypeVector %float 2
- %void = OpTypeVoid
- %548 = OpTypeFunction %void
- %CS = OpFunction %void None %548
- %550 = OpLabel
- %6275 = OpUndef %v2float
- %6280 = OpUndef %v2float
- %6282 = OpVectorShuffle %v4float %6275 %6280 0 1 4 5
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Component index 4 is out of bounds for combined (Vector1 + Vector2) "
- "size of 4."));
- EXPECT_EQ(25, getErrorPosition().index);
- }
- TEST_F(ValidateIdWithMessage, VoidStructMember) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %void = OpTypeVoid
- %struct = OpTypeStruct %void
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Structures cannot contain a void type."));
- }
- TEST_F(ValidateIdWithMessage, TypeFunctionBadUse) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypePointer Function %2
- %4 = OpFunction %1 None %2
- %5 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Invalid use of function type result id 2[%2]."));
- }
- TEST_F(ValidateIdWithMessage, BadTypeId) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpConstant %3 0
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- %7 = OpUndef %4
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 4[%float_0] is not a type "
- "id"));
- }
- TEST_F(ValidateIdWithMessage, VulkanMemoryModelLoadMakePointerVisibleGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 2
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- %9 = OpLoad %2 %4 NonPrivatePointerKHR|MakePointerVisibleKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelLoadMakePointerVisibleMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 2
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- %9 = OpLoad %2 %4 MakePointerVisibleKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR must be specified if "
- "MakePointerVisibleKHR is specified."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelLoadNonPrivatePointerBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Private %2
- %4 = OpVariable %3 Private
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 2
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- %9 = OpLoad %2 %4 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelLoadMakePointerAvailableCannotBeUsed) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 2
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- %9 = OpLoad %2 %4 NonPrivatePointerKHR|MakePointerAvailableKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad"));
- }
- TEST_F(ValidateIdWithMessage, VulkanMemoryModelStoreMakePointerAvailableGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpVariable %3 Uniform
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 5
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- OpStore %4 %6 NonPrivatePointerKHR|MakePointerAvailableKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelStoreMakePointerAvailableMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpVariable %3 Uniform
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 5
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- OpStore %4 %6 MakePointerAvailableKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR must be specified if "
- "MakePointerAvailableKHR is specified."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelStoreNonPrivatePointerBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Output %2
- %4 = OpVariable %3 Output
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 5
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- OpStore %4 %6 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelStoreMakePointerVisibleCannotBeUsed) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpVariable %3 Uniform
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 5
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- OpStore %4 %6 NonPrivatePointerKHR|MakePointerVisibleKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("MakePointerVisibleKHR cannot be used with OpStore."));
- }
- TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemoryAvailable) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR|MakePointerAvailableKHR %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemoryVisible) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR|MakePointerVisibleKHR %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemoryAvailableAndVisible) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR|MakePointerAvailableKHR|MakePointerVisibleKHR %7 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemoryAvailableMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 MakePointerAvailableKHR %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR must be specified if "
- "MakePointerAvailableKHR is specified."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemoryVisibleMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 MakePointerVisibleKHR %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR must be specified if "
- "MakePointerVisibleKHR is specified."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemoryAvailableBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Output %2
- %4 = OpVariable %3 Output
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemoryVisibleBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Input %2
- %6 = OpVariable %5 Input
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes."));
- }
- TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemorySizedAvailable) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR|MakePointerAvailableKHR %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemorySizedVisible) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR|MakePointerVisibleKHR %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedAvailableAndVisible) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR|MakePointerAvailableKHR|MakePointerVisibleKHR %7 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedAvailableMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %7 MakePointerAvailableKHR %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR must be specified if "
- "MakePointerAvailableKHR is specified."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedVisibleMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %7 MakePointerVisibleKHR %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR must be specified if "
- "MakePointerVisibleKHR is specified."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedAvailableBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Output %2
- %4 = OpVariable %3 Output
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes."));
- }
- TEST_F(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedVisibleBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Input %2
- %6 = OpVariable %5 Input
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes."));
- }
- TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock1) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpFunctionCall %3 %9
- OpUnreachable
- OpFunctionEnd
- %9 = OpFunction %3 None %4
- %10 = OpLabel
- OpReturnValue %8
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID 8[%8] defined in block 7[%7] does not dominate its "
- "use in block 10[%10]\n %10 = OpLabel"));
- }
- TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock2) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpFunctionCall %3 %9
- OpUnreachable
- OpFunctionEnd
- %9 = OpFunction %3 None %4
- %10 = OpLabel
- OpReturnValue %8
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID 8[%8] defined in block 7[%7] does not dominate its "
- "use in block 10[%10]\n %10 = OpLabel"));
- }
- TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock3) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpFunctionCall %3 %9
- OpReturn
- OpFunctionEnd
- %9 = OpFunction %3 None %4
- %10 = OpLabel
- OpReturnValue %8
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID 8[%8] defined in block 7[%7] does not dominate its "
- "use in block 10[%10]\n %10 = OpLabel"));
- }
- TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock4) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpUndef %3
- %9 = OpCopyObject %3 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock5) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpUndef %3
- OpBranch %9
- %9 = OpLabel
- %10 = OpCopyObject %3 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock6) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpBranch %7
- %8 = OpLabel
- %9 = OpUndef %3
- OpBranch %7
- %7 = OpLabel
- %10 = OpCopyObject %3 %9
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("ID 9[%9] defined in block 8[%8] does not dominate its "
- "use in block 7[%7]\n %7 = OpLabel"));
- }
- TEST_F(ValidateIdWithMessage, ReachableDefUnreachableUse) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- %7 = OpUndef %3
- OpReturn
- %8 = OpLabel
- %9 = OpCopyObject %3 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_F(ValidateIdWithMessage, UnreachableDefUsedInPhi) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %bool = OpTypeBool
- %6 = OpTypeFunction %float
- %1 = OpFunction %void None %3
- %7 = OpLabel
- %8 = OpUndef %bool
- OpSelectionMerge %9 None
- OpBranchConditional %8 %10 %9
- %10 = OpLabel
- %11 = OpUndef %float
- OpBranch %9
- %12 = OpLabel
- %13 = OpUndef %float
- OpUnreachable
- %9 = OpLabel
- %14 = OpPhi %float %11 %10 %13 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("In OpPhi instruction 14[%14], ID 13[%13] definition does not "
- "dominate its parent 7[%7]\n %14 = OpPhi %float %11 %10 %13 "
- "%7"));
- }
- TEST_F(ValidateIdWithMessage, OpTypeForwardPointerNotAPointerType) {
- std::string spirv = R"(
- OpCapability GenericPointer
- OpCapability VariablePointersStorageBuffer
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginLowerLeft
- OpTypeForwardPointer %2 CrossWorkgroup
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %1 = OpFunction %2 DontInline %3
- %4 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Pointer type in OpTypeForwardPointer is not a pointer "
- "type.\n OpTypeForwardPointer %void CrossWorkgroup"));
- }
- TEST_F(ValidateIdWithMessage, OpTypeForwardPointerWrongStorageClass) {
- std::string spirv = R"(
- OpCapability GenericPointer
- OpCapability VariablePointersStorageBuffer
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginLowerLeft
- OpTypeForwardPointer %2 CrossWorkgroup
- %int = OpTypeInt 32 1
- %2 = OpTypePointer Function %int
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %1 = OpFunction %void None %3
- %4 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Storage class in OpTypeForwardPointer does not match the "
- "pointer definition.\n OpTypeForwardPointer "
- "%_ptr_Function_int CrossWorkgroup"));
- }
- TEST_F(ValidateIdWithMessage, MissingForwardPointer) {
- const std::string spirv = R"(
- OpCapability Linkage
- OpCapability Shader
- OpMemoryModel Logical Simple
- %float = OpTypeFloat 32
- %_struct_9 = OpTypeStruct %float %_ptr_Uniform__struct_9
- %_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
- %1278 = OpVariable %_ptr_Uniform__struct_9 Uniform
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "Operand 3[%_ptr_Uniform__struct_2] requires a previous definition"));
- }
- } // namespace
- } // namespace val
- } // namespace spvtools
|