val_image_test.cpp 245 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402
  1. // Copyright (c) 2017 Google Inc.
  2. // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
  3. // reserved.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. // Tests for unique type declaration rules validator.
  17. #include <sstream>
  18. #include <string>
  19. #include "gmock/gmock.h"
  20. #include "test/unit_spirv.h"
  21. #include "test/val/val_fixtures.h"
  22. namespace spvtools {
  23. namespace val {
  24. namespace {
  25. using ::testing::Eq;
  26. using ::testing::HasSubstr;
  27. using ::testing::Not;
  28. using ValidateImage = spvtest::ValidateBase<bool>;
  29. std::string GenerateShaderCode(
  30. const std::string& body,
  31. const std::string& capabilities_and_extensions = "",
  32. const std::string& execution_model = "Fragment",
  33. const std::string& execution_mode = "",
  34. const spv_target_env env = SPV_ENV_UNIVERSAL_1_0,
  35. const std::string& memory_model = "GLSL450",
  36. const std::string& declarations = "") {
  37. std::ostringstream ss;
  38. ss << R"(
  39. OpCapability Shader
  40. OpCapability InputAttachment
  41. OpCapability ImageGatherExtended
  42. OpCapability MinLod
  43. OpCapability Sampled1D
  44. OpCapability ImageQuery
  45. OpCapability Int64
  46. OpCapability Float64
  47. OpCapability SparseResidency
  48. OpCapability ImageBuffer
  49. )";
  50. if (env == SPV_ENV_UNIVERSAL_1_0) {
  51. ss << "OpCapability SampledRect\n";
  52. }
  53. // In 1.4, the entry point must list all module-scope variables used. Just
  54. // list all of them.
  55. //
  56. // For Vulkan, anything Location decoration needs to be an interface variable
  57. std::string interface_vars =
  58. (env != SPV_ENV_UNIVERSAL_1_4) ? "%input_flat_u32" :
  59. R"(
  60. %uniform_image_f32_1d_0001
  61. %uniform_image_f32_1d_0002_rgba32f
  62. %uniform_image_f32_2d_0001
  63. %uniform_image_f32_2d_0011 ; multisampled sampled
  64. %uniform_image_u32_2d_0001
  65. %uniform_image_u32_2d_0002
  66. %uniform_image_s32_3d_0001
  67. %uniform_image_f32_2d_0002
  68. %uniform_image_s32_2d_0002
  69. %uniform_image_f32_spd_0002
  70. %uniform_image_f32_3d_0111
  71. %uniform_image_f32_cube_0101
  72. %uniform_image_f32_cube_0102_rgba32f
  73. %uniform_sampler
  74. %private_image_u32_buffer_0002_r32ui
  75. %private_image_u32_spd_0002
  76. %private_image_f32_buffer_0002_r32ui
  77. %input_flat_u32
  78. )";
  79. ss << capabilities_and_extensions;
  80. ss << "OpMemoryModel Logical " << memory_model << "\n";
  81. ss << "OpEntryPoint " << execution_model
  82. << " %main \"main\" " + interface_vars + "\n";
  83. if (execution_model == "Fragment") {
  84. ss << "OpExecutionMode %main OriginUpperLeft\n";
  85. }
  86. ss << execution_mode;
  87. if (env == SPV_ENV_VULKAN_1_0) {
  88. ss << R"(
  89. OpDecorate %uniform_image_f32_1d_0001 DescriptorSet 0
  90. OpDecorate %uniform_image_f32_1d_0001 Binding 0
  91. OpDecorate %uniform_image_f32_1d_0002_rgba32f DescriptorSet 0
  92. OpDecorate %uniform_image_f32_1d_0002_rgba32f Binding 1
  93. OpDecorate %uniform_image_f32_2d_0001 DescriptorSet 0
  94. OpDecorate %uniform_image_f32_2d_0001 Binding 2
  95. OpDecorate %uniform_image_f32_2d_0011 DescriptorSet 0
  96. OpDecorate %uniform_image_f32_2d_0011 Binding 3
  97. OpDecorate %uniform_image_u32_2d_0001 DescriptorSet 1
  98. OpDecorate %uniform_image_u32_2d_0001 Binding 0
  99. OpDecorate %uniform_image_u32_2d_0002 DescriptorSet 1
  100. OpDecorate %uniform_image_u32_2d_0002 Binding 1
  101. OpDecorate %uniform_image_s32_3d_0001 DescriptorSet 1
  102. OpDecorate %uniform_image_s32_3d_0001 Binding 2
  103. OpDecorate %uniform_image_f32_2d_0002 DescriptorSet 1
  104. OpDecorate %uniform_image_f32_2d_0002 Binding 3
  105. OpDecorate %uniform_image_s32_2d_0002 DescriptorSet 1
  106. OpDecorate %uniform_image_s32_2d_0002 Binding 4
  107. OpDecorate %uniform_image_f32_spd_0002 DescriptorSet 2
  108. OpDecorate %uniform_image_f32_spd_0002 Binding 0
  109. OpDecorate %uniform_image_f32_3d_0111 DescriptorSet 2
  110. OpDecorate %uniform_image_f32_3d_0111 Binding 1
  111. OpDecorate %uniform_image_f32_cube_0101 DescriptorSet 2
  112. OpDecorate %uniform_image_f32_cube_0101 Binding 2
  113. OpDecorate %uniform_image_f32_cube_0102_rgba32f DescriptorSet 2
  114. OpDecorate %uniform_image_f32_cube_0102_rgba32f Binding 3
  115. OpDecorate %uniform_sampler DescriptorSet 3
  116. OpDecorate %uniform_sampler Binding 0
  117. OpDecorate %input_flat_u32 Flat
  118. OpDecorate %input_flat_u32 Location 0
  119. )";
  120. }
  121. ss << R"(
  122. %void = OpTypeVoid
  123. %func = OpTypeFunction %void
  124. %bool = OpTypeBool
  125. %f32 = OpTypeFloat 32
  126. %f64 = OpTypeFloat 64
  127. %u32 = OpTypeInt 32 0
  128. %s32 = OpTypeInt 32 1
  129. %u64 = OpTypeInt 64 0
  130. %s64 = OpTypeInt 64 1
  131. %s32vec2 = OpTypeVector %s32 2
  132. %u32vec2 = OpTypeVector %u32 2
  133. %f32vec2 = OpTypeVector %f32 2
  134. %u32vec3 = OpTypeVector %u32 3
  135. %s32vec3 = OpTypeVector %s32 3
  136. %f32vec3 = OpTypeVector %f32 3
  137. %u32vec4 = OpTypeVector %u32 4
  138. %s32vec4 = OpTypeVector %s32 4
  139. %f32vec4 = OpTypeVector %f32 4
  140. %boolvec4 = OpTypeVector %bool 4
  141. %f32_0 = OpConstant %f32 0
  142. %f32_1 = OpConstant %f32 1
  143. %f32_0_5 = OpConstant %f32 0.5
  144. %f32_0_25 = OpConstant %f32 0.25
  145. %f32_0_75 = OpConstant %f32 0.75
  146. %f64_0 = OpConstant %f64 0
  147. %f64_1 = OpConstant %f64 1
  148. %s32_0 = OpConstant %s32 0
  149. %s32_1 = OpConstant %s32 1
  150. %s32_2 = OpConstant %s32 2
  151. %s32_3 = OpConstant %s32 3
  152. %s32_4 = OpConstant %s32 4
  153. %s32_m1 = OpConstant %s32 -1
  154. %u32_0 = OpConstant %u32 0
  155. %u32_1 = OpConstant %u32 1
  156. %u32_2 = OpConstant %u32 2
  157. %u32_3 = OpConstant %u32 3
  158. %u32_4 = OpConstant %u32 4
  159. %u64_0 = OpConstant %u64 0
  160. %u64_1 = OpConstant %u64 1
  161. %bool_t = OpConstantTrue %bool
  162. %u32vec2arr4 = OpTypeArray %u32vec2 %u32_4
  163. %u32vec2arr3 = OpTypeArray %u32vec2 %u32_3
  164. %u32arr4 = OpTypeArray %u32 %u32_4
  165. %u32vec3arr4 = OpTypeArray %u32vec3 %u32_4
  166. %struct_u32_f32vec4 = OpTypeStruct %u32 %f32vec4
  167. %struct_u64_f32vec4 = OpTypeStruct %u64 %f32vec4
  168. %struct_u32_u32vec4 = OpTypeStruct %u32 %u32vec4
  169. %struct_u32_f32vec3 = OpTypeStruct %u32 %f32vec3
  170. %struct_f32_f32vec4 = OpTypeStruct %f32 %f32vec4
  171. %struct_u32_u32 = OpTypeStruct %u32 %u32
  172. %struct_f32_f32 = OpTypeStruct %f32 %f32
  173. %struct_u32 = OpTypeStruct %u32
  174. %struct_u32_f32_u32 = OpTypeStruct %u32 %f32 %u32
  175. %struct_u32_f32vec4_u32 = OpTypeStruct %u32 %f32vec4 %u32
  176. %struct_u32_u32arr4 = OpTypeStruct %u32 %u32arr4
  177. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  178. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  179. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  180. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  181. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  182. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  183. %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
  184. %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
  185. %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
  186. %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
  187. %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
  188. %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
  189. %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
  190. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  191. %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
  192. %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
  193. %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
  194. %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
  195. %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
  196. %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
  197. %boolvec4_tttt = OpConstantComposite %boolvec4 %bool_t %bool_t %bool_t %bool_t
  198. %const_offsets = OpConstantComposite %u32vec2arr4 %u32vec2_01 %u32vec2_12 %u32vec2_01 %u32vec2_12
  199. %const_offsets3x2 = OpConstantComposite %u32vec2arr3 %u32vec2_01 %u32vec2_12 %u32vec2_01
  200. %const_offsets4xu = OpConstantComposite %u32arr4 %u32_0 %u32_0 %u32_0 %u32_0
  201. %const_offsets4x3 = OpConstantComposite %u32vec3arr4 %u32vec3_012 %u32vec3_012 %u32vec3_012 %u32vec3_012
  202. %type_image_f32_1d_0001 = OpTypeImage %f32 1D 0 0 0 1 Unknown
  203. %ptr_image_f32_1d_0001 = OpTypePointer UniformConstant %type_image_f32_1d_0001
  204. %uniform_image_f32_1d_0001 = OpVariable %ptr_image_f32_1d_0001 UniformConstant
  205. %type_sampled_image_f32_1d_0001 = OpTypeSampledImage %type_image_f32_1d_0001
  206. %type_image_f32_1d_0002_rgba32f = OpTypeImage %f32 1D 0 0 0 2 Rgba32f
  207. %ptr_image_f32_1d_0002_rgba32f = OpTypePointer UniformConstant %type_image_f32_1d_0002_rgba32f
  208. %uniform_image_f32_1d_0002_rgba32f = OpVariable %ptr_image_f32_1d_0002_rgba32f UniformConstant
  209. %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
  210. %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
  211. %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
  212. %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
  213. %type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown
  214. %ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011
  215. %uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant
  216. %type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011
  217. %type_image_u32_2d_0001 = OpTypeImage %u32 2D 0 0 0 1 Unknown
  218. %ptr_image_u32_2d_0001 = OpTypePointer UniformConstant %type_image_u32_2d_0001
  219. %uniform_image_u32_2d_0001 = OpVariable %ptr_image_u32_2d_0001 UniformConstant
  220. %type_sampled_image_u32_2d_0001 = OpTypeSampledImage %type_image_u32_2d_0001
  221. %type_image_u32_3d_0001 = OpTypeImage %u32 3D 0 0 0 1 Unknown
  222. %ptr_image_u32_3d_0001 = OpTypePointer UniformConstant %type_image_u32_3d_0001
  223. %uniform_image_u32_3d_0001 = OpVariable %ptr_image_u32_3d_0001 UniformConstant
  224. %type_sampled_image_u32_3d_0001 = OpTypeSampledImage %type_image_u32_3d_0001
  225. %type_image_u32_2d_0002 = OpTypeImage %u32 2D 0 0 0 2 Unknown
  226. %ptr_image_u32_2d_0002 = OpTypePointer UniformConstant %type_image_u32_2d_0002
  227. %uniform_image_u32_2d_0002 = OpVariable %ptr_image_u32_2d_0002 UniformConstant
  228. %type_image_s32_3d_0001 = OpTypeImage %s32 3D 0 0 0 1 Unknown
  229. %ptr_image_s32_3d_0001 = OpTypePointer UniformConstant %type_image_s32_3d_0001
  230. %uniform_image_s32_3d_0001 = OpVariable %ptr_image_s32_3d_0001 UniformConstant
  231. %type_sampled_image_s32_3d_0001 = OpTypeSampledImage %type_image_s32_3d_0001
  232. %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Unknown
  233. %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
  234. %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
  235. %type_image_s32_2d_0002 = OpTypeImage %s32 2D 0 0 0 2 Unknown
  236. %ptr_image_s32_2d_0002 = OpTypePointer UniformConstant %type_image_s32_2d_0002
  237. %uniform_image_s32_2d_0002 = OpVariable %ptr_image_s32_2d_0002 UniformConstant
  238. %type_image_f32_spd_0002 = OpTypeImage %f32 SubpassData 0 0 0 2 Unknown
  239. %ptr_image_f32_spd_0002 = OpTypePointer UniformConstant %type_image_f32_spd_0002
  240. %uniform_image_f32_spd_0002 = OpVariable %ptr_image_f32_spd_0002 UniformConstant
  241. %type_image_f32_3d_0111 = OpTypeImage %f32 3D 0 1 1 1 Unknown
  242. %ptr_image_f32_3d_0111 = OpTypePointer UniformConstant %type_image_f32_3d_0111
  243. %uniform_image_f32_3d_0111 = OpVariable %ptr_image_f32_3d_0111 UniformConstant
  244. %type_sampled_image_f32_3d_0111 = OpTypeSampledImage %type_image_f32_3d_0111
  245. %type_image_f32_3d_0001 = OpTypeImage %f32 3D 0 0 0 1 Unknown
  246. %ptr_image_f32_3d_0001 = OpTypePointer UniformConstant %type_image_f32_3d_0001
  247. %uniform_image_f32_3d_0001 = OpVariable %ptr_image_f32_3d_0001 UniformConstant
  248. %type_sampled_image_f32_3d_0001 = OpTypeSampledImage %type_image_f32_3d_0001
  249. %type_image_f32_cube_0101 = OpTypeImage %f32 Cube 0 1 0 1 Unknown
  250. %ptr_image_f32_cube_0101 = OpTypePointer UniformConstant %type_image_f32_cube_0101
  251. %uniform_image_f32_cube_0101 = OpVariable %ptr_image_f32_cube_0101 UniformConstant
  252. %type_sampled_image_f32_cube_0101 = OpTypeSampledImage %type_image_f32_cube_0101
  253. %type_image_f32_cube_0102_rgba32f = OpTypeImage %f32 Cube 0 1 0 2 Rgba32f
  254. %ptr_image_f32_cube_0102_rgba32f = OpTypePointer UniformConstant %type_image_f32_cube_0102_rgba32f
  255. %uniform_image_f32_cube_0102_rgba32f = OpVariable %ptr_image_f32_cube_0102_rgba32f UniformConstant
  256. %type_sampler = OpTypeSampler
  257. %ptr_sampler = OpTypePointer UniformConstant %type_sampler
  258. %uniform_sampler = OpVariable %ptr_sampler UniformConstant
  259. %type_image_u32_buffer_0002_r32ui = OpTypeImage %u32 Buffer 0 0 0 2 R32ui
  260. %ptr_Image_u32 = OpTypePointer Image %u32
  261. %ptr_image_u32_buffer_0002_r32ui = OpTypePointer Private %type_image_u32_buffer_0002_r32ui
  262. %private_image_u32_buffer_0002_r32ui = OpVariable %ptr_image_u32_buffer_0002_r32ui Private
  263. %ptr_Image_u32arr4 = OpTypePointer Image %u32arr4
  264. %type_image_u32_spd_0002 = OpTypeImage %u32 SubpassData 0 0 0 2 Unknown
  265. %ptr_image_u32_spd_0002 = OpTypePointer Private %type_image_u32_spd_0002
  266. %private_image_u32_spd_0002 = OpVariable %ptr_image_u32_spd_0002 Private
  267. %type_image_f32_buffer_0002_r32ui = OpTypeImage %f32 Buffer 0 0 0 2 R32ui
  268. %ptr_Image_f32 = OpTypePointer Image %f32
  269. %ptr_image_f32_buffer_0002_r32ui = OpTypePointer Private %type_image_f32_buffer_0002_r32ui
  270. %private_image_f32_buffer_0002_r32ui = OpVariable %ptr_image_f32_buffer_0002_r32ui Private
  271. %ptr_input_flat_u32 = OpTypePointer Input %u32
  272. %input_flat_u32 = OpVariable %ptr_input_flat_u32 Input
  273. )";
  274. if (env == SPV_ENV_UNIVERSAL_1_0) {
  275. ss << R"(
  276. %type_image_void_2d_0001 = OpTypeImage %void 2D 0 0 0 1 Unknown
  277. %ptr_image_void_2d_0001 = OpTypePointer UniformConstant %type_image_void_2d_0001
  278. %uniform_image_void_2d_0001 = OpVariable %ptr_image_void_2d_0001 UniformConstant
  279. %type_sampled_image_void_2d_0001 = OpTypeSampledImage %type_image_void_2d_0001
  280. %type_image_void_2d_0002 = OpTypeImage %void 2D 0 0 0 2 Unknown
  281. %ptr_image_void_2d_0002 = OpTypePointer UniformConstant %type_image_void_2d_0002
  282. %uniform_image_void_2d_0002 = OpVariable %ptr_image_void_2d_0002 UniformConstant
  283. %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
  284. %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
  285. %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
  286. %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
  287. )";
  288. }
  289. ss << declarations;
  290. ss << R"(
  291. %main = OpFunction %void None %func
  292. %main_entry = OpLabel
  293. )";
  294. ss << body;
  295. ss << R"(
  296. OpReturn
  297. OpFunctionEnd)";
  298. return ss.str();
  299. }
  300. std::string GenerateKernelCode(
  301. const std::string& body,
  302. const std::string& capabilities_and_extensions = "") {
  303. std::ostringstream ss;
  304. ss << R"(
  305. OpCapability Addresses
  306. OpCapability Kernel
  307. OpCapability Linkage
  308. OpCapability ImageQuery
  309. OpCapability ImageGatherExtended
  310. OpCapability InputAttachment
  311. OpCapability SampledRect
  312. )";
  313. ss << capabilities_and_extensions;
  314. ss << R"(
  315. OpMemoryModel Physical32 OpenCL
  316. %void = OpTypeVoid
  317. %func = OpTypeFunction %void
  318. %bool = OpTypeBool
  319. %f32 = OpTypeFloat 32
  320. %u32 = OpTypeInt 32 0
  321. %u32vec2 = OpTypeVector %u32 2
  322. %f32vec2 = OpTypeVector %f32 2
  323. %u32vec3 = OpTypeVector %u32 3
  324. %f32vec3 = OpTypeVector %f32 3
  325. %u32vec4 = OpTypeVector %u32 4
  326. %f32vec4 = OpTypeVector %f32 4
  327. %f32_0 = OpConstant %f32 0
  328. %f32_1 = OpConstant %f32 1
  329. %f32_0_5 = OpConstant %f32 0.5
  330. %f32_0_25 = OpConstant %f32 0.25
  331. %f32_0_75 = OpConstant %f32 0.75
  332. %u32_0 = OpConstant %u32 0
  333. %u32_1 = OpConstant %u32 1
  334. %u32_2 = OpConstant %u32 2
  335. %u32_3 = OpConstant %u32 3
  336. %u32_4 = OpConstant %u32 4
  337. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  338. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  339. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  340. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  341. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  342. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  343. %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
  344. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  345. %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
  346. %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
  347. %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
  348. %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
  349. %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
  350. %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
  351. %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
  352. %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
  353. %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
  354. %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
  355. %type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown
  356. %ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011
  357. %uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant
  358. %type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011
  359. %type_image_f32_3d_0011 = OpTypeImage %f32 3D 0 0 1 1 Unknown
  360. %ptr_image_f32_3d_0011 = OpTypePointer UniformConstant %type_image_f32_3d_0011
  361. %uniform_image_f32_3d_0011 = OpVariable %ptr_image_f32_3d_0011 UniformConstant
  362. %type_sampled_image_f32_3d_0011 = OpTypeSampledImage %type_image_f32_3d_0011
  363. %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
  364. %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
  365. %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
  366. %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
  367. %type_sampler = OpTypeSampler
  368. %ptr_sampler = OpTypePointer UniformConstant %type_sampler
  369. %uniform_sampler = OpVariable %ptr_sampler UniformConstant
  370. %main = OpFunction %void None %func
  371. %main_entry = OpLabel
  372. )";
  373. ss << body;
  374. ss << R"(
  375. OpReturn
  376. OpFunctionEnd)";
  377. return ss.str();
  378. }
  379. std::string GetKernelHeader() {
  380. return R"(
  381. OpCapability Kernel
  382. OpCapability Addresses
  383. OpCapability Linkage
  384. OpMemoryModel Physical32 OpenCL
  385. %void = OpTypeVoid
  386. %func = OpTypeFunction %void
  387. %f32 = OpTypeFloat 32
  388. %u32 = OpTypeInt 32 0
  389. )";
  390. }
  391. std::string TrivialMain() {
  392. return R"(
  393. %main = OpFunction %void None %func
  394. %entry = OpLabel
  395. OpReturn
  396. OpFunctionEnd
  397. )";
  398. }
  399. std::string GetShaderHeader(const std::string& capabilities_and_extensions = "",
  400. bool include_entry_point = true) {
  401. std::ostringstream ss;
  402. ss << R"(
  403. OpCapability Shader
  404. OpCapability Int64
  405. OpCapability Float64
  406. )";
  407. ss << capabilities_and_extensions;
  408. if (!include_entry_point) {
  409. ss << "OpCapability Linkage";
  410. }
  411. ss << R"(
  412. OpMemoryModel Logical GLSL450
  413. )";
  414. if (include_entry_point) {
  415. ss << "OpEntryPoint Fragment %main \"main\"\n";
  416. ss << "OpExecutionMode %main OriginUpperLeft";
  417. }
  418. ss << R"(
  419. %void = OpTypeVoid
  420. %func = OpTypeFunction %void
  421. %bool = OpTypeBool
  422. %f32 = OpTypeFloat 32
  423. %f64 = OpTypeFloat 64
  424. %u32 = OpTypeInt 32 0
  425. %u64 = OpTypeInt 64 0
  426. %s32 = OpTypeInt 32 1
  427. %s64 = OpTypeInt 64 1
  428. )";
  429. return ss.str();
  430. }
  431. TEST_F(ValidateImage, TypeImageWrongSampledType) {
  432. const std::string code = GetShaderHeader("", false) + R"(
  433. %img_type = OpTypeImage %bool 2D 0 0 0 1 Unknown
  434. )";
  435. CompileSuccessfully(code.c_str());
  436. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  437. EXPECT_THAT(getDiagnosticString(),
  438. HasSubstr("Expected Sampled Type to be either void or "
  439. "numerical scalar "
  440. "type"));
  441. }
  442. TEST_F(ValidateImage, TypeImageVoidSampledTypeVulkan) {
  443. const std::string code = GetShaderHeader() + R"(
  444. %img_type = OpTypeImage %void 2D 0 0 0 1 Unknown
  445. %main = OpFunction %void None %func
  446. %main_lab = OpLabel
  447. OpReturn
  448. OpFunctionEnd
  449. )";
  450. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  451. CompileSuccessfully(code, env);
  452. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  453. EXPECT_THAT(getDiagnosticString(),
  454. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
  455. EXPECT_THAT(getDiagnosticString(),
  456. HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
  457. "or 32-bit float scalar type for Vulkan environment"));
  458. }
  459. TEST_F(ValidateImage, TypeImageU32SampledTypeVulkan) {
  460. const std::string code = GetShaderHeader() + R"(
  461. %img_type = OpTypeImage %u32 2D 0 0 0 1 Unknown
  462. %main = OpFunction %void None %func
  463. %main_lab = OpLabel
  464. OpReturn
  465. OpFunctionEnd
  466. )";
  467. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  468. CompileSuccessfully(code, env);
  469. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  470. EXPECT_THAT(getDiagnosticString(), Eq(""));
  471. }
  472. TEST_F(ValidateImage, TypeImageI32SampledTypeVulkan) {
  473. const std::string code = GetShaderHeader() + R"(
  474. %img_type = OpTypeImage %s32 2D 0 0 0 1 Unknown
  475. %main = OpFunction %void None %func
  476. %main_lab = OpLabel
  477. OpReturn
  478. OpFunctionEnd
  479. )";
  480. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  481. CompileSuccessfully(code, env);
  482. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  483. EXPECT_THAT(getDiagnosticString(), Eq(""));
  484. }
  485. TEST_F(ValidateImage, TypeImageI64SampledTypeNoCapabilityVulkan) {
  486. const std::string code = GetShaderHeader() + R"(
  487. %img_type = OpTypeImage %s64 2D 0 0 0 1 Unknown
  488. %main = OpFunction %void None %func
  489. %main_lab = OpLabel
  490. OpReturn
  491. OpFunctionEnd
  492. )";
  493. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  494. CompileSuccessfully(code, env);
  495. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  496. EXPECT_THAT(getDiagnosticString(),
  497. HasSubstr("Capability Int64ImageEXT is required when using "
  498. "Sampled Type of 64-bit int"));
  499. }
  500. TEST_F(ValidateImage, TypeImageI64SampledTypeVulkan) {
  501. const std::string code = GetShaderHeader(
  502. "OpCapability Int64ImageEXT\nOpExtension "
  503. "\"SPV_EXT_shader_image_int64\"\n") +
  504. R"(
  505. %img_type = OpTypeImage %s64 2D 0 0 0 1 Unknown
  506. %main = OpFunction %void None %func
  507. %main_lab = OpLabel
  508. OpReturn
  509. OpFunctionEnd
  510. )";
  511. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  512. CompileSuccessfully(code, env);
  513. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  514. EXPECT_THAT(getDiagnosticString(), Eq(""));
  515. }
  516. TEST_F(ValidateImage, TypeImageU64SampledTypeNoCapabilityVulkan) {
  517. const std::string code = GetShaderHeader() + R"(
  518. %img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
  519. %main = OpFunction %void None %func
  520. %main_lab = OpLabel
  521. OpReturn
  522. OpFunctionEnd
  523. )";
  524. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  525. CompileSuccessfully(code, env);
  526. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  527. EXPECT_THAT(getDiagnosticString(),
  528. HasSubstr("Capability Int64ImageEXT is required when using "
  529. "Sampled Type of 64-bit int"));
  530. }
  531. TEST_F(ValidateImage, TypeImageU64SampledTypeVulkan) {
  532. const std::string code = GetShaderHeader(
  533. "OpCapability Int64ImageEXT\nOpExtension "
  534. "\"SPV_EXT_shader_image_int64\"\n") +
  535. R"(
  536. %img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
  537. %main = OpFunction %void None %func
  538. %main_lab = OpLabel
  539. OpReturn
  540. OpFunctionEnd
  541. )";
  542. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  543. CompileSuccessfully(code, env);
  544. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  545. EXPECT_THAT(getDiagnosticString(), Eq(""));
  546. }
  547. TEST_F(ValidateImage, TypeImageF32SampledTypeVulkan) {
  548. const std::string code = GetShaderHeader() + R"(
  549. %img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown
  550. %main = OpFunction %void None %func
  551. %main_lab = OpLabel
  552. OpReturn
  553. OpFunctionEnd
  554. )";
  555. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  556. CompileSuccessfully(code, env);
  557. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  558. EXPECT_THAT(getDiagnosticString(), Eq(""));
  559. }
  560. TEST_F(ValidateImage, TypeImageF64SampledTypeVulkan) {
  561. const std::string code = GetShaderHeader() + R"(
  562. %img_type = OpTypeImage %f64 2D 0 0 0 1 Unknown
  563. %main = OpFunction %void None %func
  564. %main_lab = OpLabel
  565. OpReturn
  566. OpFunctionEnd
  567. )";
  568. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  569. CompileSuccessfully(code, env);
  570. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  571. EXPECT_THAT(getDiagnosticString(),
  572. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
  573. EXPECT_THAT(getDiagnosticString(),
  574. HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
  575. "or 32-bit float scalar type for Vulkan environment"));
  576. }
  577. TEST_F(ValidateImage, TypeImageF64SampledTypeWithInt64Vulkan) {
  578. const std::string code = GetShaderHeader(
  579. "OpCapability Int64ImageEXT\nOpExtension "
  580. "\"SPV_EXT_shader_image_int64\"\n") +
  581. R"(
  582. %img_type = OpTypeImage %f64 2D 0 0 0 1 Unknown
  583. %main = OpFunction %void None %func
  584. %main_lab = OpLabel
  585. OpReturn
  586. OpFunctionEnd
  587. )";
  588. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  589. CompileSuccessfully(code, env);
  590. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  591. EXPECT_THAT(getDiagnosticString(),
  592. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
  593. EXPECT_THAT(getDiagnosticString(),
  594. HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
  595. "or 32-bit float scalar type for Vulkan environment"));
  596. }
  597. TEST_F(ValidateImage, TypeImageWrongDepth) {
  598. const std::string code = GetShaderHeader("", false) + R"(
  599. %img_type = OpTypeImage %f32 2D 3 0 0 1 Unknown
  600. )";
  601. CompileSuccessfully(code.c_str());
  602. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  603. EXPECT_THAT(getDiagnosticString(),
  604. HasSubstr("Invalid Depth 3 (must be 0, 1 or 2)"));
  605. }
  606. TEST_F(ValidateImage, TypeImageWrongArrayed) {
  607. const std::string code = GetShaderHeader("", false) + R"(
  608. %img_type = OpTypeImage %f32 2D 0 2 0 1 Unknown
  609. )";
  610. CompileSuccessfully(code.c_str());
  611. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  612. EXPECT_THAT(getDiagnosticString(),
  613. HasSubstr("Invalid Arrayed 2 (must be 0 or 1)"));
  614. }
  615. TEST_F(ValidateImage, TypeImageWrongMS) {
  616. const std::string code = GetShaderHeader("", false) + R"(
  617. %img_type = OpTypeImage %f32 2D 0 0 2 1 Unknown
  618. )";
  619. CompileSuccessfully(code.c_str());
  620. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  621. EXPECT_THAT(getDiagnosticString(),
  622. HasSubstr("Invalid MS 2 (must be 0 or 1)"));
  623. }
  624. TEST_F(ValidateImage, TypeImageWrongSampled) {
  625. const std::string code = GetShaderHeader("", false) + R"(
  626. %img_type = OpTypeImage %f32 2D 0 0 0 3 Unknown
  627. )";
  628. CompileSuccessfully(code.c_str());
  629. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  630. EXPECT_THAT(getDiagnosticString(),
  631. HasSubstr("Invalid Sampled 3 (must be 0, 1 or 2)"));
  632. }
  633. TEST_F(ValidateImage, TypeImageWrongSampledForSubpassData) {
  634. const std::string code =
  635. GetShaderHeader("OpCapability InputAttachment\n", false) +
  636. R"(
  637. %img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
  638. )";
  639. CompileSuccessfully(code.c_str());
  640. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  641. EXPECT_THAT(getDiagnosticString(),
  642. HasSubstr("Dim SubpassData requires Sampled to be 2"));
  643. }
  644. TEST_F(ValidateImage, TypeImageWrongSampledForSubpassDataVulkan) {
  645. const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
  646. R"(
  647. %img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
  648. )" + TrivialMain();
  649. CompileSuccessfully(code.c_str());
  650. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  651. EXPECT_THAT(getDiagnosticString(),
  652. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06214"));
  653. EXPECT_THAT(getDiagnosticString(),
  654. HasSubstr("Dim SubpassData requires Sampled to be 2"));
  655. }
  656. TEST_F(ValidateImage, TypeImageWrongArrayForSubpassDataVulkan) {
  657. const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
  658. R"(
  659. %img_type = OpTypeImage %f32 SubpassData 0 1 0 2 Unknown
  660. )" + TrivialMain();
  661. CompileSuccessfully(code.c_str());
  662. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  663. EXPECT_THAT(getDiagnosticString(),
  664. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06214"));
  665. EXPECT_THAT(getDiagnosticString(),
  666. HasSubstr("Dim SubpassData requires Arrayed to be 0"));
  667. }
  668. TEST_F(ValidateImage, TypeImage_OpenCL_Sampled0_OK) {
  669. const std::string code = GetKernelHeader() + R"(
  670. %img_type = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
  671. )";
  672. CompileSuccessfully(code.c_str());
  673. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_1));
  674. EXPECT_THAT(getDiagnosticString(), Eq(""));
  675. }
  676. TEST_F(ValidateImage, TypeImage_OpenCL_Sampled1_Invalid) {
  677. const std::string code = GetKernelHeader() + R"(
  678. %img_type = OpTypeImage %void 2D 0 0 0 1 Unknown ReadOnly
  679. )";
  680. CompileSuccessfully(code.c_str());
  681. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
  682. EXPECT_THAT(getDiagnosticString(),
  683. HasSubstr("Sampled must be 0 in the OpenCL environment."));
  684. }
  685. TEST_F(ValidateImage, TypeImage_OpenCL_Sampled2_Invalid) {
  686. const std::string code = GetKernelHeader() + R"(
  687. %img_type = OpTypeImage %void 2D 0 0 0 2 Unknown ReadOnly
  688. )";
  689. CompileSuccessfully(code.c_str());
  690. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
  691. EXPECT_THAT(getDiagnosticString(),
  692. HasSubstr("Sampled must be 0 in the OpenCL environment."));
  693. }
  694. TEST_F(ValidateImage, TypeImage_OpenCL_AccessQualifierMissing) {
  695. const std::string code = GetKernelHeader() + R"(
  696. %img_type = OpTypeImage %void 2D 0 0 0 0 Unknown
  697. )";
  698. CompileSuccessfully(code.c_str());
  699. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
  700. EXPECT_THAT(getDiagnosticString(),
  701. HasSubstr("In the OpenCL environment, the optional Access "
  702. "Qualifier must be present"));
  703. }
  704. TEST_F(ValidateImage, TypeImage_Vulkan_Sampled1_OK) {
  705. const std::string code = GetShaderHeader() + R"(
  706. %img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown
  707. )" + TrivialMain();
  708. CompileSuccessfully(code.c_str());
  709. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  710. EXPECT_THAT(getDiagnosticString(), Eq(""));
  711. }
  712. TEST_F(ValidateImage, TypeImage_Vulkan_Sampled2_OK) {
  713. const std::string code = GetShaderHeader() + R"(
  714. %img_type = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  715. )" + TrivialMain();
  716. CompileSuccessfully(code.c_str());
  717. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  718. EXPECT_THAT(getDiagnosticString(), Eq(""));
  719. }
  720. TEST_F(ValidateImage, TypeImage_Vulkan_Sampled0_Invalid) {
  721. const std::string code = GetShaderHeader() + R"(
  722. %img_type = OpTypeImage %f32 2D 0 0 0 0 Unknown
  723. )" + TrivialMain();
  724. CompileSuccessfully(code.c_str());
  725. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  726. EXPECT_THAT(getDiagnosticString(),
  727. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
  728. EXPECT_THAT(getDiagnosticString(),
  729. HasSubstr("Sampled must be 1 or 2 in the Vulkan environment."));
  730. }
  731. TEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) {
  732. const std::string code =
  733. GetShaderHeader("OpCapability InputAttachment\n", false) +
  734. R"(
  735. %img_type = OpTypeImage %f32 SubpassData 0 0 0 2 Rgba32f
  736. )";
  737. CompileSuccessfully(code.c_str());
  738. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  739. EXPECT_THAT(getDiagnosticString(),
  740. HasSubstr("Dim SubpassData requires format Unknown"));
  741. }
  742. TEST_F(ValidateImage, TypeImageMultisampleStorageImage_MissingCapability) {
  743. const std::string code = GetShaderHeader("", false) +
  744. R"(
  745. %img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
  746. )";
  747. CompileSuccessfully(code.c_str());
  748. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()) << code;
  749. EXPECT_THAT(getDiagnosticString(),
  750. HasSubstr("Capability StorageImageMultisample is required when "
  751. "using multisampled storage image"));
  752. }
  753. TEST_F(ValidateImage, TypeImageMultisampleStorageImage_UsesCapability) {
  754. const std::string code =
  755. GetShaderHeader("OpCapability StorageImageMultisample\n", false) +
  756. R"(
  757. %img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
  758. )";
  759. CompileSuccessfully(code.c_str());
  760. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
  761. EXPECT_THAT(getDiagnosticString(), Eq(""));
  762. }
  763. TEST_F(ValidateImage, TypeImageMultisampleSubpassData_OK) {
  764. const std::string code =
  765. GetShaderHeader("OpCapability InputAttachment\n", false) +
  766. R"(
  767. %img_type = OpTypeImage %f32 SubpassData 0 0 1 2 Unknown
  768. )";
  769. CompileSuccessfully(code.c_str());
  770. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
  771. EXPECT_THAT(getDiagnosticString(), Eq(""));
  772. }
  773. TEST_F(ValidateImage, TypeSampledImage_NotImage_Error) {
  774. const std::string code = GetShaderHeader("", false) + R"(
  775. %simg_type = OpTypeSampledImage %f32
  776. )";
  777. CompileSuccessfully(code.c_str());
  778. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  779. EXPECT_THAT(getDiagnosticString(),
  780. HasSubstr("Expected Image to be of type OpTypeImage"));
  781. }
  782. TEST_F(ValidateImage, TypeSampledImage_Sampled0_Success) {
  783. // This is ok in the OpenCL and universal environments.
  784. // Vulkan will reject an OpTypeImage with Sampled=0, checked elsewhere.
  785. const std::string code = GetShaderHeader() + R"(
  786. %imty = OpTypeImage %f32 2D 0 0 0 0 Unknown
  787. %simg_type = OpTypeSampledImage %imty
  788. )" + TrivialMain();
  789. CompileSuccessfully(code.c_str());
  790. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  791. EXPECT_EQ(getDiagnosticString(), "");
  792. }
  793. TEST_F(ValidateImage, TypeSampledImage_Sampled2_Error) {
  794. const std::string code = GetShaderHeader() + R"(
  795. %storage_image = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  796. %simg_type = OpTypeSampledImage %storage_image
  797. )" + TrivialMain();
  798. CompileSuccessfully(code.c_str());
  799. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  800. EXPECT_THAT(getDiagnosticString(),
  801. HasSubstr("Sampled image type requires an image type with "
  802. "\"Sampled\" operand set to 0 or 1"));
  803. }
  804. TEST_F(ValidateImage, TypeSampledImage_Sampled1_Success) {
  805. const std::string code = GetShaderHeader() + R"(
  806. %im = OpTypeImage %f32 2D 0 0 0 1 Unknown
  807. %simg_type = OpTypeSampledImage %im
  808. )" + TrivialMain();
  809. CompileSuccessfully(code.c_str());
  810. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  811. EXPECT_EQ(getDiagnosticString(), "");
  812. }
  813. TEST_F(ValidateImage, SampledImageSuccess) {
  814. const std::string body = R"(
  815. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  816. %sampler = OpLoad %type_sampler %uniform_sampler
  817. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  818. )";
  819. CompileSuccessfully(GenerateShaderCode(body).c_str());
  820. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  821. }
  822. TEST_F(ValidateImage, SampledImageVulkanSuccess) {
  823. const std::string body = R"(
  824. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  825. %sampler = OpLoad %type_sampler %uniform_sampler
  826. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  827. )";
  828. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  829. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
  830. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  831. }
  832. TEST_F(ValidateImage, SampledImageWrongResultType) {
  833. const std::string body = R"(
  834. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  835. %sampler = OpLoad %type_sampler %uniform_sampler
  836. %simg = OpSampledImage %type_image_f32_2d_0001 %img %sampler
  837. )";
  838. CompileSuccessfully(GenerateShaderCode(body).c_str());
  839. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  840. EXPECT_THAT(getDiagnosticString(),
  841. HasSubstr("Expected Result Type to be OpTypeSampledImage"));
  842. }
  843. TEST_F(ValidateImage, SampledImageNotImage) {
  844. const std::string body = R"(
  845. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  846. %sampler = OpLoad %type_sampler %uniform_sampler
  847. %simg1 = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  848. %simg2 = OpSampledImage %type_sampled_image_f32_2d_0001 %simg1 %sampler
  849. )";
  850. CompileSuccessfully(GenerateShaderCode(body).c_str());
  851. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  852. EXPECT_THAT(getDiagnosticString(),
  853. HasSubstr("Expected Image to be of type OpTypeImage"));
  854. }
  855. TEST_F(ValidateImage, SampledImageImageNotForSampling) {
  856. const std::string code = GetShaderHeader() + R"(
  857. %im_ty = OpTypeImage %f32 2D 0 0 0 2 Unknown
  858. %sampler_ty = OpTypeSampler
  859. %sampled_image_ty = OpTypeSampledImage %im_ty ; will fail here first!
  860. %ptr_im_ty = OpTypePointer UniformConstant %im_ty
  861. %var_im = OpVariable %ptr_im_ty UniformConstant
  862. %ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
  863. %var_sampler = OpVariable %ptr_sampler_ty UniformConstant
  864. %main = OpFunction %void None %func
  865. %entry = OpLabel
  866. %im = OpLoad %im_ty %var_im
  867. %sampler = OpLoad %sampler_ty %var_sampler
  868. %sampled_image = OpSampledImage %sampled_image_ty %im %sampler
  869. OpReturn
  870. OpFunctionEnd
  871. )";
  872. CompileSuccessfully(code.c_str());
  873. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  874. EXPECT_THAT(getDiagnosticString(),
  875. HasSubstr("Sampled image type requires an image type with "
  876. "\"Sampled\" operand set to 0 or 1"))
  877. << code;
  878. }
  879. TEST_F(ValidateImage, SampledImageNotSampler) {
  880. const std::string body = R"(
  881. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  882. %sampler = OpLoad %type_sampler %uniform_sampler
  883. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %img
  884. )";
  885. CompileSuccessfully(GenerateShaderCode(body).c_str());
  886. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  887. EXPECT_THAT(getDiagnosticString(),
  888. HasSubstr("Expected Sampler to be of type OpTypeSampler"));
  889. }
  890. TEST_F(ValidateImage, SampledImageIsStorage) {
  891. const std::string declarations = R"(
  892. %type_sampled_image_f32_2d_0002 = OpTypeSampledImage %type_image_f32_2d_0002
  893. )";
  894. const std::string body = R"(
  895. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  896. %sampler = OpLoad %type_sampler %uniform_sampler
  897. %simg = OpSampledImage %type_sampled_image_f32_2d_0002 %img %sampler
  898. )";
  899. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "",
  900. SPV_ENV_UNIVERSAL_1_0, "GLSL450",
  901. declarations)
  902. .c_str());
  903. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  904. EXPECT_THAT(getDiagnosticString(),
  905. HasSubstr("Sampled image type requires an image type with "
  906. "\"Sampled\" operand set to 0 or 1"));
  907. }
  908. TEST_F(ValidateImage, ImageTexelPointerSuccess) {
  909. const std::string body = R"(
  910. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  911. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  912. )";
  913. CompileSuccessfully(GenerateShaderCode(body).c_str());
  914. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  915. }
  916. TEST_F(ValidateImage, ImageTexelPointerResultTypeNotPointer) {
  917. const std::string body = R"(
  918. %texel_ptr = OpImageTexelPointer %type_image_u32_buffer_0002_r32ui %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  919. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  920. )";
  921. CompileSuccessfully(GenerateShaderCode(body).c_str());
  922. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  923. EXPECT_THAT(getDiagnosticString(),
  924. HasSubstr("Expected Result Type to be OpTypePointer"));
  925. }
  926. TEST_F(ValidateImage, ImageTexelPointerResultTypeNotImageClass) {
  927. const std::string body = R"(
  928. %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  929. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  930. )";
  931. CompileSuccessfully(GenerateShaderCode(body).c_str());
  932. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  933. EXPECT_THAT(getDiagnosticString(),
  934. HasSubstr("Expected Result Type to be OpTypePointer whose "
  935. "Storage Class operand is Image"));
  936. }
  937. TEST_F(ValidateImage, ImageTexelPointerResultTypeNotNumericNorVoid) {
  938. const std::string body = R"(
  939. %texel_ptr = OpImageTexelPointer %ptr_Image_u32arr4 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  940. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  941. )";
  942. CompileSuccessfully(GenerateShaderCode(body).c_str());
  943. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  944. EXPECT_THAT(
  945. getDiagnosticString(),
  946. HasSubstr("Expected Result Type to be OpTypePointer whose Type operand "
  947. "must be a scalar numerical type or OpTypeVoid"));
  948. }
  949. TEST_F(ValidateImage, ImageTexelPointerImageNotResultTypePointer) {
  950. const std::string body = R"(
  951. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %type_image_f32_buffer_0002_r32ui %u32_0 %u32_0
  952. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  953. )";
  954. CompileSuccessfully(GenerateShaderCode(body).c_str());
  955. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  956. EXPECT_THAT(getDiagnosticString(),
  957. HasSubstr("Operand '148[%148]' cannot be a "
  958. "type"));
  959. }
  960. TEST_F(ValidateImage, ImageTexelPointerImageNotImage) {
  961. const std::string body = R"(
  962. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_sampler %u32_0 %u32_0
  963. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  964. )";
  965. CompileSuccessfully(GenerateShaderCode(body).c_str());
  966. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  967. EXPECT_THAT(
  968. getDiagnosticString(),
  969. HasSubstr("Expected Image to be OpTypePointer with Type OpTypeImage"));
  970. }
  971. TEST_F(ValidateImage, ImageTexelPointerImageSampledNotResultType) {
  972. const std::string body = R"(
  973. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_f32_cube_0101 %u32_0 %u32_0
  974. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  975. )";
  976. CompileSuccessfully(GenerateShaderCode(body).c_str());
  977. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  978. EXPECT_THAT(getDiagnosticString(),
  979. HasSubstr("Expected Image 'Sampled Type' to be the same as the "
  980. "Type pointed to by Result Type"));
  981. }
  982. TEST_F(ValidateImage, ImageTexelPointerImageDimSubpassDataBad) {
  983. const std::string body = R"(
  984. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_spd_0002 %u32_0 %u32_0
  985. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  986. )";
  987. CompileSuccessfully(GenerateShaderCode(body).c_str());
  988. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  989. EXPECT_THAT(
  990. getDiagnosticString(),
  991. HasSubstr(
  992. "Image Dim SubpassData cannot be used with OpImageTexelPointer"));
  993. }
  994. TEST_F(ValidateImage, ImageTexelPointerImageCoordTypeBad) {
  995. const std::string body = R"(
  996. %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32ui %f32_0 %f32_0
  997. %sum = OpAtomicIAdd %f32 %texel_ptr %f32_1 %f32_0 %f32_1
  998. )";
  999. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1000. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1001. EXPECT_THAT(getDiagnosticString(),
  1002. HasSubstr("Expected Coordinate to be integer scalar or vector"));
  1003. }
  1004. TEST_F(ValidateImage, ImageTexelPointerImageCoordSizeBad) {
  1005. const std::string body = R"(
  1006. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_u32_2d_0002 %u32vec3_012 %u32_0
  1007. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1008. )";
  1009. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1010. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1011. EXPECT_THAT(
  1012. getDiagnosticString(),
  1013. HasSubstr("Expected Coordinate to have 2 components, but given 3"));
  1014. }
  1015. TEST_F(ValidateImage, ImageTexelPointerSampleNotIntScalar) {
  1016. const std::string body = R"(
  1017. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %f32_0
  1018. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1019. )";
  1020. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1021. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1022. EXPECT_THAT(getDiagnosticString(),
  1023. HasSubstr("Expected Sample to be integer scalar"));
  1024. }
  1025. TEST_F(ValidateImage, ImageTexelPointerSampleNotZeroForImageWithMSZero) {
  1026. const std::string body = R"(
  1027. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_1
  1028. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1029. )";
  1030. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1031. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1032. EXPECT_THAT(getDiagnosticString(),
  1033. HasSubstr("Expected Sample for Image with MS 0 to be a valid "
  1034. "<id> for the value 0"));
  1035. }
  1036. TEST_F(ValidateImage, SampleImplicitLodSuccess) {
  1037. const std::string body = R"(
  1038. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1039. %sampler = OpLoad %type_sampler %uniform_sampler
  1040. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1041. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
  1042. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0_25
  1043. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
  1044. %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
  1045. %res6 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
  1046. %res7 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  1047. %res8 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
  1048. )";
  1049. const std::string extra = R"(
  1050. OpCapability VulkanMemoryModelKHR
  1051. OpExtension "SPV_KHR_vulkan_memory_model"
  1052. )";
  1053. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  1054. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  1055. .c_str());
  1056. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1057. }
  1058. TEST_F(ValidateImage, SampleImplicitLodWrongResultType) {
  1059. const std::string body = R"(
  1060. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1061. %sampler = OpLoad %type_sampler %uniform_sampler
  1062. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1063. %res1 = OpImageSampleImplicitLod %f32 %simg %f32vec2_hh
  1064. )";
  1065. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1066. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1067. EXPECT_THAT(getDiagnosticString(),
  1068. HasSubstr("Expected Result Type to be int or float vector type"));
  1069. }
  1070. TEST_F(ValidateImage, SampleImplicitLodWrongNumComponentsResultType) {
  1071. const std::string body = R"(
  1072. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1073. %sampler = OpLoad %type_sampler %uniform_sampler
  1074. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1075. %res1 = OpImageSampleImplicitLod %f32vec3 %simg %f32vec2_hh
  1076. )";
  1077. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1078. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1079. EXPECT_THAT(getDiagnosticString(),
  1080. HasSubstr("Expected Result Type to have 4 components"));
  1081. }
  1082. TEST_F(ValidateImage, SampleImplicitLodNotSampledImage) {
  1083. const std::string body = R"(
  1084. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1085. %res1 = OpImageSampleImplicitLod %f32vec4 %img %f32vec2_hh
  1086. )";
  1087. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1088. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1089. EXPECT_THAT(
  1090. getDiagnosticString(),
  1091. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  1092. }
  1093. TEST_F(ValidateImage, SampleImplicitLodMultisampleError) {
  1094. const std::string body = R"(
  1095. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  1096. %sampler = OpLoad %type_sampler %uniform_sampler
  1097. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  1098. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
  1099. )";
  1100. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1101. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1102. EXPECT_THAT(getDiagnosticString(),
  1103. HasSubstr("Sampling operation is invalid for multisample image"));
  1104. }
  1105. TEST_F(ValidateImage, SampleImplicitLodWrongSampledType) {
  1106. const std::string body = R"(
  1107. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1108. %sampler = OpLoad %type_sampler %uniform_sampler
  1109. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1110. %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
  1111. )";
  1112. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1113. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1114. EXPECT_THAT(getDiagnosticString(),
  1115. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  1116. "Result Type components"));
  1117. }
  1118. TEST_F(ValidateImage, SampleImplicitLodVoidSampledType) {
  1119. const std::string body = R"(
  1120. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  1121. %sampler = OpLoad %type_sampler %uniform_sampler
  1122. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  1123. %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
  1124. )";
  1125. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1126. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1127. }
  1128. TEST_F(ValidateImage, SampleImplicitLodWrongCoordinateType) {
  1129. const std::string body = R"(
  1130. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1131. %sampler = OpLoad %type_sampler %uniform_sampler
  1132. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1133. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %img
  1134. )";
  1135. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1136. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1137. EXPECT_THAT(getDiagnosticString(),
  1138. HasSubstr("Expected Coordinate to be float scalar or vector"));
  1139. }
  1140. TEST_F(ValidateImage, SampleImplicitLodCoordinateSizeTooSmall) {
  1141. const std::string body = R"(
  1142. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1143. %sampler = OpLoad %type_sampler %uniform_sampler
  1144. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1145. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32_0_5
  1146. )";
  1147. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1148. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1149. EXPECT_THAT(getDiagnosticString(),
  1150. HasSubstr("Expected Coordinate to have at least 2 components, "
  1151. "but given only 1"));
  1152. }
  1153. TEST_F(ValidateImage, SampleExplicitLodSuccessShader) {
  1154. const std::string body = R"(
  1155. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1156. %sampler = OpLoad %type_sampler %uniform_sampler
  1157. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1158. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod %f32_1
  1159. %res2 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_10 %f32vec2_01
  1160. %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
  1161. %res4 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
  1162. %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset|MinLod %f32vec2_10 %f32vec2_01 %s32vec2_01 %f32_0_5
  1163. %res6 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod|NonPrivateTexelKHR %f32_1
  1164. )";
  1165. const std::string extra = R"(
  1166. OpCapability VulkanMemoryModelKHR
  1167. OpExtension "SPV_KHR_vulkan_memory_model"
  1168. )";
  1169. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  1170. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  1171. .c_str());
  1172. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1173. }
  1174. TEST_F(ValidateImage, SampleExplicitLodSuccessKernel) {
  1175. const std::string body = R"(
  1176. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1177. %sampler = OpLoad %type_sampler %uniform_sampler
  1178. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1179. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec4_0123 Lod %f32_1
  1180. %res2 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Grad %f32vec2_10 %f32vec2_01
  1181. %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %u32vec2_01
  1182. %res4 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Offset %u32vec2_01
  1183. %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset %f32vec2_10 %f32vec2_01 %u32vec2_01
  1184. )";
  1185. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1186. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1187. }
  1188. TEST_F(ValidateImage, SampleExplicitLodSuccessCubeArrayed) {
  1189. const std::string body = R"(
  1190. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1191. %sampler = OpLoad %type_sampler %uniform_sampler
  1192. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1193. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec3_hhh
  1194. )";
  1195. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1196. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1197. }
  1198. TEST_F(ValidateImage, SampleExplicitLodWrongResultType) {
  1199. const std::string body = R"(
  1200. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1201. %sampler = OpLoad %type_sampler %uniform_sampler
  1202. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1203. %res1 = OpImageSampleExplicitLod %f32 %simg %f32vec2_hh Lod %f32_1
  1204. )";
  1205. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1206. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1207. EXPECT_THAT(getDiagnosticString(),
  1208. HasSubstr("Expected Result Type to be int or float vector type"));
  1209. }
  1210. TEST_F(ValidateImage, SampleExplicitLodWrongNumComponentsResultType) {
  1211. const std::string body = R"(
  1212. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1213. %sampler = OpLoad %type_sampler %uniform_sampler
  1214. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1215. %res1 = OpImageSampleExplicitLod %f32vec3 %simg %f32vec2_hh Lod %f32_1
  1216. )";
  1217. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1218. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1219. EXPECT_THAT(getDiagnosticString(),
  1220. HasSubstr("Expected Result Type to have 4 components"));
  1221. }
  1222. TEST_F(ValidateImage, SampleExplicitLodNotSampledImage) {
  1223. const std::string body = R"(
  1224. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1225. %res1 = OpImageSampleExplicitLod %f32vec4 %img %f32vec2_hh Lod %f32_1
  1226. )";
  1227. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1228. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1229. EXPECT_THAT(
  1230. getDiagnosticString(),
  1231. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  1232. }
  1233. TEST_F(ValidateImage, SampleExplicitLodMultisampleError) {
  1234. const std::string body = R"(
  1235. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  1236. %sampler = OpLoad %type_sampler %uniform_sampler
  1237. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  1238. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_0 %u32_1
  1239. )";
  1240. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1241. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1242. EXPECT_THAT(getDiagnosticString(),
  1243. HasSubstr("Sampling operation is invalid for multisample image"));
  1244. }
  1245. TEST_F(ValidateImage, SampleExplicitLodWrongSampledType) {
  1246. const std::string body = R"(
  1247. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1248. %sampler = OpLoad %type_sampler %uniform_sampler
  1249. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1250. %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
  1251. )";
  1252. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1253. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1254. EXPECT_THAT(getDiagnosticString(),
  1255. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  1256. "Result Type components"));
  1257. }
  1258. TEST_F(ValidateImage, SampleExplicitLodVoidSampledType) {
  1259. const std::string body = R"(
  1260. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  1261. %sampler = OpLoad %type_sampler %uniform_sampler
  1262. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  1263. %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
  1264. )";
  1265. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1266. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1267. }
  1268. TEST_F(ValidateImage, SampleExplicitLodWrongCoordinateType) {
  1269. const std::string body = R"(
  1270. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1271. %sampler = OpLoad %type_sampler %uniform_sampler
  1272. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1273. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %img Lod %f32_1
  1274. )";
  1275. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1276. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1277. EXPECT_THAT(getDiagnosticString(),
  1278. HasSubstr("Expected Coordinate to be float scalar or vector"));
  1279. }
  1280. TEST_F(ValidateImage, SampleExplicitLodCoordinateSizeTooSmall) {
  1281. const std::string body = R"(
  1282. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1283. %sampler = OpLoad %type_sampler %uniform_sampler
  1284. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1285. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32_0_5 Lod %f32_1
  1286. )";
  1287. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1288. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1289. EXPECT_THAT(getDiagnosticString(),
  1290. HasSubstr("Expected Coordinate to have at least 2 components, "
  1291. "but given only 1"));
  1292. }
  1293. TEST_F(ValidateImage, SampleExplicitLodBias) {
  1294. const std::string body = R"(
  1295. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1296. %sampler = OpLoad %type_sampler %uniform_sampler
  1297. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1298. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Bias|Lod %f32_1 %f32_1
  1299. )";
  1300. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1301. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1302. EXPECT_THAT(
  1303. getDiagnosticString(),
  1304. HasSubstr(
  1305. "Image Operand Bias can only be used with ImplicitLod opcodes"));
  1306. }
  1307. TEST_F(ValidateImage, LodAndGrad) {
  1308. const std::string body = R"(
  1309. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1310. %sampler = OpLoad %type_sampler %uniform_sampler
  1311. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1312. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|Grad %f32_1 %f32vec2_hh %f32vec2_hh
  1313. )";
  1314. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1315. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1316. EXPECT_THAT(
  1317. getDiagnosticString(),
  1318. HasSubstr(
  1319. "Image Operand bits Lod and Grad cannot be set at the same time"));
  1320. }
  1321. TEST_F(ValidateImage, ImplicitLodWithLod) {
  1322. const std::string body = R"(
  1323. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1324. %sampler = OpLoad %type_sampler %uniform_sampler
  1325. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1326. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_0_5
  1327. )";
  1328. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1329. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1330. EXPECT_THAT(
  1331. getDiagnosticString(),
  1332. HasSubstr("Image Operand Lod can only be used with ExplicitLod opcodes "
  1333. "and OpImageFetch"));
  1334. }
  1335. TEST_F(ValidateImage, LodWrongType) {
  1336. const std::string body = R"(
  1337. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1338. %sampler = OpLoad %type_sampler %uniform_sampler
  1339. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1340. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32vec2_hh)";
  1341. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1342. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1343. EXPECT_THAT(getDiagnosticString(),
  1344. HasSubstr("Expected Image Operand Lod to be float scalar when "
  1345. "used with ExplicitLod"));
  1346. }
  1347. TEST_F(ValidateImage, LodWrongDim) {
  1348. const std::string body = R"(
  1349. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  1350. %sampler = OpLoad %type_sampler %uniform_sampler
  1351. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  1352. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)";
  1353. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1354. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1355. EXPECT_THAT(getDiagnosticString(),
  1356. HasSubstr("Image Operand Lod requires 'Dim' parameter to be 1D, "
  1357. "2D, 3D or Cube"));
  1358. }
  1359. TEST_F(ValidateImage, MinLodIncompatible) {
  1360. const std::string body = R"(
  1361. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1362. %sampler = OpLoad %type_sampler %uniform_sampler
  1363. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1364. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|MinLod %f32_0 %f32_0)";
  1365. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1366. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1367. EXPECT_THAT(
  1368. getDiagnosticString(),
  1369. HasSubstr(
  1370. "Image Operand MinLod can only be used with ImplicitLod opcodes or "
  1371. "together with Image Operand Grad"));
  1372. }
  1373. TEST_F(ValidateImage, ImplicitLodWithGrad) {
  1374. const std::string body = R"(
  1375. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1376. %sampler = OpLoad %type_sampler %uniform_sampler
  1377. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1378. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_hh %f32vec2_hh
  1379. )";
  1380. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1381. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1382. EXPECT_THAT(
  1383. getDiagnosticString(),
  1384. HasSubstr(
  1385. "Image Operand Grad can only be used with ExplicitLod opcodes"));
  1386. }
  1387. TEST_F(ValidateImage, SampleImplicitLodCubeArrayedSuccess) {
  1388. const std::string body = R"(
  1389. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1390. %sampler = OpLoad %type_sampler %uniform_sampler
  1391. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1392. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000
  1393. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias %f32_0_25
  1394. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %f32_0_5
  1395. %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias|MinLod %f32_0_25 %f32_0_5
  1396. )";
  1397. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1398. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1399. }
  1400. TEST_F(ValidateImage, SampleImplicitLodBiasWrongType) {
  1401. const std::string body = R"(
  1402. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1403. %sampler = OpLoad %type_sampler %uniform_sampler
  1404. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1405. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %u32_0
  1406. )";
  1407. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1408. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1409. EXPECT_THAT(getDiagnosticString(),
  1410. HasSubstr("Expected Image Operand Bias to be float scalar"));
  1411. }
  1412. TEST_F(ValidateImage, SampleImplicitLodBiasWrongDim) {
  1413. const std::string body = R"(
  1414. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  1415. %sampler = OpLoad %type_sampler %uniform_sampler
  1416. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  1417. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0
  1418. )";
  1419. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1420. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1421. EXPECT_THAT(getDiagnosticString(),
  1422. HasSubstr("Image Operand Bias requires 'Dim' parameter to be 1D, "
  1423. "2D, 3D or Cube"));
  1424. }
  1425. TEST_F(ValidateImage, SampleExplicitLodGradDxWrongType) {
  1426. const std::string body = R"(
  1427. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1428. %sampler = OpLoad %type_sampler %uniform_sampler
  1429. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1430. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %s32vec3_012 %f32vec3_hhh
  1431. )";
  1432. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1433. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1434. EXPECT_THAT(getDiagnosticString(),
  1435. HasSubstr("Expected both Image Operand Grad ids to be float "
  1436. "scalars or vectors"));
  1437. }
  1438. TEST_F(ValidateImage, SampleExplicitLodGradDyWrongType) {
  1439. const std::string body = R"(
  1440. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1441. %sampler = OpLoad %type_sampler %uniform_sampler
  1442. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1443. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %s32vec3_012
  1444. )";
  1445. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1446. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1447. EXPECT_THAT(getDiagnosticString(),
  1448. HasSubstr("Expected both Image Operand Grad ids to be float "
  1449. "scalars or vectors"));
  1450. }
  1451. TEST_F(ValidateImage, SampleExplicitLodGradDxWrongSize) {
  1452. const std::string body = R"(
  1453. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1454. %sampler = OpLoad %type_sampler %uniform_sampler
  1455. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1456. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec2_00 %f32vec3_hhh
  1457. )";
  1458. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1459. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1460. EXPECT_THAT(
  1461. getDiagnosticString(),
  1462. HasSubstr(
  1463. "Expected Image Operand Grad dx to have 3 components, but given 2"));
  1464. }
  1465. TEST_F(ValidateImage, SampleExplicitLodGradDyWrongSize) {
  1466. const std::string body = R"(
  1467. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1468. %sampler = OpLoad %type_sampler %uniform_sampler
  1469. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1470. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec2_00
  1471. )";
  1472. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1473. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1474. EXPECT_THAT(
  1475. getDiagnosticString(),
  1476. HasSubstr(
  1477. "Expected Image Operand Grad dy to have 3 components, but given 2"));
  1478. }
  1479. TEST_F(ValidateImage, SampleImplicitLodConstOffsetCubeDim) {
  1480. const std::string body = R"(
  1481. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1482. %sampler = OpLoad %type_sampler %uniform_sampler
  1483. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1484. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec3_012
  1485. )";
  1486. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1487. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1488. EXPECT_THAT(
  1489. getDiagnosticString(),
  1490. HasSubstr(
  1491. "Image Operand ConstOffset cannot be used with Cube Image 'Dim'"));
  1492. }
  1493. TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongType) {
  1494. const std::string body = R"(
  1495. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1496. %sampler = OpLoad %type_sampler %uniform_sampler
  1497. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1498. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %f32vec2_00
  1499. )";
  1500. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1501. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1502. EXPECT_THAT(
  1503. getDiagnosticString(),
  1504. HasSubstr(
  1505. "Expected Image Operand ConstOffset to be int scalar or vector"));
  1506. }
  1507. TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongSize) {
  1508. const std::string body = R"(
  1509. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1510. %sampler = OpLoad %type_sampler %uniform_sampler
  1511. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1512. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %s32vec3_012
  1513. )";
  1514. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1515. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1516. EXPECT_THAT(getDiagnosticString(),
  1517. HasSubstr("Expected Image Operand ConstOffset to have 2 "
  1518. "components, but given 3"));
  1519. }
  1520. TEST_F(ValidateImage, SampleImplicitLodConstOffsetNotConst) {
  1521. const std::string body = R"(
  1522. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1523. %sampler = OpLoad %type_sampler %uniform_sampler
  1524. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1525. %offset = OpSNegate %s32vec3 %s32vec3_012
  1526. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %offset
  1527. )";
  1528. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1529. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1530. EXPECT_THAT(
  1531. getDiagnosticString(),
  1532. HasSubstr("Expected Image Operand ConstOffset to be a const object"));
  1533. }
  1534. TEST_F(ValidateImage, SampleImplicitLodOffsetCubeDim) {
  1535. const std::string body = R"(
  1536. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1537. %sampler = OpLoad %type_sampler %uniform_sampler
  1538. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1539. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
  1540. )";
  1541. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1542. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1543. EXPECT_THAT(
  1544. getDiagnosticString(),
  1545. HasSubstr("Image Operand Offset cannot be used with Cube Image 'Dim'"));
  1546. }
  1547. TEST_F(ValidateImage, SampleImplicitLodOffsetWrongType) {
  1548. const std::string body = R"(
  1549. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1550. %sampler = OpLoad %type_sampler %uniform_sampler
  1551. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1552. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %f32vec2_00
  1553. )";
  1554. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1555. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1556. EXPECT_THAT(
  1557. getDiagnosticString(),
  1558. HasSubstr("Expected Image Operand Offset to be int scalar or vector"));
  1559. }
  1560. TEST_F(ValidateImage, SampleImplicitLodOffsetWrongSize) {
  1561. const std::string body = R"(
  1562. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1563. %sampler = OpLoad %type_sampler %uniform_sampler
  1564. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1565. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
  1566. )";
  1567. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1568. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1569. EXPECT_THAT(
  1570. getDiagnosticString(),
  1571. HasSubstr(
  1572. "Expected Image Operand Offset to have 2 components, but given 3"));
  1573. }
  1574. TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongSize) {
  1575. const std::string body = R"(
  1576. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1577. %sampler = OpLoad %type_sampler %uniform_sampler
  1578. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1579. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
  1580. )";
  1581. CompileSuccessfully(
  1582. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  1583. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1584. EXPECT_THAT(getDiagnosticString(),
  1585. AnyVUID("VUID-StandaloneSpirv-Offset-04663"));
  1586. EXPECT_THAT(getDiagnosticString(),
  1587. HasSubstr("Image Operand Offset can only be used with "
  1588. "OpImage*Gather operations"));
  1589. }
  1590. TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongBeforeLegalization) {
  1591. const std::string body = R"(
  1592. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1593. %sampler = OpLoad %type_sampler %uniform_sampler
  1594. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1595. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
  1596. )";
  1597. CompileSuccessfully(
  1598. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  1599. getValidatorOptions()->before_hlsl_legalization = true;
  1600. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1601. }
  1602. TEST_F(ValidateImage, SampleImplicitLodMoreThanOneOffset) {
  1603. const std::string body = R"(
  1604. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1605. %sampler = OpLoad %type_sampler %uniform_sampler
  1606. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1607. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
  1608. )";
  1609. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1610. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1611. EXPECT_THAT(
  1612. getDiagnosticString(),
  1613. HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
  1614. "cannot be used together"));
  1615. }
  1616. TEST_F(ValidateImage, SampleImplicitLodVulkanMoreThanOneOffset) {
  1617. const std::string body = R"(
  1618. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1619. %sampler = OpLoad %type_sampler %uniform_sampler
  1620. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1621. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
  1622. )";
  1623. CompileSuccessfully(
  1624. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  1625. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1626. EXPECT_THAT(getDiagnosticString(),
  1627. AnyVUID("VUID-StandaloneSpirv-Offset-04662"));
  1628. EXPECT_THAT(
  1629. getDiagnosticString(),
  1630. HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
  1631. "cannot be used together"));
  1632. }
  1633. TEST_F(ValidateImage, SampleImplicitLodMinLodWrongType) {
  1634. const std::string body = R"(
  1635. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1636. %sampler = OpLoad %type_sampler %uniform_sampler
  1637. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1638. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %s32_0
  1639. )";
  1640. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1641. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1642. EXPECT_THAT(getDiagnosticString(),
  1643. HasSubstr("Expected Image Operand MinLod to be float scalar"));
  1644. }
  1645. TEST_F(ValidateImage, SampleImplicitLodMinLodWrongDim) {
  1646. const std::string body = R"(
  1647. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  1648. %sampler = OpLoad %type_sampler %uniform_sampler
  1649. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  1650. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_25
  1651. )";
  1652. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1653. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1654. EXPECT_THAT(getDiagnosticString(),
  1655. HasSubstr("Image Operand MinLod requires 'Dim' parameter to be "
  1656. "1D, 2D, 3D or Cube"));
  1657. }
  1658. TEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) {
  1659. const std::string body = R"(
  1660. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1661. %sampler = OpLoad %type_sampler %uniform_sampler
  1662. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1663. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod %f32_1
  1664. %res3 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
  1665. %res4 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
  1666. %res5 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
  1667. %res7 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
  1668. %res8 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod|NonPrivateTexelKHR %f32_1
  1669. )";
  1670. const std::string extra = R"(
  1671. OpCapability VulkanMemoryModelKHR
  1672. OpExtension "SPV_KHR_vulkan_memory_model"
  1673. )";
  1674. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  1675. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  1676. .c_str());
  1677. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1678. }
  1679. TEST_F(ValidateImage, SampleProjExplicitLodSuccessRect) {
  1680. const std::string body = R"(
  1681. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  1682. %sampler = OpLoad %type_sampler %uniform_sampler
  1683. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  1684. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
  1685. %res2 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
  1686. )";
  1687. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1688. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1689. }
  1690. TEST_F(ValidateImage, SampleProjExplicitLodWrongResultType) {
  1691. const std::string body = R"(
  1692. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1693. %sampler = OpLoad %type_sampler %uniform_sampler
  1694. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1695. %res1 = OpImageSampleProjExplicitLod %f32 %simg %f32vec3_hhh Lod %f32_1
  1696. )";
  1697. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1698. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1699. EXPECT_THAT(getDiagnosticString(),
  1700. HasSubstr("Expected Result Type to be int or float vector type"));
  1701. }
  1702. TEST_F(ValidateImage, SampleProjExplicitLodWrongNumComponentsResultType) {
  1703. const std::string body = R"(
  1704. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1705. %sampler = OpLoad %type_sampler %uniform_sampler
  1706. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1707. %res1 = OpImageSampleProjExplicitLod %f32vec3 %simg %f32vec3_hhh Lod %f32_1
  1708. )";
  1709. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1710. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1711. EXPECT_THAT(getDiagnosticString(),
  1712. HasSubstr("Expected Result Type to have 4 components"));
  1713. }
  1714. TEST_F(ValidateImage, SampleProjExplicitLodNotSampledImage) {
  1715. const std::string body = R"(
  1716. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1717. %res1 = OpImageSampleProjExplicitLod %f32vec4 %img %f32vec3_hhh Lod %f32_1
  1718. )";
  1719. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1720. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1721. EXPECT_THAT(
  1722. getDiagnosticString(),
  1723. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  1724. }
  1725. TEST_F(ValidateImage, SampleProjExplicitLodMultisampleError) {
  1726. const std::string body = R"(
  1727. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  1728. %sampler = OpLoad %type_sampler %uniform_sampler
  1729. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  1730. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_1 %u32_1
  1731. )";
  1732. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1733. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1734. EXPECT_THAT(getDiagnosticString(),
  1735. HasSubstr("Expected Image 'MS' parameter to be 0"));
  1736. }
  1737. TEST_F(ValidateImage, SampleProjExplicitLodWrongSampledType) {
  1738. const std::string body = R"(
  1739. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1740. %sampler = OpLoad %type_sampler %uniform_sampler
  1741. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1742. %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
  1743. )";
  1744. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1745. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1746. EXPECT_THAT(getDiagnosticString(),
  1747. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  1748. "Result Type components"));
  1749. }
  1750. TEST_F(ValidateImage, SampleProjExplicitLodVoidSampledType) {
  1751. const std::string body = R"(
  1752. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  1753. %sampler = OpLoad %type_sampler %uniform_sampler
  1754. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  1755. %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
  1756. )";
  1757. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1758. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1759. }
  1760. TEST_F(ValidateImage, SampleProjExplicitLodWrongCoordinateType) {
  1761. const std::string body = R"(
  1762. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1763. %sampler = OpLoad %type_sampler %uniform_sampler
  1764. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1765. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %img Lod %f32_1
  1766. )";
  1767. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1768. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1769. EXPECT_THAT(getDiagnosticString(),
  1770. HasSubstr("Expected Coordinate to be float scalar or vector"));
  1771. }
  1772. TEST_F(ValidateImage, SampleProjExplicitLodCoordinateSizeTooSmall) {
  1773. const std::string body = R"(
  1774. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1775. %sampler = OpLoad %type_sampler %uniform_sampler
  1776. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1777. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_1
  1778. )";
  1779. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1780. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1781. EXPECT_THAT(getDiagnosticString(),
  1782. HasSubstr("Expected Coordinate to have at least 3 components, "
  1783. "but given only 2"));
  1784. }
  1785. TEST_F(ValidateImage, SampleProjImplicitLodSuccess) {
  1786. const std::string body = R"(
  1787. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1788. %sampler = OpLoad %type_sampler %uniform_sampler
  1789. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1790. %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh
  1791. %res2 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias %f32_0_25
  1792. %res4 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
  1793. %res5 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
  1794. %res6 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh MinLod %f32_0_5
  1795. %res7 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  1796. %res8 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh NonPrivateTexelKHR
  1797. )";
  1798. const std::string extra = R"(
  1799. OpCapability VulkanMemoryModelKHR
  1800. OpExtension "SPV_KHR_vulkan_memory_model"
  1801. )";
  1802. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  1803. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  1804. .c_str());
  1805. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1806. }
  1807. TEST_F(ValidateImage, SampleProjImplicitLodWrongResultType) {
  1808. const std::string body = R"(
  1809. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1810. %sampler = OpLoad %type_sampler %uniform_sampler
  1811. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1812. %res1 = OpImageSampleProjImplicitLod %f32 %simg %f32vec3_hhh
  1813. )";
  1814. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1815. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1816. EXPECT_THAT(getDiagnosticString(),
  1817. HasSubstr("Expected Result Type to be int or float vector type"));
  1818. }
  1819. TEST_F(ValidateImage, SampleProjImplicitLodWrongNumComponentsResultType) {
  1820. const std::string body = R"(
  1821. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1822. %sampler = OpLoad %type_sampler %uniform_sampler
  1823. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1824. %res1 = OpImageSampleProjImplicitLod %f32vec3 %simg %f32vec3_hhh
  1825. )";
  1826. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1827. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1828. EXPECT_THAT(getDiagnosticString(),
  1829. HasSubstr("Expected Result Type to have 4 components"));
  1830. }
  1831. TEST_F(ValidateImage, SampleProjImplicitLodNotSampledImage) {
  1832. const std::string body = R"(
  1833. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1834. %res1 = OpImageSampleProjImplicitLod %f32vec4 %img %f32vec3_hhh
  1835. )";
  1836. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1837. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1838. EXPECT_THAT(
  1839. getDiagnosticString(),
  1840. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  1841. }
  1842. TEST_F(ValidateImage, SampleProjImplicitLodMultisampleError) {
  1843. const std::string body = R"(
  1844. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  1845. %sampler = OpLoad %type_sampler %uniform_sampler
  1846. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  1847. %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
  1848. )";
  1849. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1850. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1851. EXPECT_THAT(getDiagnosticString(),
  1852. HasSubstr("Expected Image 'MS' parameter to be 0"));
  1853. }
  1854. TEST_F(ValidateImage, SampleProjImplicitLodWrongSampledType) {
  1855. const std::string body = R"(
  1856. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1857. %sampler = OpLoad %type_sampler %uniform_sampler
  1858. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1859. %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
  1860. )";
  1861. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1862. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1863. EXPECT_THAT(getDiagnosticString(),
  1864. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  1865. "Result Type components"));
  1866. }
  1867. TEST_F(ValidateImage, SampleProjImplicitLodVoidSampledType) {
  1868. const std::string body = R"(
  1869. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  1870. %sampler = OpLoad %type_sampler %uniform_sampler
  1871. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  1872. %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
  1873. )";
  1874. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1875. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1876. }
  1877. TEST_F(ValidateImage, SampleProjImplicitLodWrongCoordinateType) {
  1878. const std::string body = R"(
  1879. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1880. %sampler = OpLoad %type_sampler %uniform_sampler
  1881. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1882. %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %img
  1883. )";
  1884. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1885. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1886. EXPECT_THAT(getDiagnosticString(),
  1887. HasSubstr("Expected Coordinate to be float scalar or vector"));
  1888. }
  1889. TEST_F(ValidateImage, SampleProjImplicitLodCoordinateSizeTooSmall) {
  1890. const std::string body = R"(
  1891. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1892. %sampler = OpLoad %type_sampler %uniform_sampler
  1893. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1894. %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh
  1895. )";
  1896. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1897. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1898. EXPECT_THAT(getDiagnosticString(),
  1899. HasSubstr("Expected Coordinate to have at least 3 components, "
  1900. "but given only 2"));
  1901. }
  1902. TEST_F(ValidateImage, SampleDrefImplicitLodSuccess) {
  1903. const std::string body = R"(
  1904. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  1905. %sampler = OpLoad %type_sampler %uniform_sampler
  1906. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  1907. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1
  1908. %res2 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
  1909. %res4 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
  1910. %res5 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
  1911. %res6 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
  1912. %res7 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  1913. %res8 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
  1914. )";
  1915. const std::string extra = R"(
  1916. OpCapability VulkanMemoryModelKHR
  1917. OpExtension "SPV_KHR_vulkan_memory_model"
  1918. )";
  1919. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  1920. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  1921. .c_str());
  1922. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1923. }
  1924. TEST_F(ValidateImage, SampleDrefImplicitLodWrongResultType) {
  1925. const std::string body = R"(
  1926. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  1927. %sampler = OpLoad %type_sampler %uniform_sampler
  1928. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  1929. %res1 = OpImageSampleDrefImplicitLod %void %simg %f32vec2_hh %u32_1
  1930. )";
  1931. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1932. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1933. EXPECT_THAT(getDiagnosticString(),
  1934. HasSubstr("Expected Result Type to be int or float scalar type"));
  1935. }
  1936. TEST_F(ValidateImage, SampleDrefImplicitLodNotSampledImage) {
  1937. const std::string body = R"(
  1938. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  1939. %res1 = OpImageSampleDrefImplicitLod %u32 %img %f32vec2_hh %u32_1
  1940. )";
  1941. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1942. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1943. EXPECT_THAT(
  1944. getDiagnosticString(),
  1945. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  1946. }
  1947. TEST_F(ValidateImage, SampleDrefImplicitLodMultisampleError) {
  1948. const std::string body = R"(
  1949. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  1950. %sampler = OpLoad %type_sampler %uniform_sampler
  1951. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  1952. %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
  1953. )";
  1954. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1955. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1956. EXPECT_THAT(
  1957. getDiagnosticString(),
  1958. HasSubstr("Dref sampling operation is invalid for multisample image"));
  1959. }
  1960. TEST_F(ValidateImage, SampleDrefImplicitLodWrongSampledType) {
  1961. const std::string body = R"(
  1962. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  1963. %sampler = OpLoad %type_sampler %uniform_sampler
  1964. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  1965. %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_00 %u32_1
  1966. )";
  1967. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1968. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1969. EXPECT_THAT(
  1970. getDiagnosticString(),
  1971. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  1972. }
  1973. TEST_F(ValidateImage, SampleDrefImplicitLodVoidSampledType) {
  1974. const std::string body = R"(
  1975. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  1976. %sampler = OpLoad %type_sampler %uniform_sampler
  1977. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  1978. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %u32_1
  1979. )";
  1980. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1981. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1982. EXPECT_THAT(
  1983. getDiagnosticString(),
  1984. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  1985. }
  1986. TEST_F(ValidateImage, SampleDrefImplicitLodWrongCoordinateType) {
  1987. const std::string body = R"(
  1988. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  1989. %sampler = OpLoad %type_sampler %uniform_sampler
  1990. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  1991. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %img %u32_1
  1992. )";
  1993. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1994. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1995. EXPECT_THAT(getDiagnosticString(),
  1996. HasSubstr("Expected Coordinate to be float scalar or vector"));
  1997. }
  1998. TEST_F(ValidateImage, SampleDrefImplicitLodCoordinateSizeTooSmall) {
  1999. const std::string body = R"(
  2000. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2001. %sampler = OpLoad %type_sampler %uniform_sampler
  2002. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2003. %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32_0_5 %f32_0_5
  2004. )";
  2005. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2006. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2007. EXPECT_THAT(getDiagnosticString(),
  2008. HasSubstr("Expected Coordinate to have at least 2 components, "
  2009. "but given only 1"));
  2010. }
  2011. TEST_F(ValidateImage, SampleDrefImplicitLodWrongDrefType) {
  2012. const std::string body = R"(
  2013. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  2014. %sampler = OpLoad %type_sampler %uniform_sampler
  2015. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  2016. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %f64_1
  2017. )";
  2018. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2019. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2020. EXPECT_THAT(getDiagnosticString(),
  2021. HasSubstr("Expected Dref to be of 32-bit float type"));
  2022. }
  2023. TEST_F(ValidateImage, SampleDrefImplicitLodWrongDimVulkan) {
  2024. const std::string body = R"(
  2025. %img = OpLoad %type_image_u32_3d_0001 %uniform_image_u32_3d_0001
  2026. %sampler = OpLoad %type_sampler %uniform_sampler
  2027. %simg = OpSampledImage %type_sampled_image_u32_3d_0001 %img %sampler
  2028. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_1
  2029. )";
  2030. CompileSuccessfully(
  2031. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  2032. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  2033. EXPECT_THAT(getDiagnosticString(),
  2034. AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
  2035. EXPECT_THAT(getDiagnosticString(),
  2036. HasSubstr("In Vulkan, OpImage*Dref* instructions must not use "
  2037. "images with a 3D Dim"));
  2038. }
  2039. TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) {
  2040. const std::string body = R"(
  2041. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2042. %sampler = OpLoad %type_sampler %uniform_sampler
  2043. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2044. %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod %f32_1
  2045. %res3 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad %f32vec3_hhh %f32vec3_hhh
  2046. %res4 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 ConstOffset %s32vec3_012
  2047. %res5 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Offset %s32vec3_012
  2048. %res7 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad|Offset %f32vec3_hhh %f32vec3_hhh %s32vec3_012
  2049. %res8 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod|NonPrivateTexelKHR %f32_1
  2050. )";
  2051. const std::string extra = R"(
  2052. OpCapability VulkanMemoryModelKHR
  2053. OpExtension "SPV_KHR_vulkan_memory_model"
  2054. )";
  2055. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2056. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2057. .c_str());
  2058. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2059. }
  2060. TEST_F(ValidateImage, SampleDrefExplicitLodWrongResultType) {
  2061. const std::string body = R"(
  2062. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2063. %sampler = OpLoad %type_sampler %uniform_sampler
  2064. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2065. %res1 = OpImageSampleDrefExplicitLod %bool %simg %f32vec3_hhh %s32_1 Lod %f32_1
  2066. )";
  2067. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2068. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2069. EXPECT_THAT(getDiagnosticString(),
  2070. HasSubstr("Expected Result Type to be int or float scalar type"));
  2071. }
  2072. TEST_F(ValidateImage, SampleDrefExplicitLodNotSampledImage) {
  2073. const std::string body = R"(
  2074. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2075. %res1 = OpImageSampleDrefExplicitLod %s32 %img %f32vec3_hhh %s32_1 Lod %f32_1
  2076. )";
  2077. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2078. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2079. EXPECT_THAT(
  2080. getDiagnosticString(),
  2081. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2082. }
  2083. TEST_F(ValidateImage, SampleDrefExplicitLodMultisampleError) {
  2084. const std::string body = R"(
  2085. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2086. %sampler = OpLoad %type_sampler %uniform_sampler
  2087. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2088. %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
  2089. )";
  2090. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2091. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2092. EXPECT_THAT(
  2093. getDiagnosticString(),
  2094. HasSubstr("Dref sampling operation is invalid for multisample image"));
  2095. }
  2096. TEST_F(ValidateImage, SampleDrefExplicitLodWrongSampledType) {
  2097. const std::string body = R"(
  2098. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2099. %sampler = OpLoad %type_sampler %uniform_sampler
  2100. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2101. %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec3_hhh %s32_1 Lod %f32_1
  2102. )";
  2103. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2104. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2105. EXPECT_THAT(
  2106. getDiagnosticString(),
  2107. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2108. }
  2109. TEST_F(ValidateImage, SampleDrefExplicitLodVoidSampledType) {
  2110. const std::string body = R"(
  2111. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2112. %sampler = OpLoad %type_sampler %uniform_sampler
  2113. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2114. %res1 = OpImageSampleDrefExplicitLod %u32 %simg %f32vec2_00 %s32_1 Lod %f32_1
  2115. )";
  2116. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2117. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2118. EXPECT_THAT(
  2119. getDiagnosticString(),
  2120. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2121. }
  2122. TEST_F(ValidateImage, SampleDrefExplicitLodWrongCoordinateType) {
  2123. const std::string body = R"(
  2124. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2125. %sampler = OpLoad %type_sampler %uniform_sampler
  2126. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2127. %res1 = OpImageSampleDrefExplicitLod %s32 %simg %img %s32_1 Lod %f32_1
  2128. )";
  2129. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2130. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2131. EXPECT_THAT(getDiagnosticString(),
  2132. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2133. }
  2134. TEST_F(ValidateImage, SampleDrefExplicitLodCoordinateSizeTooSmall) {
  2135. const std::string body = R"(
  2136. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2137. %sampler = OpLoad %type_sampler %uniform_sampler
  2138. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2139. %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec2_hh %s32_1 Lod %f32_1
  2140. )";
  2141. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2142. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2143. EXPECT_THAT(getDiagnosticString(),
  2144. HasSubstr("Expected Coordinate to have at least 3 components, "
  2145. "but given only 2"));
  2146. }
  2147. TEST_F(ValidateImage, SampleDrefExplicitLodWrongDrefType) {
  2148. const std::string body = R"(
  2149. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2150. %sampler = OpLoad %type_sampler %uniform_sampler
  2151. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2152. %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %u32_1 Lod %f32_1
  2153. )";
  2154. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2155. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2156. EXPECT_THAT(getDiagnosticString(),
  2157. HasSubstr("Expected Dref to be of 32-bit float type"));
  2158. }
  2159. TEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) {
  2160. const std::string body = R"(
  2161. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2162. %sampler = OpLoad %type_sampler %uniform_sampler
  2163. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2164. %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5
  2165. %res2 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias %f32_0_25
  2166. %res4 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 ConstOffset %s32vec2_01
  2167. %res5 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Offset %s32vec2_01
  2168. %res6 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 MinLod %f32_0_5
  2169. %res7 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  2170. %res8 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 NonPrivateTexelKHR
  2171. )";
  2172. const std::string extra = R"(
  2173. OpCapability VulkanMemoryModelKHR
  2174. OpExtension "SPV_KHR_vulkan_memory_model"
  2175. )";
  2176. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2177. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2178. .c_str());
  2179. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2180. }
  2181. TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongResultType) {
  2182. const std::string body = R"(
  2183. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2184. %sampler = OpLoad %type_sampler %uniform_sampler
  2185. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2186. %res1 = OpImageSampleProjDrefImplicitLod %void %simg %f32vec3_hhh %f32_0_5
  2187. )";
  2188. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2189. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2190. EXPECT_THAT(getDiagnosticString(),
  2191. HasSubstr("Expected Result Type to be int or float scalar type"));
  2192. }
  2193. TEST_F(ValidateImage, SampleProjDrefImplicitLodNotSampledImage) {
  2194. const std::string body = R"(
  2195. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2196. %res1 = OpImageSampleProjDrefImplicitLod %f32 %img %f32vec3_hhh %f32_0_5
  2197. )";
  2198. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2199. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2200. EXPECT_THAT(
  2201. getDiagnosticString(),
  2202. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2203. }
  2204. TEST_F(ValidateImage, SampleProjDrefImplicitLodMultisampleError) {
  2205. const std::string body = R"(
  2206. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2207. %sampler = OpLoad %type_sampler %uniform_sampler
  2208. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2209. %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
  2210. )";
  2211. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2212. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2213. EXPECT_THAT(
  2214. getDiagnosticString(),
  2215. HasSubstr("Dref sampling operation is invalid for multisample image"));
  2216. }
  2217. TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongSampledType) {
  2218. const std::string body = R"(
  2219. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2220. %sampler = OpLoad %type_sampler %uniform_sampler
  2221. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2222. %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
  2223. )";
  2224. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2225. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2226. EXPECT_THAT(
  2227. getDiagnosticString(),
  2228. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2229. }
  2230. TEST_F(ValidateImage, SampleProjDrefImplicitLodVoidSampledType) {
  2231. const std::string body = R"(
  2232. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2233. %sampler = OpLoad %type_sampler %uniform_sampler
  2234. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2235. %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
  2236. )";
  2237. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2238. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2239. EXPECT_THAT(
  2240. getDiagnosticString(),
  2241. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2242. }
  2243. TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongCoordinateType) {
  2244. const std::string body = R"(
  2245. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2246. %sampler = OpLoad %type_sampler %uniform_sampler
  2247. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2248. %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %img %f32_0_5
  2249. )";
  2250. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2251. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2252. EXPECT_THAT(getDiagnosticString(),
  2253. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2254. }
  2255. TEST_F(ValidateImage, SampleProjDrefImplicitLodCoordinateSizeTooSmall) {
  2256. const std::string body = R"(
  2257. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2258. %sampler = OpLoad %type_sampler %uniform_sampler
  2259. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2260. %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec2_hh %f32_0_5
  2261. )";
  2262. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2263. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2264. EXPECT_THAT(getDiagnosticString(),
  2265. HasSubstr("Expected Coordinate to have at least 3 components, "
  2266. "but given only 2"));
  2267. }
  2268. TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongDrefType) {
  2269. const std::string body = R"(
  2270. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  2271. %sampler = OpLoad %type_sampler %uniform_sampler
  2272. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  2273. %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32vec4_0000
  2274. )";
  2275. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2276. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2277. EXPECT_THAT(getDiagnosticString(),
  2278. HasSubstr("Expected Dref to be of 32-bit float type"));
  2279. }
  2280. TEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) {
  2281. const std::string body = R"(
  2282. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2283. %sampler = OpLoad %type_sampler %uniform_sampler
  2284. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2285. %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
  2286. %res2 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Grad %f32_0_5 %f32_0_5
  2287. %res3 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 ConstOffset %s32_1
  2288. %res4 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Offset %s32_1
  2289. %res5 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Grad|Offset %f32_0_5 %f32_0_5 %s32_1
  2290. %res6 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod|NonPrivateTexelKHR %f32_1
  2291. )";
  2292. const std::string extra = R"(
  2293. OpCapability VulkanMemoryModelKHR
  2294. OpExtension "SPV_KHR_vulkan_memory_model"
  2295. )";
  2296. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2297. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2298. .c_str());
  2299. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2300. }
  2301. TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongResultType) {
  2302. const std::string body = R"(
  2303. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2304. %sampler = OpLoad %type_sampler %uniform_sampler
  2305. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2306. %res1 = OpImageSampleProjDrefExplicitLod %bool %simg %f32vec2_hh %f32_0_5 Lod %f32_1
  2307. )";
  2308. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2309. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2310. EXPECT_THAT(getDiagnosticString(),
  2311. HasSubstr("Expected Result Type to be int or float scalar type"));
  2312. }
  2313. TEST_F(ValidateImage, SampleProjDrefExplicitLodNotSampledImage) {
  2314. const std::string body = R"(
  2315. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2316. %res1 = OpImageSampleProjDrefExplicitLod %f32 %img %f32vec2_hh %f32_0_5 Lod %f32_1
  2317. )";
  2318. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2319. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2320. EXPECT_THAT(
  2321. getDiagnosticString(),
  2322. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2323. }
  2324. TEST_F(ValidateImage, SampleProjDrefExplicitLodMultisampleError) {
  2325. const std::string body = R"(
  2326. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2327. %sampler = OpLoad %type_sampler %uniform_sampler
  2328. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2329. %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
  2330. )";
  2331. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2332. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2333. EXPECT_THAT(
  2334. getDiagnosticString(),
  2335. HasSubstr("Dref sampling operation is invalid for multisample image"));
  2336. }
  2337. TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongSampledType) {
  2338. const std::string body = R"(
  2339. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2340. %sampler = OpLoad %type_sampler %uniform_sampler
  2341. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2342. %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
  2343. )";
  2344. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2345. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2346. EXPECT_THAT(
  2347. getDiagnosticString(),
  2348. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2349. }
  2350. TEST_F(ValidateImage, SampleProjDrefExplicitLodVoidSampledType) {
  2351. const std::string body = R"(
  2352. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2353. %sampler = OpLoad %type_sampler %uniform_sampler
  2354. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2355. %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec3_hhh %f32_0_5 Lod %f32_1
  2356. )";
  2357. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2358. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2359. EXPECT_THAT(
  2360. getDiagnosticString(),
  2361. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2362. }
  2363. TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongCoordinateType) {
  2364. const std::string body = R"(
  2365. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2366. %sampler = OpLoad %type_sampler %uniform_sampler
  2367. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2368. %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %img %f32_0_5 Lod %f32_1
  2369. )";
  2370. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2371. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2372. EXPECT_THAT(getDiagnosticString(),
  2373. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2374. }
  2375. TEST_F(ValidateImage, SampleProjDrefExplicitLodCoordinateSizeTooSmall) {
  2376. const std::string body = R"(
  2377. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2378. %sampler = OpLoad %type_sampler %uniform_sampler
  2379. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2380. %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32_0_5 %f32_0_5 Lod %f32_1
  2381. )";
  2382. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2383. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2384. EXPECT_THAT(getDiagnosticString(),
  2385. HasSubstr("Expected Coordinate to have at least 2 components, "
  2386. "but given only 1"));
  2387. }
  2388. TEST_F(ValidateImage, FetchSuccess) {
  2389. const std::string body = R"(
  2390. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2391. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
  2392. %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
  2393. )";
  2394. const std::string extra = R"(
  2395. OpCapability VulkanMemoryModelKHR
  2396. OpExtension "SPV_KHR_vulkan_memory_model"
  2397. )";
  2398. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2399. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2400. .c_str());
  2401. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2402. }
  2403. TEST_F(ValidateImage, FetchMultisampledSuccess) {
  2404. const std::string body = R"(
  2405. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2406. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample %u32_1
  2407. %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample|NonPrivateTexelKHR %u32_1
  2408. )";
  2409. const std::string extra = R"(
  2410. OpCapability VulkanMemoryModelKHR
  2411. OpExtension "SPV_KHR_vulkan_memory_model"
  2412. )";
  2413. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2414. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2415. .c_str());
  2416. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2417. }
  2418. TEST_F(ValidateImage, FetchWrongResultType) {
  2419. const std::string body = R"(
  2420. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2421. %res1 = OpImageFetch %f32 %img %u32vec2_01
  2422. )";
  2423. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2424. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2425. EXPECT_THAT(getDiagnosticString(),
  2426. HasSubstr("Expected Result Type to be int or float vector type"));
  2427. }
  2428. TEST_F(ValidateImage, FetchWrongNumComponentsResultType) {
  2429. const std::string body = R"(
  2430. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2431. %res1 = OpImageFetch %f32vec3 %img %u32vec2_01
  2432. )";
  2433. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2434. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2435. EXPECT_THAT(getDiagnosticString(),
  2436. HasSubstr("Expected Result Type to have 4 components"));
  2437. }
  2438. TEST_F(ValidateImage, FetchNotImage) {
  2439. const std::string body = R"(
  2440. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2441. %sampler = OpLoad %type_sampler %uniform_sampler
  2442. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2443. %res1 = OpImageFetch %f32vec4 %sampler %u32vec2_01
  2444. )";
  2445. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2446. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2447. EXPECT_THAT(getDiagnosticString(),
  2448. HasSubstr("Expected Image to be of type OpTypeImage"));
  2449. }
  2450. TEST_F(ValidateImage, FetchSampledImageDirectly) {
  2451. const std::string body = R"(
  2452. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2453. %sampler = OpLoad %type_sampler %uniform_sampler
  2454. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2455. %res1 = OpImageFetch %f32vec4 %simg %u32vec2_01
  2456. )";
  2457. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2458. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2459. EXPECT_THAT(getDiagnosticString(),
  2460. HasSubstr("OpSampledImage instruction must not appear as operand "
  2461. "for OpImageFetch"));
  2462. }
  2463. TEST_F(ValidateImage, FetchNotSampled) {
  2464. const std::string body = R"(
  2465. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  2466. %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
  2467. )";
  2468. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2469. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2470. EXPECT_THAT(getDiagnosticString(),
  2471. HasSubstr("Expected Image 'Sampled' parameter to be 1"));
  2472. }
  2473. TEST_F(ValidateImage, FetchCube) {
  2474. const std::string body = R"(
  2475. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2476. %res1 = OpImageFetch %f32vec4 %img %u32vec3_012
  2477. )";
  2478. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2479. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2480. EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' cannot be Cube"));
  2481. }
  2482. TEST_F(ValidateImage, FetchWrongSampledType) {
  2483. const std::string body = R"(
  2484. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2485. %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
  2486. )";
  2487. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2488. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2489. EXPECT_THAT(getDiagnosticString(),
  2490. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  2491. "Result Type components"));
  2492. }
  2493. TEST_F(ValidateImage, FetchVoidSampledType) {
  2494. const std::string body = R"(
  2495. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2496. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
  2497. %res2 = OpImageFetch %u32vec4 %img %u32vec2_01
  2498. %res3 = OpImageFetch %s32vec4 %img %u32vec2_01
  2499. )";
  2500. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2501. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2502. }
  2503. TEST_F(ValidateImage, FetchWrongCoordinateType) {
  2504. const std::string body = R"(
  2505. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2506. %res1 = OpImageFetch %f32vec4 %img %f32vec2_00
  2507. )";
  2508. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2509. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2510. EXPECT_THAT(getDiagnosticString(),
  2511. HasSubstr("Expected Coordinate to be int scalar or vector"));
  2512. }
  2513. TEST_F(ValidateImage, FetchCoordinateSizeTooSmall) {
  2514. const std::string body = R"(
  2515. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2516. %res1 = OpImageFetch %f32vec4 %img %u32_1
  2517. )";
  2518. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2519. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2520. EXPECT_THAT(getDiagnosticString(),
  2521. HasSubstr("Expected Coordinate to have at least 2 components, "
  2522. "but given only 1"));
  2523. }
  2524. TEST_F(ValidateImage, FetchLodNotInt) {
  2525. const std::string body = R"(
  2526. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2527. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Lod %f32_1
  2528. )";
  2529. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2530. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2531. EXPECT_THAT(getDiagnosticString(),
  2532. HasSubstr("Expected Image Operand Lod to be int scalar when used "
  2533. "with OpImageFetch"));
  2534. }
  2535. TEST_F(ValidateImage, FetchMultisampledMissingSample) {
  2536. const std::string body = R"(
  2537. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2538. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
  2539. )";
  2540. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2541. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions())
  2542. << GenerateShaderCode(body);
  2543. EXPECT_THAT(getDiagnosticString(),
  2544. HasSubstr("Image Operand Sample is required for operation on "
  2545. "multi-sampled image"))
  2546. << getDiagnosticString();
  2547. }
  2548. TEST_F(ValidateImage, GatherSuccess) {
  2549. const std::string body = R"(
  2550. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2551. %sampler = OpLoad %type_sampler %uniform_sampler
  2552. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2553. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1
  2554. %res2 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
  2555. %res3 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
  2556. )";
  2557. const std::string extra = R"(
  2558. OpCapability VulkanMemoryModelKHR
  2559. OpExtension "SPV_KHR_vulkan_memory_model"
  2560. )";
  2561. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2562. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2563. .c_str());
  2564. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2565. }
  2566. TEST_F(ValidateImage, GatherWrongResultType) {
  2567. const std::string body = R"(
  2568. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2569. %sampler = OpLoad %type_sampler %uniform_sampler
  2570. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2571. %res1 = OpImageGather %f32 %simg %f32vec4_0000 %u32_1
  2572. )";
  2573. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2574. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2575. EXPECT_THAT(getDiagnosticString(),
  2576. HasSubstr("Expected Result Type to be int or float vector type"));
  2577. }
  2578. TEST_F(ValidateImage, GatherWrongNumComponentsResultType) {
  2579. const std::string body = R"(
  2580. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2581. %sampler = OpLoad %type_sampler %uniform_sampler
  2582. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2583. %res1 = OpImageGather %f32vec3 %simg %f32vec4_0000 %u32_1
  2584. )";
  2585. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2586. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2587. EXPECT_THAT(getDiagnosticString(),
  2588. HasSubstr("Expected Result Type to have 4 components"));
  2589. }
  2590. TEST_F(ValidateImage, GatherNotSampledImage) {
  2591. const std::string body = R"(
  2592. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2593. %res1 = OpImageGather %f32vec4 %img %f32vec4_0000 %u32_1
  2594. )";
  2595. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2596. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2597. EXPECT_THAT(
  2598. getDiagnosticString(),
  2599. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2600. }
  2601. TEST_F(ValidateImage, GatherMultisampleError) {
  2602. const std::string body = R"(
  2603. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2604. %sampler = OpLoad %type_sampler %uniform_sampler
  2605. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2606. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Sample %u32_1
  2607. )";
  2608. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2609. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2610. EXPECT_THAT(getDiagnosticString(),
  2611. HasSubstr("Gather operation is invalid for multisample image"));
  2612. }
  2613. TEST_F(ValidateImage, GatherWrongSampledType) {
  2614. const std::string body = R"(
  2615. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2616. %sampler = OpLoad %type_sampler %uniform_sampler
  2617. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2618. %res1 = OpImageGather %u32vec4 %simg %f32vec4_0000 %u32_1
  2619. )";
  2620. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2621. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2622. EXPECT_THAT(getDiagnosticString(),
  2623. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  2624. "Result Type components"));
  2625. }
  2626. TEST_F(ValidateImage, GatherVoidSampledType) {
  2627. const std::string body = R"(
  2628. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2629. %sampler = OpLoad %type_sampler %uniform_sampler
  2630. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2631. %res1 = OpImageGather %u32vec4 %simg %f32vec2_00 %u32_1
  2632. )";
  2633. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2634. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2635. }
  2636. TEST_F(ValidateImage, GatherWrongCoordinateType) {
  2637. const std::string body = R"(
  2638. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2639. %sampler = OpLoad %type_sampler %uniform_sampler
  2640. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2641. %res1 = OpImageGather %f32vec4 %simg %u32vec4_0123 %u32_1
  2642. )";
  2643. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2644. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2645. EXPECT_THAT(getDiagnosticString(),
  2646. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2647. }
  2648. TEST_F(ValidateImage, GatherCoordinateSizeTooSmall) {
  2649. const std::string body = R"(
  2650. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2651. %sampler = OpLoad %type_sampler %uniform_sampler
  2652. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2653. %res1 = OpImageGather %f32vec4 %simg %f32_0_5 %u32_1
  2654. )";
  2655. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2656. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2657. EXPECT_THAT(getDiagnosticString(),
  2658. HasSubstr("Expected Coordinate to have at least 4 components, "
  2659. "but given only 1"));
  2660. }
  2661. TEST_F(ValidateImage, GatherWrongComponentType) {
  2662. const std::string body = R"(
  2663. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2664. %sampler = OpLoad %type_sampler %uniform_sampler
  2665. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2666. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %f32_1
  2667. )";
  2668. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2669. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2670. EXPECT_THAT(getDiagnosticString(),
  2671. HasSubstr("Expected Component to be 32-bit int scalar"));
  2672. }
  2673. TEST_F(ValidateImage, GatherComponentNot32Bit) {
  2674. const std::string body = R"(
  2675. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2676. %sampler = OpLoad %type_sampler %uniform_sampler
  2677. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2678. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u64_0
  2679. )";
  2680. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2681. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2682. EXPECT_THAT(getDiagnosticString(),
  2683. HasSubstr("Expected Component to be 32-bit int scalar"));
  2684. }
  2685. TEST_F(ValidateImage, GatherComponentSuccessVulkan) {
  2686. const std::string body = R"(
  2687. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2688. %sampler = OpLoad %type_sampler %uniform_sampler
  2689. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2690. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_0
  2691. )";
  2692. spv_target_env env = SPV_ENV_VULKAN_1_0;
  2693. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  2694. env);
  2695. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  2696. }
  2697. TEST_F(ValidateImage, GatherComponentNotConstantVulkan) {
  2698. const std::string body = R"(
  2699. %input_u32 = OpLoad %u32 %input_flat_u32
  2700. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2701. %sampler = OpLoad %type_sampler %uniform_sampler
  2702. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2703. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %input_u32
  2704. )";
  2705. spv_target_env env = SPV_ENV_VULKAN_1_0;
  2706. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  2707. env);
  2708. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  2709. EXPECT_THAT(getDiagnosticString(),
  2710. AnyVUID("VUID-StandaloneSpirv-OpImageGather-04664"));
  2711. EXPECT_THAT(getDiagnosticString(),
  2712. HasSubstr("Expected Component Operand to be a const object for "
  2713. "Vulkan environment"));
  2714. }
  2715. TEST_F(ValidateImage, GatherDimCube) {
  2716. const std::string body = R"(
  2717. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2718. %sampler = OpLoad %type_sampler %uniform_sampler
  2719. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2720. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
  2721. )";
  2722. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2723. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2724. EXPECT_THAT(
  2725. getDiagnosticString(),
  2726. HasSubstr(
  2727. "Image Operand ConstOffsets cannot be used with Cube Image 'Dim'"));
  2728. }
  2729. TEST_F(ValidateImage, GatherConstOffsetsNotArray) {
  2730. const std::string body = R"(
  2731. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2732. %sampler = OpLoad %type_sampler %uniform_sampler
  2733. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2734. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %u32vec4_0123
  2735. )";
  2736. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2737. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2738. EXPECT_THAT(
  2739. getDiagnosticString(),
  2740. HasSubstr(
  2741. "Expected Image Operand ConstOffsets to be an array of size 4"));
  2742. }
  2743. TEST_F(ValidateImage, GatherConstOffsetsArrayWrongSize) {
  2744. const std::string body = R"(
  2745. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2746. %sampler = OpLoad %type_sampler %uniform_sampler
  2747. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2748. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets3x2
  2749. )";
  2750. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2751. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2752. EXPECT_THAT(
  2753. getDiagnosticString(),
  2754. HasSubstr(
  2755. "Expected Image Operand ConstOffsets to be an array of size 4"));
  2756. }
  2757. TEST_F(ValidateImage, GatherConstOffsetsArrayNotVector) {
  2758. const std::string body = R"(
  2759. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2760. %sampler = OpLoad %type_sampler %uniform_sampler
  2761. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2762. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4xu
  2763. )";
  2764. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2765. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2766. EXPECT_THAT(getDiagnosticString(),
  2767. HasSubstr("Expected Image Operand ConstOffsets array components "
  2768. "to be int vectors of size 2"));
  2769. }
  2770. TEST_F(ValidateImage, GatherConstOffsetsArrayVectorWrongSize) {
  2771. const std::string body = R"(
  2772. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2773. %sampler = OpLoad %type_sampler %uniform_sampler
  2774. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2775. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4x3
  2776. )";
  2777. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2778. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2779. EXPECT_THAT(getDiagnosticString(),
  2780. HasSubstr("Expected Image Operand ConstOffsets array components "
  2781. "to be int vectors of size 2"));
  2782. }
  2783. TEST_F(ValidateImage, GatherConstOffsetsArrayNotConst) {
  2784. const std::string body = R"(
  2785. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2786. %sampler = OpLoad %type_sampler %uniform_sampler
  2787. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2788. %offsets = OpUndef %u32vec2arr4
  2789. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %offsets
  2790. )";
  2791. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2792. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2793. EXPECT_THAT(
  2794. getDiagnosticString(),
  2795. HasSubstr("Expected Image Operand ConstOffsets to be a const object"));
  2796. }
  2797. TEST_F(ValidateImage, NotGatherWithConstOffsets) {
  2798. const std::string body = R"(
  2799. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2800. %sampler = OpLoad %type_sampler %uniform_sampler
  2801. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2802. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffsets %const_offsets
  2803. )";
  2804. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2805. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2806. EXPECT_THAT(
  2807. getDiagnosticString(),
  2808. HasSubstr(
  2809. "Image Operand ConstOffsets can only be used with OpImageGather "
  2810. "and OpImageDrefGather"));
  2811. }
  2812. TEST_F(ValidateImage, DrefGatherSuccess) {
  2813. const std::string body = R"(
  2814. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2815. %sampler = OpLoad %type_sampler %uniform_sampler
  2816. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2817. %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
  2818. %res2 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 ConstOffsets %const_offsets
  2819. %res3 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 NonPrivateTexelKHR
  2820. )";
  2821. const std::string extra = R"(
  2822. OpCapability VulkanMemoryModelKHR
  2823. OpExtension "SPV_KHR_vulkan_memory_model"
  2824. )";
  2825. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2826. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2827. .c_str());
  2828. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2829. }
  2830. TEST_F(ValidateImage, DrefGatherMultisampleError) {
  2831. const std::string body = R"(
  2832. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2833. %sampler = OpLoad %type_sampler %uniform_sampler
  2834. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2835. %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_1 Sample %u32_1
  2836. )";
  2837. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2838. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2839. EXPECT_THAT(getDiagnosticString(),
  2840. HasSubstr("Gather operation is invalid for multisample image"));
  2841. }
  2842. TEST_F(ValidateImage, DrefGatherVoidSampledType) {
  2843. const std::string body = R"(
  2844. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2845. %sampler = OpLoad %type_sampler %uniform_sampler
  2846. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2847. %res1 = OpImageDrefGather %u32vec4 %simg %f32vec2_00 %f32_0_5
  2848. )";
  2849. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2850. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2851. EXPECT_THAT(getDiagnosticString(),
  2852. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  2853. "Result Type components"));
  2854. }
  2855. TEST_F(ValidateImage, DrefGatherWrongDrefType) {
  2856. const std::string body = R"(
  2857. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2858. %sampler = OpLoad %type_sampler %uniform_sampler
  2859. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2860. %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %u32_1
  2861. )";
  2862. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2863. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2864. EXPECT_THAT(getDiagnosticString(),
  2865. HasSubstr("Expected Dref to be of 32-bit float type"));
  2866. }
  2867. TEST_F(ValidateImage, DrefGatherWrongDimVulkan) {
  2868. const std::string body = R"(
  2869. %img = OpLoad %type_image_f32_3d_0001 %uniform_image_f32_3d_0001
  2870. %sampler = OpLoad %type_sampler %uniform_sampler
  2871. %simg = OpSampledImage %type_sampled_image_f32_3d_0001 %img %sampler
  2872. %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
  2873. )";
  2874. CompileSuccessfully(
  2875. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  2876. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  2877. EXPECT_THAT(getDiagnosticString(),
  2878. AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
  2879. EXPECT_THAT(getDiagnosticString(),
  2880. HasSubstr("Expected Image 'Dim' to be 2D, Cube, or Rect"));
  2881. }
  2882. TEST_F(ValidateImage, ReadSuccess1) {
  2883. const std::string body = R"(
  2884. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  2885. %res1 = OpImageRead %u32vec4 %img %u32vec2_01
  2886. )";
  2887. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  2888. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  2889. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2890. }
  2891. TEST_F(ValidateImage, ReadSuccess2) {
  2892. const std::string body = R"(
  2893. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  2894. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  2895. )";
  2896. const std::string extra = "\nOpCapability Image1D\n";
  2897. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  2898. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2899. }
  2900. TEST_F(ValidateImage, ReadSuccess3) {
  2901. const std::string body = R"(
  2902. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  2903. %res1 = OpImageRead %f32vec4 %img %u32vec3_012
  2904. )";
  2905. const std::string extra = "\nOpCapability ImageCubeArray\n";
  2906. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  2907. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2908. }
  2909. TEST_F(ValidateImage, ReadSuccess4) {
  2910. const std::string body = R"(
  2911. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  2912. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  2913. )";
  2914. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2915. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2916. }
  2917. TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) {
  2918. const std::string body = R"(
  2919. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  2920. %res1 = OpImageRead %u32vec4 %img %u32vec2_01
  2921. )";
  2922. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2923. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2924. }
  2925. TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
  2926. const std::string body = R"(
  2927. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  2928. %res1 = OpImageRead %u32vec4 %img %u32vec2_01
  2929. )";
  2930. spv_target_env env = SPV_ENV_VULKAN_1_0;
  2931. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  2932. env);
  2933. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  2934. EXPECT_THAT(getDiagnosticString(),
  2935. HasSubstr("Capability StorageImageReadWithoutFormat is required "
  2936. "to read storage image"));
  2937. }
  2938. TEST_F(ValidateImage, ReadNeedCapabilityImage1D) {
  2939. const std::string body = R"(
  2940. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  2941. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  2942. )";
  2943. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2944. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2945. EXPECT_THAT(
  2946. getDiagnosticString(),
  2947. HasSubstr("Capability Image1D is required to access storage image"));
  2948. }
  2949. TEST_F(ValidateImage, ReadNeedCapabilityImageCubeArray) {
  2950. const std::string body = R"(
  2951. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  2952. %res1 = OpImageRead %f32vec4 %img %u32vec3_012
  2953. )";
  2954. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2955. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2956. EXPECT_THAT(
  2957. getDiagnosticString(),
  2958. HasSubstr(
  2959. "Capability ImageCubeArray is required to access storage image"));
  2960. }
  2961. // TODO([email protected]) Disabled until the spec is clarified.
  2962. TEST_F(ValidateImage, DISABLED_ReadWrongResultType) {
  2963. const std::string body = R"(
  2964. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  2965. %res1 = OpImageRead %f32 %img %u32vec2_01
  2966. )";
  2967. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  2968. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  2969. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2970. EXPECT_THAT(getDiagnosticString(),
  2971. HasSubstr("Expected Result Type to be int or float vector type"));
  2972. }
  2973. TEST_F(ValidateImage, ReadScalarResultType_Universal) {
  2974. const std::string body = R"(
  2975. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  2976. %res1 = OpImageRead %u32 %img %u32vec2_01
  2977. )";
  2978. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  2979. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  2980. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
  2981. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2982. }
  2983. TEST_F(ValidateImage, ReadUnusualNumComponentsResultType_Universal) {
  2984. const std::string body = R"(
  2985. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  2986. %res1 = OpImageRead %u32vec3 %img %u32vec2_01
  2987. )";
  2988. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  2989. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  2990. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
  2991. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2992. }
  2993. TEST_F(ValidateImage, ReadWrongNumComponentsResultType_Vulkan) {
  2994. const std::string body = R"(
  2995. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  2996. %res1 = OpImageRead %u32vec3 %img %u32vec2_01
  2997. )";
  2998. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  2999. CompileSuccessfully(
  3000. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_VULKAN_1_0)
  3001. .c_str());
  3002. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3003. EXPECT_THAT(getDiagnosticString(),
  3004. AnyVUID("VUID-StandaloneSpirv-Result-04780"));
  3005. EXPECT_THAT(getDiagnosticString(),
  3006. HasSubstr("Expected Result Type to have 4 components"));
  3007. }
  3008. TEST_F(ValidateImage, ReadNotImage) {
  3009. const std::string body = R"(
  3010. %sampler = OpLoad %type_sampler %uniform_sampler
  3011. %res1 = OpImageRead %f32vec4 %sampler %u32vec2_01
  3012. )";
  3013. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3014. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3015. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3016. EXPECT_THAT(getDiagnosticString(),
  3017. HasSubstr("Expected Image to be of type OpTypeImage"));
  3018. }
  3019. TEST_F(ValidateImage, ReadImageSampled) {
  3020. const std::string body = R"(
  3021. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3022. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  3023. )";
  3024. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3025. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3026. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3027. EXPECT_THAT(getDiagnosticString(),
  3028. HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
  3029. }
  3030. TEST_F(ValidateImage, ReadWrongSampledType) {
  3031. const std::string body = R"(
  3032. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3033. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  3034. )";
  3035. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3036. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3037. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3038. EXPECT_THAT(getDiagnosticString(),
  3039. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  3040. "Result Type components"));
  3041. }
  3042. TEST_F(ValidateImage, ReadVoidSampledType) {
  3043. const std::string body = R"(
  3044. %img = OpLoad %type_image_void_2d_0002 %uniform_image_void_2d_0002
  3045. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  3046. %res2 = OpImageRead %u32vec4 %img %u32vec2_01
  3047. %res3 = OpImageRead %s32vec4 %img %u32vec2_01
  3048. )";
  3049. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3050. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3051. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3052. }
  3053. TEST_F(ValidateImage, ReadWrongCoordinateType) {
  3054. const std::string body = R"(
  3055. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3056. %res1 = OpImageRead %u32vec4 %img %f32vec2_00
  3057. )";
  3058. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3059. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3060. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3061. EXPECT_THAT(getDiagnosticString(),
  3062. HasSubstr("Expected Coordinate to be int scalar or vector"));
  3063. }
  3064. TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) {
  3065. const std::string body = R"(
  3066. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3067. %res1 = OpImageRead %u32vec4 %img %u32_1
  3068. )";
  3069. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3070. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3071. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3072. EXPECT_THAT(getDiagnosticString(),
  3073. HasSubstr("Expected Coordinate to have at least 2 components, "
  3074. "but given only 1"));
  3075. }
  3076. TEST_F(ValidateImage, WriteSuccess1) {
  3077. const std::string body = R"(
  3078. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3079. OpImageWrite %img %u32vec2_01 %u32vec4_0123
  3080. )";
  3081. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3082. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3083. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3084. }
  3085. TEST_F(ValidateImage, WriteSuccess2) {
  3086. const std::string body = R"(
  3087. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  3088. OpImageWrite %img %u32_1 %f32vec4_0000
  3089. )";
  3090. const std::string extra = "\nOpCapability Image1D\n";
  3091. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3092. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3093. }
  3094. TEST_F(ValidateImage, WriteSuccess3) {
  3095. const std::string body = R"(
  3096. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  3097. OpImageWrite %img %u32vec3_012 %f32vec4_0000
  3098. )";
  3099. const std::string extra = "\nOpCapability ImageCubeArray\n";
  3100. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3101. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3102. }
  3103. TEST_F(ValidateImage, WriteSuccess4) {
  3104. const std::string body = R"(
  3105. %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
  3106. OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
  3107. )";
  3108. const std::string extra = R"(
  3109. OpCapability StorageImageWriteWithoutFormat
  3110. OpCapability StorageImageMultisample
  3111. )";
  3112. const std::string declarations = R"(
  3113. %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
  3114. %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
  3115. %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
  3116. )";
  3117. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  3118. SPV_ENV_UNIVERSAL_1_0, "GLSL450",
  3119. declarations)
  3120. .c_str());
  3121. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3122. }
  3123. TEST_F(ValidateImage, WriteSubpassData) {
  3124. const std::string body = R"(
  3125. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  3126. OpImageWrite %img %u32vec2_01 %f32vec4_0000
  3127. )";
  3128. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3129. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3130. EXPECT_THAT(getDiagnosticString(),
  3131. HasSubstr("Image 'Dim' cannot be SubpassData"));
  3132. }
  3133. TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
  3134. const std::string body = R"(
  3135. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3136. OpImageWrite %img %u32vec2_01 %u32vec4_0123
  3137. )";
  3138. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3139. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3140. }
  3141. TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
  3142. const std::string body = R"(
  3143. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3144. OpImageWrite %img %u32vec2_01 %u32vec4_0123
  3145. )";
  3146. spv_target_env env = SPV_ENV_VULKAN_1_0;
  3147. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  3148. env);
  3149. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  3150. EXPECT_THAT(
  3151. getDiagnosticString(),
  3152. HasSubstr(
  3153. "Capability StorageImageWriteWithoutFormat is required to write to "
  3154. "storage image"));
  3155. }
  3156. TEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
  3157. const std::string body = R"(
  3158. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  3159. OpImageWrite %img %u32vec2_01 %f32vec4_0000
  3160. )";
  3161. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3162. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3163. EXPECT_THAT(getDiagnosticString(),
  3164. HasSubstr("Capability Image1D is required to access storage "
  3165. "image"));
  3166. }
  3167. TEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
  3168. const std::string body = R"(
  3169. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  3170. OpImageWrite %img %u32vec3_012 %f32vec4_0000
  3171. )";
  3172. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3173. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3174. EXPECT_THAT(
  3175. getDiagnosticString(),
  3176. HasSubstr(
  3177. "Capability ImageCubeArray is required to access storage image"));
  3178. }
  3179. TEST_F(ValidateImage, WriteNotImage) {
  3180. const std::string body = R"(
  3181. %sampler = OpLoad %type_sampler %uniform_sampler
  3182. OpImageWrite %sampler %u32vec2_01 %f32vec4_0000
  3183. )";
  3184. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3185. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3186. EXPECT_THAT(getDiagnosticString(),
  3187. HasSubstr("Expected Image to be of type OpTypeImage"));
  3188. }
  3189. TEST_F(ValidateImage, WriteImageSampled) {
  3190. const std::string body = R"(
  3191. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3192. OpImageWrite %img %u32vec2_01 %f32vec4_0000
  3193. )";
  3194. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3195. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3196. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3197. EXPECT_THAT(getDiagnosticString(),
  3198. HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
  3199. }
  3200. TEST_F(ValidateImage, WriteWrongCoordinateType) {
  3201. const std::string body = R"(
  3202. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3203. OpImageWrite %img %f32vec2_00 %u32vec4_0123
  3204. )";
  3205. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3206. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3207. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3208. EXPECT_THAT(getDiagnosticString(),
  3209. HasSubstr("Expected Coordinate to be int scalar or vector"));
  3210. }
  3211. TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
  3212. const std::string body = R"(
  3213. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3214. OpImageWrite %img %u32_1 %u32vec4_0123
  3215. )";
  3216. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3217. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3218. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3219. EXPECT_THAT(getDiagnosticString(),
  3220. HasSubstr("Expected Coordinate to have at least 2 components, "
  3221. "but given only 1"));
  3222. }
  3223. TEST_F(ValidateImage, WriteTexelScalarSuccess) {
  3224. const std::string body = R"(
  3225. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3226. OpImageWrite %img %u32vec2_01 %u32_2
  3227. )";
  3228. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3229. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3230. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3231. }
  3232. TEST_F(ValidateImage, WriteTexelWrongType) {
  3233. const std::string body = R"(
  3234. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3235. OpImageWrite %img %u32vec2_01 %img
  3236. )";
  3237. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3238. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3239. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3240. EXPECT_THAT(getDiagnosticString(),
  3241. HasSubstr("Expected Texel to be int or float vector or scalar"));
  3242. }
  3243. TEST_F(ValidateImage, WriteTexelNonNumericalType) {
  3244. const std::string body = R"(
  3245. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3246. OpImageWrite %img %u32vec2_01 %boolvec4_tttt
  3247. )";
  3248. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3249. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3250. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3251. EXPECT_THAT(getDiagnosticString(),
  3252. HasSubstr("Expected Texel to be int or float vector or scalar"));
  3253. }
  3254. TEST_F(ValidateImage, WriteTexelWrongComponentType) {
  3255. const std::string body = R"(
  3256. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3257. OpImageWrite %img %u32vec2_01 %f32vec4_0000
  3258. )";
  3259. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3260. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3261. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3262. EXPECT_THAT(
  3263. getDiagnosticString(),
  3264. HasSubstr(
  3265. "Expected Image 'Sampled Type' to be the same as Texel components"));
  3266. }
  3267. TEST_F(ValidateImage, WriteSampleNotInteger) {
  3268. const std::string body = R"(
  3269. %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
  3270. OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
  3271. )";
  3272. const std::string extra = R"(
  3273. OpCapability StorageImageWriteWithoutFormat
  3274. OpCapability StorageImageMultisample
  3275. )";
  3276. const std::string declarations = R"(
  3277. %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
  3278. %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
  3279. %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
  3280. )";
  3281. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  3282. SPV_ENV_UNIVERSAL_1_0, "GLSL450",
  3283. declarations)
  3284. .c_str());
  3285. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3286. EXPECT_THAT(getDiagnosticString(),
  3287. HasSubstr("Expected Image Operand Sample to be int scalar"));
  3288. }
  3289. TEST_F(ValidateImage, WriteSampleNotMultisampled) {
  3290. const std::string body = R"(
  3291. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  3292. OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
  3293. )";
  3294. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3295. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3296. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3297. EXPECT_THAT(
  3298. getDiagnosticString(),
  3299. HasSubstr("Image Operand Sample requires non-zero 'MS' parameter"));
  3300. }
  3301. TEST_F(ValidateImage, SampleWrongOpcode) {
  3302. const std::string body = R"(
  3303. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3304. %sampler = OpLoad %type_sampler %uniform_sampler
  3305. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  3306. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Sample %u32_1
  3307. )";
  3308. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3309. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3310. EXPECT_THAT(getDiagnosticString(),
  3311. HasSubstr("Sampling operation is invalid for multisample image"));
  3312. }
  3313. TEST_F(ValidateImage, SampleImageToImageSuccess) {
  3314. const std::string body = R"(
  3315. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3316. %sampler = OpLoad %type_sampler %uniform_sampler
  3317. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3318. %img2 = OpImage %type_image_f32_2d_0001 %simg
  3319. )";
  3320. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3321. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3322. }
  3323. TEST_F(ValidateImage, SampleImageToImageWrongResultType) {
  3324. const std::string body = R"(
  3325. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3326. %sampler = OpLoad %type_sampler %uniform_sampler
  3327. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3328. %img2 = OpImage %type_sampled_image_f32_2d_0001 %simg
  3329. )";
  3330. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3331. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3332. EXPECT_THAT(getDiagnosticString(),
  3333. HasSubstr("Expected Result Type to be OpTypeImage"));
  3334. }
  3335. TEST_F(ValidateImage, SampleImageToImageNotSampledImage) {
  3336. const std::string body = R"(
  3337. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3338. %img2 = OpImage %type_image_f32_2d_0001 %img
  3339. )";
  3340. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3341. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3342. EXPECT_THAT(
  3343. getDiagnosticString(),
  3344. HasSubstr("Expected Sample Image to be of type OpTypeSampleImage"));
  3345. }
  3346. TEST_F(ValidateImage, SampleImageToImageNotTheSameImageType) {
  3347. const std::string body = R"(
  3348. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3349. %sampler = OpLoad %type_sampler %uniform_sampler
  3350. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3351. %img2 = OpImage %type_image_f32_2d_0002 %simg
  3352. )";
  3353. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3354. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3355. EXPECT_THAT(getDiagnosticString(),
  3356. HasSubstr("Expected Sample Image image type to be equal to "
  3357. "Result Type"));
  3358. }
  3359. TEST_F(ValidateImage, QueryFormatSuccess) {
  3360. const std::string body = R"(
  3361. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3362. %res1 = OpImageQueryFormat %u32 %img
  3363. )";
  3364. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3365. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3366. }
  3367. TEST_F(ValidateImage, QueryFormatWrongResultType) {
  3368. const std::string body = R"(
  3369. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3370. %res1 = OpImageQueryFormat %bool %img
  3371. )";
  3372. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3373. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3374. EXPECT_THAT(getDiagnosticString(),
  3375. HasSubstr("Expected Result Type to be int scalar type"));
  3376. }
  3377. TEST_F(ValidateImage, QueryFormatNotImage) {
  3378. const std::string body = R"(
  3379. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3380. %sampler = OpLoad %type_sampler %uniform_sampler
  3381. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3382. %res1 = OpImageQueryFormat %u32 %sampler
  3383. )";
  3384. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3385. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3386. EXPECT_THAT(getDiagnosticString(),
  3387. HasSubstr("Expected operand to be of type OpTypeImage"));
  3388. }
  3389. TEST_F(ValidateImage, QueryOrderSuccess) {
  3390. const std::string body = R"(
  3391. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3392. %res1 = OpImageQueryOrder %u32 %img
  3393. )";
  3394. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3395. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3396. }
  3397. TEST_F(ValidateImage, QueryOrderWrongResultType) {
  3398. const std::string body = R"(
  3399. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3400. %res1 = OpImageQueryOrder %bool %img
  3401. )";
  3402. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3403. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3404. EXPECT_THAT(getDiagnosticString(),
  3405. HasSubstr("Expected Result Type to be int scalar type"));
  3406. }
  3407. TEST_F(ValidateImage, QueryOrderNotImage) {
  3408. const std::string body = R"(
  3409. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3410. %sampler = OpLoad %type_sampler %uniform_sampler
  3411. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3412. %res1 = OpImageQueryOrder %u32 %sampler
  3413. )";
  3414. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3415. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3416. EXPECT_THAT(getDiagnosticString(),
  3417. HasSubstr("Expected operand to be of type OpTypeImage"));
  3418. }
  3419. TEST_F(ValidateImage, QuerySizeLodSuccess) {
  3420. const std::string body = R"(
  3421. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3422. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
  3423. )";
  3424. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3425. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3426. }
  3427. TEST_F(ValidateImage, QuerySizeLodWrongResultType) {
  3428. const std::string body = R"(
  3429. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3430. %res1 = OpImageQuerySizeLod %f32vec2 %img %u32_1
  3431. )";
  3432. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3433. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3434. EXPECT_THAT(
  3435. getDiagnosticString(),
  3436. HasSubstr("Expected Result Type to be int scalar or vector type"));
  3437. }
  3438. TEST_F(ValidateImage, QuerySizeLodResultTypeWrongSize) {
  3439. const std::string body = R"(
  3440. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3441. %res1 = OpImageQuerySizeLod %u32 %img %u32_1
  3442. )";
  3443. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3444. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3445. EXPECT_THAT(getDiagnosticString(),
  3446. HasSubstr("Result Type has 1 components, but 2 expected"));
  3447. }
  3448. TEST_F(ValidateImage, QuerySizeLodNotImage) {
  3449. const std::string body = R"(
  3450. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3451. %sampler = OpLoad %type_sampler %uniform_sampler
  3452. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3453. %res1 = OpImageQuerySizeLod %u32vec2 %sampler %u32_1
  3454. )";
  3455. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3456. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3457. EXPECT_THAT(getDiagnosticString(),
  3458. HasSubstr("Expected Image to be of type OpTypeImage"));
  3459. }
  3460. TEST_F(ValidateImage, QuerySizeLodSampledImageDirectly) {
  3461. const std::string body = R"(
  3462. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3463. %sampler = OpLoad %type_sampler %uniform_sampler
  3464. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3465. %res1 = OpImageQuerySizeLod %u32vec2 %simg %u32_1
  3466. )";
  3467. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3468. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3469. EXPECT_THAT(getDiagnosticString(),
  3470. HasSubstr("OpSampledImage instruction must not appear as operand "
  3471. "for OpImageQuerySizeLod"));
  3472. }
  3473. TEST_F(ValidateImage, QuerySizeLodMultisampledError) {
  3474. const std::string body = R"(
  3475. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3476. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
  3477. )";
  3478. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3479. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3480. EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 0"));
  3481. }
  3482. TEST_F(ValidateImage, QuerySizeLodNonSampledUniversalSuccess) {
  3483. const std::string body = R"(
  3484. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  3485. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
  3486. )";
  3487. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3488. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3489. EXPECT_EQ(getDiagnosticString(), "");
  3490. }
  3491. TEST_F(ValidateImage, QuerySizeLodVulkanNonSampledError) {
  3492. // Create a whole shader module. Avoid Vulkan incompatibility with
  3493. // SampledRrect images inserted by helper function GenerateShaderCode.
  3494. const std::string body = R"(
  3495. OpCapability Shader
  3496. OpCapability ImageQuery
  3497. OpMemoryModel Logical Simple
  3498. OpEntryPoint Fragment %main "main"
  3499. OpExecutionMode %main OriginUpperLeft
  3500. %f32 = OpTypeFloat 32
  3501. %u32 = OpTypeInt 32 0
  3502. %u32_0 = OpConstant %u32 0
  3503. %u32vec2 = OpTypeVector %u32 2
  3504. %void = OpTypeVoid
  3505. %voidfn = OpTypeFunction %void
  3506. ; Test with a storage image.
  3507. %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  3508. %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
  3509. %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
  3510. %main = OpFunction %void None %voidfn
  3511. %entry = OpLabel
  3512. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  3513. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_0
  3514. OpReturn
  3515. OpFunctionEnd
  3516. )";
  3517. CompileSuccessfully(body.c_str());
  3518. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3519. EXPECT_THAT(getDiagnosticString(),
  3520. AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
  3521. EXPECT_THAT(
  3522. getDiagnosticString(),
  3523. HasSubstr(
  3524. "OpImageQuerySizeLod must only consume an \"Image\" operand whose "
  3525. "type has its \"Sampled\" operand set to 1"));
  3526. }
  3527. TEST_F(ValidateImage, QuerySizeLodWrongImageDim) {
  3528. const std::string body = R"(
  3529. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  3530. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
  3531. )";
  3532. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3533. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3534. EXPECT_THAT(getDiagnosticString(),
  3535. HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
  3536. }
  3537. TEST_F(ValidateImage, QuerySizeLodWrongLodType) {
  3538. const std::string body = R"(
  3539. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3540. %res1 = OpImageQuerySizeLod %u32vec2 %img %f32_0
  3541. )";
  3542. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3543. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3544. EXPECT_THAT(getDiagnosticString(),
  3545. HasSubstr("Expected Level of Detail to be int scalar"));
  3546. }
  3547. TEST_F(ValidateImage, QuerySizeSuccess) {
  3548. const std::string body = R"(
  3549. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3550. %res1 = OpImageQuerySize %u32vec2 %img
  3551. )";
  3552. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3553. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3554. }
  3555. TEST_F(ValidateImage, QuerySizeWrongResultType) {
  3556. const std::string body = R"(
  3557. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3558. %res1 = OpImageQuerySize %f32vec2 %img
  3559. )";
  3560. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3561. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3562. EXPECT_THAT(
  3563. getDiagnosticString(),
  3564. HasSubstr("Expected Result Type to be int scalar or vector type"));
  3565. }
  3566. TEST_F(ValidateImage, QuerySizeNotImage) {
  3567. const std::string body = R"(
  3568. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3569. %sampler = OpLoad %type_sampler %uniform_sampler
  3570. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3571. %res1 = OpImageQuerySize %u32vec2 %sampler
  3572. )";
  3573. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3574. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3575. EXPECT_THAT(getDiagnosticString(),
  3576. HasSubstr("Expected Image to be of type OpTypeImage"));
  3577. }
  3578. TEST_F(ValidateImage, QuerySizeSampledImageDirectly) {
  3579. const std::string body = R"(
  3580. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3581. %sampler = OpLoad %type_sampler %uniform_sampler
  3582. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3583. %res1 = OpImageQuerySize %u32vec2 %simg
  3584. )";
  3585. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3586. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3587. EXPECT_THAT(getDiagnosticString(),
  3588. HasSubstr("OpSampledImage instruction must not appear as operand "
  3589. "for OpImageQuerySize"));
  3590. }
  3591. TEST_F(ValidateImage, QuerySizeDimSubpassDataBad) {
  3592. const std::string body = R"(
  3593. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  3594. %res1 = OpImageQuerySize %u32vec2 %img
  3595. )";
  3596. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3597. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3598. EXPECT_THAT(
  3599. getDiagnosticString(),
  3600. HasSubstr("Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"));
  3601. }
  3602. TEST_F(ValidateImage, QuerySizeWrongSampling) {
  3603. const std::string body = R"(
  3604. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3605. %res1 = OpImageQuerySize %u32vec2 %img
  3606. )";
  3607. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3608. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3609. EXPECT_THAT(
  3610. getDiagnosticString(),
  3611. HasSubstr("Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"));
  3612. }
  3613. TEST_F(ValidateImage, QuerySizeWrongNumberOfComponents) {
  3614. const std::string body = R"(
  3615. %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
  3616. %res1 = OpImageQuerySize %u32vec2 %img
  3617. )";
  3618. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3619. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3620. EXPECT_THAT(getDiagnosticString(),
  3621. HasSubstr("Result Type has 2 components, but 4 expected"));
  3622. }
  3623. TEST_F(ValidateImage, QueryLodSuccessKernel) {
  3624. const std::string body = R"(
  3625. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3626. %sampler = OpLoad %type_sampler %uniform_sampler
  3627. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3628. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3629. %res2 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
  3630. )";
  3631. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3632. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3633. }
  3634. TEST_F(ValidateImage, QueryLodSuccessShader) {
  3635. const std::string body = R"(
  3636. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3637. %sampler = OpLoad %type_sampler %uniform_sampler
  3638. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3639. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3640. )";
  3641. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3642. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3643. }
  3644. TEST_F(ValidateImage, QueryLodWrongResultType) {
  3645. const std::string body = R"(
  3646. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3647. %sampler = OpLoad %type_sampler %uniform_sampler
  3648. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3649. %res1 = OpImageQueryLod %u32vec2 %simg %f32vec2_hh
  3650. )";
  3651. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3652. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3653. EXPECT_THAT(getDiagnosticString(),
  3654. HasSubstr("Expected Result Type to be float vector type"));
  3655. }
  3656. TEST_F(ValidateImage, QueryLodResultTypeWrongSize) {
  3657. const std::string body = R"(
  3658. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3659. %sampler = OpLoad %type_sampler %uniform_sampler
  3660. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3661. %res1 = OpImageQueryLod %f32vec3 %simg %f32vec2_hh
  3662. )";
  3663. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3664. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3665. EXPECT_THAT(getDiagnosticString(),
  3666. HasSubstr("Expected Result Type to have 2 components"));
  3667. }
  3668. TEST_F(ValidateImage, QueryLodNotSampledImage) {
  3669. const std::string body = R"(
  3670. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3671. %res1 = OpImageQueryLod %f32vec2 %img %f32vec2_hh
  3672. )";
  3673. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3674. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3675. EXPECT_THAT(
  3676. getDiagnosticString(),
  3677. HasSubstr("Expected Image operand to be of type OpTypeSampledImage"));
  3678. }
  3679. TEST_F(ValidateImage, QueryLodWrongDim) {
  3680. const std::string body = R"(
  3681. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  3682. %sampler = OpLoad %type_sampler %uniform_sampler
  3683. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  3684. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3685. )";
  3686. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3687. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3688. EXPECT_THAT(getDiagnosticString(),
  3689. HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
  3690. }
  3691. TEST_F(ValidateImage, QueryLodWrongCoordinateType) {
  3692. const std::string body = R"(
  3693. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3694. %sampler = OpLoad %type_sampler %uniform_sampler
  3695. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3696. %res1 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
  3697. )";
  3698. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3699. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3700. EXPECT_THAT(getDiagnosticString(),
  3701. HasSubstr("Expected Coordinate to be float scalar or vector"));
  3702. }
  3703. TEST_F(ValidateImage, QueryLodCoordinateSizeTooSmall) {
  3704. const std::string body = R"(
  3705. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3706. %sampler = OpLoad %type_sampler %uniform_sampler
  3707. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3708. %res1 = OpImageQueryLod %f32vec2 %simg %f32_0
  3709. )";
  3710. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3711. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3712. EXPECT_THAT(getDiagnosticString(),
  3713. HasSubstr("Expected Coordinate to have at least 2 components, "
  3714. "but given only 1"));
  3715. }
  3716. TEST_F(ValidateImage, QueryLevelsSuccess) {
  3717. const std::string body = R"(
  3718. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3719. %res1 = OpImageQueryLevels %u32 %img
  3720. )";
  3721. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3722. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3723. }
  3724. TEST_F(ValidateImage, QueryLevelsWrongResultType) {
  3725. const std::string body = R"(
  3726. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3727. %res1 = OpImageQueryLevels %f32 %img
  3728. )";
  3729. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3730. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3731. EXPECT_THAT(getDiagnosticString(),
  3732. HasSubstr("Expected Result Type to be int scalar type"));
  3733. }
  3734. TEST_F(ValidateImage, QueryLevelsNotImage) {
  3735. const std::string body = R"(
  3736. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3737. %sampler = OpLoad %type_sampler %uniform_sampler
  3738. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3739. %res1 = OpImageQueryLevels %u32 %sampler
  3740. )";
  3741. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3742. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3743. EXPECT_THAT(getDiagnosticString(),
  3744. HasSubstr("Expected Image to be of type OpTypeImage"));
  3745. }
  3746. TEST_F(ValidateImage, QueryLevelsSampledImageDirectly) {
  3747. const std::string body = R"(
  3748. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3749. %sampler = OpLoad %type_sampler %uniform_sampler
  3750. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3751. %res1 = OpImageQueryLevels %u32 %simg
  3752. )";
  3753. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3754. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3755. EXPECT_THAT(getDiagnosticString(),
  3756. HasSubstr("OpSampledImage instruction must not appear as operand "
  3757. "for OpImageQueryLevels"));
  3758. }
  3759. TEST_F(ValidateImage, QueryLevelsWrongDim) {
  3760. const std::string body = R"(
  3761. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  3762. %res1 = OpImageQueryLevels %u32 %img
  3763. )";
  3764. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3765. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3766. EXPECT_THAT(getDiagnosticString(),
  3767. HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
  3768. }
  3769. TEST_F(ValidateImage, QuerySizeLevelsNonSampledUniversalSuccess) {
  3770. const std::string body = R"(
  3771. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  3772. %res1 = OpImageQueryLevels %u32 %img
  3773. )";
  3774. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3775. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3776. EXPECT_EQ(getDiagnosticString(), "");
  3777. }
  3778. TEST_F(ValidateImage, QuerySizeLevelsVulkanNonSampledError) {
  3779. // Create a whole shader module. Avoid Vulkan incompatibility with
  3780. // SampledRrect images inserted by helper function GenerateShaderCode.
  3781. const std::string body = R"(
  3782. OpCapability Shader
  3783. OpCapability ImageQuery
  3784. OpMemoryModel Logical Simple
  3785. OpEntryPoint Fragment %main "main"
  3786. OpExecutionMode %main OriginUpperLeft
  3787. %f32 = OpTypeFloat 32
  3788. %u32 = OpTypeInt 32 0
  3789. %void = OpTypeVoid
  3790. %voidfn = OpTypeFunction %void
  3791. ; Test with a storage image.
  3792. %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  3793. %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
  3794. %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
  3795. %main = OpFunction %void None %voidfn
  3796. %entry = OpLabel
  3797. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  3798. %res1 = OpImageQueryLevels %u32 %img
  3799. OpReturn
  3800. OpFunctionEnd
  3801. )";
  3802. CompileSuccessfully(body.c_str());
  3803. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3804. EXPECT_THAT(getDiagnosticString(),
  3805. AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
  3806. EXPECT_THAT(
  3807. getDiagnosticString(),
  3808. HasSubstr("OpImageQueryLevels must only consume an \"Image\" operand "
  3809. "whose type has its \"Sampled\" operand set to 1"));
  3810. }
  3811. TEST_F(ValidateImage, QuerySamplesSuccess) {
  3812. const std::string body = R"(
  3813. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3814. %res1 = OpImageQuerySamples %u32 %img
  3815. )";
  3816. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3817. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3818. }
  3819. TEST_F(ValidateImage, QuerySamplesNot2D) {
  3820. const std::string body = R"(
  3821. %img = OpLoad %type_image_f32_3d_0011 %uniform_image_f32_3d_0011
  3822. %res1 = OpImageQuerySamples %u32 %img
  3823. )";
  3824. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3825. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3826. EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' must be 2D"));
  3827. }
  3828. TEST_F(ValidateImage, QuerySamplesNotMultisampled) {
  3829. const std::string body = R"(
  3830. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3831. %res1 = OpImageQuerySamples %u32 %img
  3832. )";
  3833. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3834. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3835. EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 1"));
  3836. }
  3837. TEST_F(ValidateImage, QueryLodWrongExecutionModel) {
  3838. const std::string body = R"(
  3839. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3840. %sampler = OpLoad %type_sampler %uniform_sampler
  3841. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3842. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3843. )";
  3844. CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
  3845. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3846. EXPECT_THAT(
  3847. getDiagnosticString(),
  3848. HasSubstr(
  3849. "OpImageQueryLod requires Fragment or GLCompute execution model"));
  3850. }
  3851. TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
  3852. const std::string body = R"(
  3853. %call_ret = OpFunctionCall %void %my_func
  3854. OpReturn
  3855. OpFunctionEnd
  3856. %my_func = OpFunction %void None %func
  3857. %my_func_entry = OpLabel
  3858. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3859. %sampler = OpLoad %type_sampler %uniform_sampler
  3860. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3861. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3862. )";
  3863. CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
  3864. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3865. EXPECT_THAT(
  3866. getDiagnosticString(),
  3867. HasSubstr(
  3868. "OpImageQueryLod requires Fragment or GLCompute execution model"));
  3869. }
  3870. TEST_F(ValidateImage, QueryLodComputeShaderDerivatives) {
  3871. const std::string body = R"(
  3872. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3873. %sampler = OpLoad %type_sampler %uniform_sampler
  3874. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3875. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3876. )";
  3877. const std::string extra = R"(
  3878. OpCapability ComputeDerivativeGroupLinearNV
  3879. OpExtension "SPV_NV_compute_shader_derivatives"
  3880. )";
  3881. const std::string mode = R"(
  3882. OpExecutionMode %main LocalSize 8 8 1
  3883. OpExecutionMode %main DerivativeGroupLinearNV
  3884. )";
  3885. CompileSuccessfully(
  3886. GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
  3887. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3888. }
  3889. TEST_F(ValidateImage, QueryLodUniversalSuccess) {
  3890. // Create a whole shader module. Avoid Vulkan incompatibility with
  3891. // SampledRrect images inserted by helper function GenerateShaderCode.
  3892. const std::string body = R"(
  3893. OpCapability Shader
  3894. OpCapability ImageQuery
  3895. OpMemoryModel Logical Simple
  3896. OpEntryPoint Fragment %main "main"
  3897. OpExecutionMode %main OriginUpperLeft
  3898. OpDecorate %uniform_image_f32_2d_0000 DescriptorSet 0
  3899. OpDecorate %uniform_image_f32_2d_0000 Binding 0
  3900. OpDecorate %sampler DescriptorSet 0
  3901. OpDecorate %sampler Binding 1
  3902. %f32 = OpTypeFloat 32
  3903. %f32vec2 = OpTypeVector %f32 2
  3904. %f32vec2_null = OpConstantNull %f32vec2
  3905. %u32 = OpTypeInt 32 0
  3906. %u32vec2 = OpTypeVector %u32 2
  3907. %void = OpTypeVoid
  3908. %voidfn = OpTypeFunction %void
  3909. ; Test with an image with sampled = 0
  3910. %type_image_f32_2d_0000 = OpTypeImage %f32 2D 0 0 0 0 Rgba32f
  3911. %ptr_image_f32_2d_0000 = OpTypePointer UniformConstant %type_image_f32_2d_0000
  3912. %uniform_image_f32_2d_0000 = OpVariable %ptr_image_f32_2d_0000 UniformConstant
  3913. %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0000
  3914. %sampler_ty = OpTypeSampler
  3915. %ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
  3916. %sampler = OpVariable %ptr_sampler_ty UniformConstant
  3917. %main = OpFunction %void None %voidfn
  3918. %entry = OpLabel
  3919. %img = OpLoad %type_image_f32_2d_0000 %uniform_image_f32_2d_0000
  3920. %s = OpLoad %sampler_ty %sampler
  3921. %simg = OpSampledImage %sampled_image_ty %img %s
  3922. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
  3923. OpReturn
  3924. OpFunctionEnd
  3925. )";
  3926. CompileSuccessfully(body.c_str());
  3927. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3928. }
  3929. TEST_F(ValidateImage, QueryLodVulkanNonSampledError) {
  3930. // Create a whole shader module. Avoid Vulkan incompatibility with
  3931. // SampledRrect images inserted by helper function GenerateShaderCode.
  3932. const std::string body = R"(
  3933. OpCapability Shader
  3934. OpCapability ImageQuery
  3935. OpMemoryModel Logical Simple
  3936. OpEntryPoint Fragment %main "main"
  3937. OpExecutionMode %main OriginUpperLeft
  3938. OpDecorate %sampled_image DescriptorSet 0
  3939. OpDecorate %sampled_image Binding 0
  3940. %f32 = OpTypeFloat 32
  3941. %f32vec2 = OpTypeVector %f32 2
  3942. %f32vec2_null = OpConstantNull %f32vec2
  3943. %u32 = OpTypeInt 32 0
  3944. %u32vec2 = OpTypeVector %u32 2
  3945. %void = OpTypeVoid
  3946. %voidfn = OpTypeFunction %void
  3947. ; Test with an image with Sampled = 2
  3948. ; In Vulkan it Sampled must be 1 or 2, checked in another part of the
  3949. ; validation flow.
  3950. %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  3951. ; Expect to fail here.
  3952. %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0002
  3953. %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
  3954. %sampled_image = OpVariable %ptr_sampled_image_ty UniformConstant
  3955. %main = OpFunction %void None %voidfn
  3956. %entry = OpLabel
  3957. %simg = OpLoad %sampled_image_ty %sampled_image
  3958. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
  3959. OpReturn
  3960. OpFunctionEnd
  3961. )";
  3962. CompileSuccessfully(body.c_str());
  3963. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3964. EXPECT_THAT(getDiagnosticString(),
  3965. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
  3966. EXPECT_THAT(getDiagnosticString(),
  3967. HasSubstr("Sampled image type requires an image type with "
  3968. "\"Sampled\" operand set to 0 or 1"));
  3969. }
  3970. TEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) {
  3971. const std::string body = R"(
  3972. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3973. %sampler = OpLoad %type_sampler %uniform_sampler
  3974. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3975. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3976. )";
  3977. const std::string extra = R"(
  3978. OpCapability ComputeDerivativeGroupLinearNV
  3979. OpExtension "SPV_NV_compute_shader_derivatives"
  3980. )";
  3981. const std::string mode = R"(
  3982. OpExecutionMode %main LocalSize 8 8 1
  3983. )";
  3984. CompileSuccessfully(
  3985. GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
  3986. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3987. EXPECT_THAT(getDiagnosticString(),
  3988. HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsNV or "
  3989. "DerivativeGroupLinearNV execution mode for GLCompute "
  3990. "execution model"));
  3991. }
  3992. TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
  3993. const std::string body = R"(
  3994. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3995. %sampler = OpLoad %type_sampler %uniform_sampler
  3996. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3997. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
  3998. )";
  3999. CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
  4000. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4001. EXPECT_THAT(getDiagnosticString(),
  4002. HasSubstr("ImplicitLod instructions require Fragment or "
  4003. "GLCompute execution model"));
  4004. }
  4005. TEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) {
  4006. const std::string body = R"(
  4007. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4008. %sampler = OpLoad %type_sampler %uniform_sampler
  4009. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4010. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
  4011. )";
  4012. const std::string extra = R"(
  4013. OpCapability ComputeDerivativeGroupLinearNV
  4014. OpExtension "SPV_NV_compute_shader_derivatives"
  4015. )";
  4016. const std::string mode = R"(
  4017. OpExecutionMode %main LocalSize 8 8 1
  4018. OpExecutionMode %main DerivativeGroupLinearNV
  4019. )";
  4020. CompileSuccessfully(
  4021. GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
  4022. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4023. }
  4024. TEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) {
  4025. const std::string body = R"(
  4026. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4027. %sampler = OpLoad %type_sampler %uniform_sampler
  4028. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4029. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
  4030. )";
  4031. const std::string extra = R"(
  4032. OpCapability ComputeDerivativeGroupLinearNV
  4033. OpExtension "SPV_NV_compute_shader_derivatives"
  4034. )";
  4035. const std::string mode = R"(
  4036. OpExecutionMode %main LocalSize 8 8 1
  4037. )";
  4038. CompileSuccessfully(
  4039. GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
  4040. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4041. EXPECT_THAT(
  4042. getDiagnosticString(),
  4043. HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsNV or "
  4044. "DerivativeGroupLinearNV execution mode for GLCompute "
  4045. "execution model"));
  4046. }
  4047. TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
  4048. const std::string body = R"(
  4049. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  4050. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  4051. )";
  4052. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4053. CompileSuccessfully(GenerateShaderCode(body, extra, "Vertex").c_str());
  4054. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4055. EXPECT_THAT(getDiagnosticString(),
  4056. HasSubstr("Dim SubpassData requires Fragment execution model"));
  4057. }
  4058. TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
  4059. const std::string body = R"(
  4060. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4061. %sampler = OpLoad %type_sampler %uniform_sampler
  4062. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4063. %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh
  4064. %res2 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Bias %f32_0_25
  4065. %res4 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
  4066. %res5 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
  4067. %res6 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
  4068. %res7 = OpImageSparseSampleImplicitLod %struct_u64_f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  4069. %res8 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
  4070. )";
  4071. const std::string extra = R"(
  4072. OpCapability VulkanMemoryModelKHR
  4073. OpExtension "SPV_KHR_vulkan_memory_model"
  4074. )";
  4075. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4076. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4077. .c_str());
  4078. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4079. }
  4080. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotStruct) {
  4081. const std::string body = R"(
  4082. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4083. %sampler = OpLoad %type_sampler %uniform_sampler
  4084. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4085. %res1 = OpImageSparseSampleImplicitLod %f32 %simg %f32vec2_hh
  4086. )";
  4087. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4088. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4089. EXPECT_THAT(getDiagnosticString(),
  4090. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4091. }
  4092. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers1) {
  4093. const std::string body = R"(
  4094. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4095. %sampler = OpLoad %type_sampler %uniform_sampler
  4096. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4097. %res1 = OpImageSparseSampleImplicitLod %struct_u32 %simg %f32vec2_hh
  4098. )";
  4099. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4100. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4101. EXPECT_THAT(getDiagnosticString(),
  4102. HasSubstr("Expected Result Type to be a struct containing an int "
  4103. "scalar and a texel"));
  4104. }
  4105. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers2) {
  4106. const std::string body = R"(
  4107. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4108. %sampler = OpLoad %type_sampler %uniform_sampler
  4109. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4110. %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4_u32 %simg %f32vec2_hh
  4111. )";
  4112. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4113. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4114. EXPECT_THAT(getDiagnosticString(),
  4115. HasSubstr("Expected Result Type to be a struct containing an "
  4116. "int scalar and a texel"));
  4117. }
  4118. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeFirstMemberNotInt) {
  4119. const std::string body = R"(
  4120. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4121. %sampler = OpLoad %type_sampler %uniform_sampler
  4122. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4123. %res1 = OpImageSparseSampleImplicitLod %struct_f32_f32vec4 %simg %f32vec2_hh
  4124. )";
  4125. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4126. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4127. EXPECT_THAT(getDiagnosticString(),
  4128. HasSubstr("Expected Result Type to be a struct containing an "
  4129. "int scalar and a texel"));
  4130. }
  4131. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeTexelNotVector) {
  4132. const std::string body = R"(
  4133. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4134. %sampler = OpLoad %type_sampler %uniform_sampler
  4135. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4136. %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32 %simg %f32vec2_hh
  4137. )";
  4138. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4139. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4140. EXPECT_THAT(getDiagnosticString(),
  4141. HasSubstr("Expected Result Type's second member to be int or "
  4142. "float vector type"));
  4143. }
  4144. TEST_F(ValidateImage, SparseSampleImplicitLodWrongNumComponentsTexel) {
  4145. const std::string body = R"(
  4146. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4147. %sampler = OpLoad %type_sampler %uniform_sampler
  4148. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4149. %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec3 %simg %f32vec2_hh
  4150. )";
  4151. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4152. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4153. EXPECT_THAT(getDiagnosticString(),
  4154. HasSubstr("Expected Result Type's second member to have 4 "
  4155. "components"));
  4156. }
  4157. TEST_F(ValidateImage, SparseSampleImplicitLodWrongComponentTypeTexel) {
  4158. const std::string body = R"(
  4159. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4160. %sampler = OpLoad %type_sampler %uniform_sampler
  4161. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4162. %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32vec4 %simg %f32vec2_hh
  4163. )";
  4164. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4165. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4166. EXPECT_THAT(getDiagnosticString(),
  4167. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4168. "Result Type's second member components"));
  4169. }
  4170. TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
  4171. const std::string body = R"(
  4172. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  4173. %sampler = OpLoad %type_sampler %uniform_sampler
  4174. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  4175. %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
  4176. %res2 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
  4177. %res4 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
  4178. %res5 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
  4179. %res6 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
  4180. %res7 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  4181. %res8 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
  4182. )";
  4183. const std::string extra = R"(
  4184. OpCapability VulkanMemoryModelKHR
  4185. OpExtension "SPV_KHR_vulkan_memory_model"
  4186. )";
  4187. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4188. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4189. .c_str());
  4190. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4191. }
  4192. TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotStruct) {
  4193. const std::string body = R"(
  4194. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4195. %sampler = OpLoad %type_sampler %uniform_sampler
  4196. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4197. %res1 = OpImageSparseSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1
  4198. )";
  4199. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4200. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4201. EXPECT_THAT(getDiagnosticString(),
  4202. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4203. }
  4204. TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers1) {
  4205. const std::string body = R"(
  4206. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4207. %sampler = OpLoad %type_sampler %uniform_sampler
  4208. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4209. %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32 %simg %f32vec2_hh %f32_1
  4210. )";
  4211. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4212. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4213. EXPECT_THAT(
  4214. getDiagnosticString(),
  4215. HasSubstr("Expected Result Type to be a struct containing an int scalar "
  4216. "and a texel"));
  4217. }
  4218. TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers2) {
  4219. const std::string body = R"(
  4220. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4221. %sampler = OpLoad %type_sampler %uniform_sampler
  4222. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4223. %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_f32_u32 %simg %f32vec2_hh %f32_1
  4224. )";
  4225. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4226. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4227. EXPECT_THAT(
  4228. getDiagnosticString(),
  4229. HasSubstr("Expected Result Type to be a struct containing an int scalar "
  4230. "and a texel"));
  4231. }
  4232. TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt) {
  4233. const std::string body = R"(
  4234. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4235. %sampler = OpLoad %type_sampler %uniform_sampler
  4236. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4237. %res1 = OpImageSparseSampleDrefImplicitLod %struct_f32_f32 %simg %f32vec2_hh %f32_1
  4238. )";
  4239. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4240. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4241. EXPECT_THAT(
  4242. getDiagnosticString(),
  4243. HasSubstr("Expected Result Type to be a struct containing an int scalar "
  4244. "and a texel"));
  4245. }
  4246. TEST_F(ValidateImage, SparseSampleDrefImplicitLodDifferentSampledType) {
  4247. const std::string body = R"(
  4248. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4249. %sampler = OpLoad %type_sampler %uniform_sampler
  4250. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4251. %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
  4252. )";
  4253. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4254. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4255. EXPECT_THAT(getDiagnosticString(),
  4256. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4257. "Result Type's second member"));
  4258. }
  4259. TEST_F(ValidateImage, SparseFetchSuccess) {
  4260. const std::string body = R"(
  4261. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  4262. %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
  4263. %res2 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
  4264. )";
  4265. const std::string extra = R"(
  4266. OpCapability VulkanMemoryModelKHR
  4267. OpExtension "SPV_KHR_vulkan_memory_model"
  4268. )";
  4269. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4270. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4271. .c_str());
  4272. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4273. }
  4274. TEST_F(ValidateImage, SparseFetchResultTypeNotStruct) {
  4275. const std::string body = R"(
  4276. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4277. %res1 = OpImageSparseFetch %f32 %img %u32vec2_01
  4278. )";
  4279. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4280. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4281. EXPECT_THAT(getDiagnosticString(),
  4282. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4283. }
  4284. TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers1) {
  4285. const std::string body = R"(
  4286. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4287. %res1 = OpImageSparseFetch %struct_u32 %img %u32vec2_01
  4288. )";
  4289. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4290. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4291. EXPECT_THAT(getDiagnosticString(),
  4292. HasSubstr("Expected Result Type to be a struct containing an "
  4293. "int scalar and a texel"));
  4294. }
  4295. TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers2) {
  4296. const std::string body = R"(
  4297. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4298. %res1 = OpImageSparseFetch %struct_u32_f32vec4_u32 %img %u32vec2_01
  4299. )";
  4300. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4301. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4302. EXPECT_THAT(getDiagnosticString(),
  4303. HasSubstr("Expected Result Type to be a struct containing an "
  4304. "int scalar and a texel"));
  4305. }
  4306. TEST_F(ValidateImage, SparseFetchResultTypeFirstMemberNotInt) {
  4307. const std::string body = R"(
  4308. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4309. %res1 = OpImageSparseFetch %struct_f32_f32vec4 %img %u32vec2_01
  4310. )";
  4311. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4312. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4313. EXPECT_THAT(getDiagnosticString(),
  4314. HasSubstr("Expected Result Type to be a struct containing an "
  4315. "int scalar and a texel"));
  4316. }
  4317. TEST_F(ValidateImage, SparseFetchResultTypeTexelNotVector) {
  4318. const std::string body = R"(
  4319. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4320. %res1 = OpImageSparseFetch %struct_u32_u32 %img %u32vec2_01
  4321. )";
  4322. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4323. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4324. EXPECT_THAT(getDiagnosticString(),
  4325. HasSubstr("Expected Result Type's second member to be int or "
  4326. "float vector type"));
  4327. }
  4328. TEST_F(ValidateImage, SparseFetchWrongNumComponentsTexel) {
  4329. const std::string body = R"(
  4330. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4331. %res1 = OpImageSparseFetch %struct_u32_f32vec3 %img %u32vec2_01
  4332. )";
  4333. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4334. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4335. EXPECT_THAT(getDiagnosticString(),
  4336. HasSubstr("Expected Result Type's second member to have 4 "
  4337. "components"));
  4338. }
  4339. TEST_F(ValidateImage, SparseFetchWrongComponentTypeTexel) {
  4340. const std::string body = R"(
  4341. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4342. %res1 = OpImageSparseFetch %struct_u32_u32vec4 %img %u32vec2_01
  4343. )";
  4344. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4345. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4346. EXPECT_THAT(getDiagnosticString(),
  4347. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4348. "Result Type's second member components"));
  4349. }
  4350. TEST_F(ValidateImage, SparseReadSuccess) {
  4351. const std::string body = R"(
  4352. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4353. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
  4354. )";
  4355. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4356. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4357. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4358. }
  4359. TEST_F(ValidateImage, SparseReadResultTypeNotStruct) {
  4360. const std::string body = R"(
  4361. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4362. %res1 = OpImageSparseRead %f32 %img %u32vec2_01
  4363. )";
  4364. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4365. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4366. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4367. EXPECT_THAT(getDiagnosticString(),
  4368. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4369. }
  4370. TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers1) {
  4371. const std::string body = R"(
  4372. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4373. %res1 = OpImageSparseRead %struct_u32 %img %u32vec2_01
  4374. )";
  4375. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4376. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4377. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4378. EXPECT_THAT(getDiagnosticString(),
  4379. HasSubstr("Expected Result Type to be a struct containing an "
  4380. "int scalar and a texel"));
  4381. }
  4382. TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers2) {
  4383. const std::string body = R"(
  4384. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4385. %res1 = OpImageSparseRead %struct_u32_f32vec4_u32 %img %u32vec2_01
  4386. )";
  4387. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4388. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4389. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4390. EXPECT_THAT(getDiagnosticString(),
  4391. HasSubstr("Expected Result Type to be a struct containing an "
  4392. "int scalar and a texel"));
  4393. }
  4394. TEST_F(ValidateImage, SparseReadResultTypeFirstMemberNotInt) {
  4395. const std::string body = R"(
  4396. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4397. %res1 = OpImageSparseRead %struct_f32_f32vec4 %img %u32vec2_01
  4398. )";
  4399. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4400. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4401. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4402. EXPECT_THAT(getDiagnosticString(),
  4403. HasSubstr("Expected Result Type to be a struct containing an "
  4404. "int scalar and a texel"));
  4405. }
  4406. TEST_F(ValidateImage, SparseReadResultTypeTexelWrongType) {
  4407. const std::string body = R"(
  4408. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4409. %res1 = OpImageSparseRead %struct_u32_u32arr4 %img %u32vec2_01
  4410. )";
  4411. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4412. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4413. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4414. EXPECT_THAT(getDiagnosticString(),
  4415. HasSubstr("Expected Result Type's second member to be int or "
  4416. "float scalar or vector type"));
  4417. }
  4418. TEST_F(ValidateImage, SparseReadWrongComponentTypeTexel) {
  4419. const std::string body = R"(
  4420. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4421. %res1 = OpImageSparseRead %struct_u32_u32vec4 %img %u32vec2_01
  4422. )";
  4423. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4424. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4425. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4426. EXPECT_THAT(getDiagnosticString(),
  4427. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4428. "Result Type's second member components"));
  4429. }
  4430. TEST_F(ValidateImage, SparseReadSubpassDataNotAllowed) {
  4431. const std::string body = R"(
  4432. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  4433. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
  4434. )";
  4435. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4436. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment").c_str());
  4437. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4438. EXPECT_THAT(
  4439. getDiagnosticString(),
  4440. HasSubstr("Image Dim SubpassData cannot be used with ImageSparseRead"));
  4441. }
  4442. TEST_F(ValidateImage, SparseGatherSuccess) {
  4443. const std::string body = R"(
  4444. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4445. %sampler = OpLoad %type_sampler %uniform_sampler
  4446. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4447. %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1
  4448. %res2 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
  4449. )";
  4450. const std::string extra = R"(
  4451. OpCapability VulkanMemoryModelKHR
  4452. OpExtension "SPV_KHR_vulkan_memory_model"
  4453. )";
  4454. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4455. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4456. .c_str());
  4457. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4458. }
  4459. TEST_F(ValidateImage, SparseGatherResultTypeNotStruct) {
  4460. const std::string body = R"(
  4461. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4462. %sampler = OpLoad %type_sampler %uniform_sampler
  4463. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4464. %res1 = OpImageSparseGather %f32 %simg %f32vec2_hh %u32_1
  4465. )";
  4466. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4467. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4468. EXPECT_THAT(getDiagnosticString(),
  4469. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4470. }
  4471. TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers1) {
  4472. const std::string body = R"(
  4473. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4474. %sampler = OpLoad %type_sampler %uniform_sampler
  4475. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4476. %res1 = OpImageSparseGather %struct_u32 %simg %f32vec2_hh %u32_1
  4477. )";
  4478. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4479. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4480. EXPECT_THAT(getDiagnosticString(),
  4481. HasSubstr("Expected Result Type to be a struct containing an int "
  4482. "scalar and a texel"));
  4483. }
  4484. TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers2) {
  4485. const std::string body = R"(
  4486. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4487. %sampler = OpLoad %type_sampler %uniform_sampler
  4488. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4489. %res1 = OpImageSparseGather %struct_u32_f32vec4_u32 %simg %f32vec2_hh %u32_1
  4490. )";
  4491. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4492. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4493. EXPECT_THAT(getDiagnosticString(),
  4494. HasSubstr("Expected Result Type to be a struct containing an int "
  4495. "scalar and a texel"));
  4496. }
  4497. TEST_F(ValidateImage, SparseGatherResultTypeFirstMemberNotInt) {
  4498. const std::string body = R"(
  4499. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4500. %sampler = OpLoad %type_sampler %uniform_sampler
  4501. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4502. %res1 = OpImageSparseGather %struct_f32_f32vec4 %simg %f32vec2_hh %u32_1
  4503. )";
  4504. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4505. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4506. EXPECT_THAT(getDiagnosticString(),
  4507. HasSubstr("Expected Result Type to be a struct containing an "
  4508. "int scalar and a texel"));
  4509. }
  4510. TEST_F(ValidateImage, SparseGatherResultTypeTexelNotVector) {
  4511. const std::string body = R"(
  4512. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4513. %sampler = OpLoad %type_sampler %uniform_sampler
  4514. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4515. %res1 = OpImageSparseGather %struct_u32_u32 %simg %f32vec2_hh %u32_1
  4516. )";
  4517. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4518. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4519. EXPECT_THAT(getDiagnosticString(),
  4520. HasSubstr("Expected Result Type's second member to be int or "
  4521. "float vector type"));
  4522. }
  4523. TEST_F(ValidateImage, SparseGatherWrongNumComponentsTexel) {
  4524. const std::string body = R"(
  4525. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4526. %sampler = OpLoad %type_sampler %uniform_sampler
  4527. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4528. %res1 = OpImageSparseGather %struct_u32_f32vec3 %simg %f32vec2_hh %u32_1
  4529. )";
  4530. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4531. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4532. EXPECT_THAT(getDiagnosticString(),
  4533. HasSubstr("Expected Result Type's second member to have 4 "
  4534. "components"));
  4535. }
  4536. TEST_F(ValidateImage, SparseGatherWrongComponentTypeTexel) {
  4537. const std::string body = R"(
  4538. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4539. %sampler = OpLoad %type_sampler %uniform_sampler
  4540. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4541. %res1 = OpImageSparseGather %struct_u32_u32vec4 %simg %f32vec2_hh %u32_1
  4542. )";
  4543. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4544. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4545. EXPECT_THAT(getDiagnosticString(),
  4546. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4547. "Result Type's second member components"));
  4548. }
  4549. TEST_F(ValidateImage, SparseTexelsResidentSuccess) {
  4550. const std::string body = R"(
  4551. %res1 = OpImageSparseTexelsResident %bool %u32_1
  4552. )";
  4553. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4554. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4555. }
  4556. TEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) {
  4557. const std::string body = R"(
  4558. %res1 = OpImageSparseTexelsResident %u32 %u32_1
  4559. )";
  4560. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4561. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4562. EXPECT_THAT(getDiagnosticString(),
  4563. HasSubstr("Expected Result Type to be bool scalar type"));
  4564. }
  4565. TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageRead) {
  4566. const std::string body = R"(
  4567. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4568. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
  4569. )";
  4570. const std::string extra = R"(
  4571. OpCapability StorageImageReadWithoutFormat
  4572. OpCapability VulkanMemoryModelKHR
  4573. OpExtension "SPV_KHR_vulkan_memory_model"
  4574. )";
  4575. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4576. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4577. .c_str());
  4578. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4579. }
  4580. TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageSparseRead) {
  4581. const std::string body = R"(
  4582. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4583. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
  4584. )";
  4585. const std::string extra = R"(
  4586. OpCapability StorageImageReadWithoutFormat
  4587. OpCapability VulkanMemoryModelKHR
  4588. OpExtension "SPV_KHR_vulkan_memory_model"
  4589. )";
  4590. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4591. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4592. .c_str());
  4593. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4594. }
  4595. TEST_F(ValidateImage, MakeTexelVisibleKHRFailureOpcode) {
  4596. const std::string body = R"(
  4597. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4598. %sampler = OpLoad %type_sampler %uniform_sampler
  4599. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4600. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
  4601. )";
  4602. const std::string extra = R"(
  4603. OpCapability StorageImageReadWithoutFormat
  4604. OpCapability VulkanMemoryModelKHR
  4605. OpExtension "SPV_KHR_vulkan_memory_model"
  4606. )";
  4607. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4608. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4609. .c_str());
  4610. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4611. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4612. EXPECT_THAT(
  4613. getDiagnosticString(),
  4614. HasSubstr("Image Operand MakeTexelVisibleKHR can only be used with "
  4615. "OpImageRead or OpImageSparseRead: OpImageSampleImplicitLod"));
  4616. }
  4617. TEST_F(ValidateImage, MakeTexelVisibleKHRFailureMissingNonPrivate) {
  4618. const std::string body = R"(
  4619. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4620. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR %u32_1
  4621. )";
  4622. const std::string extra = R"(
  4623. OpCapability StorageImageReadWithoutFormat
  4624. OpCapability VulkanMemoryModelKHR
  4625. OpExtension "SPV_KHR_vulkan_memory_model"
  4626. )";
  4627. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4628. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4629. .c_str());
  4630. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4631. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4632. EXPECT_THAT(getDiagnosticString(),
  4633. HasSubstr("Image Operand MakeTexelVisibleKHR requires "
  4634. "NonPrivateTexelKHR is also specified: OpImageRead"));
  4635. }
  4636. TEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) {
  4637. const std::string body = R"(
  4638. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4639. OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
  4640. )";
  4641. const std::string extra = R"(
  4642. OpCapability StorageImageWriteWithoutFormat
  4643. OpCapability VulkanMemoryModelKHR
  4644. OpExtension "SPV_KHR_vulkan_memory_model"
  4645. )";
  4646. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4647. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4648. .c_str());
  4649. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4650. }
  4651. TEST_F(ValidateImage, MakeTexelAvailableKHRFailureOpcode) {
  4652. const std::string body = R"(
  4653. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4654. %sampler = OpLoad %type_sampler %uniform_sampler
  4655. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4656. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
  4657. )";
  4658. const std::string extra = R"(
  4659. OpCapability StorageImageReadWithoutFormat
  4660. OpCapability VulkanMemoryModelKHR
  4661. OpExtension "SPV_KHR_vulkan_memory_model"
  4662. )";
  4663. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4664. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4665. .c_str());
  4666. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4667. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4668. EXPECT_THAT(getDiagnosticString(),
  4669. HasSubstr("Image Operand MakeTexelAvailableKHR can only be used "
  4670. "with OpImageWrite: OpImageSampleImplicitLod"));
  4671. }
  4672. TEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) {
  4673. const std::string body = R"(
  4674. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4675. OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
  4676. )";
  4677. const std::string extra = R"(
  4678. OpCapability StorageImageWriteWithoutFormat
  4679. OpCapability VulkanMemoryModelKHR
  4680. OpExtension "SPV_KHR_vulkan_memory_model"
  4681. )";
  4682. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4683. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4684. .c_str());
  4685. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4686. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4687. EXPECT_THAT(getDiagnosticString(),
  4688. HasSubstr("Image Operand MakeTexelAvailableKHR requires "
  4689. "NonPrivateTexelKHR is also specified: OpImageWrite"));
  4690. }
  4691. TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) {
  4692. const std::string body = R"(
  4693. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4694. OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
  4695. )";
  4696. const std::string extra = R"(
  4697. OpCapability StorageImageWriteWithoutFormat
  4698. OpCapability VulkanMemoryModelKHR
  4699. OpExtension "SPV_KHR_vulkan_memory_model"
  4700. )";
  4701. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4702. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4703. .c_str());
  4704. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4705. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4706. EXPECT_THAT(
  4707. getDiagnosticString(),
  4708. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  4709. "VulkanMemoryModelDeviceScopeKHR capability"));
  4710. }
  4711. TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) {
  4712. const std::string body = R"(
  4713. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4714. OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
  4715. )";
  4716. const std::string extra = R"(
  4717. OpCapability StorageImageWriteWithoutFormat
  4718. OpCapability VulkanMemoryModelKHR
  4719. OpCapability VulkanMemoryModelDeviceScopeKHR
  4720. OpExtension "SPV_KHR_vulkan_memory_model"
  4721. )";
  4722. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4723. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4724. .c_str());
  4725. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4726. }
  4727. TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadBad) {
  4728. const std::string body = R"(
  4729. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4730. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
  4731. )";
  4732. const std::string extra = R"(
  4733. OpCapability StorageImageReadWithoutFormat
  4734. OpCapability VulkanMemoryModelKHR
  4735. OpExtension "SPV_KHR_vulkan_memory_model"
  4736. )";
  4737. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4738. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4739. .c_str());
  4740. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4741. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4742. EXPECT_THAT(
  4743. getDiagnosticString(),
  4744. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  4745. "VulkanMemoryModelDeviceScopeKHR capability"));
  4746. }
  4747. TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadGood) {
  4748. const std::string body = R"(
  4749. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4750. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
  4751. )";
  4752. const std::string extra = R"(
  4753. OpCapability StorageImageReadWithoutFormat
  4754. OpCapability VulkanMemoryModelKHR
  4755. OpCapability VulkanMemoryModelDeviceScopeKHR
  4756. OpExtension "SPV_KHR_vulkan_memory_model"
  4757. )";
  4758. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4759. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4760. .c_str());
  4761. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4762. }
  4763. // This example used to cause a seg fault on OpReturnValue, verifying it doesn't
  4764. // anymore.
  4765. TEST_F(ValidateImage, Issue2463NoSegFault) {
  4766. const std::string spirv = R"(
  4767. OpCapability Linkage
  4768. OpCapability Shader
  4769. %1 = OpExtInstImport "GLSL.std.450"
  4770. OpMemoryModel Logical GLSL450
  4771. %void = OpTypeVoid
  4772. %6 = OpTypeFunction %void
  4773. %float = OpTypeFloat 32
  4774. %8 = OpTypeImage %float 3D 0 0 0 1 Unknown
  4775. %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
  4776. %10 = OpTypeSampler
  4777. %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
  4778. %12 = OpTypeSampledImage %8
  4779. %13 = OpTypeFunction %12 %_ptr_UniformConstant_8 %_ptr_UniformConstant_10
  4780. %23 = OpFunction %12 None %13
  4781. %24 = OpFunctionParameter %_ptr_UniformConstant_8
  4782. %25 = OpFunctionParameter %_ptr_UniformConstant_10
  4783. %26 = OpLabel
  4784. %27 = OpLoad %8 %24
  4785. %28 = OpLoad %10 %25
  4786. %29 = OpSampledImage %12 %27 %28
  4787. OpReturnValue %29
  4788. OpFunctionEnd
  4789. )";
  4790. CompileSuccessfully(spirv);
  4791. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4792. EXPECT_THAT(getDiagnosticString(),
  4793. HasSubstr("OpSampledImage instruction must not appear as operand "
  4794. "for OpReturnValue"));
  4795. }
  4796. TEST_F(ValidateImage, SignExtendV13Bad) {
  4797. const std::string body = R"(
  4798. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4799. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
  4800. )";
  4801. EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
  4802. SPV_ENV_UNIVERSAL_1_3),
  4803. SPV_ENV_UNIVERSAL_1_3, SPV_ERROR_WRONG_VERSION),
  4804. HasSubstr("Invalid image operand 'SignExtend'"));
  4805. }
  4806. TEST_F(ValidateImage, ZeroExtendV13Bad) {
  4807. const std::string body = R"(
  4808. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4809. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
  4810. )";
  4811. EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
  4812. SPV_ENV_UNIVERSAL_1_3),
  4813. SPV_ENV_UNIVERSAL_1_3, SPV_ERROR_WRONG_VERSION),
  4814. HasSubstr("Invalid image operand 'ZeroExtend'"));
  4815. }
  4816. TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
  4817. // Unsigned int sampled type
  4818. const std::string body = R"(
  4819. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4820. %res1 = OpImageRead %u32 %img %u32vec2_01 SignExtend
  4821. )";
  4822. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4823. CompileSuccessfully(
  4824. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  4825. SPV_ENV_UNIVERSAL_1_4);
  4826. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  4827. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4828. }
  4829. TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) {
  4830. // Signed int sampled type
  4831. const std::string body = R"(
  4832. %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
  4833. %res1 = OpImageRead %s32 %img %u32vec2_01 SignExtend
  4834. )";
  4835. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4836. CompileSuccessfully(
  4837. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  4838. SPV_ENV_UNIVERSAL_1_4);
  4839. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  4840. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4841. }
  4842. TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) {
  4843. const std::string body = R"(
  4844. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4845. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
  4846. )";
  4847. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4848. CompileSuccessfully(
  4849. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  4850. SPV_ENV_UNIVERSAL_1_4);
  4851. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  4852. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4853. }
  4854. TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) {
  4855. const std::string body = R"(
  4856. %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
  4857. %res1 = OpImageRead %s32vec4 %img %u32vec2_01 SignExtend
  4858. )";
  4859. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4860. CompileSuccessfully(
  4861. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  4862. SPV_ENV_UNIVERSAL_1_4);
  4863. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  4864. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4865. }
  4866. // No negative tests for SignExtend since we don't truly know the
  4867. // texel format.
  4868. TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) {
  4869. // Unsigned int sampled type
  4870. const std::string body = R"(
  4871. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4872. %res1 = OpImageRead %u32 %img %u32vec2_01 ZeroExtend
  4873. )";
  4874. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4875. CompileSuccessfully(
  4876. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  4877. SPV_ENV_UNIVERSAL_1_4);
  4878. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  4879. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4880. }
  4881. TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) {
  4882. // Zeroed int sampled type
  4883. const std::string body = R"(
  4884. %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
  4885. %res1 = OpImageRead %s32 %img %u32vec2_01 ZeroExtend
  4886. )";
  4887. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4888. CompileSuccessfully(
  4889. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  4890. SPV_ENV_UNIVERSAL_1_4);
  4891. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  4892. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4893. }
  4894. TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) {
  4895. const std::string body = R"(
  4896. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4897. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
  4898. )";
  4899. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4900. CompileSuccessfully(
  4901. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  4902. SPV_ENV_UNIVERSAL_1_4);
  4903. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  4904. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4905. }
  4906. TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) {
  4907. const std::string body = R"(
  4908. %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
  4909. %res1 = OpImageRead %s32vec4 %img %u32vec2_01 ZeroExtend
  4910. )";
  4911. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4912. CompileSuccessfully(
  4913. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  4914. SPV_ENV_UNIVERSAL_1_4);
  4915. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  4916. EXPECT_THAT(getDiagnosticString(), Eq(""));
  4917. }
  4918. TEST_F(ValidateImage, ReadLodAMDSuccess1) {
  4919. const std::string body = R"(
  4920. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4921. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 Lod %u32_0
  4922. )";
  4923. const std::string extra =
  4924. "\nOpCapability StorageImageReadWithoutFormat\n"
  4925. "OpCapability ImageReadWriteLodAMD\n"
  4926. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  4927. CompileSuccessfully(
  4928. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  4929. SPV_ENV_UNIVERSAL_1_1);
  4930. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  4931. }
  4932. TEST_F(ValidateImage, ReadLodAMDSuccess2) {
  4933. const std::string body = R"(
  4934. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  4935. %res1 = OpImageRead %f32vec4 %img %u32vec2_01 Lod %u32_0
  4936. )";
  4937. const std::string extra =
  4938. "\nOpCapability Image1D\n"
  4939. "OpCapability ImageReadWriteLodAMD\n"
  4940. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  4941. CompileSuccessfully(
  4942. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  4943. SPV_ENV_UNIVERSAL_1_1);
  4944. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  4945. }
  4946. TEST_F(ValidateImage, ReadLodAMDSuccess3) {
  4947. const std::string body = R"(
  4948. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  4949. %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
  4950. )";
  4951. const std::string extra =
  4952. "\nOpCapability ImageCubeArray\n"
  4953. "OpCapability ImageReadWriteLodAMD\n"
  4954. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  4955. CompileSuccessfully(
  4956. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  4957. SPV_ENV_UNIVERSAL_1_1);
  4958. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  4959. }
  4960. TEST_F(ValidateImage, ReadLodAMDNeedCapability) {
  4961. const std::string body = R"(
  4962. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  4963. %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
  4964. )";
  4965. const std::string extra = "\nOpCapability ImageCubeArray\n";
  4966. CompileSuccessfully(
  4967. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  4968. SPV_ENV_UNIVERSAL_1_1);
  4969. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4970. ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  4971. EXPECT_THAT(getDiagnosticString(),
  4972. HasSubstr("Image Operand Lod can only be used with ExplicitLod "
  4973. "opcodes and OpImageFetch"));
  4974. }
  4975. TEST_F(ValidateImage, WriteLodAMDSuccess1) {
  4976. const std::string body = R"(
  4977. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4978. OpImageWrite %img %u32vec2_01 %u32vec4_0123 Lod %u32_0
  4979. )";
  4980. const std::string extra =
  4981. "\nOpCapability StorageImageWriteWithoutFormat\n"
  4982. "OpCapability ImageReadWriteLodAMD\n"
  4983. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  4984. CompileSuccessfully(
  4985. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  4986. SPV_ENV_UNIVERSAL_1_1);
  4987. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  4988. }
  4989. TEST_F(ValidateImage, WriteLodAMDSuccess2) {
  4990. const std::string body = R"(
  4991. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  4992. OpImageWrite %img %u32_1 %f32vec4_0000 Lod %u32_0
  4993. )";
  4994. const std::string extra =
  4995. "\nOpCapability Image1D\n"
  4996. "OpCapability ImageReadWriteLodAMD\n"
  4997. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  4998. CompileSuccessfully(
  4999. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5000. SPV_ENV_UNIVERSAL_1_1);
  5001. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5002. }
  5003. TEST_F(ValidateImage, WriteLodAMDSuccess3) {
  5004. const std::string body = R"(
  5005. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  5006. OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
  5007. )";
  5008. const std::string extra =
  5009. "\nOpCapability ImageCubeArray\n"
  5010. "OpCapability ImageReadWriteLodAMD\n"
  5011. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  5012. CompileSuccessfully(
  5013. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5014. SPV_ENV_UNIVERSAL_1_1);
  5015. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5016. }
  5017. TEST_F(ValidateImage, WriteLodAMDNeedCapability) {
  5018. const std::string body = R"(
  5019. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  5020. OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
  5021. )";
  5022. const std::string extra = "\nOpCapability ImageCubeArray\n";
  5023. CompileSuccessfully(
  5024. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5025. SPV_ENV_UNIVERSAL_1_1);
  5026. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  5027. ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5028. EXPECT_THAT(getDiagnosticString(),
  5029. HasSubstr("Image Operand Lod can only be used with ExplicitLod "
  5030. "opcodes and OpImageFetch"));
  5031. }
  5032. TEST_F(ValidateImage, SparseReadLodAMDSuccess) {
  5033. const std::string body = R"(
  5034. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  5035. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
  5036. )";
  5037. const std::string extra =
  5038. "\nOpCapability StorageImageReadWithoutFormat\n"
  5039. "OpCapability ImageReadWriteLodAMD\n"
  5040. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  5041. CompileSuccessfully(
  5042. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5043. SPV_ENV_UNIVERSAL_1_1);
  5044. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5045. }
  5046. TEST_F(ValidateImage, SparseReadLodAMDNeedCapability) {
  5047. const std::string body = R"(
  5048. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  5049. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
  5050. )";
  5051. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5052. CompileSuccessfully(
  5053. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5054. SPV_ENV_UNIVERSAL_1_1);
  5055. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  5056. ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5057. EXPECT_THAT(getDiagnosticString(),
  5058. HasSubstr("Image Operand Lod can only be used with ExplicitLod "
  5059. "opcodes and OpImageFetch"));
  5060. }
  5061. TEST_F(ValidateImage, GatherBiasAMDSuccess) {
  5062. const std::string body = R"(
  5063. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  5064. %sampler = OpLoad %type_sampler %uniform_sampler
  5065. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  5066. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
  5067. )";
  5068. const std::string extra = R"(
  5069. OpCapability ImageGatherBiasLodAMD
  5070. OpExtension "SPV_AMD_texture_gather_bias_lod"
  5071. )";
  5072. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  5073. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5074. }
  5075. TEST_F(ValidateImage, GatherLodAMDSuccess) {
  5076. const std::string body = R"(
  5077. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  5078. %sampler = OpLoad %type_sampler %uniform_sampler
  5079. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  5080. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
  5081. )";
  5082. const std::string extra = R"(
  5083. OpCapability ImageGatherBiasLodAMD
  5084. OpExtension "SPV_AMD_texture_gather_bias_lod"
  5085. )";
  5086. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  5087. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5088. }
  5089. TEST_F(ValidateImage, SparseGatherBiasAMDSuccess) {
  5090. const std::string body = R"(
  5091. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  5092. %sampler = OpLoad %type_sampler %uniform_sampler
  5093. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  5094. %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
  5095. )";
  5096. const std::string extra = R"(
  5097. OpCapability ImageGatherBiasLodAMD
  5098. OpExtension "SPV_AMD_texture_gather_bias_lod"
  5099. )";
  5100. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  5101. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5102. }
  5103. TEST_F(ValidateImage, SparseGatherLodAMDSuccess) {
  5104. const std::string body = R"(
  5105. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  5106. %sampler = OpLoad %type_sampler %uniform_sampler
  5107. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  5108. %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
  5109. )";
  5110. const std::string extra = R"(
  5111. OpCapability ImageGatherBiasLodAMD
  5112. OpExtension "SPV_AMD_texture_gather_bias_lod"
  5113. )";
  5114. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  5115. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5116. }
  5117. // No negative tests for ZeroExtend since we don't truly know the
  5118. // texel format.
  5119. // Tests for 64-bit images
  5120. static const std::string capabilities_and_extensions_image64 = R"(
  5121. OpCapability Int64ImageEXT
  5122. OpExtension "SPV_EXT_shader_image_int64"
  5123. )";
  5124. static const std::string capabilities_and_extensions_image64_atomic = R"(
  5125. OpCapability Int64Atomics
  5126. OpCapability Int64ImageEXT
  5127. OpExtension "SPV_EXT_shader_image_int64"
  5128. )";
  5129. static const std::string declarations_image64 = R"(
  5130. %type_image_u64_buffer_0002_r64ui = OpTypeImage %u64 Buffer 0 0 0 2 R64ui
  5131. %ptr_Image_u64 = OpTypePointer Image %u64
  5132. %ptr_image_u64_buffer_0002_r64ui = OpTypePointer Private %type_image_u64_buffer_0002_r64ui
  5133. %private_image_u64_buffer_0002_r64ui = OpVariable %ptr_image_u64_buffer_0002_r64ui Private
  5134. )";
  5135. static const std::string declarations_image64i = R"(
  5136. %type_image_s64_buffer_0002_r64i = OpTypeImage %s64 Buffer 0 0 0 2 R64i
  5137. %ptr_Image_s64 = OpTypePointer Image %s64
  5138. %ptr_image_s64_buffer_0002_r64i = OpTypePointer Private %type_image_s64_buffer_0002_r64i
  5139. %private_image_s64_buffer_0002_r64i = OpVariable %ptr_image_s64_buffer_0002_r64i Private
  5140. )";
  5141. TEST_F(ValidateImage, Image64MissingCapability) {
  5142. CompileSuccessfully(GenerateShaderCode("", "", "Fragment", "",
  5143. SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5144. declarations_image64)
  5145. .c_str());
  5146. ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
  5147. }
  5148. TEST_F(ValidateImage, Image64MissingExtension) {
  5149. const std::string extra = R"(
  5150. OpCapability Int64ImageEXT
  5151. )";
  5152. CompileSuccessfully(GenerateShaderCode("", extra, "Fragment", "",
  5153. SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5154. declarations_image64)
  5155. .c_str());
  5156. ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
  5157. }
  5158. TEST_F(ValidateImage, ImageTexelPointer64Success) {
  5159. const std::string body = R"(
  5160. %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
  5161. %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
  5162. )";
  5163. CompileSuccessfully(
  5164. GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
  5165. "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5166. declarations_image64)
  5167. .c_str());
  5168. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5169. }
  5170. TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotPointer) {
  5171. const std::string body = R"(
  5172. %texel_ptr = OpImageTexelPointer %type_image_u64_buffer_0002_r64ui %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
  5173. %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
  5174. )";
  5175. CompileSuccessfully(
  5176. GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
  5177. "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5178. declarations_image64)
  5179. .c_str());
  5180. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5181. EXPECT_THAT(getDiagnosticString(),
  5182. HasSubstr("Expected Result Type to be OpTypePointer"));
  5183. }
  5184. TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotImageClass) {
  5185. const std::string body = R"(
  5186. %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
  5187. %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
  5188. )";
  5189. CompileSuccessfully(
  5190. GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
  5191. "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5192. declarations_image64)
  5193. .c_str());
  5194. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5195. EXPECT_THAT(getDiagnosticString(),
  5196. HasSubstr("Expected Result Type to be OpTypePointer whose "
  5197. "Storage Class operand is Image"));
  5198. }
  5199. TEST_F(ValidateImage, ImageTexelPointer64SampleNotZeroForImageWithMSZero) {
  5200. const std::string body = R"(
  5201. %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_1
  5202. %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
  5203. )";
  5204. CompileSuccessfully(
  5205. GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
  5206. "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5207. declarations_image64)
  5208. .c_str());
  5209. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5210. EXPECT_THAT(getDiagnosticString(),
  5211. HasSubstr("Expected Sample for Image with MS 0 to be a valid "
  5212. "<id> for the value 0"));
  5213. }
  5214. TEST_F(ValidateImage, ImageTexelPointerR32uiSuccessVulkan) {
  5215. const std::string body = R"(
  5216. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  5217. )";
  5218. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5219. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  5220. env);
  5221. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5222. }
  5223. TEST_F(ValidateImage, ImageTexelPointerR32iSuccessVulkan) {
  5224. const std::string& declarations = R"(
  5225. %type_image_s32_buffer_0002_r32i = OpTypeImage %s32 Buffer 0 0 0 2 R32i
  5226. %ptr_Image_s32 = OpTypePointer Image %s32
  5227. %ptr_image_s32_buffer_0002_r32i = OpTypePointer Private %type_image_s32_buffer_0002_r32i
  5228. %private_image_s32_buffer_0002_r32i = OpVariable %ptr_image_s32_buffer_0002_r32i Private
  5229. )";
  5230. const std::string body = R"(
  5231. %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_r32i %u32_0 %u32_0
  5232. )";
  5233. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5234. CompileSuccessfully(
  5235. GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
  5236. .c_str(),
  5237. env);
  5238. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5239. }
  5240. TEST_F(ValidateImage, ImageTexelPointerR64uiSuccessVulkan) {
  5241. const std::string body = R"(
  5242. %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
  5243. )";
  5244. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5245. CompileSuccessfully(
  5246. GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
  5247. "", env, "GLSL450", declarations_image64)
  5248. .c_str(),
  5249. env);
  5250. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5251. }
  5252. TEST_F(ValidateImage, ImageTexelPointerR64iSuccessVulkan) {
  5253. const std::string body = R"(
  5254. %texel_ptr = OpImageTexelPointer %ptr_Image_s64 %private_image_s64_buffer_0002_r64i %u32_0 %u32_0
  5255. )";
  5256. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5257. CompileSuccessfully(
  5258. GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
  5259. "", env, "GLSL450", declarations_image64i)
  5260. .c_str(),
  5261. env);
  5262. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5263. }
  5264. TEST_F(ValidateImage, ImageTexelPointerR32fSuccessVulkan) {
  5265. const std::string& declarations = R"(
  5266. %type_image_f32_buffer_0002_r32f = OpTypeImage %f32 Buffer 0 0 0 2 R32f
  5267. %ptr_image_f32_buffer_0002_r32f = OpTypePointer Private %type_image_f32_buffer_0002_r32f
  5268. %private_image_f32_buffer_0002_r32f = OpVariable %ptr_image_f32_buffer_0002_r32f Private
  5269. )";
  5270. const std::string body = R"(
  5271. %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32f %u32_0 %u32_0
  5272. )";
  5273. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5274. CompileSuccessfully(
  5275. GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
  5276. .c_str(),
  5277. env);
  5278. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5279. }
  5280. TEST_F(ValidateImage, ImageTexelPointerRgba32iVulkan) {
  5281. const std::string& declarations = R"(
  5282. %type_image_s32_buffer_0002_rgba32i = OpTypeImage %s32 Buffer 0 0 0 2 Rgba32i
  5283. %ptr_Image_s32 = OpTypePointer Image %s32
  5284. %ptr_image_s32_buffer_0002_rgba32i = OpTypePointer Private %type_image_s32_buffer_0002_rgba32i
  5285. %private_image_s32_buffer_0002_rgba32i = OpVariable %ptr_image_s32_buffer_0002_rgba32i Private
  5286. )";
  5287. const std::string body = R"(
  5288. %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba32i %u32_0 %u32_0
  5289. )";
  5290. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5291. CompileSuccessfully(
  5292. GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
  5293. .c_str(),
  5294. env);
  5295. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  5296. EXPECT_THAT(getDiagnosticString(),
  5297. AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
  5298. EXPECT_THAT(getDiagnosticString(),
  5299. HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
  5300. "R32f, R32i, or R32ui for Vulkan environment"));
  5301. }
  5302. TEST_F(ValidateImage, ImageTexelPointerRgba16fVulkan) {
  5303. const std::string& declarations = R"(
  5304. %type_image_s32_buffer_0002_rgba16f = OpTypeImage %s32 Buffer 0 0 0 2 Rgba16f
  5305. %ptr_Image_s32 = OpTypePointer Image %s32
  5306. %ptr_image_s32_buffer_0002_rgba16f = OpTypePointer Private %type_image_s32_buffer_0002_rgba16f
  5307. %private_image_s32_buffer_0002_rgba16f = OpVariable %ptr_image_s32_buffer_0002_rgba16f Private
  5308. )";
  5309. const std::string body = R"(
  5310. %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba16f %u32_0 %u32_0
  5311. )";
  5312. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5313. CompileSuccessfully(
  5314. GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
  5315. .c_str(),
  5316. env);
  5317. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  5318. EXPECT_THAT(getDiagnosticString(),
  5319. AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
  5320. EXPECT_THAT(getDiagnosticString(),
  5321. HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
  5322. "R32f, R32i, or R32ui for Vulkan environment"));
  5323. }
  5324. TEST_F(ValidateImage, ImageExecutionModeLimitationNoMode) {
  5325. const std::string text = R"(
  5326. OpCapability Shader
  5327. OpMemoryModel Logical GLSL450
  5328. OpEntryPoint GLCompute %2 " " %4
  5329. %void = OpTypeVoid
  5330. %8 = OpTypeFunction %void
  5331. %float = OpTypeFloat 32
  5332. %v4float = OpTypeVector %float 4
  5333. %12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
  5334. %13 = OpTypeSampledImage %12
  5335. %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
  5336. %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
  5337. %_ptr_Input_v4float = OpTypePointer Input %v4float
  5338. %4 = OpVariable %_ptr_Input_v4float Input
  5339. %v2float = OpTypeVector %float 2
  5340. %float_1_35631564en19 = OpConstant %float 1.35631564e-19
  5341. %2 = OpFunction %void None %8
  5342. %8224 = OpLabel
  5343. %6 = OpLoad %13 %5
  5344. %19 = OpLoad %v4float %4
  5345. %20 = OpVectorShuffle %v2float %19 %19 0 1
  5346. %21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
  5347. %65312 = OpImageSampleImplicitLod %v4float %6 %21
  5348. OpUnreachable
  5349. OpFunctionEnd
  5350. )";
  5351. CompileSuccessfully(text);
  5352. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5353. EXPECT_THAT(getDiagnosticString(),
  5354. HasSubstr("ImplicitLod instructions require "
  5355. "DerivativeGroupQuadsNV or DerivativeGroupLinearNV "
  5356. "execution mode for GLCompute execution model"));
  5357. }
  5358. TEST_F(ValidateImage, TypeSampledImageNotBufferPost1p6) {
  5359. const std::string text = R"(
  5360. OpCapability Shader
  5361. OpCapability Linkage
  5362. OpCapability SampledBuffer
  5363. OpMemoryModel Logical GLSL450
  5364. %float = OpTypeFloat 32
  5365. %image = OpTypeImage %float Buffer 0 0 0 1 Unknown
  5366. %sampled = OpTypeSampledImage %image
  5367. )";
  5368. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
  5369. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
  5370. EXPECT_THAT(getDiagnosticString(),
  5371. HasSubstr("In SPIR-V 1.6 or later, sampled image dimension must "
  5372. "not be Buffer"));
  5373. }
  5374. TEST_F(ValidateImage, NonTemporalImage) {
  5375. const std::string text = R"(
  5376. OpCapability Shader
  5377. OpMemoryModel Logical GLSL450
  5378. OpEntryPoint Fragment %2 " " %4 %5
  5379. OpExecutionMode %2 OriginUpperLeft
  5380. %void = OpTypeVoid
  5381. %8 = OpTypeFunction %void
  5382. %float = OpTypeFloat 32
  5383. %v4float = OpTypeVector %float 4
  5384. %12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
  5385. %13 = OpTypeSampledImage %12
  5386. %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
  5387. %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
  5388. %_ptr_Input_v4float = OpTypePointer Input %v4float
  5389. %4 = OpVariable %_ptr_Input_v4float Input
  5390. %v2float = OpTypeVector %float 2
  5391. %float_1_35631564en19 = OpConstant %float 1.35631564e-19
  5392. %2 = OpFunction %void None %8
  5393. %8224 = OpLabel
  5394. %6 = OpLoad %13 %5
  5395. %19 = OpLoad %v4float %4
  5396. %20 = OpVectorShuffle %v2float %19 %19 0 1
  5397. %21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
  5398. %65312 = OpImageSampleImplicitLod %v4float %6 %21 Nontemporal
  5399. OpReturn
  5400. OpFunctionEnd
  5401. )";
  5402. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
  5403. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
  5404. }
  5405. TEST_F(ValidateImage, NVBindlessSamplerBuiltins) {
  5406. const std::string text = R"(
  5407. OpCapability Shader
  5408. OpCapability Int64
  5409. OpCapability Image1D
  5410. OpCapability BindlessTextureNV
  5411. OpExtension "SPV_NV_bindless_texture"
  5412. %1 = OpExtInstImport "GLSL.std.450"
  5413. OpMemoryModel Logical GLSL450
  5414. OpSamplerImageAddressingModeNV 64
  5415. OpEntryPoint Fragment %main "main"
  5416. OpExecutionMode %main OriginUpperLeft
  5417. OpSource GLSL 450
  5418. OpName %main "main"
  5419. OpName %s2D "s2D"
  5420. OpName %textureHandle "textureHandle"
  5421. OpName %i1D "i1D"
  5422. OpName %s "s"
  5423. OpName %temp "temp"
  5424. %void = OpTypeVoid
  5425. %3 = OpTypeFunction %void
  5426. %float = OpTypeFloat 32
  5427. %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
  5428. %8 = OpTypeSampledImage %7
  5429. %_ptr_Function_8 = OpTypePointer Function %8
  5430. %ulong = OpTypeInt 64 0
  5431. %_ptr_Private_ulong = OpTypePointer Private %ulong
  5432. %textureHandle = OpVariable %_ptr_Private_ulong Private
  5433. %16 = OpTypeImage %float 1D 0 0 0 2 Rgba32f
  5434. %_ptr_Function_16 = OpTypePointer Function %16
  5435. %21 = OpTypeSampler
  5436. %_ptr_Function_21 = OpTypePointer Function %21
  5437. %_ptr_Function_ulong = OpTypePointer Function %ulong
  5438. %main = OpFunction %void None %3
  5439. %5 = OpLabel
  5440. %s2D = OpVariable %_ptr_Function_8 Function
  5441. %i1D = OpVariable %_ptr_Function_16 Function
  5442. %s = OpVariable %_ptr_Function_21 Function
  5443. %temp = OpVariable %_ptr_Function_ulong Function
  5444. %14 = OpLoad %ulong %textureHandle
  5445. %15 = OpConvertUToSampledImageNV %8 %14
  5446. OpStore %s2D %15
  5447. %19 = OpLoad %ulong %textureHandle
  5448. %20 = OpConvertUToImageNV %16 %19
  5449. OpStore %i1D %20
  5450. %24 = OpLoad %ulong %textureHandle
  5451. %25 = OpConvertUToSamplerNV %21 %24
  5452. OpStore %s %25
  5453. %28 = OpLoad %8 %s2D
  5454. %29 = OpConvertSampledImageToUNV %ulong %28
  5455. OpStore %temp %29
  5456. %30 = OpLoad %16 %i1D
  5457. %31 = OpConvertImageToUNV %ulong %30
  5458. OpStore %temp %31
  5459. %32 = OpLoad %21 %s
  5460. %33 = OpConvertSamplerToUNV %ulong %32
  5461. OpStore %temp %33
  5462. OpReturn
  5463. OpFunctionEnd
  5464. )";
  5465. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  5466. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5467. }
  5468. TEST_F(ValidateImage, NVBindlessAddressingMode64) {
  5469. std::string text = R"(
  5470. OpCapability Shader
  5471. OpCapability BindlessTextureNV
  5472. OpExtension "SPV_NV_bindless_texture"
  5473. OpMemoryModel Logical GLSL450
  5474. OpSamplerImageAddressingModeNV 64
  5475. OpEntryPoint GLCompute %func "main"
  5476. %voidt = OpTypeVoid
  5477. %uintt = OpTypeInt 32 0
  5478. %funct = OpTypeFunction %voidt
  5479. %func = OpFunction %voidt None %funct
  5480. %entry = OpLabel
  5481. %udef = OpUndef %uintt
  5482. OpReturn
  5483. OpFunctionEnd
  5484. )";
  5485. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  5486. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5487. }
  5488. TEST_F(ValidateImage, NVBindlessAddressingMode32) {
  5489. std::string text = R"(
  5490. OpCapability Shader
  5491. OpCapability BindlessTextureNV
  5492. OpExtension "SPV_NV_bindless_texture"
  5493. OpMemoryModel Logical GLSL450
  5494. OpSamplerImageAddressingModeNV 32
  5495. OpEntryPoint GLCompute %func "main"
  5496. %voidt = OpTypeVoid
  5497. %uintt = OpTypeInt 32 0
  5498. %funct = OpTypeFunction %voidt
  5499. %func = OpFunction %voidt None %funct
  5500. %entry = OpLabel
  5501. %udef = OpUndef %uintt
  5502. OpReturn
  5503. OpFunctionEnd
  5504. )";
  5505. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  5506. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5507. }
  5508. TEST_F(ValidateImage, NVBindlessInvalidAddressingMode) {
  5509. std::string text = R"(
  5510. OpCapability Shader
  5511. OpCapability BindlessTextureNV
  5512. OpExtension "SPV_NV_bindless_texture"
  5513. OpMemoryModel Logical GLSL450
  5514. OpSamplerImageAddressingModeNV 0
  5515. OpEntryPoint GLCompute %func "main"
  5516. %voidt = OpTypeVoid
  5517. %uintt = OpTypeInt 32 0
  5518. %funct = OpTypeFunction %voidt
  5519. %func = OpFunction %voidt None %funct
  5520. %entry = OpLabel
  5521. %udef = OpUndef %uintt
  5522. OpReturn
  5523. OpFunctionEnd
  5524. )";
  5525. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  5526. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  5527. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5528. EXPECT_THAT(
  5529. getDiagnosticString(),
  5530. HasSubstr("OpSamplerImageAddressingModeNV bitwidth should be 64 or 32"));
  5531. }
  5532. } // namespace
  5533. } // namespace val
  5534. } // namespace spvtools