val_image_test.cpp 424 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916
  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 "spirv-tools/libspirv.h"
  21. #include "test/unit_spirv.h"
  22. #include "test/val/val_fixtures.h"
  23. namespace spvtools {
  24. namespace val {
  25. namespace {
  26. using ::testing::Eq;
  27. using ::testing::HasSubstr;
  28. using ::testing::Not;
  29. using ValidateImage = spvtest::ValidateBase<bool>;
  30. std::string GenerateShaderCode(
  31. const std::string& body,
  32. const std::string& capabilities_and_extensions = "",
  33. const std::string& execution_model = "Fragment",
  34. const std::string& execution_mode = "",
  35. const spv_target_env env = SPV_ENV_UNIVERSAL_1_0,
  36. const std::string& memory_model = "GLSL450",
  37. const std::string& declarations = "") {
  38. std::ostringstream ss;
  39. ss << R"(
  40. OpCapability Shader
  41. OpCapability InputAttachment
  42. OpCapability ImageGatherExtended
  43. OpCapability MinLod
  44. OpCapability Sampled1D
  45. OpCapability ImageQuery
  46. OpCapability Int64
  47. OpCapability Float64
  48. OpCapability SparseResidency
  49. OpCapability ImageBuffer
  50. )";
  51. if (env == SPV_ENV_UNIVERSAL_1_0) {
  52. ss << "OpCapability SampledRect\n";
  53. }
  54. // In 1.4, the entry point must list all module-scope variables used. Just
  55. // list all of them.
  56. //
  57. // For Vulkan, anything Location decoration needs to be an interface variable
  58. std::string interface_vars =
  59. (env != SPV_ENV_UNIVERSAL_1_4) ? "%input_flat_u32" :
  60. R"(
  61. %uniform_image_f32_1d_0001
  62. %uniform_image_f32_1d_0002_rgba32f
  63. %uniform_image_f32_2d_0001
  64. %uniform_image_f32_2d_0011 ; multisampled sampled
  65. %uniform_image_u32_2d_0001
  66. %uniform_image_u32_2d_0002
  67. %uniform_image_s32_3d_0001
  68. %uniform_image_f32_2d_0002
  69. %uniform_image_s32_2d_0002
  70. %uniform_image_f32_spd_0002
  71. %uniform_image_f32_3d_0111
  72. %uniform_image_f32_cube_0101
  73. %uniform_image_f32_cube_0102_rgba32f
  74. %uniform_sampler
  75. %private_image_u32_buffer_0002_r32ui
  76. %private_image_u32_spd_0002
  77. %private_image_f32_buffer_0002_r32ui
  78. %input_flat_u32
  79. )";
  80. ss << capabilities_and_extensions;
  81. ss << "OpMemoryModel Logical " << memory_model << "\n";
  82. ss << "OpEntryPoint " << execution_model
  83. << " %main \"main\" " + interface_vars + "\n";
  84. if (execution_model == "Fragment") {
  85. ss << "OpExecutionMode %main OriginUpperLeft\n";
  86. }
  87. ss << execution_mode;
  88. if (env == SPV_ENV_VULKAN_1_0) {
  89. ss << R"(
  90. OpDecorate %uniform_image_f32_1d_0001 DescriptorSet 0
  91. OpDecorate %uniform_image_f32_1d_0001 Binding 0
  92. OpDecorate %uniform_image_f32_1d_0002_rgba32f DescriptorSet 0
  93. OpDecorate %uniform_image_f32_1d_0002_rgba32f Binding 1
  94. OpDecorate %uniform_image_f32_2d_0001 DescriptorSet 0
  95. OpDecorate %uniform_image_f32_2d_0001 Binding 2
  96. OpDecorate %uniform_image_f32_2d_0011 DescriptorSet 0
  97. OpDecorate %uniform_image_f32_2d_0011 Binding 3
  98. OpDecorate %uniform_image_u32_2d_0001 DescriptorSet 1
  99. OpDecorate %uniform_image_u32_2d_0001 Binding 0
  100. OpDecorate %uniform_image_u32_2d_0002 DescriptorSet 1
  101. OpDecorate %uniform_image_u32_2d_0002 Binding 1
  102. OpDecorate %uniform_image_s32_3d_0001 DescriptorSet 1
  103. OpDecorate %uniform_image_s32_3d_0001 Binding 2
  104. OpDecorate %uniform_image_f32_2d_0002 DescriptorSet 1
  105. OpDecorate %uniform_image_f32_2d_0002 Binding 3
  106. OpDecorate %uniform_image_s32_2d_0002 DescriptorSet 1
  107. OpDecorate %uniform_image_s32_2d_0002 Binding 4
  108. OpDecorate %uniform_image_f32_spd_0002 DescriptorSet 2
  109. OpDecorate %uniform_image_f32_spd_0002 Binding 0
  110. OpDecorate %uniform_image_f32_3d_0111 DescriptorSet 2
  111. OpDecorate %uniform_image_f32_3d_0111 Binding 1
  112. OpDecorate %uniform_image_f32_cube_0101 DescriptorSet 2
  113. OpDecorate %uniform_image_f32_cube_0101 Binding 2
  114. OpDecorate %uniform_image_f32_cube_0102_rgba32f DescriptorSet 2
  115. OpDecorate %uniform_image_f32_cube_0102_rgba32f Binding 3
  116. OpDecorate %uniform_sampler DescriptorSet 3
  117. OpDecorate %uniform_sampler Binding 0
  118. OpDecorate %input_flat_u32 Flat
  119. OpDecorate %input_flat_u32 Location 0
  120. )";
  121. }
  122. ss << R"(
  123. %void = OpTypeVoid
  124. %func = OpTypeFunction %void
  125. %bool = OpTypeBool
  126. %f32 = OpTypeFloat 32
  127. %f64 = OpTypeFloat 64
  128. %u32 = OpTypeInt 32 0
  129. %s32 = OpTypeInt 32 1
  130. %u64 = OpTypeInt 64 0
  131. %s64 = OpTypeInt 64 1
  132. %s32vec2 = OpTypeVector %s32 2
  133. %u32vec2 = OpTypeVector %u32 2
  134. %f32vec2 = OpTypeVector %f32 2
  135. %u32vec3 = OpTypeVector %u32 3
  136. %s32vec3 = OpTypeVector %s32 3
  137. %f32vec3 = OpTypeVector %f32 3
  138. %u32vec4 = OpTypeVector %u32 4
  139. %s32vec4 = OpTypeVector %s32 4
  140. %f32vec4 = OpTypeVector %f32 4
  141. %boolvec4 = OpTypeVector %bool 4
  142. %f32_0 = OpConstant %f32 0
  143. %f32_1 = OpConstant %f32 1
  144. %f32_0_5 = OpConstant %f32 0.5
  145. %f32_0_25 = OpConstant %f32 0.25
  146. %f32_0_75 = OpConstant %f32 0.75
  147. %f64_0 = OpConstant %f64 0
  148. %f64_1 = OpConstant %f64 1
  149. %s32_0 = OpConstant %s32 0
  150. %s32_1 = OpConstant %s32 1
  151. %s32_2 = OpConstant %s32 2
  152. %s32_3 = OpConstant %s32 3
  153. %s32_4 = OpConstant %s32 4
  154. %s32_m1 = OpConstant %s32 -1
  155. %u32_0 = OpConstant %u32 0
  156. %u32_1 = OpConstant %u32 1
  157. %u32_2 = OpConstant %u32 2
  158. %u32_3 = OpConstant %u32 3
  159. %u32_4 = OpConstant %u32 4
  160. %u64_0 = OpConstant %u64 0
  161. %u64_1 = OpConstant %u64 1
  162. %bool_t = OpConstantTrue %bool
  163. %u32vec2arr4 = OpTypeArray %u32vec2 %u32_4
  164. %u32vec2arr3 = OpTypeArray %u32vec2 %u32_3
  165. %u32arr4 = OpTypeArray %u32 %u32_4
  166. %u32vec3arr4 = OpTypeArray %u32vec3 %u32_4
  167. %struct_u32_f32vec4 = OpTypeStruct %u32 %f32vec4
  168. %struct_u64_f32vec4 = OpTypeStruct %u64 %f32vec4
  169. %struct_u32_u32vec4 = OpTypeStruct %u32 %u32vec4
  170. %struct_u32_f32vec3 = OpTypeStruct %u32 %f32vec3
  171. %struct_f32_f32vec4 = OpTypeStruct %f32 %f32vec4
  172. %struct_u32_u32 = OpTypeStruct %u32 %u32
  173. %struct_f32_f32 = OpTypeStruct %f32 %f32
  174. %struct_u32 = OpTypeStruct %u32
  175. %struct_u32_f32_u32 = OpTypeStruct %u32 %f32 %u32
  176. %struct_u32_f32vec4_u32 = OpTypeStruct %u32 %f32vec4 %u32
  177. %struct_u32_u32arr4 = OpTypeStruct %u32 %u32arr4
  178. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  179. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  180. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  181. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  182. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  183. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  184. %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
  185. %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
  186. %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
  187. %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
  188. %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
  189. %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
  190. %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
  191. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  192. %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
  193. %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
  194. %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
  195. %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
  196. %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
  197. %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
  198. %boolvec4_tttt = OpConstantComposite %boolvec4 %bool_t %bool_t %bool_t %bool_t
  199. %const_offsets = OpConstantComposite %u32vec2arr4 %u32vec2_01 %u32vec2_12 %u32vec2_01 %u32vec2_12
  200. %const_offsets3x2 = OpConstantComposite %u32vec2arr3 %u32vec2_01 %u32vec2_12 %u32vec2_01
  201. %const_offsets4xu = OpConstantComposite %u32arr4 %u32_0 %u32_0 %u32_0 %u32_0
  202. %const_offsets4x3 = OpConstantComposite %u32vec3arr4 %u32vec3_012 %u32vec3_012 %u32vec3_012 %u32vec3_012
  203. %type_image_f32_1d_0001 = OpTypeImage %f32 1D 0 0 0 1 Unknown
  204. %ptr_image_f32_1d_0001 = OpTypePointer UniformConstant %type_image_f32_1d_0001
  205. %uniform_image_f32_1d_0001 = OpVariable %ptr_image_f32_1d_0001 UniformConstant
  206. %type_sampled_image_f32_1d_0001 = OpTypeSampledImage %type_image_f32_1d_0001
  207. %type_image_f32_1d_0002_rgba32f = OpTypeImage %f32 1D 0 0 0 2 Rgba32f
  208. %ptr_image_f32_1d_0002_rgba32f = OpTypePointer UniformConstant %type_image_f32_1d_0002_rgba32f
  209. %uniform_image_f32_1d_0002_rgba32f = OpVariable %ptr_image_f32_1d_0002_rgba32f UniformConstant
  210. %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
  211. %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
  212. %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
  213. %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
  214. %type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown
  215. %ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011
  216. %uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant
  217. %type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011
  218. %type_image_u32_2d_0001 = OpTypeImage %u32 2D 0 0 0 1 Unknown
  219. %ptr_image_u32_2d_0001 = OpTypePointer UniformConstant %type_image_u32_2d_0001
  220. %uniform_image_u32_2d_0001 = OpVariable %ptr_image_u32_2d_0001 UniformConstant
  221. %type_sampled_image_u32_2d_0001 = OpTypeSampledImage %type_image_u32_2d_0001
  222. %type_image_u32_3d_0001 = OpTypeImage %u32 3D 0 0 0 1 Unknown
  223. %ptr_image_u32_3d_0001 = OpTypePointer UniformConstant %type_image_u32_3d_0001
  224. %uniform_image_u32_3d_0001 = OpVariable %ptr_image_u32_3d_0001 UniformConstant
  225. %type_sampled_image_u32_3d_0001 = OpTypeSampledImage %type_image_u32_3d_0001
  226. %type_image_u32_2d_0002 = OpTypeImage %u32 2D 0 0 0 2 Unknown
  227. %ptr_image_u32_2d_0002 = OpTypePointer UniformConstant %type_image_u32_2d_0002
  228. %uniform_image_u32_2d_0002 = OpVariable %ptr_image_u32_2d_0002 UniformConstant
  229. %type_image_s32_3d_0001 = OpTypeImage %s32 3D 0 0 0 1 Unknown
  230. %ptr_image_s32_3d_0001 = OpTypePointer UniformConstant %type_image_s32_3d_0001
  231. %uniform_image_s32_3d_0001 = OpVariable %ptr_image_s32_3d_0001 UniformConstant
  232. %type_sampled_image_s32_3d_0001 = OpTypeSampledImage %type_image_s32_3d_0001
  233. %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Unknown
  234. %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
  235. %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
  236. %type_image_s32_2d_0002 = OpTypeImage %s32 2D 0 0 0 2 Unknown
  237. %ptr_image_s32_2d_0002 = OpTypePointer UniformConstant %type_image_s32_2d_0002
  238. %uniform_image_s32_2d_0002 = OpVariable %ptr_image_s32_2d_0002 UniformConstant
  239. %type_image_f32_spd_0002 = OpTypeImage %f32 SubpassData 0 0 0 2 Unknown
  240. %ptr_image_f32_spd_0002 = OpTypePointer UniformConstant %type_image_f32_spd_0002
  241. %uniform_image_f32_spd_0002 = OpVariable %ptr_image_f32_spd_0002 UniformConstant
  242. %type_image_f32_3d_0111 = OpTypeImage %f32 3D 0 1 1 1 Unknown
  243. %ptr_image_f32_3d_0111 = OpTypePointer UniformConstant %type_image_f32_3d_0111
  244. %uniform_image_f32_3d_0111 = OpVariable %ptr_image_f32_3d_0111 UniformConstant
  245. %type_sampled_image_f32_3d_0111 = OpTypeSampledImage %type_image_f32_3d_0111
  246. %type_image_f32_3d_0001 = OpTypeImage %f32 3D 0 0 0 1 Unknown
  247. %ptr_image_f32_3d_0001 = OpTypePointer UniformConstant %type_image_f32_3d_0001
  248. %uniform_image_f32_3d_0001 = OpVariable %ptr_image_f32_3d_0001 UniformConstant
  249. %type_sampled_image_f32_3d_0001 = OpTypeSampledImage %type_image_f32_3d_0001
  250. %type_image_f32_cube_0101 = OpTypeImage %f32 Cube 0 1 0 1 Unknown
  251. %ptr_image_f32_cube_0101 = OpTypePointer UniformConstant %type_image_f32_cube_0101
  252. %uniform_image_f32_cube_0101 = OpVariable %ptr_image_f32_cube_0101 UniformConstant
  253. %type_sampled_image_f32_cube_0101 = OpTypeSampledImage %type_image_f32_cube_0101
  254. %type_image_f32_cube_0102_rgba32f = OpTypeImage %f32 Cube 0 1 0 2 Rgba32f
  255. %ptr_image_f32_cube_0102_rgba32f = OpTypePointer UniformConstant %type_image_f32_cube_0102_rgba32f
  256. %uniform_image_f32_cube_0102_rgba32f = OpVariable %ptr_image_f32_cube_0102_rgba32f UniformConstant
  257. %type_sampler = OpTypeSampler
  258. %ptr_sampler = OpTypePointer UniformConstant %type_sampler
  259. %uniform_sampler = OpVariable %ptr_sampler UniformConstant
  260. %type_image_u32_buffer_0002_r32ui = OpTypeImage %u32 Buffer 0 0 0 2 R32ui
  261. %ptr_Image_u32 = OpTypePointer Image %u32
  262. %ptr_image_u32_buffer_0002_r32ui = OpTypePointer Private %type_image_u32_buffer_0002_r32ui
  263. %private_image_u32_buffer_0002_r32ui = OpVariable %ptr_image_u32_buffer_0002_r32ui Private
  264. %ptr_Image_u32arr4 = OpTypePointer Image %u32arr4
  265. %type_image_u32_spd_0002 = OpTypeImage %u32 SubpassData 0 0 0 2 Unknown
  266. %ptr_image_u32_spd_0002 = OpTypePointer Private %type_image_u32_spd_0002
  267. %private_image_u32_spd_0002 = OpVariable %ptr_image_u32_spd_0002 Private
  268. %type_image_f32_buffer_0002_r32ui = OpTypeImage %f32 Buffer 0 0 0 2 R32ui
  269. %ptr_Image_f32 = OpTypePointer Image %f32
  270. %ptr_image_f32_buffer_0002_r32ui = OpTypePointer Private %type_image_f32_buffer_0002_r32ui
  271. %private_image_f32_buffer_0002_r32ui = OpVariable %ptr_image_f32_buffer_0002_r32ui Private
  272. %ptr_input_flat_u32 = OpTypePointer Input %u32
  273. %input_flat_u32 = OpVariable %ptr_input_flat_u32 Input
  274. )";
  275. if (env == SPV_ENV_UNIVERSAL_1_0) {
  276. ss << R"(
  277. %type_image_void_2d_0001 = OpTypeImage %void 2D 0 0 0 1 Unknown
  278. %ptr_image_void_2d_0001 = OpTypePointer UniformConstant %type_image_void_2d_0001
  279. %uniform_image_void_2d_0001 = OpVariable %ptr_image_void_2d_0001 UniformConstant
  280. %type_sampled_image_void_2d_0001 = OpTypeSampledImage %type_image_void_2d_0001
  281. %type_image_void_2d_0002 = OpTypeImage %void 2D 0 0 0 2 Unknown
  282. %ptr_image_void_2d_0002 = OpTypePointer UniformConstant %type_image_void_2d_0002
  283. %uniform_image_void_2d_0002 = OpVariable %ptr_image_void_2d_0002 UniformConstant
  284. %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
  285. %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
  286. %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
  287. %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
  288. )";
  289. }
  290. ss << declarations;
  291. ss << R"(
  292. %main = OpFunction %void None %func
  293. %main_entry = OpLabel
  294. )";
  295. ss << body;
  296. ss << R"(
  297. OpReturn
  298. OpFunctionEnd)";
  299. return ss.str();
  300. }
  301. std::string GenerateKernelCode(
  302. const std::string& body,
  303. const std::string& capabilities_and_extensions = "",
  304. const std::string& declarations = "") {
  305. std::ostringstream ss;
  306. ss << R"(
  307. OpCapability Addresses
  308. OpCapability Kernel
  309. OpCapability Linkage
  310. OpCapability ImageQuery
  311. OpCapability ImageGatherExtended
  312. OpCapability InputAttachment
  313. OpCapability SampledRect
  314. )";
  315. ss << capabilities_and_extensions;
  316. ss << R"(
  317. OpMemoryModel Physical32 OpenCL
  318. %void = OpTypeVoid
  319. %func = OpTypeFunction %void
  320. %bool = OpTypeBool
  321. %f32 = OpTypeFloat 32
  322. %u32 = OpTypeInt 32 0
  323. %u32vec2 = OpTypeVector %u32 2
  324. %f32vec2 = OpTypeVector %f32 2
  325. %u32vec3 = OpTypeVector %u32 3
  326. %f32vec3 = OpTypeVector %f32 3
  327. %u32vec4 = OpTypeVector %u32 4
  328. %f32vec4 = OpTypeVector %f32 4
  329. %f32_0 = OpConstant %f32 0
  330. %f32_1 = OpConstant %f32 1
  331. %f32_0_5 = OpConstant %f32 0.5
  332. %f32_0_25 = OpConstant %f32 0.25
  333. %f32_0_75 = OpConstant %f32 0.75
  334. %u32_0 = OpConstant %u32 0
  335. %u32_1 = OpConstant %u32 1
  336. %u32_2 = OpConstant %u32 2
  337. %u32_3 = OpConstant %u32 3
  338. %u32_4 = OpConstant %u32 4
  339. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  340. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  341. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  342. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  343. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  344. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  345. %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
  346. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  347. %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
  348. %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
  349. %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
  350. %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
  351. %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
  352. %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
  353. %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
  354. %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
  355. %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
  356. %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
  357. %type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown
  358. %ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011
  359. %uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant
  360. %type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011
  361. %type_image_f32_3d_0011 = OpTypeImage %f32 3D 0 0 1 1 Unknown
  362. %ptr_image_f32_3d_0011 = OpTypePointer UniformConstant %type_image_f32_3d_0011
  363. %uniform_image_f32_3d_0011 = OpVariable %ptr_image_f32_3d_0011 UniformConstant
  364. %type_sampled_image_f32_3d_0011 = OpTypeSampledImage %type_image_f32_3d_0011
  365. %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
  366. %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
  367. %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
  368. %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
  369. %type_sampler = OpTypeSampler
  370. %ptr_sampler = OpTypePointer UniformConstant %type_sampler
  371. %uniform_sampler = OpVariable %ptr_sampler UniformConstant
  372. )";
  373. ss << declarations;
  374. ss << R"(
  375. %main = OpFunction %void None %func
  376. %main_entry = OpLabel
  377. )";
  378. ss << body;
  379. ss << R"(
  380. OpReturn
  381. OpFunctionEnd)";
  382. return ss.str();
  383. }
  384. std::string GetKernelHeader() {
  385. return R"(
  386. OpCapability Kernel
  387. OpCapability Addresses
  388. OpCapability Linkage
  389. OpMemoryModel Physical32 OpenCL
  390. %void = OpTypeVoid
  391. %func = OpTypeFunction %void
  392. %f32 = OpTypeFloat 32
  393. %u32 = OpTypeInt 32 0
  394. )";
  395. }
  396. std::string TrivialMain() {
  397. return R"(
  398. %main = OpFunction %void None %func
  399. %entry = OpLabel
  400. OpReturn
  401. OpFunctionEnd
  402. )";
  403. }
  404. std::string GetShaderHeader(const std::string& capabilities_and_extensions = "",
  405. bool include_entry_point = true) {
  406. std::ostringstream ss;
  407. ss << R"(
  408. OpCapability Shader
  409. OpCapability Int64
  410. OpCapability Float64
  411. )";
  412. if (!include_entry_point) {
  413. ss << "OpCapability Linkage\n";
  414. }
  415. ss << capabilities_and_extensions;
  416. ss << R"(
  417. OpMemoryModel Logical GLSL450
  418. )";
  419. if (include_entry_point) {
  420. ss << "OpEntryPoint Fragment %main \"main\"\n";
  421. ss << "OpExecutionMode %main OriginUpperLeft";
  422. }
  423. ss << R"(
  424. %void = OpTypeVoid
  425. %func = OpTypeFunction %void
  426. %bool = OpTypeBool
  427. %f32 = OpTypeFloat 32
  428. %f64 = OpTypeFloat 64
  429. %u32 = OpTypeInt 32 0
  430. %u64 = OpTypeInt 64 0
  431. %s32 = OpTypeInt 32 1
  432. %s64 = OpTypeInt 64 1
  433. )";
  434. return ss.str();
  435. }
  436. TEST_F(ValidateImage, TypeImageWrongSampledType) {
  437. const std::string code = GetShaderHeader("", false) + R"(
  438. %img_type = OpTypeImage %bool 2D 0 0 0 1 Unknown
  439. )";
  440. CompileSuccessfully(code.c_str());
  441. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  442. EXPECT_THAT(getDiagnosticString(),
  443. HasSubstr("Expected Sampled Type to be either void or "
  444. "numerical scalar "
  445. "type"));
  446. }
  447. TEST_F(ValidateImage, TypeImageVoidSampledTypeVulkan) {
  448. const std::string code = GetShaderHeader() + R"(
  449. %img_type = OpTypeImage %void 2D 0 0 0 1 Unknown
  450. %main = OpFunction %void None %func
  451. %main_lab = OpLabel
  452. OpReturn
  453. OpFunctionEnd
  454. )";
  455. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  456. CompileSuccessfully(code, env);
  457. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  458. EXPECT_THAT(getDiagnosticString(),
  459. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
  460. EXPECT_THAT(getDiagnosticString(),
  461. HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
  462. "or 32-bit float scalar type for Vulkan environment"));
  463. }
  464. TEST_F(ValidateImage, TypeImageU32SampledTypeVulkan) {
  465. const std::string code = GetShaderHeader() + R"(
  466. %img_type = OpTypeImage %u32 2D 0 0 0 1 Unknown
  467. %main = OpFunction %void None %func
  468. %main_lab = OpLabel
  469. OpReturn
  470. OpFunctionEnd
  471. )";
  472. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  473. CompileSuccessfully(code, env);
  474. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  475. EXPECT_THAT(getDiagnosticString(), Eq(""));
  476. }
  477. TEST_F(ValidateImage, TypeImageI32SampledTypeVulkan) {
  478. const std::string code = GetShaderHeader() + R"(
  479. %img_type = OpTypeImage %s32 2D 0 0 0 1 Unknown
  480. %main = OpFunction %void None %func
  481. %main_lab = OpLabel
  482. OpReturn
  483. OpFunctionEnd
  484. )";
  485. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  486. CompileSuccessfully(code, env);
  487. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  488. EXPECT_THAT(getDiagnosticString(), Eq(""));
  489. }
  490. TEST_F(ValidateImage, TypeImageI64SampledTypeNoCapabilityVulkan) {
  491. const std::string code = GetShaderHeader() + R"(
  492. %img_type = OpTypeImage %s64 2D 0 0 0 1 Unknown
  493. %main = OpFunction %void None %func
  494. %main_lab = OpLabel
  495. OpReturn
  496. OpFunctionEnd
  497. )";
  498. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  499. CompileSuccessfully(code, env);
  500. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  501. EXPECT_THAT(getDiagnosticString(),
  502. HasSubstr("Capability Int64ImageEXT is required when using "
  503. "Sampled Type of 64-bit int"));
  504. }
  505. TEST_F(ValidateImage, TypeImageI64SampledTypeVulkan) {
  506. const std::string code = GetShaderHeader(
  507. "OpCapability Int64ImageEXT\nOpExtension "
  508. "\"SPV_EXT_shader_image_int64\"\n") +
  509. R"(
  510. %img_type = OpTypeImage %s64 2D 0 0 0 1 Unknown
  511. %main = OpFunction %void None %func
  512. %main_lab = OpLabel
  513. OpReturn
  514. OpFunctionEnd
  515. )";
  516. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  517. CompileSuccessfully(code, env);
  518. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  519. EXPECT_THAT(getDiagnosticString(), Eq(""));
  520. }
  521. TEST_F(ValidateImage, TypeImageU64SampledTypeNoCapabilityVulkan) {
  522. const std::string code = GetShaderHeader() + R"(
  523. %img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
  524. %main = OpFunction %void None %func
  525. %main_lab = OpLabel
  526. OpReturn
  527. OpFunctionEnd
  528. )";
  529. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  530. CompileSuccessfully(code, env);
  531. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  532. EXPECT_THAT(getDiagnosticString(),
  533. HasSubstr("Capability Int64ImageEXT is required when using "
  534. "Sampled Type of 64-bit int"));
  535. }
  536. TEST_F(ValidateImage, TypeImageU64SampledTypeVulkan) {
  537. const std::string code = GetShaderHeader(
  538. "OpCapability Int64ImageEXT\nOpExtension "
  539. "\"SPV_EXT_shader_image_int64\"\n") +
  540. R"(
  541. %img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
  542. %main = OpFunction %void None %func
  543. %main_lab = OpLabel
  544. OpReturn
  545. OpFunctionEnd
  546. )";
  547. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  548. CompileSuccessfully(code, env);
  549. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  550. EXPECT_THAT(getDiagnosticString(), Eq(""));
  551. }
  552. TEST_F(ValidateImage, TypeImageF32SampledTypeVulkan) {
  553. const std::string code = GetShaderHeader() + R"(
  554. %img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown
  555. %main = OpFunction %void None %func
  556. %main_lab = OpLabel
  557. OpReturn
  558. OpFunctionEnd
  559. )";
  560. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  561. CompileSuccessfully(code, env);
  562. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  563. EXPECT_THAT(getDiagnosticString(), Eq(""));
  564. }
  565. TEST_F(ValidateImage, TypeImageF64SampledTypeVulkan) {
  566. const std::string code = GetShaderHeader() + R"(
  567. %img_type = OpTypeImage %f64 2D 0 0 0 1 Unknown
  568. %main = OpFunction %void None %func
  569. %main_lab = OpLabel
  570. OpReturn
  571. OpFunctionEnd
  572. )";
  573. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  574. CompileSuccessfully(code, env);
  575. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  576. EXPECT_THAT(getDiagnosticString(),
  577. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
  578. EXPECT_THAT(getDiagnosticString(),
  579. HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
  580. "or 32-bit float scalar type for Vulkan environment"));
  581. }
  582. TEST_F(ValidateImage, TypeImageF64SampledTypeWithInt64Vulkan) {
  583. const std::string code = GetShaderHeader(
  584. "OpCapability Int64ImageEXT\nOpExtension "
  585. "\"SPV_EXT_shader_image_int64\"\n") +
  586. R"(
  587. %img_type = OpTypeImage %f64 2D 0 0 0 1 Unknown
  588. %main = OpFunction %void None %func
  589. %main_lab = OpLabel
  590. OpReturn
  591. OpFunctionEnd
  592. )";
  593. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  594. CompileSuccessfully(code, env);
  595. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  596. EXPECT_THAT(getDiagnosticString(),
  597. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
  598. EXPECT_THAT(getDiagnosticString(),
  599. HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
  600. "or 32-bit float scalar type for Vulkan environment"));
  601. }
  602. TEST_F(ValidateImage, TypeImageWrongDepth) {
  603. const std::string code = GetShaderHeader("", false) + R"(
  604. %img_type = OpTypeImage %f32 2D 3 0 0 1 Unknown
  605. )";
  606. CompileSuccessfully(code.c_str());
  607. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  608. EXPECT_THAT(getDiagnosticString(),
  609. HasSubstr("Invalid Depth 3 (must be 0, 1 or 2)"));
  610. }
  611. TEST_F(ValidateImage, TypeImageWrongArrayed) {
  612. const std::string code = GetShaderHeader("", false) + R"(
  613. %img_type = OpTypeImage %f32 2D 0 2 0 1 Unknown
  614. )";
  615. CompileSuccessfully(code.c_str());
  616. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  617. EXPECT_THAT(getDiagnosticString(),
  618. HasSubstr("Invalid Arrayed 2 (must be 0 or 1)"));
  619. }
  620. TEST_F(ValidateImage, TypeImageWrongMS) {
  621. const std::string code = GetShaderHeader("", false) + R"(
  622. %img_type = OpTypeImage %f32 2D 0 0 2 1 Unknown
  623. )";
  624. CompileSuccessfully(code.c_str());
  625. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  626. EXPECT_THAT(getDiagnosticString(),
  627. HasSubstr("Invalid MS 2 (must be 0 or 1)"));
  628. }
  629. TEST_F(ValidateImage, TypeImageWrongSampled) {
  630. const std::string code = GetShaderHeader("", false) + R"(
  631. %img_type = OpTypeImage %f32 2D 0 0 0 3 Unknown
  632. )";
  633. CompileSuccessfully(code.c_str());
  634. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  635. EXPECT_THAT(getDiagnosticString(),
  636. HasSubstr("Invalid Sampled 3 (must be 0, 1 or 2)"));
  637. }
  638. TEST_F(ValidateImage, TypeImageWrongSampledForSubpassData) {
  639. const std::string code =
  640. GetShaderHeader("OpCapability InputAttachment\n", false) +
  641. R"(
  642. %img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
  643. )";
  644. CompileSuccessfully(code.c_str());
  645. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  646. EXPECT_THAT(getDiagnosticString(),
  647. HasSubstr("Dim SubpassData requires Sampled to be 2"));
  648. }
  649. TEST_F(ValidateImage, TypeImageWrongSampledForSubpassDataVulkan) {
  650. const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
  651. R"(
  652. %img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
  653. )" + TrivialMain();
  654. CompileSuccessfully(code.c_str());
  655. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  656. EXPECT_THAT(getDiagnosticString(),
  657. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06214"));
  658. EXPECT_THAT(getDiagnosticString(),
  659. HasSubstr("Dim SubpassData requires Sampled to be 2"));
  660. }
  661. TEST_F(ValidateImage, TypeImageWrongArrayForSubpassDataVulkan) {
  662. const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
  663. R"(
  664. %img_type = OpTypeImage %f32 SubpassData 0 1 0 2 Unknown
  665. )" + TrivialMain();
  666. CompileSuccessfully(code.c_str());
  667. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  668. EXPECT_THAT(getDiagnosticString(),
  669. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06214"));
  670. EXPECT_THAT(getDiagnosticString(),
  671. HasSubstr("Dim SubpassData requires Arrayed to be 0"));
  672. }
  673. TEST_F(ValidateImage, TypeImageDimRectVulkan) {
  674. const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
  675. R"(
  676. %img_type = OpTypeImage %f32 Rect 0 1 0 2 Unknown
  677. )" + TrivialMain();
  678. CompileSuccessfully(code.c_str());
  679. ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
  680. ValidateInstructions(SPV_ENV_VULKAN_1_0));
  681. // Can't actually hit VUID-StandaloneSpirv-OpTypeImage-09638
  682. EXPECT_THAT(
  683. getDiagnosticString(),
  684. AnyVUID("TypeImage requires one of these capabilities: SampledRect"));
  685. }
  686. TEST_F(ValidateImage, TypeImageWrongSampledTypeForTileImageDataEXT) {
  687. const std::string code = GetShaderHeader(
  688. "OpCapability TileImageColorReadAccessEXT\n"
  689. "OpExtension \"SPV_EXT_shader_tile_image\"\n",
  690. false) +
  691. R"(
  692. %img_type = OpTypeImage %void TileImageDataEXT 0 0 0 2 Unknown
  693. )";
  694. CompileSuccessfully(code.c_str());
  695. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  696. EXPECT_THAT(
  697. getDiagnosticString(),
  698. HasSubstr(
  699. "Dim TileImageDataEXT requires Sampled Type to be not OpTypeVoid"));
  700. }
  701. TEST_F(ValidateImage, TypeImageWrongSampledForTileImageDataEXT) {
  702. const std::string code = GetShaderHeader(
  703. "OpCapability TileImageColorReadAccessEXT\n"
  704. "OpExtension \"SPV_EXT_shader_tile_image\"\n",
  705. false) +
  706. R"(
  707. %img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 1 Unknown
  708. )";
  709. CompileSuccessfully(code.c_str());
  710. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  711. EXPECT_THAT(getDiagnosticString(),
  712. HasSubstr("Dim TileImageDataEXT requires Sampled to be 2"));
  713. }
  714. TEST_F(ValidateImage, TypeImageWrongFormatForTileImageDataEXT) {
  715. const std::string code = GetShaderHeader(
  716. "OpCapability TileImageColorReadAccessEXT\n"
  717. "OpExtension \"SPV_EXT_shader_tile_image\"\n",
  718. false) +
  719. R"(
  720. %img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Rgba32f
  721. )";
  722. CompileSuccessfully(code.c_str());
  723. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  724. EXPECT_THAT(getDiagnosticString(),
  725. HasSubstr("Dim TileImageDataEXT requires format Unknown"));
  726. }
  727. TEST_F(ValidateImage, TypeImageWrongDepthForTileImageDataEXT) {
  728. const std::string code = GetShaderHeader(
  729. "OpCapability TileImageColorReadAccessEXT\n"
  730. "OpExtension \"SPV_EXT_shader_tile_image\"\n",
  731. false) +
  732. R"(
  733. %img_type = OpTypeImage %f32 TileImageDataEXT 1 0 0 2 Unknown
  734. )";
  735. CompileSuccessfully(code.c_str());
  736. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  737. EXPECT_THAT(getDiagnosticString(),
  738. HasSubstr("Dim TileImageDataEXT requires Depth to be 0"));
  739. }
  740. TEST_F(ValidateImage, TypeImageWrongArrayedForTileImageDataEXT) {
  741. const std::string code = GetShaderHeader(
  742. "OpCapability TileImageColorReadAccessEXT\n"
  743. "OpExtension \"SPV_EXT_shader_tile_image\"\n",
  744. false) +
  745. R"(
  746. %img_type = OpTypeImage %f32 TileImageDataEXT 0 1 0 2 Unknown
  747. )";
  748. CompileSuccessfully(code.c_str());
  749. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  750. EXPECT_THAT(getDiagnosticString(),
  751. HasSubstr("Dim TileImageDataEXT requires Arrayed to be 0"));
  752. }
  753. TEST_F(ValidateImage, TypeSampledImage_TileImageDataEXT_Error) {
  754. const std::string code = GetShaderHeader(
  755. "OpCapability TileImageColorReadAccessEXT\n"
  756. "OpExtension \"SPV_EXT_shader_tile_image\"\n",
  757. false) +
  758. R"(
  759. %img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
  760. %simg_type = OpTypeSampledImage %img_type
  761. )";
  762. CompileSuccessfully(code.c_str());
  763. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  764. EXPECT_THAT(getDiagnosticString(),
  765. HasSubstr("Sampled image type requires an image type with "
  766. "\"Sampled\" operand set to 0 or 1"));
  767. }
  768. TEST_F(ValidateImage, ImageTexelPointerImageDimTileImageDataEXTBad) {
  769. const std::string body = R"(
  770. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %tile_image_u32_tid_0002 %u32_0 %u32_0
  771. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  772. )";
  773. const std::string decl = R"(
  774. %type_image_u32_tid_0002 = OpTypeImage %u32 TileImageDataEXT 0 0 0 2 Unknown
  775. %ptr_image_u32_tid_0002 = OpTypePointer TileImageEXT %type_image_u32_tid_0002
  776. %tile_image_u32_tid_0002 = OpVariable %ptr_image_u32_tid_0002 TileImageEXT
  777. )";
  778. const std::string extra = R"(
  779. OpCapability TileImageColorReadAccessEXT
  780. OpExtension "SPV_EXT_shader_tile_image"
  781. )";
  782. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  783. SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
  784. .c_str());
  785. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  786. EXPECT_THAT(getDiagnosticString(),
  787. HasSubstr("Image Dim TileImageDataEXT cannot be used with "
  788. "OpImageTexelPointer"));
  789. }
  790. TEST_F(ValidateImage, ReadTileImageDataEXT) {
  791. const std::string body = R"(
  792. %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
  793. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  794. )";
  795. const std::string decl = R"(
  796. %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
  797. %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
  798. %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
  799. )";
  800. const std::string extra = R"(
  801. OpCapability StorageImageReadWithoutFormat
  802. OpCapability TileImageColorReadAccessEXT
  803. OpExtension "SPV_EXT_shader_tile_image"
  804. )";
  805. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  806. SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
  807. .c_str());
  808. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  809. EXPECT_THAT(
  810. getDiagnosticString(),
  811. HasSubstr("Image Dim TileImageDataEXT cannot be used with ImageRead"));
  812. }
  813. TEST_F(ValidateImage, WriteTileImageDataEXT) {
  814. const std::string body = R"(
  815. %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
  816. OpImageWrite %img %u32vec2_01 %f32vec4_0000
  817. )";
  818. const std::string decl = R"(
  819. %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
  820. %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
  821. %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
  822. )";
  823. const std::string extra = R"(
  824. OpCapability TileImageColorReadAccessEXT
  825. OpExtension "SPV_EXT_shader_tile_image"
  826. )";
  827. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  828. SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
  829. .c_str());
  830. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  831. EXPECT_THAT(getDiagnosticString(),
  832. HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
  833. }
  834. TEST_F(ValidateImage, QueryFormatTileImageDataEXT) {
  835. const std::string body = R"(
  836. %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
  837. %res1 = OpImageQueryFormat %u32 %img
  838. )";
  839. const std::string decl = R"(
  840. %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
  841. %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
  842. %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
  843. )";
  844. const std::string extra = R"(
  845. OpCapability TileImageColorReadAccessEXT
  846. OpExtension "SPV_EXT_shader_tile_image"
  847. )";
  848. CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str());
  849. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  850. EXPECT_THAT(getDiagnosticString(),
  851. HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
  852. }
  853. TEST_F(ValidateImage, QueryOrderTileImageDataEXT) {
  854. const std::string body = R"(
  855. %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
  856. %res1 = OpImageQueryOrder %u32 %img
  857. )";
  858. const std::string decl = R"(
  859. %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
  860. %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
  861. %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
  862. )";
  863. const std::string extra = R"(
  864. OpCapability TileImageColorReadAccessEXT
  865. OpExtension "SPV_EXT_shader_tile_image"
  866. )";
  867. CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str());
  868. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  869. EXPECT_THAT(getDiagnosticString(),
  870. HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
  871. }
  872. TEST_F(ValidateImage, SparseFetchTileImageDataEXT) {
  873. const std::string body = R"(
  874. %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
  875. %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
  876. )";
  877. const std::string decl = R"(
  878. %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
  879. %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
  880. %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
  881. )";
  882. const std::string extra = R"(
  883. OpCapability StorageImageReadWithoutFormat
  884. OpCapability TileImageColorReadAccessEXT
  885. OpExtension "SPV_EXT_shader_tile_image"
  886. )";
  887. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  888. SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
  889. .c_str());
  890. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  891. EXPECT_THAT(getDiagnosticString(),
  892. HasSubstr("Expected Image 'Sampled' parameter to be 1"));
  893. }
  894. TEST_F(ValidateImage, SparseReadTileImageDataEXT) {
  895. const std::string body = R"(
  896. %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
  897. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
  898. )";
  899. const std::string decl = R"(
  900. %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
  901. %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
  902. %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
  903. )";
  904. const std::string extra = R"(
  905. OpCapability StorageImageReadWithoutFormat
  906. OpCapability TileImageColorReadAccessEXT
  907. OpExtension "SPV_EXT_shader_tile_image"
  908. )";
  909. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  910. SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
  911. .c_str());
  912. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  913. EXPECT_THAT(
  914. getDiagnosticString(),
  915. HasSubstr(
  916. "Image Dim TileImageDataEXT cannot be used with ImageSparseRead"));
  917. }
  918. TEST_F(ValidateImage, TypeImage_OpenCL_Sampled0_OK) {
  919. const std::string code = GetKernelHeader() + R"(
  920. %img_type = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
  921. )";
  922. CompileSuccessfully(code.c_str());
  923. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_1));
  924. EXPECT_THAT(getDiagnosticString(), Eq(""));
  925. }
  926. TEST_F(ValidateImage, TypeImage_OpenCL_Sampled1_Invalid) {
  927. const std::string code = GetKernelHeader() + R"(
  928. %img_type = OpTypeImage %void 2D 0 0 0 1 Unknown ReadOnly
  929. )";
  930. CompileSuccessfully(code.c_str());
  931. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
  932. EXPECT_THAT(getDiagnosticString(),
  933. HasSubstr("Sampled must be 0 in the OpenCL environment."));
  934. }
  935. TEST_F(ValidateImage, TypeImage_OpenCL_Sampled2_Invalid) {
  936. const std::string code = GetKernelHeader() + R"(
  937. %img_type = OpTypeImage %void 2D 0 0 0 2 Unknown ReadOnly
  938. )";
  939. CompileSuccessfully(code.c_str());
  940. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
  941. EXPECT_THAT(getDiagnosticString(),
  942. HasSubstr("Sampled must be 0 in the OpenCL environment."));
  943. }
  944. TEST_F(ValidateImage, TypeImage_OpenCL_AccessQualifierMissing) {
  945. const std::string code = GetKernelHeader() + R"(
  946. %img_type = OpTypeImage %void 2D 0 0 0 0 Unknown
  947. )";
  948. CompileSuccessfully(code.c_str());
  949. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
  950. EXPECT_THAT(getDiagnosticString(),
  951. HasSubstr("In the OpenCL environment, the optional Access "
  952. "Qualifier must be present"));
  953. }
  954. TEST_F(ValidateImage, TypeImage_Vulkan_Sampled1_OK) {
  955. const std::string code = GetShaderHeader() + R"(
  956. %img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown
  957. )" + TrivialMain();
  958. CompileSuccessfully(code.c_str());
  959. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  960. EXPECT_THAT(getDiagnosticString(), Eq(""));
  961. }
  962. TEST_F(ValidateImage, TypeImage_Vulkan_Sampled2_OK) {
  963. const std::string code = GetShaderHeader() + R"(
  964. %img_type = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  965. )" + TrivialMain();
  966. CompileSuccessfully(code.c_str());
  967. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  968. EXPECT_THAT(getDiagnosticString(), Eq(""));
  969. }
  970. TEST_F(ValidateImage, TypeImage_Vulkan_Sampled0_Invalid) {
  971. const std::string code = GetShaderHeader() + R"(
  972. %img_type = OpTypeImage %f32 2D 0 0 0 0 Unknown
  973. )" + TrivialMain();
  974. CompileSuccessfully(code.c_str());
  975. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  976. EXPECT_THAT(getDiagnosticString(),
  977. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
  978. EXPECT_THAT(getDiagnosticString(),
  979. HasSubstr("Sampled must be 1 or 2 in the Vulkan environment."));
  980. }
  981. TEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) {
  982. const std::string code =
  983. GetShaderHeader("OpCapability InputAttachment\n", false) +
  984. R"(
  985. %img_type = OpTypeImage %f32 SubpassData 0 0 0 2 Rgba32f
  986. )";
  987. CompileSuccessfully(code.c_str());
  988. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  989. EXPECT_THAT(getDiagnosticString(),
  990. HasSubstr("Dim SubpassData requires format Unknown"));
  991. }
  992. TEST_F(ValidateImage, TypeImageMultisampleStorageImage_MissingCapability) {
  993. const std::string code = GetShaderHeader("", false) +
  994. R"(
  995. %img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
  996. )";
  997. CompileSuccessfully(code.c_str());
  998. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()) << code;
  999. EXPECT_THAT(getDiagnosticString(),
  1000. HasSubstr("Capability StorageImageMultisample is required when "
  1001. "using multisampled storage image"));
  1002. }
  1003. TEST_F(ValidateImage, TypeImageMultisampleStorageImage_UsesCapability) {
  1004. const std::string code =
  1005. GetShaderHeader("OpCapability StorageImageMultisample\n", false) +
  1006. R"(
  1007. %img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
  1008. )";
  1009. CompileSuccessfully(code.c_str());
  1010. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
  1011. EXPECT_THAT(getDiagnosticString(), Eq(""));
  1012. }
  1013. TEST_F(ValidateImage, TypeImageMultisampleSubpassData_OK) {
  1014. const std::string code =
  1015. GetShaderHeader("OpCapability InputAttachment\n", false) +
  1016. R"(
  1017. %img_type = OpTypeImage %f32 SubpassData 0 0 1 2 Unknown
  1018. )";
  1019. CompileSuccessfully(code.c_str());
  1020. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
  1021. EXPECT_THAT(getDiagnosticString(), Eq(""));
  1022. }
  1023. TEST_F(ValidateImage, TypeSampledImage_NotImage_Error) {
  1024. const std::string code = GetShaderHeader("", false) + R"(
  1025. %simg_type = OpTypeSampledImage %f32
  1026. )";
  1027. CompileSuccessfully(code.c_str());
  1028. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1029. EXPECT_THAT(getDiagnosticString(),
  1030. HasSubstr("Expected Image to be of type OpTypeImage"));
  1031. }
  1032. TEST_F(ValidateImage, TypeSampledImage_Sampled0_Success) {
  1033. // This is ok in the OpenCL and universal environments.
  1034. // Vulkan will reject an OpTypeImage with Sampled=0, checked elsewhere.
  1035. const std::string code = GetShaderHeader() + R"(
  1036. %imty = OpTypeImage %f32 2D 0 0 0 0 Unknown
  1037. %simg_type = OpTypeSampledImage %imty
  1038. )" + TrivialMain();
  1039. CompileSuccessfully(code.c_str());
  1040. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1041. EXPECT_EQ(getDiagnosticString(), "");
  1042. }
  1043. TEST_F(ValidateImage, TypeSampledImage_Sampled2_Error) {
  1044. const std::string code = GetShaderHeader() + R"(
  1045. %storage_image = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  1046. %simg_type = OpTypeSampledImage %storage_image
  1047. )" + TrivialMain();
  1048. CompileSuccessfully(code.c_str());
  1049. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1050. EXPECT_THAT(getDiagnosticString(),
  1051. HasSubstr("Sampled image type requires an image type with "
  1052. "\"Sampled\" operand set to 0 or 1"));
  1053. }
  1054. TEST_F(ValidateImage, TypeSampledImage_Sampled1_Success) {
  1055. const std::string code = GetShaderHeader() + R"(
  1056. %im = OpTypeImage %f32 2D 0 0 0 1 Unknown
  1057. %simg_type = OpTypeSampledImage %im
  1058. )" + TrivialMain();
  1059. CompileSuccessfully(code.c_str());
  1060. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1061. EXPECT_EQ(getDiagnosticString(), "");
  1062. }
  1063. TEST_F(ValidateImage, SampledImageSuccess) {
  1064. const std::string body = R"(
  1065. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1066. %sampler = OpLoad %type_sampler %uniform_sampler
  1067. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1068. )";
  1069. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1070. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1071. }
  1072. TEST_F(ValidateImage, SampledImageVulkanSuccess) {
  1073. const std::string body = R"(
  1074. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1075. %sampler = OpLoad %type_sampler %uniform_sampler
  1076. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1077. )";
  1078. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  1079. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
  1080. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  1081. }
  1082. TEST_F(ValidateImage, SampledImageWrongResultType) {
  1083. const std::string body = R"(
  1084. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1085. %sampler = OpLoad %type_sampler %uniform_sampler
  1086. %simg = OpSampledImage %type_image_f32_2d_0001 %img %sampler
  1087. )";
  1088. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1089. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1090. EXPECT_THAT(getDiagnosticString(),
  1091. HasSubstr("Expected Result Type to be OpTypeSampledImage"));
  1092. }
  1093. TEST_F(ValidateImage, SampledImageNotImage) {
  1094. const std::string body = R"(
  1095. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1096. %sampler = OpLoad %type_sampler %uniform_sampler
  1097. %simg1 = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1098. %simg2 = OpSampledImage %type_sampled_image_f32_2d_0001 %simg1 %sampler
  1099. )";
  1100. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1101. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1102. EXPECT_THAT(getDiagnosticString(),
  1103. HasSubstr("Expected Image to be of type OpTypeImage"));
  1104. }
  1105. TEST_F(ValidateImage, SampledImageImageNotForSampling) {
  1106. const std::string code = GetShaderHeader() + R"(
  1107. %im_ty = OpTypeImage %f32 2D 0 0 0 2 Unknown
  1108. %sampler_ty = OpTypeSampler
  1109. %sampled_image_ty = OpTypeSampledImage %im_ty ; will fail here first!
  1110. %ptr_im_ty = OpTypePointer UniformConstant %im_ty
  1111. %var_im = OpVariable %ptr_im_ty UniformConstant
  1112. %ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
  1113. %var_sampler = OpVariable %ptr_sampler_ty UniformConstant
  1114. %main = OpFunction %void None %func
  1115. %entry = OpLabel
  1116. %im = OpLoad %im_ty %var_im
  1117. %sampler = OpLoad %sampler_ty %var_sampler
  1118. %sampled_image = OpSampledImage %sampled_image_ty %im %sampler
  1119. OpReturn
  1120. OpFunctionEnd
  1121. )";
  1122. CompileSuccessfully(code.c_str());
  1123. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1124. EXPECT_THAT(getDiagnosticString(),
  1125. HasSubstr("Sampled image type requires an image type with "
  1126. "\"Sampled\" operand set to 0 or 1"))
  1127. << code;
  1128. }
  1129. TEST_F(ValidateImage, SampledImageNotSampler) {
  1130. const std::string body = R"(
  1131. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1132. %sampler = OpLoad %type_sampler %uniform_sampler
  1133. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %img
  1134. )";
  1135. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1136. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1137. EXPECT_THAT(getDiagnosticString(),
  1138. HasSubstr("Expected Sampler to be of type OpTypeSampler"));
  1139. }
  1140. TEST_F(ValidateImage, SampledImageIsStorage) {
  1141. const std::string declarations = R"(
  1142. %type_sampled_image_f32_2d_0002 = OpTypeSampledImage %type_image_f32_2d_0002
  1143. )";
  1144. const std::string body = R"(
  1145. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  1146. %sampler = OpLoad %type_sampler %uniform_sampler
  1147. %simg = OpSampledImage %type_sampled_image_f32_2d_0002 %img %sampler
  1148. )";
  1149. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "",
  1150. SPV_ENV_UNIVERSAL_1_0, "GLSL450",
  1151. declarations)
  1152. .c_str());
  1153. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1154. EXPECT_THAT(getDiagnosticString(),
  1155. HasSubstr("Sampled image type requires an image type with "
  1156. "\"Sampled\" operand set to 0 or 1"));
  1157. }
  1158. TEST_F(ValidateImage, ImageTexelPointerSuccess) {
  1159. const std::string body = R"(
  1160. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  1161. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1162. )";
  1163. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1164. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1165. }
  1166. TEST_F(ValidateImage, ImageTexelPointerResultTypeNotPointer) {
  1167. const std::string body = R"(
  1168. %texel_ptr = OpImageTexelPointer %type_image_u32_buffer_0002_r32ui %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  1169. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1170. )";
  1171. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1172. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1173. EXPECT_THAT(getDiagnosticString(),
  1174. HasSubstr("Expected Result Type to be a pointer"));
  1175. }
  1176. TEST_F(ValidateImage, ImageTexelPointerResultTypeNotImageClass) {
  1177. const std::string body = R"(
  1178. %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  1179. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1180. )";
  1181. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1182. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1183. EXPECT_THAT(getDiagnosticString(),
  1184. HasSubstr("Expected Result Type to be a pointer whose "
  1185. "Storage Class operand is Image"));
  1186. }
  1187. TEST_F(ValidateImage, ImageTexelPointerResultTypeNotNumericNorVoid) {
  1188. const std::string body = R"(
  1189. %texel_ptr = OpImageTexelPointer %ptr_Image_u32arr4 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  1190. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1191. )";
  1192. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1193. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1194. EXPECT_THAT(
  1195. getDiagnosticString(),
  1196. HasSubstr("Expected Result Type to be a pointer whose Type operand "
  1197. "must be a scalar numerical type or OpTypeVoid"));
  1198. }
  1199. TEST_F(ValidateImage, ImageTexelPointerImageNotResultTypePointer) {
  1200. const std::string body = R"(
  1201. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %type_image_f32_buffer_0002_r32ui %u32_0 %u32_0
  1202. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1203. )";
  1204. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1205. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1206. EXPECT_THAT(getDiagnosticString(),
  1207. HasSubstr("Operand '148[%148]' cannot be a "
  1208. "type"));
  1209. }
  1210. TEST_F(ValidateImage, ImageTexelPointerImageNotImage) {
  1211. const std::string body = R"(
  1212. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_sampler %u32_0 %u32_0
  1213. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1214. )";
  1215. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1216. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1217. EXPECT_THAT(
  1218. getDiagnosticString(),
  1219. HasSubstr("Expected Image to be OpTypePointer with Type OpTypeImage"));
  1220. }
  1221. TEST_F(ValidateImage, ImageTexelPointerImageSampledNotResultType) {
  1222. const std::string body = R"(
  1223. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_f32_cube_0101 %u32_0 %u32_0
  1224. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1225. )";
  1226. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1227. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1228. EXPECT_THAT(getDiagnosticString(),
  1229. HasSubstr("Expected Image 'Sampled Type' to be the same as the "
  1230. "Type pointed to by Result Type"));
  1231. }
  1232. TEST_F(ValidateImage, ImageTexelPointerImageDimSubpassDataBad) {
  1233. const std::string body = R"(
  1234. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_spd_0002 %u32_0 %u32_0
  1235. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1236. )";
  1237. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1238. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1239. EXPECT_THAT(
  1240. getDiagnosticString(),
  1241. HasSubstr(
  1242. "Image Dim SubpassData cannot be used with OpImageTexelPointer"));
  1243. }
  1244. TEST_F(ValidateImage, ImageTexelPointerImageCoordTypeBad) {
  1245. const std::string body = R"(
  1246. %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32ui %f32_0 %f32_0
  1247. %sum = OpAtomicIAdd %f32 %texel_ptr %f32_1 %f32_0 %f32_1
  1248. )";
  1249. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1250. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1251. EXPECT_THAT(getDiagnosticString(),
  1252. HasSubstr("Expected Coordinate to be integer scalar or vector"));
  1253. }
  1254. TEST_F(ValidateImage, ImageTexelPointerImageCoordSizeBad) {
  1255. const std::string body = R"(
  1256. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_u32_2d_0002 %u32vec3_012 %u32_0
  1257. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1258. )";
  1259. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1260. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1261. EXPECT_THAT(
  1262. getDiagnosticString(),
  1263. HasSubstr("Expected Coordinate to have 2 components, but given 3"));
  1264. }
  1265. TEST_F(ValidateImage, ImageTexelPointerSampleNotIntScalar) {
  1266. const std::string body = R"(
  1267. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %f32_0
  1268. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1269. )";
  1270. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1271. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1272. EXPECT_THAT(getDiagnosticString(),
  1273. HasSubstr("Expected Sample to be integer scalar"));
  1274. }
  1275. TEST_F(ValidateImage, ImageTexelPointerSampleNotZeroForImageWithMSZero) {
  1276. const std::string body = R"(
  1277. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_1
  1278. %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
  1279. )";
  1280. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1281. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1282. EXPECT_THAT(getDiagnosticString(),
  1283. HasSubstr("Expected Sample for Image with MS 0 to be a valid "
  1284. "<id> for the value 0"));
  1285. }
  1286. TEST_F(ValidateImage, SampleImplicitLodSuccess) {
  1287. const std::string body = R"(
  1288. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1289. %sampler = OpLoad %type_sampler %uniform_sampler
  1290. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1291. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
  1292. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0_25
  1293. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
  1294. %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
  1295. %res6 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
  1296. %res7 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  1297. %res8 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
  1298. )";
  1299. const std::string extra = R"(
  1300. OpCapability VulkanMemoryModelKHR
  1301. OpExtension "SPV_KHR_vulkan_memory_model"
  1302. )";
  1303. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  1304. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  1305. .c_str());
  1306. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1307. }
  1308. TEST_F(ValidateImage, SampleImplicitLodWrongResultType) {
  1309. const std::string body = R"(
  1310. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1311. %sampler = OpLoad %type_sampler %uniform_sampler
  1312. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1313. %res1 = OpImageSampleImplicitLod %f32 %simg %f32vec2_hh
  1314. )";
  1315. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1316. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1317. EXPECT_THAT(getDiagnosticString(),
  1318. HasSubstr("Expected Result Type to be int or float vector type"));
  1319. }
  1320. TEST_F(ValidateImage, SampleImplicitLodWrongNumComponentsResultType) {
  1321. const std::string body = R"(
  1322. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1323. %sampler = OpLoad %type_sampler %uniform_sampler
  1324. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1325. %res1 = OpImageSampleImplicitLod %f32vec3 %simg %f32vec2_hh
  1326. )";
  1327. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1328. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1329. EXPECT_THAT(getDiagnosticString(),
  1330. HasSubstr("Expected Result Type to have 4 components"));
  1331. }
  1332. TEST_F(ValidateImage, SampleImplicitLodNotSampledImage) {
  1333. const std::string body = R"(
  1334. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1335. %res1 = OpImageSampleImplicitLod %f32vec4 %img %f32vec2_hh
  1336. )";
  1337. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1338. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1339. EXPECT_THAT(
  1340. getDiagnosticString(),
  1341. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  1342. }
  1343. TEST_F(ValidateImage, SampleImplicitLodMultisampleError) {
  1344. const std::string body = R"(
  1345. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  1346. %sampler = OpLoad %type_sampler %uniform_sampler
  1347. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  1348. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
  1349. )";
  1350. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1351. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1352. EXPECT_THAT(getDiagnosticString(),
  1353. HasSubstr("Sampling operation is invalid for multisample image"));
  1354. }
  1355. TEST_F(ValidateImage, SampleImplicitLodWrongSampledType) {
  1356. const std::string body = R"(
  1357. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1358. %sampler = OpLoad %type_sampler %uniform_sampler
  1359. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1360. %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
  1361. )";
  1362. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1363. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1364. EXPECT_THAT(getDiagnosticString(),
  1365. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  1366. "Result Type components"));
  1367. }
  1368. TEST_F(ValidateImage, SampleImplicitLodVoidSampledType) {
  1369. const std::string body = R"(
  1370. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  1371. %sampler = OpLoad %type_sampler %uniform_sampler
  1372. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  1373. %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
  1374. )";
  1375. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1376. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1377. }
  1378. TEST_F(ValidateImage, SampleImplicitLodWrongCoordinateType) {
  1379. const std::string body = R"(
  1380. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1381. %sampler = OpLoad %type_sampler %uniform_sampler
  1382. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1383. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %img
  1384. )";
  1385. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1386. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1387. EXPECT_THAT(getDiagnosticString(),
  1388. HasSubstr("Expected Coordinate to be float scalar or vector"));
  1389. }
  1390. TEST_F(ValidateImage, SampleImplicitLodCoordinateSizeTooSmall) {
  1391. const std::string body = R"(
  1392. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1393. %sampler = OpLoad %type_sampler %uniform_sampler
  1394. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1395. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32_0_5
  1396. )";
  1397. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1398. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1399. EXPECT_THAT(getDiagnosticString(),
  1400. HasSubstr("Expected Coordinate to have at least 2 components, "
  1401. "but given only 1"));
  1402. }
  1403. TEST_F(ValidateImage, SampleExplicitLodSuccessShader) {
  1404. const std::string body = R"(
  1405. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1406. %sampler = OpLoad %type_sampler %uniform_sampler
  1407. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1408. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod %f32_1
  1409. %res2 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_10 %f32vec2_01
  1410. %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
  1411. %res4 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
  1412. %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset|MinLod %f32vec2_10 %f32vec2_01 %s32vec2_01 %f32_0_5
  1413. %res6 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod|NonPrivateTexelKHR %f32_1
  1414. )";
  1415. const std::string extra = R"(
  1416. OpCapability VulkanMemoryModelKHR
  1417. OpExtension "SPV_KHR_vulkan_memory_model"
  1418. )";
  1419. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  1420. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  1421. .c_str());
  1422. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1423. }
  1424. TEST_F(ValidateImage, SampleExplicitLodSuccessKernel) {
  1425. const std::string body = R"(
  1426. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1427. %sampler = OpLoad %type_sampler %uniform_sampler
  1428. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1429. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec4_0123 Lod %f32_1
  1430. %res2 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Grad %f32vec2_10 %f32vec2_01
  1431. %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %u32vec2_01
  1432. %res4 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Offset %u32vec2_01
  1433. %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset %f32vec2_10 %f32vec2_01 %u32vec2_01
  1434. )";
  1435. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1436. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1437. }
  1438. TEST_F(ValidateImage, SampleExplicitLodSuccessCubeArrayed) {
  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 %f32vec3_hhh
  1444. )";
  1445. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1446. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1447. }
  1448. TEST_F(ValidateImage, SampleExplicitLodWrongResultType) {
  1449. const std::string body = R"(
  1450. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1451. %sampler = OpLoad %type_sampler %uniform_sampler
  1452. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1453. %res1 = OpImageSampleExplicitLod %f32 %simg %f32vec2_hh Lod %f32_1
  1454. )";
  1455. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1456. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1457. EXPECT_THAT(getDiagnosticString(),
  1458. HasSubstr("Expected Result Type to be int or float vector type"));
  1459. }
  1460. TEST_F(ValidateImage, SampleExplicitLodWrongNumComponentsResultType) {
  1461. const std::string body = R"(
  1462. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1463. %sampler = OpLoad %type_sampler %uniform_sampler
  1464. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1465. %res1 = OpImageSampleExplicitLod %f32vec3 %simg %f32vec2_hh Lod %f32_1
  1466. )";
  1467. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1468. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1469. EXPECT_THAT(getDiagnosticString(),
  1470. HasSubstr("Expected Result Type to have 4 components"));
  1471. }
  1472. TEST_F(ValidateImage, SampleExplicitLodNotSampledImage) {
  1473. const std::string body = R"(
  1474. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1475. %res1 = OpImageSampleExplicitLod %f32vec4 %img %f32vec2_hh Lod %f32_1
  1476. )";
  1477. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1478. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1479. EXPECT_THAT(
  1480. getDiagnosticString(),
  1481. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  1482. }
  1483. TEST_F(ValidateImage, SampleExplicitLodMultisampleError) {
  1484. const std::string body = R"(
  1485. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  1486. %sampler = OpLoad %type_sampler %uniform_sampler
  1487. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  1488. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_0 %u32_1
  1489. )";
  1490. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1491. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1492. EXPECT_THAT(getDiagnosticString(),
  1493. HasSubstr("Sampling operation is invalid for multisample image"));
  1494. }
  1495. TEST_F(ValidateImage, SampleExplicitLodWrongSampledType) {
  1496. const std::string body = R"(
  1497. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1498. %sampler = OpLoad %type_sampler %uniform_sampler
  1499. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1500. %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
  1501. )";
  1502. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1503. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1504. EXPECT_THAT(getDiagnosticString(),
  1505. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  1506. "Result Type components"));
  1507. }
  1508. TEST_F(ValidateImage, SampleExplicitLodVoidSampledType) {
  1509. const std::string body = R"(
  1510. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  1511. %sampler = OpLoad %type_sampler %uniform_sampler
  1512. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  1513. %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
  1514. )";
  1515. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1516. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1517. }
  1518. TEST_F(ValidateImage, SampleExplicitLodWrongCoordinateType) {
  1519. const std::string body = R"(
  1520. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1521. %sampler = OpLoad %type_sampler %uniform_sampler
  1522. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1523. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %img Lod %f32_1
  1524. )";
  1525. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1526. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1527. EXPECT_THAT(getDiagnosticString(),
  1528. HasSubstr("Expected Coordinate to be float scalar or vector"));
  1529. }
  1530. TEST_F(ValidateImage, SampleExplicitLodCoordinateSizeTooSmall) {
  1531. const std::string body = R"(
  1532. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1533. %sampler = OpLoad %type_sampler %uniform_sampler
  1534. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1535. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32_0_5 Lod %f32_1
  1536. )";
  1537. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1538. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1539. EXPECT_THAT(getDiagnosticString(),
  1540. HasSubstr("Expected Coordinate to have at least 2 components, "
  1541. "but given only 1"));
  1542. }
  1543. TEST_F(ValidateImage, SampleExplicitLodBias) {
  1544. const std::string body = R"(
  1545. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1546. %sampler = OpLoad %type_sampler %uniform_sampler
  1547. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1548. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Bias|Lod %f32_1 %f32_1
  1549. )";
  1550. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1551. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1552. EXPECT_THAT(
  1553. getDiagnosticString(),
  1554. HasSubstr(
  1555. "Image Operand Bias can only be used with ImplicitLod opcodes"));
  1556. }
  1557. TEST_F(ValidateImage, LodAndGrad) {
  1558. const std::string body = R"(
  1559. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1560. %sampler = OpLoad %type_sampler %uniform_sampler
  1561. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1562. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|Grad %f32_1 %f32vec2_hh %f32vec2_hh
  1563. )";
  1564. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1565. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1566. EXPECT_THAT(
  1567. getDiagnosticString(),
  1568. HasSubstr(
  1569. "Image Operand bits Lod and Grad cannot be set at the same time"));
  1570. }
  1571. TEST_F(ValidateImage, ImplicitLodWithLod) {
  1572. const std::string body = R"(
  1573. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1574. %sampler = OpLoad %type_sampler %uniform_sampler
  1575. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1576. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_0_5
  1577. )";
  1578. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1579. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1580. EXPECT_THAT(
  1581. getDiagnosticString(),
  1582. HasSubstr("Image Operand Lod can only be used with ExplicitLod opcodes "
  1583. "and OpImageFetch"));
  1584. }
  1585. TEST_F(ValidateImage, LodWrongType) {
  1586. const std::string body = R"(
  1587. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1588. %sampler = OpLoad %type_sampler %uniform_sampler
  1589. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1590. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32vec2_hh)";
  1591. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1592. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1593. EXPECT_THAT(getDiagnosticString(),
  1594. HasSubstr("Expected Image Operand Lod to be float scalar when "
  1595. "used with ExplicitLod"));
  1596. }
  1597. TEST_F(ValidateImage, LodWrongDim) {
  1598. const std::string body = R"(
  1599. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  1600. %sampler = OpLoad %type_sampler %uniform_sampler
  1601. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  1602. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)";
  1603. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1604. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1605. EXPECT_THAT(getDiagnosticString(),
  1606. HasSubstr("Image Operand Lod requires 'Dim' parameter to be 1D, "
  1607. "2D, 3D or Cube"));
  1608. }
  1609. TEST_F(ValidateImage, MinLodIncompatible) {
  1610. const std::string body = R"(
  1611. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1612. %sampler = OpLoad %type_sampler %uniform_sampler
  1613. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1614. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|MinLod %f32_0 %f32_0)";
  1615. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1616. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1617. EXPECT_THAT(
  1618. getDiagnosticString(),
  1619. HasSubstr(
  1620. "Image Operand MinLod can only be used with ImplicitLod opcodes or "
  1621. "together with Image Operand Grad"));
  1622. }
  1623. TEST_F(ValidateImage, ImplicitLodWithGrad) {
  1624. const std::string body = R"(
  1625. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1626. %sampler = OpLoad %type_sampler %uniform_sampler
  1627. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1628. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_hh %f32vec2_hh
  1629. )";
  1630. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1631. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1632. EXPECT_THAT(
  1633. getDiagnosticString(),
  1634. HasSubstr(
  1635. "Image Operand Grad can only be used with ExplicitLod opcodes"));
  1636. }
  1637. TEST_F(ValidateImage, SampleImplicitLodCubeArrayedSuccess) {
  1638. const std::string body = R"(
  1639. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1640. %sampler = OpLoad %type_sampler %uniform_sampler
  1641. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1642. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000
  1643. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias %f32_0_25
  1644. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %f32_0_5
  1645. %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias|MinLod %f32_0_25 %f32_0_5
  1646. )";
  1647. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1648. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1649. }
  1650. TEST_F(ValidateImage, SampleImplicitLodBiasWrongType) {
  1651. const std::string body = R"(
  1652. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1653. %sampler = OpLoad %type_sampler %uniform_sampler
  1654. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1655. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %u32_0
  1656. )";
  1657. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1658. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1659. EXPECT_THAT(getDiagnosticString(),
  1660. HasSubstr("Expected Image Operand Bias to be float scalar"));
  1661. }
  1662. TEST_F(ValidateImage, SampleImplicitLodBiasWrongDim) {
  1663. const std::string body = R"(
  1664. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  1665. %sampler = OpLoad %type_sampler %uniform_sampler
  1666. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  1667. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0
  1668. )";
  1669. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1670. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1671. EXPECT_THAT(getDiagnosticString(),
  1672. HasSubstr("Image Operand Bias requires 'Dim' parameter to be 1D, "
  1673. "2D, 3D or Cube"));
  1674. }
  1675. TEST_F(ValidateImage, SampleExplicitLodGradDxWrongType) {
  1676. const std::string body = R"(
  1677. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1678. %sampler = OpLoad %type_sampler %uniform_sampler
  1679. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1680. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %s32vec3_012 %f32vec3_hhh
  1681. )";
  1682. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1683. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1684. EXPECT_THAT(getDiagnosticString(),
  1685. HasSubstr("Expected both Image Operand Grad ids to be float "
  1686. "scalars or vectors"));
  1687. }
  1688. TEST_F(ValidateImage, SampleExplicitLodGradDyWrongType) {
  1689. const std::string body = R"(
  1690. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1691. %sampler = OpLoad %type_sampler %uniform_sampler
  1692. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1693. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %s32vec3_012
  1694. )";
  1695. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1696. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1697. EXPECT_THAT(getDiagnosticString(),
  1698. HasSubstr("Expected both Image Operand Grad ids to be float "
  1699. "scalars or vectors"));
  1700. }
  1701. TEST_F(ValidateImage, SampleExplicitLodGradDxWrongSize) {
  1702. const std::string body = R"(
  1703. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1704. %sampler = OpLoad %type_sampler %uniform_sampler
  1705. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1706. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec2_00 %f32vec3_hhh
  1707. )";
  1708. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1709. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1710. EXPECT_THAT(
  1711. getDiagnosticString(),
  1712. HasSubstr(
  1713. "Expected Image Operand Grad dx to have 3 components, but given 2"));
  1714. }
  1715. TEST_F(ValidateImage, SampleExplicitLodGradDyWrongSize) {
  1716. const std::string body = R"(
  1717. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1718. %sampler = OpLoad %type_sampler %uniform_sampler
  1719. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1720. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec2_00
  1721. )";
  1722. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1723. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1724. EXPECT_THAT(
  1725. getDiagnosticString(),
  1726. HasSubstr(
  1727. "Expected Image Operand Grad dy to have 3 components, but given 2"));
  1728. }
  1729. TEST_F(ValidateImage, SampleImplicitLodConstOffsetCubeDim) {
  1730. const std::string body = R"(
  1731. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1732. %sampler = OpLoad %type_sampler %uniform_sampler
  1733. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1734. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec3_012
  1735. )";
  1736. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1737. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1738. EXPECT_THAT(
  1739. getDiagnosticString(),
  1740. HasSubstr(
  1741. "Image Operand ConstOffset cannot be used with Cube Image 'Dim'"));
  1742. }
  1743. TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongType) {
  1744. const std::string body = R"(
  1745. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1746. %sampler = OpLoad %type_sampler %uniform_sampler
  1747. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1748. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %f32vec2_00
  1749. )";
  1750. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1751. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1752. EXPECT_THAT(
  1753. getDiagnosticString(),
  1754. HasSubstr(
  1755. "Expected Image Operand ConstOffset to be int scalar or vector"));
  1756. }
  1757. TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongSize) {
  1758. const std::string body = R"(
  1759. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1760. %sampler = OpLoad %type_sampler %uniform_sampler
  1761. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1762. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %s32vec3_012
  1763. )";
  1764. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1765. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1766. EXPECT_THAT(getDiagnosticString(),
  1767. HasSubstr("Expected Image Operand ConstOffset to have 2 "
  1768. "components, but given 3"));
  1769. }
  1770. TEST_F(ValidateImage, SampleImplicitLodConstOffsetNotConst) {
  1771. const std::string body = R"(
  1772. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1773. %sampler = OpLoad %type_sampler %uniform_sampler
  1774. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1775. %offset = OpSNegate %s32vec3 %s32vec3_012
  1776. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %offset
  1777. )";
  1778. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1779. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1780. EXPECT_THAT(
  1781. getDiagnosticString(),
  1782. HasSubstr("Expected Image Operand ConstOffset to be a const object"));
  1783. }
  1784. TEST_F(ValidateImage, SampleImplicitLodOffsetCubeDim) {
  1785. const std::string body = R"(
  1786. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1787. %sampler = OpLoad %type_sampler %uniform_sampler
  1788. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1789. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
  1790. )";
  1791. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1792. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1793. EXPECT_THAT(
  1794. getDiagnosticString(),
  1795. HasSubstr("Image Operand Offset cannot be used with Cube Image 'Dim'"));
  1796. }
  1797. TEST_F(ValidateImage, SampleImplicitLodOffsetWrongType) {
  1798. const std::string body = R"(
  1799. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1800. %sampler = OpLoad %type_sampler %uniform_sampler
  1801. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1802. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %f32vec2_00
  1803. )";
  1804. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1805. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1806. EXPECT_THAT(
  1807. getDiagnosticString(),
  1808. HasSubstr("Expected Image Operand Offset to be int scalar or vector"));
  1809. }
  1810. TEST_F(ValidateImage, SampleImplicitLodOffsetWrongSize) {
  1811. const std::string body = R"(
  1812. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1813. %sampler = OpLoad %type_sampler %uniform_sampler
  1814. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1815. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
  1816. )";
  1817. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1818. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1819. EXPECT_THAT(
  1820. getDiagnosticString(),
  1821. HasSubstr(
  1822. "Expected Image Operand Offset to have 2 components, but given 3"));
  1823. }
  1824. TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongSize) {
  1825. const std::string body = R"(
  1826. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1827. %sampler = OpLoad %type_sampler %uniform_sampler
  1828. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1829. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
  1830. )";
  1831. CompileSuccessfully(
  1832. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  1833. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1834. EXPECT_THAT(getDiagnosticString(), AnyVUID("VUID-RuntimeSpirv-Offset-10213"));
  1835. EXPECT_THAT(getDiagnosticString(),
  1836. HasSubstr("Image Operand Offset can only be used with "
  1837. "OpImage*Gather operations"));
  1838. }
  1839. TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetMaintenance8) {
  1840. const std::string body = R"(
  1841. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1842. %sampler = OpLoad %type_sampler %uniform_sampler
  1843. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1844. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
  1845. )";
  1846. CompileSuccessfully(
  1847. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  1848. spvValidatorOptionsSetAllowOffsetTextureOperand(getValidatorOptions(), true);
  1849. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1850. }
  1851. TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongBeforeLegalization) {
  1852. const std::string body = R"(
  1853. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1854. %sampler = OpLoad %type_sampler %uniform_sampler
  1855. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1856. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
  1857. )";
  1858. CompileSuccessfully(
  1859. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  1860. getValidatorOptions()->before_hlsl_legalization = true;
  1861. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1862. }
  1863. TEST_F(ValidateImage, SampleImplicitLodMoreThanOneOffset) {
  1864. const std::string body = R"(
  1865. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1866. %sampler = OpLoad %type_sampler %uniform_sampler
  1867. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1868. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
  1869. )";
  1870. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1871. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1872. EXPECT_THAT(
  1873. getDiagnosticString(),
  1874. HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
  1875. "cannot be used together"));
  1876. }
  1877. TEST_F(ValidateImage, SampleImplicitLodVulkanMoreThanOneOffset) {
  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. %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
  1883. )";
  1884. CompileSuccessfully(
  1885. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  1886. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1887. EXPECT_THAT(
  1888. getDiagnosticString(),
  1889. HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
  1890. "cannot be used together"));
  1891. }
  1892. TEST_F(ValidateImage, SampleImplicitLodMinLodWrongType) {
  1893. const std::string body = R"(
  1894. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  1895. %sampler = OpLoad %type_sampler %uniform_sampler
  1896. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  1897. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %s32_0
  1898. )";
  1899. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1900. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1901. EXPECT_THAT(getDiagnosticString(),
  1902. HasSubstr("Expected Image Operand MinLod to be float scalar"));
  1903. }
  1904. TEST_F(ValidateImage, SampleImplicitLodMinLodWrongDim) {
  1905. const std::string body = R"(
  1906. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  1907. %sampler = OpLoad %type_sampler %uniform_sampler
  1908. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  1909. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_25
  1910. )";
  1911. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1912. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1913. EXPECT_THAT(getDiagnosticString(),
  1914. HasSubstr("Image Operand MinLod requires 'Dim' parameter to be "
  1915. "1D, 2D, 3D or Cube"));
  1916. }
  1917. TEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) {
  1918. const std::string body = R"(
  1919. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1920. %sampler = OpLoad %type_sampler %uniform_sampler
  1921. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1922. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod %f32_1
  1923. %res3 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
  1924. %res4 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
  1925. %res5 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
  1926. %res7 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
  1927. %res8 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod|NonPrivateTexelKHR %f32_1
  1928. )";
  1929. const std::string extra = R"(
  1930. OpCapability VulkanMemoryModelKHR
  1931. OpExtension "SPV_KHR_vulkan_memory_model"
  1932. )";
  1933. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  1934. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  1935. .c_str());
  1936. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1937. }
  1938. TEST_F(ValidateImage, SampleProjExplicitLodSuccessRect) {
  1939. const std::string body = R"(
  1940. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  1941. %sampler = OpLoad %type_sampler %uniform_sampler
  1942. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  1943. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
  1944. %res2 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
  1945. )";
  1946. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1947. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1948. }
  1949. TEST_F(ValidateImage, SampleProjExplicitLodWrongResultType) {
  1950. const std::string body = R"(
  1951. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1952. %sampler = OpLoad %type_sampler %uniform_sampler
  1953. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1954. %res1 = OpImageSampleProjExplicitLod %f32 %simg %f32vec3_hhh Lod %f32_1
  1955. )";
  1956. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1957. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1958. EXPECT_THAT(getDiagnosticString(),
  1959. HasSubstr("Expected Result Type to be int or float vector type"));
  1960. }
  1961. TEST_F(ValidateImage, SampleProjExplicitLodWrongNumComponentsResultType) {
  1962. const std::string body = R"(
  1963. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1964. %sampler = OpLoad %type_sampler %uniform_sampler
  1965. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  1966. %res1 = OpImageSampleProjExplicitLod %f32vec3 %simg %f32vec3_hhh Lod %f32_1
  1967. )";
  1968. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1969. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1970. EXPECT_THAT(getDiagnosticString(),
  1971. HasSubstr("Expected Result Type to have 4 components"));
  1972. }
  1973. TEST_F(ValidateImage, SampleProjExplicitLodNotSampledImage) {
  1974. const std::string body = R"(
  1975. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1976. %res1 = OpImageSampleProjExplicitLod %f32vec4 %img %f32vec3_hhh Lod %f32_1
  1977. )";
  1978. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1979. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1980. EXPECT_THAT(
  1981. getDiagnosticString(),
  1982. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  1983. }
  1984. TEST_F(ValidateImage, SampleProjExplicitLodMultisampleError) {
  1985. const std::string body = R"(
  1986. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  1987. %sampler = OpLoad %type_sampler %uniform_sampler
  1988. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  1989. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_1 %u32_1
  1990. )";
  1991. CompileSuccessfully(GenerateShaderCode(body).c_str());
  1992. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1993. EXPECT_THAT(getDiagnosticString(),
  1994. HasSubstr("Expected Image 'MS' parameter to be 0"));
  1995. }
  1996. TEST_F(ValidateImage, SampleProjExplicitLodWrongSampledType) {
  1997. const std::string body = R"(
  1998. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  1999. %sampler = OpLoad %type_sampler %uniform_sampler
  2000. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2001. %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
  2002. )";
  2003. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2004. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2005. EXPECT_THAT(getDiagnosticString(),
  2006. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  2007. "Result Type components"));
  2008. }
  2009. TEST_F(ValidateImage, SampleProjExplicitLodVoidSampledType) {
  2010. const std::string body = R"(
  2011. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2012. %sampler = OpLoad %type_sampler %uniform_sampler
  2013. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2014. %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
  2015. )";
  2016. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2017. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2018. }
  2019. TEST_F(ValidateImage, SampleProjExplicitLodWrongCoordinateType) {
  2020. const std::string body = R"(
  2021. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2022. %sampler = OpLoad %type_sampler %uniform_sampler
  2023. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2024. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %img Lod %f32_1
  2025. )";
  2026. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2027. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2028. EXPECT_THAT(getDiagnosticString(),
  2029. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2030. }
  2031. TEST_F(ValidateImage, SampleProjExplicitLodCoordinateSizeTooSmall) {
  2032. const std::string body = R"(
  2033. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2034. %sampler = OpLoad %type_sampler %uniform_sampler
  2035. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2036. %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_1
  2037. )";
  2038. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2039. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2040. EXPECT_THAT(getDiagnosticString(),
  2041. HasSubstr("Expected Coordinate to have at least 3 components, "
  2042. "but given only 2"));
  2043. }
  2044. TEST_F(ValidateImage, SampleProjImplicitLodSuccess) {
  2045. const std::string body = R"(
  2046. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2047. %sampler = OpLoad %type_sampler %uniform_sampler
  2048. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2049. %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh
  2050. %res2 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias %f32_0_25
  2051. %res4 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
  2052. %res5 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
  2053. %res6 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh MinLod %f32_0_5
  2054. %res7 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  2055. %res8 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh NonPrivateTexelKHR
  2056. )";
  2057. const std::string extra = R"(
  2058. OpCapability VulkanMemoryModelKHR
  2059. OpExtension "SPV_KHR_vulkan_memory_model"
  2060. )";
  2061. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2062. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2063. .c_str());
  2064. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2065. }
  2066. TEST_F(ValidateImage, SampleProjImplicitLodWrongResultType) {
  2067. const std::string body = R"(
  2068. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2069. %sampler = OpLoad %type_sampler %uniform_sampler
  2070. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2071. %res1 = OpImageSampleProjImplicitLod %f32 %simg %f32vec3_hhh
  2072. )";
  2073. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2074. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2075. EXPECT_THAT(getDiagnosticString(),
  2076. HasSubstr("Expected Result Type to be int or float vector type"));
  2077. }
  2078. TEST_F(ValidateImage, SampleProjImplicitLodWrongNumComponentsResultType) {
  2079. const std::string body = R"(
  2080. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2081. %sampler = OpLoad %type_sampler %uniform_sampler
  2082. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2083. %res1 = OpImageSampleProjImplicitLod %f32vec3 %simg %f32vec3_hhh
  2084. )";
  2085. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2086. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2087. EXPECT_THAT(getDiagnosticString(),
  2088. HasSubstr("Expected Result Type to have 4 components"));
  2089. }
  2090. TEST_F(ValidateImage, SampleProjImplicitLodNotSampledImage) {
  2091. const std::string body = R"(
  2092. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2093. %res1 = OpImageSampleProjImplicitLod %f32vec4 %img %f32vec3_hhh
  2094. )";
  2095. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2096. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2097. EXPECT_THAT(
  2098. getDiagnosticString(),
  2099. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2100. }
  2101. TEST_F(ValidateImage, SampleProjImplicitLodMultisampleError) {
  2102. const std::string body = R"(
  2103. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2104. %sampler = OpLoad %type_sampler %uniform_sampler
  2105. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2106. %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
  2107. )";
  2108. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2109. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2110. EXPECT_THAT(getDiagnosticString(),
  2111. HasSubstr("Expected Image 'MS' parameter to be 0"));
  2112. }
  2113. TEST_F(ValidateImage, SampleProjImplicitLodWrongSampledType) {
  2114. const std::string body = R"(
  2115. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2116. %sampler = OpLoad %type_sampler %uniform_sampler
  2117. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2118. %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
  2119. )";
  2120. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2121. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2122. EXPECT_THAT(getDiagnosticString(),
  2123. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  2124. "Result Type components"));
  2125. }
  2126. TEST_F(ValidateImage, SampleProjImplicitLodVoidSampledType) {
  2127. const std::string body = R"(
  2128. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2129. %sampler = OpLoad %type_sampler %uniform_sampler
  2130. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2131. %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
  2132. )";
  2133. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2134. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2135. }
  2136. TEST_F(ValidateImage, SampleProjImplicitLodWrongCoordinateType) {
  2137. const std::string body = R"(
  2138. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2139. %sampler = OpLoad %type_sampler %uniform_sampler
  2140. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2141. %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %img
  2142. )";
  2143. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2144. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2145. EXPECT_THAT(getDiagnosticString(),
  2146. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2147. }
  2148. TEST_F(ValidateImage, SampleProjImplicitLodCoordinateSizeTooSmall) {
  2149. const std::string body = R"(
  2150. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2151. %sampler = OpLoad %type_sampler %uniform_sampler
  2152. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2153. %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh
  2154. )";
  2155. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2156. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2157. EXPECT_THAT(getDiagnosticString(),
  2158. HasSubstr("Expected Coordinate to have at least 3 components, "
  2159. "but given only 2"));
  2160. }
  2161. TEST_F(ValidateImage, SampleDrefImplicitLodSuccess) {
  2162. const std::string body = R"(
  2163. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  2164. %sampler = OpLoad %type_sampler %uniform_sampler
  2165. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  2166. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1
  2167. %res2 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
  2168. %res4 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
  2169. %res5 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
  2170. %res6 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
  2171. %res7 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  2172. %res8 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
  2173. )";
  2174. const std::string extra = R"(
  2175. OpCapability VulkanMemoryModelKHR
  2176. OpExtension "SPV_KHR_vulkan_memory_model"
  2177. )";
  2178. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2179. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2180. .c_str());
  2181. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2182. }
  2183. TEST_F(ValidateImage, SampleDrefImplicitLodWrongResultType) {
  2184. const std::string body = R"(
  2185. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2186. %sampler = OpLoad %type_sampler %uniform_sampler
  2187. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2188. %res1 = OpImageSampleDrefImplicitLod %void %simg %f32vec2_hh %u32_1
  2189. )";
  2190. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2191. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2192. EXPECT_THAT(getDiagnosticString(),
  2193. HasSubstr("Expected Result Type to be int or float scalar type"));
  2194. }
  2195. TEST_F(ValidateImage, SampleDrefImplicitLodNotSampledImage) {
  2196. const std::string body = R"(
  2197. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  2198. %res1 = OpImageSampleDrefImplicitLod %u32 %img %f32vec2_hh %u32_1
  2199. )";
  2200. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2201. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2202. EXPECT_THAT(
  2203. getDiagnosticString(),
  2204. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2205. }
  2206. TEST_F(ValidateImage, SampleDrefImplicitLodMultisampleError) {
  2207. const std::string body = R"(
  2208. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2209. %sampler = OpLoad %type_sampler %uniform_sampler
  2210. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2211. %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
  2212. )";
  2213. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2214. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2215. EXPECT_THAT(
  2216. getDiagnosticString(),
  2217. HasSubstr("Dref sampling operation is invalid for multisample image"));
  2218. }
  2219. TEST_F(ValidateImage, SampleDrefImplicitLodWrongSampledType) {
  2220. const std::string body = R"(
  2221. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  2222. %sampler = OpLoad %type_sampler %uniform_sampler
  2223. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  2224. %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_00 %u32_1
  2225. )";
  2226. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2227. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2228. EXPECT_THAT(
  2229. getDiagnosticString(),
  2230. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2231. }
  2232. TEST_F(ValidateImage, SampleDrefImplicitLodVoidSampledType) {
  2233. const std::string body = R"(
  2234. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2235. %sampler = OpLoad %type_sampler %uniform_sampler
  2236. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2237. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %u32_1
  2238. )";
  2239. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2240. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2241. EXPECT_THAT(
  2242. getDiagnosticString(),
  2243. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2244. }
  2245. TEST_F(ValidateImage, SampleDrefImplicitLodWrongCoordinateType) {
  2246. const std::string body = R"(
  2247. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  2248. %sampler = OpLoad %type_sampler %uniform_sampler
  2249. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  2250. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %img %u32_1
  2251. )";
  2252. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2253. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2254. EXPECT_THAT(getDiagnosticString(),
  2255. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2256. }
  2257. TEST_F(ValidateImage, SampleDrefImplicitLodCoordinateSizeTooSmall) {
  2258. const std::string body = R"(
  2259. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2260. %sampler = OpLoad %type_sampler %uniform_sampler
  2261. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2262. %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32_0_5 %f32_0_5
  2263. )";
  2264. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2265. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2266. EXPECT_THAT(getDiagnosticString(),
  2267. HasSubstr("Expected Coordinate to have at least 2 components, "
  2268. "but given only 1"));
  2269. }
  2270. TEST_F(ValidateImage, SampleDrefImplicitLodWrongDrefType) {
  2271. const std::string body = R"(
  2272. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  2273. %sampler = OpLoad %type_sampler %uniform_sampler
  2274. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  2275. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %f64_1
  2276. )";
  2277. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2278. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2279. EXPECT_THAT(getDiagnosticString(),
  2280. HasSubstr("Expected Dref to be of 32-bit float type"));
  2281. }
  2282. TEST_F(ValidateImage, SampleDrefImplicitLodWrongDimVulkan) {
  2283. const std::string body = R"(
  2284. %img = OpLoad %type_image_u32_3d_0001 %uniform_image_u32_3d_0001
  2285. %sampler = OpLoad %type_sampler %uniform_sampler
  2286. %simg = OpSampledImage %type_sampled_image_u32_3d_0001 %img %sampler
  2287. %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_1
  2288. )";
  2289. CompileSuccessfully(
  2290. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  2291. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  2292. EXPECT_THAT(getDiagnosticString(),
  2293. AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
  2294. EXPECT_THAT(getDiagnosticString(),
  2295. HasSubstr("In Vulkan, OpImage*Dref* instructions must not use "
  2296. "images with a 3D Dim"));
  2297. }
  2298. TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) {
  2299. const std::string body = R"(
  2300. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2301. %sampler = OpLoad %type_sampler %uniform_sampler
  2302. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2303. %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod %f32_1
  2304. %res3 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad %f32vec3_hhh %f32vec3_hhh
  2305. %res4 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 ConstOffset %s32vec3_012
  2306. %res5 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Offset %s32vec3_012
  2307. %res7 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad|Offset %f32vec3_hhh %f32vec3_hhh %s32vec3_012
  2308. %res8 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod|NonPrivateTexelKHR %f32_1
  2309. )";
  2310. const std::string extra = R"(
  2311. OpCapability VulkanMemoryModelKHR
  2312. OpExtension "SPV_KHR_vulkan_memory_model"
  2313. )";
  2314. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2315. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2316. .c_str());
  2317. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2318. }
  2319. TEST_F(ValidateImage, SampleDrefExplicitLodWrongResultType) {
  2320. const std::string body = R"(
  2321. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2322. %sampler = OpLoad %type_sampler %uniform_sampler
  2323. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2324. %res1 = OpImageSampleDrefExplicitLod %bool %simg %f32vec3_hhh %s32_1 Lod %f32_1
  2325. )";
  2326. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2327. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2328. EXPECT_THAT(getDiagnosticString(),
  2329. HasSubstr("Expected Result Type to be int or float scalar type"));
  2330. }
  2331. TEST_F(ValidateImage, SampleDrefExplicitLodNotSampledImage) {
  2332. const std::string body = R"(
  2333. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2334. %res1 = OpImageSampleDrefExplicitLod %s32 %img %f32vec3_hhh %s32_1 Lod %f32_1
  2335. )";
  2336. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2337. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2338. EXPECT_THAT(
  2339. getDiagnosticString(),
  2340. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2341. }
  2342. TEST_F(ValidateImage, SampleDrefExplicitLodMultisampleError) {
  2343. const std::string body = R"(
  2344. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2345. %sampler = OpLoad %type_sampler %uniform_sampler
  2346. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2347. %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
  2348. )";
  2349. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2350. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2351. EXPECT_THAT(
  2352. getDiagnosticString(),
  2353. HasSubstr("Dref sampling operation is invalid for multisample image"));
  2354. }
  2355. TEST_F(ValidateImage, SampleDrefExplicitLodWrongSampledType) {
  2356. const std::string body = R"(
  2357. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2358. %sampler = OpLoad %type_sampler %uniform_sampler
  2359. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2360. %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec3_hhh %s32_1 Lod %f32_1
  2361. )";
  2362. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2363. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2364. EXPECT_THAT(
  2365. getDiagnosticString(),
  2366. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2367. }
  2368. TEST_F(ValidateImage, SampleDrefExplicitLodVoidSampledType) {
  2369. const std::string body = R"(
  2370. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2371. %sampler = OpLoad %type_sampler %uniform_sampler
  2372. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2373. %res1 = OpImageSampleDrefExplicitLod %u32 %simg %f32vec2_00 %s32_1 Lod %f32_1
  2374. )";
  2375. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2376. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2377. EXPECT_THAT(
  2378. getDiagnosticString(),
  2379. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2380. }
  2381. TEST_F(ValidateImage, SampleDrefExplicitLodWrongCoordinateType) {
  2382. const std::string body = R"(
  2383. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2384. %sampler = OpLoad %type_sampler %uniform_sampler
  2385. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2386. %res1 = OpImageSampleDrefExplicitLod %s32 %simg %img %s32_1 Lod %f32_1
  2387. )";
  2388. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2389. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2390. EXPECT_THAT(getDiagnosticString(),
  2391. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2392. }
  2393. TEST_F(ValidateImage, SampleDrefExplicitLodCoordinateSizeTooSmall) {
  2394. const std::string body = R"(
  2395. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2396. %sampler = OpLoad %type_sampler %uniform_sampler
  2397. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2398. %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec2_hh %s32_1 Lod %f32_1
  2399. )";
  2400. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2401. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2402. EXPECT_THAT(getDiagnosticString(),
  2403. HasSubstr("Expected Coordinate to have at least 3 components, "
  2404. "but given only 2"));
  2405. }
  2406. TEST_F(ValidateImage, SampleDrefExplicitLodWrongDrefType) {
  2407. const std::string body = R"(
  2408. %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
  2409. %sampler = OpLoad %type_sampler %uniform_sampler
  2410. %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
  2411. %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %u32_1 Lod %f32_1
  2412. )";
  2413. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2414. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2415. EXPECT_THAT(getDiagnosticString(),
  2416. HasSubstr("Expected Dref to be of 32-bit float type"));
  2417. }
  2418. TEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) {
  2419. const std::string body = R"(
  2420. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2421. %sampler = OpLoad %type_sampler %uniform_sampler
  2422. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2423. %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5
  2424. %res2 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias %f32_0_25
  2425. %res4 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 ConstOffset %s32vec2_01
  2426. %res5 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Offset %s32vec2_01
  2427. %res6 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 MinLod %f32_0_5
  2428. %res7 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  2429. %res8 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 NonPrivateTexelKHR
  2430. )";
  2431. const std::string extra = R"(
  2432. OpCapability VulkanMemoryModelKHR
  2433. OpExtension "SPV_KHR_vulkan_memory_model"
  2434. )";
  2435. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2436. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2437. .c_str());
  2438. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2439. }
  2440. TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongResultType) {
  2441. const std::string body = R"(
  2442. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2443. %sampler = OpLoad %type_sampler %uniform_sampler
  2444. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2445. %res1 = OpImageSampleProjDrefImplicitLod %void %simg %f32vec3_hhh %f32_0_5
  2446. )";
  2447. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2448. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2449. EXPECT_THAT(getDiagnosticString(),
  2450. HasSubstr("Expected Result Type to be int or float scalar type"));
  2451. }
  2452. TEST_F(ValidateImage, SampleProjDrefImplicitLodNotSampledImage) {
  2453. const std::string body = R"(
  2454. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2455. %res1 = OpImageSampleProjDrefImplicitLod %f32 %img %f32vec3_hhh %f32_0_5
  2456. )";
  2457. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2458. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2459. EXPECT_THAT(
  2460. getDiagnosticString(),
  2461. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2462. }
  2463. TEST_F(ValidateImage, SampleProjDrefImplicitLodMultisampleError) {
  2464. const std::string body = R"(
  2465. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2466. %sampler = OpLoad %type_sampler %uniform_sampler
  2467. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2468. %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
  2469. )";
  2470. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2471. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2472. EXPECT_THAT(
  2473. getDiagnosticString(),
  2474. HasSubstr("Dref sampling operation is invalid for multisample image"));
  2475. }
  2476. TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongSampledType) {
  2477. const std::string body = R"(
  2478. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2479. %sampler = OpLoad %type_sampler %uniform_sampler
  2480. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2481. %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
  2482. )";
  2483. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2484. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2485. EXPECT_THAT(
  2486. getDiagnosticString(),
  2487. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2488. }
  2489. TEST_F(ValidateImage, SampleProjDrefImplicitLodVoidSampledType) {
  2490. const std::string body = R"(
  2491. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2492. %sampler = OpLoad %type_sampler %uniform_sampler
  2493. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2494. %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
  2495. )";
  2496. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2497. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2498. EXPECT_THAT(
  2499. getDiagnosticString(),
  2500. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2501. }
  2502. TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongCoordinateType) {
  2503. const std::string body = R"(
  2504. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2505. %sampler = OpLoad %type_sampler %uniform_sampler
  2506. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2507. %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %img %f32_0_5
  2508. )";
  2509. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2510. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2511. EXPECT_THAT(getDiagnosticString(),
  2512. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2513. }
  2514. TEST_F(ValidateImage, SampleProjDrefImplicitLodCoordinateSizeTooSmall) {
  2515. const std::string body = R"(
  2516. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2517. %sampler = OpLoad %type_sampler %uniform_sampler
  2518. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2519. %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec2_hh %f32_0_5
  2520. )";
  2521. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2522. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2523. EXPECT_THAT(getDiagnosticString(),
  2524. HasSubstr("Expected Coordinate to have at least 3 components, "
  2525. "but given only 2"));
  2526. }
  2527. TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongDrefType) {
  2528. const std::string body = R"(
  2529. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  2530. %sampler = OpLoad %type_sampler %uniform_sampler
  2531. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  2532. %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32vec4_0000
  2533. )";
  2534. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2535. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2536. EXPECT_THAT(getDiagnosticString(),
  2537. HasSubstr("Expected Dref to be of 32-bit float type"));
  2538. }
  2539. TEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) {
  2540. const std::string body = R"(
  2541. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2542. %sampler = OpLoad %type_sampler %uniform_sampler
  2543. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2544. %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
  2545. %res2 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Grad %f32_0_5 %f32_0_5
  2546. %res3 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 ConstOffset %s32_1
  2547. %res4 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Offset %s32_1
  2548. %res5 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Grad|Offset %f32_0_5 %f32_0_5 %s32_1
  2549. %res6 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod|NonPrivateTexelKHR %f32_1
  2550. )";
  2551. const std::string extra = R"(
  2552. OpCapability VulkanMemoryModelKHR
  2553. OpExtension "SPV_KHR_vulkan_memory_model"
  2554. )";
  2555. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2556. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2557. .c_str());
  2558. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2559. }
  2560. TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongResultType) {
  2561. const std::string body = R"(
  2562. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2563. %sampler = OpLoad %type_sampler %uniform_sampler
  2564. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2565. %res1 = OpImageSampleProjDrefExplicitLod %bool %simg %f32vec2_hh %f32_0_5 Lod %f32_1
  2566. )";
  2567. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2568. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2569. EXPECT_THAT(getDiagnosticString(),
  2570. HasSubstr("Expected Result Type to be int or float scalar type"));
  2571. }
  2572. TEST_F(ValidateImage, SampleProjDrefExplicitLodNotSampledImage) {
  2573. const std::string body = R"(
  2574. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2575. %res1 = OpImageSampleProjDrefExplicitLod %f32 %img %f32vec2_hh %f32_0_5 Lod %f32_1
  2576. )";
  2577. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2578. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2579. EXPECT_THAT(
  2580. getDiagnosticString(),
  2581. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2582. }
  2583. TEST_F(ValidateImage, SampleProjDrefExplicitLodMultisampleError) {
  2584. const std::string body = R"(
  2585. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2586. %sampler = OpLoad %type_sampler %uniform_sampler
  2587. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2588. %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
  2589. )";
  2590. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2591. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2592. EXPECT_THAT(
  2593. getDiagnosticString(),
  2594. HasSubstr("Dref sampling operation is invalid for multisample image"));
  2595. }
  2596. TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongSampledType) {
  2597. const std::string body = R"(
  2598. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2599. %sampler = OpLoad %type_sampler %uniform_sampler
  2600. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2601. %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
  2602. )";
  2603. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2604. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2605. EXPECT_THAT(
  2606. getDiagnosticString(),
  2607. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2608. }
  2609. TEST_F(ValidateImage, SampleProjDrefExplicitLodVoidSampledType) {
  2610. const std::string body = R"(
  2611. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2612. %sampler = OpLoad %type_sampler %uniform_sampler
  2613. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2614. %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec3_hhh %f32_0_5 Lod %f32_1
  2615. )";
  2616. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2617. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2618. EXPECT_THAT(
  2619. getDiagnosticString(),
  2620. HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
  2621. }
  2622. TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongCoordinateType) {
  2623. const std::string body = R"(
  2624. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2625. %sampler = OpLoad %type_sampler %uniform_sampler
  2626. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2627. %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %img %f32_0_5 Lod %f32_1
  2628. )";
  2629. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2630. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2631. EXPECT_THAT(getDiagnosticString(),
  2632. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2633. }
  2634. TEST_F(ValidateImage, SampleProjDrefExplicitLodCoordinateSizeTooSmall) {
  2635. const std::string body = R"(
  2636. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2637. %sampler = OpLoad %type_sampler %uniform_sampler
  2638. %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
  2639. %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32_0_5 %f32_0_5 Lod %f32_1
  2640. )";
  2641. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2642. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2643. EXPECT_THAT(getDiagnosticString(),
  2644. HasSubstr("Expected Coordinate to have at least 2 components, "
  2645. "but given only 1"));
  2646. }
  2647. TEST_F(ValidateImage, FetchSuccess) {
  2648. const std::string body = R"(
  2649. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  2650. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
  2651. %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
  2652. )";
  2653. const std::string extra = R"(
  2654. OpCapability VulkanMemoryModelKHR
  2655. OpExtension "SPV_KHR_vulkan_memory_model"
  2656. )";
  2657. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2658. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2659. .c_str());
  2660. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2661. }
  2662. TEST_F(ValidateImage, FetchMultisampledSuccess) {
  2663. const std::string body = R"(
  2664. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2665. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample %u32_1
  2666. %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample|NonPrivateTexelKHR %u32_1
  2667. )";
  2668. const std::string extra = R"(
  2669. OpCapability VulkanMemoryModelKHR
  2670. OpExtension "SPV_KHR_vulkan_memory_model"
  2671. )";
  2672. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2673. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2674. .c_str());
  2675. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2676. }
  2677. TEST_F(ValidateImage, FetchWrongResultType) {
  2678. const std::string body = R"(
  2679. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2680. %res1 = OpImageFetch %f32 %img %u32vec2_01
  2681. )";
  2682. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2683. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2684. EXPECT_THAT(getDiagnosticString(),
  2685. HasSubstr("Expected Result Type to be int or float vector type"));
  2686. }
  2687. TEST_F(ValidateImage, FetchWrongNumComponentsResultType) {
  2688. const std::string body = R"(
  2689. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2690. %res1 = OpImageFetch %f32vec3 %img %u32vec2_01
  2691. )";
  2692. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2693. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2694. EXPECT_THAT(getDiagnosticString(),
  2695. HasSubstr("Expected Result Type to have 4 components"));
  2696. }
  2697. TEST_F(ValidateImage, FetchNotImage) {
  2698. const std::string body = R"(
  2699. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2700. %sampler = OpLoad %type_sampler %uniform_sampler
  2701. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2702. %res1 = OpImageFetch %f32vec4 %sampler %u32vec2_01
  2703. )";
  2704. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2705. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2706. EXPECT_THAT(getDiagnosticString(),
  2707. HasSubstr("Expected Image to be of type OpTypeImage"));
  2708. }
  2709. TEST_F(ValidateImage, FetchSampledImageDirectly) {
  2710. const std::string body = R"(
  2711. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2712. %sampler = OpLoad %type_sampler %uniform_sampler
  2713. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2714. %res1 = OpImageFetch %f32vec4 %simg %u32vec2_01
  2715. )";
  2716. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2717. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2718. EXPECT_THAT(getDiagnosticString(),
  2719. HasSubstr("OpSampledImage instruction must not appear as operand "
  2720. "for OpImageFetch"));
  2721. }
  2722. TEST_F(ValidateImage, FetchNotSampled) {
  2723. const std::string body = R"(
  2724. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  2725. %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
  2726. )";
  2727. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2728. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2729. EXPECT_THAT(getDiagnosticString(),
  2730. HasSubstr("Expected Image 'Sampled' parameter to be 1"));
  2731. }
  2732. TEST_F(ValidateImage, FetchCube) {
  2733. const std::string body = R"(
  2734. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2735. %res1 = OpImageFetch %f32vec4 %img %u32vec3_012
  2736. )";
  2737. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2738. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2739. EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' cannot be Cube"));
  2740. }
  2741. TEST_F(ValidateImage, FetchWrongSampledType) {
  2742. const std::string body = R"(
  2743. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2744. %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
  2745. )";
  2746. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2747. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2748. EXPECT_THAT(getDiagnosticString(),
  2749. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  2750. "Result Type components"));
  2751. }
  2752. TEST_F(ValidateImage, FetchVoidSampledType) {
  2753. const std::string body = R"(
  2754. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2755. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
  2756. %res2 = OpImageFetch %u32vec4 %img %u32vec2_01
  2757. %res3 = OpImageFetch %s32vec4 %img %u32vec2_01
  2758. )";
  2759. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2760. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2761. }
  2762. TEST_F(ValidateImage, FetchWrongCoordinateType) {
  2763. const std::string body = R"(
  2764. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2765. %res1 = OpImageFetch %f32vec4 %img %f32vec2_00
  2766. )";
  2767. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2768. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2769. EXPECT_THAT(getDiagnosticString(),
  2770. HasSubstr("Expected Coordinate to be int scalar or vector"));
  2771. }
  2772. TEST_F(ValidateImage, FetchCoordinateSizeTooSmall) {
  2773. const std::string body = R"(
  2774. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  2775. %res1 = OpImageFetch %f32vec4 %img %u32_1
  2776. )";
  2777. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2778. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2779. EXPECT_THAT(getDiagnosticString(),
  2780. HasSubstr("Expected Coordinate to have at least 2 components, "
  2781. "but given only 1"));
  2782. }
  2783. TEST_F(ValidateImage, FetchLodNotInt) {
  2784. const std::string body = R"(
  2785. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2786. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Lod %f32_1
  2787. )";
  2788. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2789. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2790. EXPECT_THAT(getDiagnosticString(),
  2791. HasSubstr("Expected Image Operand Lod to be int scalar when used "
  2792. "with OpImageFetch"));
  2793. }
  2794. TEST_F(ValidateImage, FetchMultisampledMissingSample) {
  2795. const std::string body = R"(
  2796. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2797. %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
  2798. )";
  2799. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2800. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions())
  2801. << GenerateShaderCode(body);
  2802. EXPECT_THAT(getDiagnosticString(),
  2803. HasSubstr("Image Operand Sample is required for operation on "
  2804. "multi-sampled image"))
  2805. << getDiagnosticString();
  2806. }
  2807. TEST_F(ValidateImage, GatherSuccess) {
  2808. const std::string body = R"(
  2809. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2810. %sampler = OpLoad %type_sampler %uniform_sampler
  2811. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2812. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1
  2813. %res2 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
  2814. %res3 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
  2815. )";
  2816. const std::string extra = R"(
  2817. OpCapability VulkanMemoryModelKHR
  2818. OpExtension "SPV_KHR_vulkan_memory_model"
  2819. )";
  2820. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  2821. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  2822. .c_str());
  2823. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  2824. }
  2825. TEST_F(ValidateImage, GatherWrongResultType) {
  2826. const std::string body = R"(
  2827. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2828. %sampler = OpLoad %type_sampler %uniform_sampler
  2829. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2830. %res1 = OpImageGather %f32 %simg %f32vec4_0000 %u32_1
  2831. )";
  2832. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2833. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2834. EXPECT_THAT(getDiagnosticString(),
  2835. HasSubstr("Expected Result Type to be int or float vector type"));
  2836. }
  2837. TEST_F(ValidateImage, GatherWrongNumComponentsResultType) {
  2838. const std::string body = R"(
  2839. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2840. %sampler = OpLoad %type_sampler %uniform_sampler
  2841. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2842. %res1 = OpImageGather %f32vec3 %simg %f32vec4_0000 %u32_1
  2843. )";
  2844. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2845. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2846. EXPECT_THAT(getDiagnosticString(),
  2847. HasSubstr("Expected Result Type to have 4 components"));
  2848. }
  2849. TEST_F(ValidateImage, GatherNotSampledImage) {
  2850. const std::string body = R"(
  2851. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2852. %res1 = OpImageGather %f32vec4 %img %f32vec4_0000 %u32_1
  2853. )";
  2854. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2855. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2856. EXPECT_THAT(
  2857. getDiagnosticString(),
  2858. HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
  2859. }
  2860. TEST_F(ValidateImage, GatherMultisampleError) {
  2861. const std::string body = R"(
  2862. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  2863. %sampler = OpLoad %type_sampler %uniform_sampler
  2864. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  2865. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Sample %u32_1
  2866. )";
  2867. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2868. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2869. EXPECT_THAT(getDiagnosticString(),
  2870. HasSubstr("Gather operation is invalid for multisample image"));
  2871. }
  2872. TEST_F(ValidateImage, GatherWrongSampledType) {
  2873. const std::string body = R"(
  2874. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2875. %sampler = OpLoad %type_sampler %uniform_sampler
  2876. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2877. %res1 = OpImageGather %u32vec4 %simg %f32vec4_0000 %u32_1
  2878. )";
  2879. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2880. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2881. EXPECT_THAT(getDiagnosticString(),
  2882. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  2883. "Result Type components"));
  2884. }
  2885. TEST_F(ValidateImage, GatherVoidSampledType) {
  2886. const std::string body = R"(
  2887. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  2888. %sampler = OpLoad %type_sampler %uniform_sampler
  2889. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  2890. %res1 = OpImageGather %u32vec4 %simg %f32vec2_00 %u32_1
  2891. )";
  2892. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2893. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2894. }
  2895. TEST_F(ValidateImage, GatherWrongCoordinateType) {
  2896. const std::string body = R"(
  2897. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2898. %sampler = OpLoad %type_sampler %uniform_sampler
  2899. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2900. %res1 = OpImageGather %f32vec4 %simg %u32vec4_0123 %u32_1
  2901. )";
  2902. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2903. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2904. EXPECT_THAT(getDiagnosticString(),
  2905. HasSubstr("Expected Coordinate to be float scalar or vector"));
  2906. }
  2907. TEST_F(ValidateImage, GatherCoordinateSizeTooSmall) {
  2908. const std::string body = R"(
  2909. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2910. %sampler = OpLoad %type_sampler %uniform_sampler
  2911. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2912. %res1 = OpImageGather %f32vec4 %simg %f32_0_5 %u32_1
  2913. )";
  2914. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2915. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2916. EXPECT_THAT(getDiagnosticString(),
  2917. HasSubstr("Expected Coordinate to have at least 4 components, "
  2918. "but given only 1"));
  2919. }
  2920. TEST_F(ValidateImage, GatherWrongComponentType) {
  2921. const std::string body = R"(
  2922. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2923. %sampler = OpLoad %type_sampler %uniform_sampler
  2924. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2925. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %f32_1
  2926. )";
  2927. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2928. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2929. EXPECT_THAT(getDiagnosticString(),
  2930. HasSubstr("Expected Component to be 32-bit int scalar"));
  2931. }
  2932. TEST_F(ValidateImage, GatherComponentNot32Bit) {
  2933. const std::string body = R"(
  2934. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2935. %sampler = OpLoad %type_sampler %uniform_sampler
  2936. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2937. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u64_0
  2938. )";
  2939. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2940. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2941. EXPECT_THAT(getDiagnosticString(),
  2942. HasSubstr("Expected Component to be 32-bit int scalar"));
  2943. }
  2944. TEST_F(ValidateImage, GatherComponentSuccessVulkan) {
  2945. const std::string body = R"(
  2946. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2947. %sampler = OpLoad %type_sampler %uniform_sampler
  2948. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2949. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_0
  2950. )";
  2951. spv_target_env env = SPV_ENV_VULKAN_1_0;
  2952. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  2953. env);
  2954. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  2955. }
  2956. TEST_F(ValidateImage, GatherComponentNotConstantVulkan) {
  2957. const std::string body = R"(
  2958. %input_u32 = OpLoad %u32 %input_flat_u32
  2959. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2960. %sampler = OpLoad %type_sampler %uniform_sampler
  2961. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2962. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %input_u32
  2963. )";
  2964. spv_target_env env = SPV_ENV_VULKAN_1_0;
  2965. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  2966. env);
  2967. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  2968. EXPECT_THAT(getDiagnosticString(),
  2969. AnyVUID("VUID-StandaloneSpirv-OpImageGather-04664"));
  2970. EXPECT_THAT(getDiagnosticString(),
  2971. HasSubstr("Expected Component Operand to be a const object for "
  2972. "Vulkan environment"));
  2973. }
  2974. TEST_F(ValidateImage, GatherDimCube) {
  2975. const std::string body = R"(
  2976. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  2977. %sampler = OpLoad %type_sampler %uniform_sampler
  2978. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  2979. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
  2980. )";
  2981. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2982. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2983. EXPECT_THAT(
  2984. getDiagnosticString(),
  2985. HasSubstr(
  2986. "Image Operand ConstOffsets cannot be used with Cube Image 'Dim'"));
  2987. }
  2988. TEST_F(ValidateImage, GatherConstOffsetsNotArray) {
  2989. const std::string body = R"(
  2990. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  2991. %sampler = OpLoad %type_sampler %uniform_sampler
  2992. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  2993. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %u32vec4_0123
  2994. )";
  2995. CompileSuccessfully(GenerateShaderCode(body).c_str());
  2996. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2997. EXPECT_THAT(
  2998. getDiagnosticString(),
  2999. HasSubstr(
  3000. "Expected Image Operand ConstOffsets to be an array of size 4"));
  3001. }
  3002. TEST_F(ValidateImage, GatherConstOffsetsArrayWrongSize) {
  3003. const std::string body = R"(
  3004. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3005. %sampler = OpLoad %type_sampler %uniform_sampler
  3006. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3007. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets3x2
  3008. )";
  3009. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3010. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3011. EXPECT_THAT(
  3012. getDiagnosticString(),
  3013. HasSubstr(
  3014. "Expected Image Operand ConstOffsets to be an array of size 4"));
  3015. }
  3016. TEST_F(ValidateImage, GatherConstOffsetsArrayNotVector) {
  3017. const std::string body = R"(
  3018. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3019. %sampler = OpLoad %type_sampler %uniform_sampler
  3020. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3021. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4xu
  3022. )";
  3023. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3024. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3025. EXPECT_THAT(getDiagnosticString(),
  3026. HasSubstr("Expected Image Operand ConstOffsets array components "
  3027. "to be int vectors of size 2"));
  3028. }
  3029. TEST_F(ValidateImage, GatherConstOffsetsArrayVectorWrongSize) {
  3030. const std::string body = R"(
  3031. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3032. %sampler = OpLoad %type_sampler %uniform_sampler
  3033. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3034. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4x3
  3035. )";
  3036. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3037. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3038. EXPECT_THAT(getDiagnosticString(),
  3039. HasSubstr("Expected Image Operand ConstOffsets array components "
  3040. "to be int vectors of size 2"));
  3041. }
  3042. TEST_F(ValidateImage, GatherConstOffsetsArrayNotConst) {
  3043. const std::string body = R"(
  3044. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3045. %sampler = OpLoad %type_sampler %uniform_sampler
  3046. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3047. %offsets = OpUndef %u32vec2arr4
  3048. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %offsets
  3049. )";
  3050. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3051. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3052. EXPECT_THAT(
  3053. getDiagnosticString(),
  3054. HasSubstr("Expected Image Operand ConstOffsets to be a const object"));
  3055. }
  3056. TEST_F(ValidateImage, NotGatherWithConstOffsets) {
  3057. const std::string body = R"(
  3058. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3059. %sampler = OpLoad %type_sampler %uniform_sampler
  3060. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3061. %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffsets %const_offsets
  3062. )";
  3063. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3064. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3065. EXPECT_THAT(
  3066. getDiagnosticString(),
  3067. HasSubstr(
  3068. "Image Operand ConstOffsets can only be used with OpImageGather "
  3069. "and OpImageDrefGather"));
  3070. }
  3071. TEST_F(ValidateImage, DrefGatherSuccess) {
  3072. const std::string body = R"(
  3073. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3074. %sampler = OpLoad %type_sampler %uniform_sampler
  3075. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3076. %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
  3077. %res2 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 ConstOffsets %const_offsets
  3078. %res3 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 NonPrivateTexelKHR
  3079. )";
  3080. const std::string extra = R"(
  3081. OpCapability VulkanMemoryModelKHR
  3082. OpExtension "SPV_KHR_vulkan_memory_model"
  3083. )";
  3084. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  3085. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  3086. .c_str());
  3087. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3088. }
  3089. TEST_F(ValidateImage, DrefGatherMultisampleError) {
  3090. const std::string body = R"(
  3091. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3092. %sampler = OpLoad %type_sampler %uniform_sampler
  3093. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  3094. %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_1 Sample %u32_1
  3095. )";
  3096. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3097. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3098. EXPECT_THAT(getDiagnosticString(),
  3099. HasSubstr("Gather operation is invalid for multisample image"));
  3100. }
  3101. TEST_F(ValidateImage, DrefGatherVoidSampledType) {
  3102. const std::string body = R"(
  3103. %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
  3104. %sampler = OpLoad %type_sampler %uniform_sampler
  3105. %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
  3106. %res1 = OpImageDrefGather %u32vec4 %simg %f32vec2_00 %f32_0_5
  3107. )";
  3108. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3109. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3110. EXPECT_THAT(getDiagnosticString(),
  3111. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  3112. "Result Type components"));
  3113. }
  3114. TEST_F(ValidateImage, DrefGatherWrongDrefType) {
  3115. const std::string body = R"(
  3116. %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
  3117. %sampler = OpLoad %type_sampler %uniform_sampler
  3118. %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
  3119. %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %u32_1
  3120. )";
  3121. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3122. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3123. EXPECT_THAT(getDiagnosticString(),
  3124. HasSubstr("Expected Dref to be of 32-bit float type"));
  3125. }
  3126. TEST_F(ValidateImage, DrefGatherWrongDimVulkan) {
  3127. const std::string body = R"(
  3128. %img = OpLoad %type_image_f32_3d_0001 %uniform_image_f32_3d_0001
  3129. %sampler = OpLoad %type_sampler %uniform_sampler
  3130. %simg = OpSampledImage %type_sampled_image_f32_3d_0001 %img %sampler
  3131. %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
  3132. )";
  3133. CompileSuccessfully(
  3134. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
  3135. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3136. EXPECT_THAT(getDiagnosticString(),
  3137. AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
  3138. EXPECT_THAT(getDiagnosticString(),
  3139. HasSubstr("Expected Image 'Dim' to be 2D, Cube, or Rect"));
  3140. }
  3141. TEST_F(ValidateImage, ReadSuccess1) {
  3142. const std::string body = R"(
  3143. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3144. %res1 = OpImageRead %u32vec4 %img %u32vec2_01
  3145. )";
  3146. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3147. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3148. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3149. }
  3150. TEST_F(ValidateImage, ReadSuccess2) {
  3151. const std::string body = R"(
  3152. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  3153. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  3154. )";
  3155. const std::string extra = "\nOpCapability Image1D\n";
  3156. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3157. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3158. }
  3159. TEST_F(ValidateImage, ReadSuccess3) {
  3160. const std::string body = R"(
  3161. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  3162. %res1 = OpImageRead %f32vec4 %img %u32vec3_012
  3163. )";
  3164. const std::string extra = "\nOpCapability ImageCubeArray\n";
  3165. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3166. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3167. }
  3168. TEST_F(ValidateImage, ReadSuccess4) {
  3169. const std::string body = R"(
  3170. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  3171. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  3172. )";
  3173. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3174. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3175. }
  3176. TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) {
  3177. const std::string body = R"(
  3178. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3179. %res1 = OpImageRead %u32vec4 %img %u32vec2_01
  3180. )";
  3181. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3182. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3183. }
  3184. TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
  3185. const std::string body = R"(
  3186. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3187. %res1 = OpImageRead %u32vec4 %img %u32vec2_01
  3188. )";
  3189. spv_target_env env = SPV_ENV_VULKAN_1_0;
  3190. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  3191. env);
  3192. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  3193. EXPECT_THAT(getDiagnosticString(),
  3194. HasSubstr("Capability StorageImageReadWithoutFormat is required "
  3195. "to read storage image"));
  3196. }
  3197. TEST_F(ValidateImage, ReadNeedCapabilityImage1D) {
  3198. const std::string body = R"(
  3199. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  3200. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  3201. )";
  3202. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3203. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3204. EXPECT_THAT(
  3205. getDiagnosticString(),
  3206. HasSubstr("Capability Image1D is required to access storage image"));
  3207. }
  3208. TEST_F(ValidateImage, ReadNeedCapabilityImageCubeArray) {
  3209. const std::string body = R"(
  3210. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  3211. %res1 = OpImageRead %f32vec4 %img %u32vec3_012
  3212. )";
  3213. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3214. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3215. EXPECT_THAT(
  3216. getDiagnosticString(),
  3217. HasSubstr(
  3218. "Capability ImageCubeArray is required to access storage image"));
  3219. }
  3220. // TODO([email protected]) Disabled until the spec is clarified.
  3221. TEST_F(ValidateImage, DISABLED_ReadWrongResultType) {
  3222. const std::string body = R"(
  3223. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3224. %res1 = OpImageRead %f32 %img %u32vec2_01
  3225. )";
  3226. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3227. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3228. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3229. EXPECT_THAT(getDiagnosticString(),
  3230. HasSubstr("Expected Result Type to be int or float vector type"));
  3231. }
  3232. TEST_F(ValidateImage, ReadScalarResultType_Universal) {
  3233. const std::string body = R"(
  3234. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3235. %res1 = OpImageRead %u32 %img %u32vec2_01
  3236. )";
  3237. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3238. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3239. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
  3240. EXPECT_THAT(getDiagnosticString(), Eq(""));
  3241. }
  3242. TEST_F(ValidateImage, ReadUnusualNumComponentsResultType_Universal) {
  3243. const std::string body = R"(
  3244. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3245. %res1 = OpImageRead %u32vec3 %img %u32vec2_01
  3246. )";
  3247. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3248. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3249. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
  3250. EXPECT_THAT(getDiagnosticString(), Eq(""));
  3251. }
  3252. TEST_F(ValidateImage, ReadWrongNumComponentsResultType_Vulkan) {
  3253. const std::string body = R"(
  3254. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3255. %res1 = OpImageRead %u32vec3 %img %u32vec2_01
  3256. )";
  3257. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3258. CompileSuccessfully(
  3259. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_VULKAN_1_0)
  3260. .c_str());
  3261. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3262. EXPECT_THAT(getDiagnosticString(),
  3263. AnyVUID("VUID-StandaloneSpirv-Result-04780"));
  3264. EXPECT_THAT(getDiagnosticString(),
  3265. HasSubstr("Expected Result Type to have 4 components"));
  3266. }
  3267. TEST_F(ValidateImage, ReadNotImage) {
  3268. const std::string body = R"(
  3269. %sampler = OpLoad %type_sampler %uniform_sampler
  3270. %res1 = OpImageRead %f32vec4 %sampler %u32vec2_01
  3271. )";
  3272. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3273. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3274. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3275. EXPECT_THAT(getDiagnosticString(),
  3276. HasSubstr("Expected Image to be of type OpTypeImage"));
  3277. }
  3278. TEST_F(ValidateImage, ReadImageSampled) {
  3279. const std::string body = R"(
  3280. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3281. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  3282. )";
  3283. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3284. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3285. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3286. EXPECT_THAT(getDiagnosticString(),
  3287. HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
  3288. }
  3289. TEST_F(ValidateImage, ReadWrongSampledType) {
  3290. const std::string body = R"(
  3291. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3292. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  3293. )";
  3294. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3295. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3296. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3297. EXPECT_THAT(getDiagnosticString(),
  3298. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  3299. "Result Type components"));
  3300. }
  3301. TEST_F(ValidateImage, ReadVoidSampledType) {
  3302. const std::string body = R"(
  3303. %img = OpLoad %type_image_void_2d_0002 %uniform_image_void_2d_0002
  3304. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  3305. %res2 = OpImageRead %u32vec4 %img %u32vec2_01
  3306. %res3 = OpImageRead %s32vec4 %img %u32vec2_01
  3307. )";
  3308. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3309. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3310. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3311. }
  3312. TEST_F(ValidateImage, ReadWrongCoordinateType) {
  3313. const std::string body = R"(
  3314. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3315. %res1 = OpImageRead %u32vec4 %img %f32vec2_00
  3316. )";
  3317. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3318. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3319. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3320. EXPECT_THAT(getDiagnosticString(),
  3321. HasSubstr("Expected Coordinate to be int scalar or vector"));
  3322. }
  3323. TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) {
  3324. const std::string body = R"(
  3325. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3326. %res1 = OpImageRead %u32vec4 %img %u32_1
  3327. )";
  3328. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  3329. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3330. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3331. EXPECT_THAT(getDiagnosticString(),
  3332. HasSubstr("Expected Coordinate to have at least 2 components, "
  3333. "but given only 1"));
  3334. }
  3335. TEST_F(ValidateImage, WriteSuccess1) {
  3336. const std::string body = R"(
  3337. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3338. OpImageWrite %img %u32vec2_01 %u32vec4_0123
  3339. )";
  3340. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3341. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3342. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3343. }
  3344. TEST_F(ValidateImage, WriteSuccess2) {
  3345. const std::string body = R"(
  3346. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  3347. OpImageWrite %img %u32_1 %f32vec4_0000
  3348. )";
  3349. const std::string extra = "\nOpCapability Image1D\n";
  3350. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3351. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3352. }
  3353. TEST_F(ValidateImage, WriteSuccess3) {
  3354. const std::string body = R"(
  3355. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  3356. OpImageWrite %img %u32vec3_012 %f32vec4_0000
  3357. )";
  3358. const std::string extra = "\nOpCapability ImageCubeArray\n";
  3359. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3360. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3361. }
  3362. TEST_F(ValidateImage, WriteSuccess4) {
  3363. const std::string body = R"(
  3364. %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
  3365. OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
  3366. )";
  3367. const std::string extra = R"(
  3368. OpCapability StorageImageWriteWithoutFormat
  3369. OpCapability StorageImageMultisample
  3370. )";
  3371. const std::string declarations = R"(
  3372. %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
  3373. %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
  3374. %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
  3375. )";
  3376. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  3377. SPV_ENV_UNIVERSAL_1_0, "GLSL450",
  3378. declarations)
  3379. .c_str());
  3380. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3381. }
  3382. TEST_F(ValidateImage, WriteSubpassData) {
  3383. const std::string body = R"(
  3384. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  3385. OpImageWrite %img %u32vec2_01 %f32vec4_0000
  3386. )";
  3387. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3388. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3389. EXPECT_THAT(getDiagnosticString(),
  3390. HasSubstr("Image 'Dim' cannot be SubpassData"));
  3391. }
  3392. TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
  3393. const std::string body = R"(
  3394. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3395. OpImageWrite %img %u32vec2_01 %u32vec4_0123
  3396. )";
  3397. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3398. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3399. }
  3400. TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
  3401. const std::string body = R"(
  3402. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3403. OpImageWrite %img %u32vec2_01 %u32vec4_0123
  3404. )";
  3405. spv_target_env env = SPV_ENV_VULKAN_1_0;
  3406. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  3407. env);
  3408. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  3409. EXPECT_THAT(
  3410. getDiagnosticString(),
  3411. HasSubstr(
  3412. "Capability StorageImageWriteWithoutFormat is required to write to "
  3413. "storage image"));
  3414. }
  3415. TEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
  3416. const std::string body = R"(
  3417. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  3418. OpImageWrite %img %u32vec2_01 %f32vec4_0000
  3419. )";
  3420. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3421. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3422. EXPECT_THAT(getDiagnosticString(),
  3423. HasSubstr("Capability Image1D is required to access storage "
  3424. "image"));
  3425. }
  3426. TEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
  3427. const std::string body = R"(
  3428. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  3429. OpImageWrite %img %u32vec3_012 %f32vec4_0000
  3430. )";
  3431. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3432. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3433. EXPECT_THAT(
  3434. getDiagnosticString(),
  3435. HasSubstr(
  3436. "Capability ImageCubeArray is required to access storage image"));
  3437. }
  3438. TEST_F(ValidateImage, WriteNotImage) {
  3439. const std::string body = R"(
  3440. %sampler = OpLoad %type_sampler %uniform_sampler
  3441. OpImageWrite %sampler %u32vec2_01 %f32vec4_0000
  3442. )";
  3443. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3444. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3445. EXPECT_THAT(getDiagnosticString(),
  3446. HasSubstr("Expected Image to be of type OpTypeImage"));
  3447. }
  3448. TEST_F(ValidateImage, WriteImageSampled) {
  3449. const std::string body = R"(
  3450. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3451. OpImageWrite %img %u32vec2_01 %f32vec4_0000
  3452. )";
  3453. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3454. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3455. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3456. EXPECT_THAT(getDiagnosticString(),
  3457. HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
  3458. }
  3459. TEST_F(ValidateImage, WriteWrongCoordinateType) {
  3460. const std::string body = R"(
  3461. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3462. OpImageWrite %img %f32vec2_00 %u32vec4_0123
  3463. )";
  3464. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3465. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3466. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3467. EXPECT_THAT(getDiagnosticString(),
  3468. HasSubstr("Expected Coordinate to be int scalar or vector"));
  3469. }
  3470. TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
  3471. const std::string body = R"(
  3472. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3473. OpImageWrite %img %u32_1 %u32vec4_0123
  3474. )";
  3475. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3476. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3477. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3478. EXPECT_THAT(getDiagnosticString(),
  3479. HasSubstr("Expected Coordinate to have at least 2 components, "
  3480. "but given only 1"));
  3481. }
  3482. TEST_F(ValidateImage, WriteTexelScalarSuccess) {
  3483. const std::string body = R"(
  3484. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3485. OpImageWrite %img %u32vec2_01 %u32_2
  3486. )";
  3487. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3488. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3489. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3490. }
  3491. TEST_F(ValidateImage, WriteTexelWrongType) {
  3492. const std::string body = R"(
  3493. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3494. OpImageWrite %img %u32vec2_01 %img
  3495. )";
  3496. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3497. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3498. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3499. EXPECT_THAT(getDiagnosticString(),
  3500. HasSubstr("Expected Texel to be int or float vector or scalar"));
  3501. }
  3502. TEST_F(ValidateImage, WriteTexelNonNumericalType) {
  3503. const std::string body = R"(
  3504. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3505. OpImageWrite %img %u32vec2_01 %boolvec4_tttt
  3506. )";
  3507. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3508. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3509. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3510. EXPECT_THAT(getDiagnosticString(),
  3511. HasSubstr("Expected Texel to be int or float vector or scalar"));
  3512. }
  3513. TEST_F(ValidateImage, WriteTexelWrongComponentType) {
  3514. const std::string body = R"(
  3515. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  3516. OpImageWrite %img %u32vec2_01 %f32vec4_0000
  3517. )";
  3518. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3519. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3520. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3521. EXPECT_THAT(
  3522. getDiagnosticString(),
  3523. HasSubstr(
  3524. "Expected Image 'Sampled Type' to be the same as Texel components"));
  3525. }
  3526. TEST_F(ValidateImage, WriteSampleNotInteger) {
  3527. const std::string body = R"(
  3528. %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
  3529. OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
  3530. )";
  3531. const std::string extra = R"(
  3532. OpCapability StorageImageWriteWithoutFormat
  3533. OpCapability StorageImageMultisample
  3534. )";
  3535. const std::string declarations = R"(
  3536. %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
  3537. %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
  3538. %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
  3539. )";
  3540. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  3541. SPV_ENV_UNIVERSAL_1_0, "GLSL450",
  3542. declarations)
  3543. .c_str());
  3544. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3545. EXPECT_THAT(getDiagnosticString(),
  3546. HasSubstr("Expected Image Operand Sample to be int scalar"));
  3547. }
  3548. TEST_F(ValidateImage, WriteSampleNotMultisampled) {
  3549. const std::string body = R"(
  3550. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  3551. OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
  3552. )";
  3553. const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
  3554. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  3555. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3556. EXPECT_THAT(
  3557. getDiagnosticString(),
  3558. HasSubstr("Image Operand Sample requires non-zero 'MS' parameter"));
  3559. }
  3560. TEST_F(ValidateImage, SampleWrongOpcode) {
  3561. const std::string body = R"(
  3562. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3563. %sampler = OpLoad %type_sampler %uniform_sampler
  3564. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  3565. %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Sample %u32_1
  3566. )";
  3567. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3568. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3569. EXPECT_THAT(getDiagnosticString(),
  3570. HasSubstr("Sampling operation is invalid for multisample image"));
  3571. }
  3572. TEST_F(ValidateImage, SampleImageToImageSuccess) {
  3573. const std::string body = R"(
  3574. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3575. %sampler = OpLoad %type_sampler %uniform_sampler
  3576. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3577. %img2 = OpImage %type_image_f32_2d_0001 %simg
  3578. )";
  3579. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3580. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3581. }
  3582. TEST_F(ValidateImage, SampleImageToImageWrongResultType) {
  3583. const std::string body = R"(
  3584. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3585. %sampler = OpLoad %type_sampler %uniform_sampler
  3586. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3587. %img2 = OpImage %type_sampled_image_f32_2d_0001 %simg
  3588. )";
  3589. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3590. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3591. EXPECT_THAT(getDiagnosticString(),
  3592. HasSubstr("Expected Result Type to be OpTypeImage"));
  3593. }
  3594. TEST_F(ValidateImage, SampleImageToImageNotSampledImage) {
  3595. const std::string body = R"(
  3596. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3597. %img2 = OpImage %type_image_f32_2d_0001 %img
  3598. )";
  3599. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3600. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3601. EXPECT_THAT(
  3602. getDiagnosticString(),
  3603. HasSubstr("Expected Sample Image to be of type OpTypeSampleImage"));
  3604. }
  3605. TEST_F(ValidateImage, SampleImageToImageNotTheSameImageType) {
  3606. const std::string body = R"(
  3607. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3608. %sampler = OpLoad %type_sampler %uniform_sampler
  3609. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3610. %img2 = OpImage %type_image_f32_2d_0002 %simg
  3611. )";
  3612. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3613. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3614. EXPECT_THAT(getDiagnosticString(),
  3615. HasSubstr("Expected Sample Image image type to be equal to "
  3616. "Result Type"));
  3617. }
  3618. TEST_F(ValidateImage, QueryFormatSuccess) {
  3619. const std::string body = R"(
  3620. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3621. %res1 = OpImageQueryFormat %u32 %img
  3622. )";
  3623. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3624. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3625. }
  3626. TEST_F(ValidateImage, QueryFormatWrongResultType) {
  3627. const std::string body = R"(
  3628. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3629. %res1 = OpImageQueryFormat %bool %img
  3630. )";
  3631. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3632. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3633. EXPECT_THAT(getDiagnosticString(),
  3634. HasSubstr("Expected Result Type to be int scalar type"));
  3635. }
  3636. TEST_F(ValidateImage, QueryFormatNotImage) {
  3637. const std::string body = R"(
  3638. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3639. %sampler = OpLoad %type_sampler %uniform_sampler
  3640. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3641. %res1 = OpImageQueryFormat %u32 %sampler
  3642. )";
  3643. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3644. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3645. EXPECT_THAT(getDiagnosticString(),
  3646. HasSubstr("Expected operand to be of type OpTypeImage"));
  3647. }
  3648. TEST_F(ValidateImage, QueryOrderSuccess) {
  3649. const std::string body = R"(
  3650. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3651. %res1 = OpImageQueryOrder %u32 %img
  3652. )";
  3653. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3654. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3655. }
  3656. TEST_F(ValidateImage, QueryOrderWrongResultType) {
  3657. const std::string body = R"(
  3658. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3659. %res1 = OpImageQueryOrder %bool %img
  3660. )";
  3661. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3662. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3663. EXPECT_THAT(getDiagnosticString(),
  3664. HasSubstr("Expected Result Type to be int scalar type"));
  3665. }
  3666. TEST_F(ValidateImage, QueryOrderNotImage) {
  3667. const std::string body = R"(
  3668. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3669. %sampler = OpLoad %type_sampler %uniform_sampler
  3670. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3671. %res1 = OpImageQueryOrder %u32 %sampler
  3672. )";
  3673. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3674. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3675. EXPECT_THAT(getDiagnosticString(),
  3676. HasSubstr("Expected operand to be of type OpTypeImage"));
  3677. }
  3678. TEST_F(ValidateImage, QuerySizeLodSuccess) {
  3679. const std::string body = R"(
  3680. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3681. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
  3682. )";
  3683. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3684. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3685. }
  3686. TEST_F(ValidateImage, QuerySizeLodWrongResultType) {
  3687. const std::string body = R"(
  3688. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3689. %res1 = OpImageQuerySizeLod %f32vec2 %img %u32_1
  3690. )";
  3691. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3692. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3693. EXPECT_THAT(
  3694. getDiagnosticString(),
  3695. HasSubstr("Expected Result Type to be int scalar or vector type"));
  3696. }
  3697. TEST_F(ValidateImage, QuerySizeLodResultTypeWrongSize) {
  3698. const std::string body = R"(
  3699. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3700. %res1 = OpImageQuerySizeLod %u32 %img %u32_1
  3701. )";
  3702. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3703. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3704. EXPECT_THAT(getDiagnosticString(),
  3705. HasSubstr("Result Type has 1 components, but 2 expected"));
  3706. }
  3707. TEST_F(ValidateImage, QuerySizeLodNotImage) {
  3708. const std::string body = R"(
  3709. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3710. %sampler = OpLoad %type_sampler %uniform_sampler
  3711. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3712. %res1 = OpImageQuerySizeLod %u32vec2 %sampler %u32_1
  3713. )";
  3714. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3715. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3716. EXPECT_THAT(getDiagnosticString(),
  3717. HasSubstr("Expected Image to be of type OpTypeImage"));
  3718. }
  3719. TEST_F(ValidateImage, QuerySizeLodSampledImageDirectly) {
  3720. const std::string body = R"(
  3721. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3722. %sampler = OpLoad %type_sampler %uniform_sampler
  3723. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3724. %res1 = OpImageQuerySizeLod %u32vec2 %simg %u32_1
  3725. )";
  3726. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3727. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3728. EXPECT_THAT(getDiagnosticString(),
  3729. HasSubstr("OpSampledImage instruction must not appear as operand "
  3730. "for OpImageQuerySizeLod"));
  3731. }
  3732. TEST_F(ValidateImage, QuerySizeLodMultisampledError) {
  3733. const std::string body = R"(
  3734. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3735. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
  3736. )";
  3737. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3738. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3739. EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 0"));
  3740. }
  3741. TEST_F(ValidateImage, QuerySizeLodNonSampledUniversalSuccess) {
  3742. const std::string body = R"(
  3743. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  3744. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
  3745. )";
  3746. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3747. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3748. EXPECT_EQ(getDiagnosticString(), "");
  3749. }
  3750. TEST_F(ValidateImage, QuerySizeLodVulkanNonSampledError) {
  3751. // Create a whole shader module. Avoid Vulkan incompatibility with
  3752. // SampledRrect images inserted by helper function GenerateShaderCode.
  3753. const std::string body = R"(
  3754. OpCapability Shader
  3755. OpCapability ImageQuery
  3756. OpMemoryModel Logical Simple
  3757. OpEntryPoint Fragment %main "main"
  3758. OpExecutionMode %main OriginUpperLeft
  3759. %f32 = OpTypeFloat 32
  3760. %u32 = OpTypeInt 32 0
  3761. %u32_0 = OpConstant %u32 0
  3762. %u32vec2 = OpTypeVector %u32 2
  3763. %void = OpTypeVoid
  3764. %voidfn = OpTypeFunction %void
  3765. ; Test with a storage image.
  3766. %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  3767. %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
  3768. %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
  3769. %main = OpFunction %void None %voidfn
  3770. %entry = OpLabel
  3771. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  3772. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_0
  3773. OpReturn
  3774. OpFunctionEnd
  3775. )";
  3776. CompileSuccessfully(body.c_str());
  3777. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  3778. EXPECT_THAT(getDiagnosticString(),
  3779. AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
  3780. EXPECT_THAT(
  3781. getDiagnosticString(),
  3782. HasSubstr(
  3783. "OpImageQuerySizeLod must only consume an \"Image\" operand whose "
  3784. "type has its \"Sampled\" operand set to 1"));
  3785. }
  3786. TEST_F(ValidateImage, QuerySizeLodWrongImageDim) {
  3787. const std::string body = R"(
  3788. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  3789. %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
  3790. )";
  3791. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3792. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3793. EXPECT_THAT(getDiagnosticString(),
  3794. HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
  3795. }
  3796. TEST_F(ValidateImage, QuerySizeLodWrongLodType) {
  3797. const std::string body = R"(
  3798. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3799. %res1 = OpImageQuerySizeLod %u32vec2 %img %f32_0
  3800. )";
  3801. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3802. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3803. EXPECT_THAT(getDiagnosticString(),
  3804. HasSubstr("Expected Level of Detail to be int scalar"));
  3805. }
  3806. TEST_F(ValidateImage, QuerySizeSuccess) {
  3807. const std::string body = R"(
  3808. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3809. %res1 = OpImageQuerySize %u32vec2 %img
  3810. )";
  3811. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3812. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3813. }
  3814. TEST_F(ValidateImage, QuerySizeWrongResultType) {
  3815. const std::string body = R"(
  3816. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3817. %res1 = OpImageQuerySize %f32vec2 %img
  3818. )";
  3819. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3820. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3821. EXPECT_THAT(
  3822. getDiagnosticString(),
  3823. HasSubstr("Expected Result Type to be int scalar or vector type"));
  3824. }
  3825. TEST_F(ValidateImage, QuerySizeNotImage) {
  3826. const std::string body = R"(
  3827. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3828. %sampler = OpLoad %type_sampler %uniform_sampler
  3829. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  3830. %res1 = OpImageQuerySize %u32vec2 %sampler
  3831. )";
  3832. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3833. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3834. EXPECT_THAT(getDiagnosticString(),
  3835. HasSubstr("Expected Image to be of type OpTypeImage"));
  3836. }
  3837. TEST_F(ValidateImage, QuerySizeSampledImageDirectly) {
  3838. const std::string body = R"(
  3839. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  3840. %sampler = OpLoad %type_sampler %uniform_sampler
  3841. %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
  3842. %res1 = OpImageQuerySize %u32vec2 %simg
  3843. )";
  3844. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3845. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3846. EXPECT_THAT(getDiagnosticString(),
  3847. HasSubstr("OpSampledImage instruction must not appear as operand "
  3848. "for OpImageQuerySize"));
  3849. }
  3850. TEST_F(ValidateImage, QuerySizeDimSubpassDataBad) {
  3851. const std::string body = R"(
  3852. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  3853. %res1 = OpImageQuerySize %u32vec2 %img
  3854. )";
  3855. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3856. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3857. EXPECT_THAT(
  3858. getDiagnosticString(),
  3859. HasSubstr("Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"));
  3860. }
  3861. TEST_F(ValidateImage, QuerySizeWrongSampling) {
  3862. const std::string body = R"(
  3863. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3864. %res1 = OpImageQuerySize %u32vec2 %img
  3865. )";
  3866. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3867. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3868. EXPECT_THAT(
  3869. getDiagnosticString(),
  3870. HasSubstr("Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"));
  3871. }
  3872. TEST_F(ValidateImage, QuerySizeWrongNumberOfComponents) {
  3873. const std::string body = R"(
  3874. %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
  3875. %res1 = OpImageQuerySize %u32vec2 %img
  3876. )";
  3877. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3878. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3879. EXPECT_THAT(getDiagnosticString(),
  3880. HasSubstr("Result Type has 2 components, but 4 expected"));
  3881. }
  3882. TEST_F(ValidateImage, QueryLodSuccessKernel) {
  3883. const std::string body = R"(
  3884. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3885. %sampler = OpLoad %type_sampler %uniform_sampler
  3886. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3887. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3888. %res2 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
  3889. )";
  3890. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3891. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3892. }
  3893. TEST_F(ValidateImage, QueryLodSuccessShader) {
  3894. const std::string body = R"(
  3895. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3896. %sampler = OpLoad %type_sampler %uniform_sampler
  3897. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3898. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3899. )";
  3900. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3901. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3902. }
  3903. TEST_F(ValidateImage, QueryLodWrongResultType) {
  3904. const std::string body = R"(
  3905. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3906. %sampler = OpLoad %type_sampler %uniform_sampler
  3907. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3908. %res1 = OpImageQueryLod %u32vec2 %simg %f32vec2_hh
  3909. )";
  3910. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3911. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3912. EXPECT_THAT(getDiagnosticString(),
  3913. HasSubstr("Expected Result Type to be float vector type"));
  3914. }
  3915. TEST_F(ValidateImage, QueryLodResultTypeWrongSize) {
  3916. const std::string body = R"(
  3917. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3918. %sampler = OpLoad %type_sampler %uniform_sampler
  3919. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3920. %res1 = OpImageQueryLod %f32vec3 %simg %f32vec2_hh
  3921. )";
  3922. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3923. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3924. EXPECT_THAT(getDiagnosticString(),
  3925. HasSubstr("Expected Result Type to have 2 components"));
  3926. }
  3927. TEST_F(ValidateImage, QueryLodNotSampledImage) {
  3928. const std::string body = R"(
  3929. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3930. %res1 = OpImageQueryLod %f32vec2 %img %f32vec2_hh
  3931. )";
  3932. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3933. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3934. EXPECT_THAT(
  3935. getDiagnosticString(),
  3936. HasSubstr("Expected Image operand to be of type OpTypeSampledImage"));
  3937. }
  3938. TEST_F(ValidateImage, QueryLodWrongDim) {
  3939. const std::string body = R"(
  3940. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  3941. %sampler = OpLoad %type_sampler %uniform_sampler
  3942. %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
  3943. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  3944. )";
  3945. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3946. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3947. EXPECT_THAT(getDiagnosticString(),
  3948. HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
  3949. }
  3950. TEST_F(ValidateImage, QueryLodWrongCoordinateType) {
  3951. const std::string body = R"(
  3952. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3953. %sampler = OpLoad %type_sampler %uniform_sampler
  3954. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3955. %res1 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
  3956. )";
  3957. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3958. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3959. EXPECT_THAT(getDiagnosticString(),
  3960. HasSubstr("Expected Coordinate to be float scalar or vector"));
  3961. }
  3962. TEST_F(ValidateImage, QueryLodCoordinateSizeTooSmall) {
  3963. const std::string body = R"(
  3964. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3965. %sampler = OpLoad %type_sampler %uniform_sampler
  3966. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3967. %res1 = OpImageQueryLod %f32vec2 %simg %f32_0
  3968. )";
  3969. CompileSuccessfully(GenerateShaderCode(body).c_str());
  3970. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3971. EXPECT_THAT(getDiagnosticString(),
  3972. HasSubstr("Expected Coordinate to have at least 2 components, "
  3973. "but given only 1"));
  3974. }
  3975. TEST_F(ValidateImage, QueryLevelsSuccess) {
  3976. const std::string body = R"(
  3977. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3978. %res1 = OpImageQueryLevels %u32 %img
  3979. )";
  3980. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3981. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3982. }
  3983. TEST_F(ValidateImage, QueryLevelsWrongResultType) {
  3984. const std::string body = R"(
  3985. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3986. %res1 = OpImageQueryLevels %f32 %img
  3987. )";
  3988. CompileSuccessfully(GenerateKernelCode(body).c_str());
  3989. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3990. EXPECT_THAT(getDiagnosticString(),
  3991. HasSubstr("Expected Result Type to be int scalar type"));
  3992. }
  3993. TEST_F(ValidateImage, QueryLevelsNotImage) {
  3994. const std::string body = R"(
  3995. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  3996. %sampler = OpLoad %type_sampler %uniform_sampler
  3997. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  3998. %res1 = OpImageQueryLevels %u32 %sampler
  3999. )";
  4000. CompileSuccessfully(GenerateKernelCode(body).c_str());
  4001. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4002. EXPECT_THAT(getDiagnosticString(),
  4003. HasSubstr("Expected Image to be of type OpTypeImage"));
  4004. }
  4005. TEST_F(ValidateImage, QueryLevelsSampledImageDirectly) {
  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 = OpImageQueryLevels %u32 %simg
  4011. )";
  4012. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4013. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4014. EXPECT_THAT(getDiagnosticString(),
  4015. HasSubstr("OpSampledImage instruction must not appear as operand "
  4016. "for OpImageQueryLevels"));
  4017. }
  4018. TEST_F(ValidateImage, QueryLevelsWrongDim) {
  4019. const std::string body = R"(
  4020. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4021. %res1 = OpImageQueryLevels %u32 %img
  4022. )";
  4023. CompileSuccessfully(GenerateKernelCode(body).c_str());
  4024. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4025. EXPECT_THAT(getDiagnosticString(),
  4026. HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
  4027. }
  4028. TEST_F(ValidateImage, QuerySizeLevelsNonSampledUniversalSuccess) {
  4029. const std::string body = R"(
  4030. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4031. %res1 = OpImageQueryLevels %u32 %img
  4032. )";
  4033. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4034. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4035. EXPECT_EQ(getDiagnosticString(), "");
  4036. }
  4037. TEST_F(ValidateImage, QuerySizeLevelsVulkanNonSampledError) {
  4038. // Create a whole shader module. Avoid Vulkan incompatibility with
  4039. // SampledRrect images inserted by helper function GenerateShaderCode.
  4040. const std::string body = R"(
  4041. OpCapability Shader
  4042. OpCapability ImageQuery
  4043. OpMemoryModel Logical Simple
  4044. OpEntryPoint Fragment %main "main"
  4045. OpExecutionMode %main OriginUpperLeft
  4046. %f32 = OpTypeFloat 32
  4047. %u32 = OpTypeInt 32 0
  4048. %void = OpTypeVoid
  4049. %voidfn = OpTypeFunction %void
  4050. ; Test with a storage image.
  4051. %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  4052. %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
  4053. %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
  4054. %main = OpFunction %void None %voidfn
  4055. %entry = OpLabel
  4056. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4057. %res1 = OpImageQueryLevels %u32 %img
  4058. OpReturn
  4059. OpFunctionEnd
  4060. )";
  4061. CompileSuccessfully(body.c_str());
  4062. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4063. EXPECT_THAT(getDiagnosticString(),
  4064. AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
  4065. EXPECT_THAT(
  4066. getDiagnosticString(),
  4067. HasSubstr("OpImageQueryLevels must only consume an \"Image\" operand "
  4068. "whose type has its \"Sampled\" operand set to 1"));
  4069. }
  4070. TEST_F(ValidateImage, QuerySamplesSuccess) {
  4071. const std::string body = R"(
  4072. %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
  4073. %res1 = OpImageQuerySamples %u32 %img
  4074. )";
  4075. CompileSuccessfully(GenerateKernelCode(body).c_str());
  4076. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4077. }
  4078. TEST_F(ValidateImage, QuerySamplesNot2D) {
  4079. const std::string body = R"(
  4080. %img = OpLoad %type_image_f32_3d_0011 %uniform_image_f32_3d_0011
  4081. %res1 = OpImageQuerySamples %u32 %img
  4082. )";
  4083. CompileSuccessfully(GenerateKernelCode(body).c_str());
  4084. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4085. EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' must be 2D"));
  4086. }
  4087. TEST_F(ValidateImage, QuerySamplesNotMultisampled) {
  4088. const std::string body = R"(
  4089. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4090. %res1 = OpImageQuerySamples %u32 %img
  4091. )";
  4092. CompileSuccessfully(GenerateKernelCode(body).c_str());
  4093. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4094. EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 1"));
  4095. }
  4096. TEST_F(ValidateImage, QueryLodWrongExecutionModel) {
  4097. const std::string body = R"(
  4098. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4099. %sampler = OpLoad %type_sampler %uniform_sampler
  4100. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4101. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  4102. )";
  4103. CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
  4104. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4105. EXPECT_THAT(
  4106. getDiagnosticString(),
  4107. HasSubstr(
  4108. "OpImageQueryLod requires Fragment, GLCompute, MeshEXT or TaskEXT "
  4109. "execution model"));
  4110. }
  4111. TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
  4112. const std::string body = R"(
  4113. %call_ret = OpFunctionCall %void %my_func
  4114. OpReturn
  4115. OpFunctionEnd
  4116. %my_func = OpFunction %void None %func
  4117. %my_func_entry = OpLabel
  4118. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4119. %sampler = OpLoad %type_sampler %uniform_sampler
  4120. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4121. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  4122. )";
  4123. CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
  4124. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4125. EXPECT_THAT(
  4126. getDiagnosticString(),
  4127. HasSubstr(
  4128. "OpImageQueryLod requires Fragment, GLCompute, MeshEXT or TaskEXT "
  4129. "execution model"));
  4130. }
  4131. TEST_F(ValidateImage, QueryLodComputeShaderDerivatives) {
  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 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  4137. )";
  4138. const std::string extra = R"(
  4139. OpCapability ComputeDerivativeGroupLinearKHR
  4140. OpExtension "SPV_KHR_compute_shader_derivatives"
  4141. )";
  4142. const std::string mode = R"(
  4143. OpExecutionMode %main LocalSize 8 8 1
  4144. OpExecutionMode %main DerivativeGroupLinearKHR
  4145. )";
  4146. CompileSuccessfully(
  4147. GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
  4148. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4149. }
  4150. TEST_F(ValidateImage, QueryLodUniversalSuccess) {
  4151. // Create a whole shader module. Avoid Vulkan incompatibility with
  4152. // SampledRrect images inserted by helper function GenerateShaderCode.
  4153. const std::string body = R"(
  4154. OpCapability Shader
  4155. OpCapability ImageQuery
  4156. OpMemoryModel Logical Simple
  4157. OpEntryPoint Fragment %main "main"
  4158. OpExecutionMode %main OriginUpperLeft
  4159. OpDecorate %uniform_image_f32_2d_0000 DescriptorSet 0
  4160. OpDecorate %uniform_image_f32_2d_0000 Binding 0
  4161. OpDecorate %sampler DescriptorSet 0
  4162. OpDecorate %sampler Binding 1
  4163. %f32 = OpTypeFloat 32
  4164. %f32vec2 = OpTypeVector %f32 2
  4165. %f32vec2_null = OpConstantNull %f32vec2
  4166. %u32 = OpTypeInt 32 0
  4167. %u32vec2 = OpTypeVector %u32 2
  4168. %void = OpTypeVoid
  4169. %voidfn = OpTypeFunction %void
  4170. ; Test with an image with sampled = 0
  4171. %type_image_f32_2d_0000 = OpTypeImage %f32 2D 0 0 0 0 Rgba32f
  4172. %ptr_image_f32_2d_0000 = OpTypePointer UniformConstant %type_image_f32_2d_0000
  4173. %uniform_image_f32_2d_0000 = OpVariable %ptr_image_f32_2d_0000 UniformConstant
  4174. %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0000
  4175. %sampler_ty = OpTypeSampler
  4176. %ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
  4177. %sampler = OpVariable %ptr_sampler_ty UniformConstant
  4178. %main = OpFunction %void None %voidfn
  4179. %entry = OpLabel
  4180. %img = OpLoad %type_image_f32_2d_0000 %uniform_image_f32_2d_0000
  4181. %s = OpLoad %sampler_ty %sampler
  4182. %simg = OpSampledImage %sampled_image_ty %img %s
  4183. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
  4184. OpReturn
  4185. OpFunctionEnd
  4186. )";
  4187. CompileSuccessfully(body.c_str());
  4188. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4189. }
  4190. TEST_F(ValidateImage, QueryLodVulkanNonSampledError) {
  4191. // Create a whole shader module. Avoid Vulkan incompatibility with
  4192. // SampledRrect images inserted by helper function GenerateShaderCode.
  4193. const std::string body = R"(
  4194. OpCapability Shader
  4195. OpCapability ImageQuery
  4196. OpMemoryModel Logical Simple
  4197. OpEntryPoint Fragment %main "main"
  4198. OpExecutionMode %main OriginUpperLeft
  4199. OpDecorate %sampled_image DescriptorSet 0
  4200. OpDecorate %sampled_image Binding 0
  4201. %f32 = OpTypeFloat 32
  4202. %f32vec2 = OpTypeVector %f32 2
  4203. %f32vec2_null = OpConstantNull %f32vec2
  4204. %u32 = OpTypeInt 32 0
  4205. %u32vec2 = OpTypeVector %u32 2
  4206. %void = OpTypeVoid
  4207. %voidfn = OpTypeFunction %void
  4208. ; Test with an image with Sampled = 2
  4209. ; In Vulkan it Sampled must be 1 or 2, checked in another part of the
  4210. ; validation flow.
  4211. %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
  4212. ; Expect to fail here.
  4213. %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0002
  4214. %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
  4215. %sampled_image = OpVariable %ptr_sampled_image_ty UniformConstant
  4216. %main = OpFunction %void None %voidfn
  4217. %entry = OpLabel
  4218. %simg = OpLoad %sampled_image_ty %sampled_image
  4219. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
  4220. OpReturn
  4221. OpFunctionEnd
  4222. )";
  4223. CompileSuccessfully(body.c_str());
  4224. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4225. EXPECT_THAT(getDiagnosticString(),
  4226. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
  4227. EXPECT_THAT(getDiagnosticString(),
  4228. HasSubstr("Sampled image type requires an image type with "
  4229. "\"Sampled\" operand set to 0 or 1"));
  4230. }
  4231. TEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) {
  4232. const std::string body = R"(
  4233. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4234. %sampler = OpLoad %type_sampler %uniform_sampler
  4235. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4236. %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
  4237. )";
  4238. const std::string extra = R"(
  4239. OpCapability ComputeDerivativeGroupLinearKHR
  4240. OpExtension "SPV_KHR_compute_shader_derivatives"
  4241. )";
  4242. const std::string mode = R"(
  4243. OpExecutionMode %main LocalSize 8 8 1
  4244. )";
  4245. CompileSuccessfully(
  4246. GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
  4247. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4248. EXPECT_THAT(getDiagnosticString(),
  4249. HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsKHR or "
  4250. "DerivativeGroupLinearKHR execution mode for "
  4251. "GLCompute, MeshEXT or TaskEXT execution model"));
  4252. }
  4253. TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
  4254. const std::string body = R"(
  4255. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4256. %sampler = OpLoad %type_sampler %uniform_sampler
  4257. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4258. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
  4259. )";
  4260. CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
  4261. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4262. EXPECT_THAT(getDiagnosticString(),
  4263. HasSubstr("ImplicitLod instructions require Fragment, "
  4264. "GLCompute, MeshEXT or TaskEXT execution model"));
  4265. }
  4266. TEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) {
  4267. const std::string body = R"(
  4268. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4269. %sampler = OpLoad %type_sampler %uniform_sampler
  4270. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4271. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
  4272. )";
  4273. const std::string extra = R"(
  4274. OpCapability ComputeDerivativeGroupLinearKHR
  4275. OpExtension "SPV_KHR_compute_shader_derivatives"
  4276. )";
  4277. const std::string mode = R"(
  4278. OpExecutionMode %main LocalSize 8 8 1
  4279. OpExecutionMode %main DerivativeGroupLinearKHR
  4280. )";
  4281. CompileSuccessfully(
  4282. GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
  4283. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4284. }
  4285. TEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) {
  4286. const std::string body = R"(
  4287. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4288. %sampler = OpLoad %type_sampler %uniform_sampler
  4289. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4290. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
  4291. )";
  4292. const std::string extra = R"(
  4293. OpCapability ComputeDerivativeGroupLinearKHR
  4294. OpExtension "SPV_KHR_compute_shader_derivatives"
  4295. )";
  4296. const std::string mode = R"(
  4297. OpExecutionMode %main LocalSize 8 8 1
  4298. )";
  4299. CompileSuccessfully(
  4300. GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
  4301. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4302. EXPECT_THAT(
  4303. getDiagnosticString(),
  4304. HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsKHR or "
  4305. "DerivativeGroupLinearKHR execution mode for GLCompute, "
  4306. "MeshEXT or TaskEXT execution model"));
  4307. }
  4308. TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
  4309. const std::string body = R"(
  4310. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  4311. %res1 = OpImageRead %f32vec4 %img %u32vec2_01
  4312. )";
  4313. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4314. CompileSuccessfully(GenerateShaderCode(body, extra, "Vertex").c_str());
  4315. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4316. EXPECT_THAT(getDiagnosticString(),
  4317. HasSubstr("Dim SubpassData requires Fragment execution model"));
  4318. }
  4319. TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
  4320. const std::string body = R"(
  4321. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4322. %sampler = OpLoad %type_sampler %uniform_sampler
  4323. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4324. %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh
  4325. %res2 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Bias %f32_0_25
  4326. %res4 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
  4327. %res5 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
  4328. %res6 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
  4329. %res7 = OpImageSparseSampleImplicitLod %struct_u64_f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  4330. %res8 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
  4331. )";
  4332. const std::string extra = R"(
  4333. OpCapability VulkanMemoryModelKHR
  4334. OpExtension "SPV_KHR_vulkan_memory_model"
  4335. )";
  4336. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4337. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4338. .c_str());
  4339. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4340. }
  4341. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotStruct) {
  4342. const std::string body = R"(
  4343. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4344. %sampler = OpLoad %type_sampler %uniform_sampler
  4345. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4346. %res1 = OpImageSparseSampleImplicitLod %f32 %simg %f32vec2_hh
  4347. )";
  4348. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4349. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4350. EXPECT_THAT(getDiagnosticString(),
  4351. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4352. }
  4353. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers1) {
  4354. const std::string body = R"(
  4355. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4356. %sampler = OpLoad %type_sampler %uniform_sampler
  4357. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4358. %res1 = OpImageSparseSampleImplicitLod %struct_u32 %simg %f32vec2_hh
  4359. )";
  4360. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4361. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4362. EXPECT_THAT(getDiagnosticString(),
  4363. HasSubstr("Expected Result Type to be a struct containing an int "
  4364. "scalar and a texel"));
  4365. }
  4366. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers2) {
  4367. const std::string body = R"(
  4368. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4369. %sampler = OpLoad %type_sampler %uniform_sampler
  4370. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4371. %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4_u32 %simg %f32vec2_hh
  4372. )";
  4373. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4374. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4375. EXPECT_THAT(getDiagnosticString(),
  4376. HasSubstr("Expected Result Type to be a struct containing an "
  4377. "int scalar and a texel"));
  4378. }
  4379. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeFirstMemberNotInt) {
  4380. const std::string body = R"(
  4381. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4382. %sampler = OpLoad %type_sampler %uniform_sampler
  4383. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4384. %res1 = OpImageSparseSampleImplicitLod %struct_f32_f32vec4 %simg %f32vec2_hh
  4385. )";
  4386. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4387. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4388. EXPECT_THAT(getDiagnosticString(),
  4389. HasSubstr("Expected Result Type to be a struct containing an "
  4390. "int scalar and a texel"));
  4391. }
  4392. TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeTexelNotVector) {
  4393. const std::string body = R"(
  4394. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4395. %sampler = OpLoad %type_sampler %uniform_sampler
  4396. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4397. %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32 %simg %f32vec2_hh
  4398. )";
  4399. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4400. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4401. EXPECT_THAT(getDiagnosticString(),
  4402. HasSubstr("Expected Result Type's second member to be int or "
  4403. "float vector type"));
  4404. }
  4405. TEST_F(ValidateImage, SparseSampleImplicitLodWrongNumComponentsTexel) {
  4406. const std::string body = R"(
  4407. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4408. %sampler = OpLoad %type_sampler %uniform_sampler
  4409. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4410. %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec3 %simg %f32vec2_hh
  4411. )";
  4412. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4413. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4414. EXPECT_THAT(getDiagnosticString(),
  4415. HasSubstr("Expected Result Type's second member to have 4 "
  4416. "components"));
  4417. }
  4418. TEST_F(ValidateImage, SparseSampleImplicitLodWrongComponentTypeTexel) {
  4419. const std::string body = R"(
  4420. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4421. %sampler = OpLoad %type_sampler %uniform_sampler
  4422. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4423. %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32vec4 %simg %f32vec2_hh
  4424. )";
  4425. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4426. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4427. EXPECT_THAT(getDiagnosticString(),
  4428. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4429. "Result Type's second member components"));
  4430. }
  4431. TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
  4432. const std::string body = R"(
  4433. %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
  4434. %sampler = OpLoad %type_sampler %uniform_sampler
  4435. %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
  4436. %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
  4437. %res2 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
  4438. %res4 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
  4439. %res5 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
  4440. %res6 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
  4441. %res7 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
  4442. %res8 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
  4443. )";
  4444. const std::string extra = R"(
  4445. OpCapability VulkanMemoryModelKHR
  4446. OpExtension "SPV_KHR_vulkan_memory_model"
  4447. )";
  4448. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4449. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4450. .c_str());
  4451. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4452. }
  4453. TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotStruct) {
  4454. const std::string body = R"(
  4455. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4456. %sampler = OpLoad %type_sampler %uniform_sampler
  4457. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4458. %res1 = OpImageSparseSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1
  4459. )";
  4460. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4461. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4462. EXPECT_THAT(getDiagnosticString(),
  4463. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4464. }
  4465. TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers1) {
  4466. const std::string body = R"(
  4467. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4468. %sampler = OpLoad %type_sampler %uniform_sampler
  4469. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4470. %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32 %simg %f32vec2_hh %f32_1
  4471. )";
  4472. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4473. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4474. EXPECT_THAT(
  4475. getDiagnosticString(),
  4476. HasSubstr("Expected Result Type to be a struct containing an int scalar "
  4477. "and a texel"));
  4478. }
  4479. TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers2) {
  4480. const std::string body = R"(
  4481. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4482. %sampler = OpLoad %type_sampler %uniform_sampler
  4483. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4484. %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_f32_u32 %simg %f32vec2_hh %f32_1
  4485. )";
  4486. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4487. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4488. EXPECT_THAT(
  4489. getDiagnosticString(),
  4490. HasSubstr("Expected Result Type to be a struct containing an int scalar "
  4491. "and a texel"));
  4492. }
  4493. TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt) {
  4494. const std::string body = R"(
  4495. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4496. %sampler = OpLoad %type_sampler %uniform_sampler
  4497. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4498. %res1 = OpImageSparseSampleDrefImplicitLod %struct_f32_f32 %simg %f32vec2_hh %f32_1
  4499. )";
  4500. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4501. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4502. EXPECT_THAT(
  4503. getDiagnosticString(),
  4504. HasSubstr("Expected Result Type to be a struct containing an int scalar "
  4505. "and a texel"));
  4506. }
  4507. TEST_F(ValidateImage, SparseSampleDrefImplicitLodDifferentSampledType) {
  4508. const std::string body = R"(
  4509. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4510. %sampler = OpLoad %type_sampler %uniform_sampler
  4511. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4512. %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
  4513. )";
  4514. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4515. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4516. EXPECT_THAT(getDiagnosticString(),
  4517. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4518. "Result Type's second member"));
  4519. }
  4520. TEST_F(ValidateImage, SparseFetchSuccess) {
  4521. const std::string body = R"(
  4522. %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
  4523. %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
  4524. %res2 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
  4525. )";
  4526. const std::string extra = R"(
  4527. OpCapability VulkanMemoryModelKHR
  4528. OpExtension "SPV_KHR_vulkan_memory_model"
  4529. )";
  4530. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4531. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4532. .c_str());
  4533. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4534. }
  4535. TEST_F(ValidateImage, SparseFetchResultTypeNotStruct) {
  4536. const std::string body = R"(
  4537. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4538. %res1 = OpImageSparseFetch %f32 %img %u32vec2_01
  4539. )";
  4540. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4541. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4542. EXPECT_THAT(getDiagnosticString(),
  4543. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4544. }
  4545. TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers1) {
  4546. const std::string body = R"(
  4547. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4548. %res1 = OpImageSparseFetch %struct_u32 %img %u32vec2_01
  4549. )";
  4550. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4551. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4552. EXPECT_THAT(getDiagnosticString(),
  4553. HasSubstr("Expected Result Type to be a struct containing an "
  4554. "int scalar and a texel"));
  4555. }
  4556. TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers2) {
  4557. const std::string body = R"(
  4558. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4559. %res1 = OpImageSparseFetch %struct_u32_f32vec4_u32 %img %u32vec2_01
  4560. )";
  4561. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4562. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4563. EXPECT_THAT(getDiagnosticString(),
  4564. HasSubstr("Expected Result Type to be a struct containing an "
  4565. "int scalar and a texel"));
  4566. }
  4567. TEST_F(ValidateImage, SparseFetchResultTypeFirstMemberNotInt) {
  4568. const std::string body = R"(
  4569. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4570. %res1 = OpImageSparseFetch %struct_f32_f32vec4 %img %u32vec2_01
  4571. )";
  4572. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4573. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4574. EXPECT_THAT(getDiagnosticString(),
  4575. HasSubstr("Expected Result Type to be a struct containing an "
  4576. "int scalar and a texel"));
  4577. }
  4578. TEST_F(ValidateImage, SparseFetchResultTypeTexelNotVector) {
  4579. const std::string body = R"(
  4580. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4581. %res1 = OpImageSparseFetch %struct_u32_u32 %img %u32vec2_01
  4582. )";
  4583. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4584. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4585. EXPECT_THAT(getDiagnosticString(),
  4586. HasSubstr("Expected Result Type's second member to be int or "
  4587. "float vector type"));
  4588. }
  4589. TEST_F(ValidateImage, SparseFetchWrongNumComponentsTexel) {
  4590. const std::string body = R"(
  4591. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4592. %res1 = OpImageSparseFetch %struct_u32_f32vec3 %img %u32vec2_01
  4593. )";
  4594. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4595. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4596. EXPECT_THAT(getDiagnosticString(),
  4597. HasSubstr("Expected Result Type's second member to have 4 "
  4598. "components"));
  4599. }
  4600. TEST_F(ValidateImage, SparseFetchWrongComponentTypeTexel) {
  4601. const std::string body = R"(
  4602. %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
  4603. %res1 = OpImageSparseFetch %struct_u32_u32vec4 %img %u32vec2_01
  4604. )";
  4605. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4606. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4607. EXPECT_THAT(getDiagnosticString(),
  4608. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4609. "Result Type's second member components"));
  4610. }
  4611. TEST_F(ValidateImage, SparseReadSuccess) {
  4612. const std::string body = R"(
  4613. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4614. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
  4615. )";
  4616. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4617. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4618. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4619. }
  4620. TEST_F(ValidateImage, SparseReadResultTypeNotStruct) {
  4621. const std::string body = R"(
  4622. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4623. %res1 = OpImageSparseRead %f32 %img %u32vec2_01
  4624. )";
  4625. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4626. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4627. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4628. EXPECT_THAT(getDiagnosticString(),
  4629. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4630. }
  4631. TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers1) {
  4632. const std::string body = R"(
  4633. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4634. %res1 = OpImageSparseRead %struct_u32 %img %u32vec2_01
  4635. )";
  4636. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4637. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4638. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4639. EXPECT_THAT(getDiagnosticString(),
  4640. HasSubstr("Expected Result Type to be a struct containing an "
  4641. "int scalar and a texel"));
  4642. }
  4643. TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers2) {
  4644. const std::string body = R"(
  4645. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4646. %res1 = OpImageSparseRead %struct_u32_f32vec4_u32 %img %u32vec2_01
  4647. )";
  4648. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4649. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4650. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4651. EXPECT_THAT(getDiagnosticString(),
  4652. HasSubstr("Expected Result Type to be a struct containing an "
  4653. "int scalar and a texel"));
  4654. }
  4655. TEST_F(ValidateImage, SparseReadResultTypeFirstMemberNotInt) {
  4656. const std::string body = R"(
  4657. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4658. %res1 = OpImageSparseRead %struct_f32_f32vec4 %img %u32vec2_01
  4659. )";
  4660. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4661. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4662. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4663. EXPECT_THAT(getDiagnosticString(),
  4664. HasSubstr("Expected Result Type to be a struct containing an "
  4665. "int scalar and a texel"));
  4666. }
  4667. TEST_F(ValidateImage, SparseReadResultTypeTexelWrongType) {
  4668. const std::string body = R"(
  4669. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4670. %res1 = OpImageSparseRead %struct_u32_u32arr4 %img %u32vec2_01
  4671. )";
  4672. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4673. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4674. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4675. EXPECT_THAT(getDiagnosticString(),
  4676. HasSubstr("Expected Result Type's second member to be int or "
  4677. "float scalar or vector type"));
  4678. }
  4679. TEST_F(ValidateImage, SparseReadWrongComponentTypeTexel) {
  4680. const std::string body = R"(
  4681. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4682. %res1 = OpImageSparseRead %struct_u32_u32vec4 %img %u32vec2_01
  4683. )";
  4684. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4685. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  4686. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4687. EXPECT_THAT(getDiagnosticString(),
  4688. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4689. "Result Type's second member components"));
  4690. }
  4691. TEST_F(ValidateImage, SparseReadSubpassDataNotAllowed) {
  4692. const std::string body = R"(
  4693. %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
  4694. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
  4695. )";
  4696. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  4697. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment").c_str());
  4698. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4699. EXPECT_THAT(
  4700. getDiagnosticString(),
  4701. HasSubstr("Image Dim SubpassData cannot be used with ImageSparseRead"));
  4702. }
  4703. TEST_F(ValidateImage, SparseGatherSuccess) {
  4704. const std::string body = R"(
  4705. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4706. %sampler = OpLoad %type_sampler %uniform_sampler
  4707. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4708. %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1
  4709. %res2 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
  4710. )";
  4711. const std::string extra = R"(
  4712. OpCapability VulkanMemoryModelKHR
  4713. OpExtension "SPV_KHR_vulkan_memory_model"
  4714. )";
  4715. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4716. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4717. .c_str());
  4718. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4719. }
  4720. TEST_F(ValidateImage, SparseGatherResultTypeNotStruct) {
  4721. const std::string body = R"(
  4722. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4723. %sampler = OpLoad %type_sampler %uniform_sampler
  4724. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4725. %res1 = OpImageSparseGather %f32 %simg %f32vec2_hh %u32_1
  4726. )";
  4727. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4728. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4729. EXPECT_THAT(getDiagnosticString(),
  4730. HasSubstr("Expected Result Type to be OpTypeStruct"));
  4731. }
  4732. TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers1) {
  4733. const std::string body = R"(
  4734. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4735. %sampler = OpLoad %type_sampler %uniform_sampler
  4736. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4737. %res1 = OpImageSparseGather %struct_u32 %simg %f32vec2_hh %u32_1
  4738. )";
  4739. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4740. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4741. EXPECT_THAT(getDiagnosticString(),
  4742. HasSubstr("Expected Result Type to be a struct containing an int "
  4743. "scalar and a texel"));
  4744. }
  4745. TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers2) {
  4746. const std::string body = R"(
  4747. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4748. %sampler = OpLoad %type_sampler %uniform_sampler
  4749. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4750. %res1 = OpImageSparseGather %struct_u32_f32vec4_u32 %simg %f32vec2_hh %u32_1
  4751. )";
  4752. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4753. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4754. EXPECT_THAT(getDiagnosticString(),
  4755. HasSubstr("Expected Result Type to be a struct containing an int "
  4756. "scalar and a texel"));
  4757. }
  4758. TEST_F(ValidateImage, SparseGatherResultTypeFirstMemberNotInt) {
  4759. const std::string body = R"(
  4760. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4761. %sampler = OpLoad %type_sampler %uniform_sampler
  4762. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4763. %res1 = OpImageSparseGather %struct_f32_f32vec4 %simg %f32vec2_hh %u32_1
  4764. )";
  4765. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4766. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4767. EXPECT_THAT(getDiagnosticString(),
  4768. HasSubstr("Expected Result Type to be a struct containing an "
  4769. "int scalar and a texel"));
  4770. }
  4771. TEST_F(ValidateImage, SparseGatherResultTypeTexelNotVector) {
  4772. const std::string body = R"(
  4773. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4774. %sampler = OpLoad %type_sampler %uniform_sampler
  4775. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4776. %res1 = OpImageSparseGather %struct_u32_u32 %simg %f32vec2_hh %u32_1
  4777. )";
  4778. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4779. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4780. EXPECT_THAT(getDiagnosticString(),
  4781. HasSubstr("Expected Result Type's second member to be int or "
  4782. "float vector type"));
  4783. }
  4784. TEST_F(ValidateImage, SparseGatherWrongNumComponentsTexel) {
  4785. const std::string body = R"(
  4786. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4787. %sampler = OpLoad %type_sampler %uniform_sampler
  4788. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4789. %res1 = OpImageSparseGather %struct_u32_f32vec3 %simg %f32vec2_hh %u32_1
  4790. )";
  4791. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4792. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4793. EXPECT_THAT(getDiagnosticString(),
  4794. HasSubstr("Expected Result Type's second member to have 4 "
  4795. "components"));
  4796. }
  4797. TEST_F(ValidateImage, SparseGatherWrongComponentTypeTexel) {
  4798. const std::string body = R"(
  4799. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4800. %sampler = OpLoad %type_sampler %uniform_sampler
  4801. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4802. %res1 = OpImageSparseGather %struct_u32_u32vec4 %simg %f32vec2_hh %u32_1
  4803. )";
  4804. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4805. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4806. EXPECT_THAT(getDiagnosticString(),
  4807. HasSubstr("Expected Image 'Sampled Type' to be the same as "
  4808. "Result Type's second member components"));
  4809. }
  4810. TEST_F(ValidateImage, SparseTexelsResidentSuccess) {
  4811. const std::string body = R"(
  4812. %res1 = OpImageSparseTexelsResident %bool %u32_1
  4813. )";
  4814. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4815. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4816. }
  4817. TEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) {
  4818. const std::string body = R"(
  4819. %res1 = OpImageSparseTexelsResident %u32 %u32_1
  4820. )";
  4821. CompileSuccessfully(GenerateShaderCode(body).c_str());
  4822. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4823. EXPECT_THAT(getDiagnosticString(),
  4824. HasSubstr("Expected Result Type to be bool scalar type"));
  4825. }
  4826. TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageRead) {
  4827. const std::string body = R"(
  4828. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4829. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
  4830. )";
  4831. const std::string extra = R"(
  4832. OpCapability StorageImageReadWithoutFormat
  4833. OpCapability VulkanMemoryModelKHR
  4834. OpExtension "SPV_KHR_vulkan_memory_model"
  4835. )";
  4836. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4837. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4838. .c_str());
  4839. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4840. }
  4841. TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageSparseRead) {
  4842. const std::string body = R"(
  4843. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  4844. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
  4845. )";
  4846. const std::string extra = R"(
  4847. OpCapability StorageImageReadWithoutFormat
  4848. OpCapability VulkanMemoryModelKHR
  4849. OpExtension "SPV_KHR_vulkan_memory_model"
  4850. )";
  4851. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4852. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4853. .c_str());
  4854. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4855. }
  4856. TEST_F(ValidateImage, MakeTexelVisibleKHRFailureOpcode) {
  4857. const std::string body = R"(
  4858. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4859. %sampler = OpLoad %type_sampler %uniform_sampler
  4860. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4861. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
  4862. )";
  4863. const std::string extra = R"(
  4864. OpCapability StorageImageReadWithoutFormat
  4865. OpCapability VulkanMemoryModelKHR
  4866. OpExtension "SPV_KHR_vulkan_memory_model"
  4867. )";
  4868. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4869. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4870. .c_str());
  4871. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4872. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4873. EXPECT_THAT(
  4874. getDiagnosticString(),
  4875. HasSubstr("Image Operand MakeTexelVisibleKHR can only be used with "
  4876. "OpImageRead or OpImageSparseRead: OpImageSampleImplicitLod"));
  4877. }
  4878. TEST_F(ValidateImage, MakeTexelVisibleKHRFailureMissingNonPrivate) {
  4879. const std::string body = R"(
  4880. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4881. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR %u32_1
  4882. )";
  4883. const std::string extra = R"(
  4884. OpCapability StorageImageReadWithoutFormat
  4885. OpCapability VulkanMemoryModelKHR
  4886. OpExtension "SPV_KHR_vulkan_memory_model"
  4887. )";
  4888. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4889. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4890. .c_str());
  4891. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4892. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4893. EXPECT_THAT(getDiagnosticString(),
  4894. HasSubstr("Image Operand MakeTexelVisibleKHR requires "
  4895. "NonPrivateTexelKHR is also specified: OpImageRead"));
  4896. }
  4897. TEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) {
  4898. const std::string body = R"(
  4899. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4900. OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
  4901. )";
  4902. const std::string extra = R"(
  4903. OpCapability StorageImageWriteWithoutFormat
  4904. OpCapability VulkanMemoryModelKHR
  4905. OpExtension "SPV_KHR_vulkan_memory_model"
  4906. )";
  4907. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4908. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4909. .c_str());
  4910. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4911. }
  4912. TEST_F(ValidateImage, MakeTexelAvailableKHRFailureOpcode) {
  4913. const std::string body = R"(
  4914. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  4915. %sampler = OpLoad %type_sampler %uniform_sampler
  4916. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  4917. %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
  4918. )";
  4919. const std::string extra = R"(
  4920. OpCapability StorageImageReadWithoutFormat
  4921. OpCapability VulkanMemoryModelKHR
  4922. OpExtension "SPV_KHR_vulkan_memory_model"
  4923. )";
  4924. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4925. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4926. .c_str());
  4927. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4928. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4929. EXPECT_THAT(getDiagnosticString(),
  4930. HasSubstr("Image Operand MakeTexelAvailableKHR can only be used "
  4931. "with OpImageWrite: OpImageSampleImplicitLod"));
  4932. }
  4933. TEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) {
  4934. const std::string body = R"(
  4935. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4936. OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
  4937. )";
  4938. const std::string extra = R"(
  4939. OpCapability StorageImageWriteWithoutFormat
  4940. OpCapability VulkanMemoryModelKHR
  4941. OpExtension "SPV_KHR_vulkan_memory_model"
  4942. )";
  4943. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4944. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4945. .c_str());
  4946. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4947. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4948. EXPECT_THAT(getDiagnosticString(),
  4949. HasSubstr("Image Operand MakeTexelAvailableKHR requires "
  4950. "NonPrivateTexelKHR is also specified: OpImageWrite"));
  4951. }
  4952. TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) {
  4953. const std::string body = R"(
  4954. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4955. OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
  4956. )";
  4957. const std::string extra = R"(
  4958. OpCapability StorageImageWriteWithoutFormat
  4959. OpCapability VulkanMemoryModelKHR
  4960. OpExtension "SPV_KHR_vulkan_memory_model"
  4961. )";
  4962. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4963. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4964. .c_str());
  4965. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  4966. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4967. EXPECT_THAT(
  4968. getDiagnosticString(),
  4969. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  4970. "VulkanMemoryModelDeviceScopeKHR capability"));
  4971. }
  4972. TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) {
  4973. const std::string body = R"(
  4974. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4975. OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
  4976. )";
  4977. const std::string extra = R"(
  4978. OpCapability StorageImageWriteWithoutFormat
  4979. OpCapability VulkanMemoryModelKHR
  4980. OpCapability VulkanMemoryModelDeviceScopeKHR
  4981. OpExtension "SPV_KHR_vulkan_memory_model"
  4982. )";
  4983. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4984. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  4985. .c_str());
  4986. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4987. }
  4988. TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadBad) {
  4989. const std::string body = R"(
  4990. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  4991. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
  4992. )";
  4993. const std::string extra = R"(
  4994. OpCapability StorageImageReadWithoutFormat
  4995. OpCapability VulkanMemoryModelKHR
  4996. OpExtension "SPV_KHR_vulkan_memory_model"
  4997. )";
  4998. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  4999. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  5000. .c_str());
  5001. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  5002. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5003. EXPECT_THAT(
  5004. getDiagnosticString(),
  5005. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  5006. "VulkanMemoryModelDeviceScopeKHR capability"));
  5007. }
  5008. TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadGood) {
  5009. const std::string body = R"(
  5010. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  5011. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
  5012. )";
  5013. const std::string extra = R"(
  5014. OpCapability StorageImageReadWithoutFormat
  5015. OpCapability VulkanMemoryModelKHR
  5016. OpCapability VulkanMemoryModelDeviceScopeKHR
  5017. OpExtension "SPV_KHR_vulkan_memory_model"
  5018. )";
  5019. CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
  5020. SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
  5021. .c_str());
  5022. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5023. }
  5024. // This example used to cause a seg fault on OpReturnValue, verifying it doesn't
  5025. // anymore.
  5026. TEST_F(ValidateImage, Issue2463NoSegFault) {
  5027. const std::string spirv = R"(
  5028. OpCapability Linkage
  5029. OpCapability Shader
  5030. %1 = OpExtInstImport "GLSL.std.450"
  5031. OpMemoryModel Logical GLSL450
  5032. %void = OpTypeVoid
  5033. %6 = OpTypeFunction %void
  5034. %float = OpTypeFloat 32
  5035. %8 = OpTypeImage %float 3D 0 0 0 1 Unknown
  5036. %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
  5037. %10 = OpTypeSampler
  5038. %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
  5039. %12 = OpTypeSampledImage %8
  5040. %13 = OpTypeFunction %12 %_ptr_UniformConstant_8 %_ptr_UniformConstant_10
  5041. %23 = OpFunction %12 None %13
  5042. %24 = OpFunctionParameter %_ptr_UniformConstant_8
  5043. %25 = OpFunctionParameter %_ptr_UniformConstant_10
  5044. %26 = OpLabel
  5045. %27 = OpLoad %8 %24
  5046. %28 = OpLoad %10 %25
  5047. %29 = OpSampledImage %12 %27 %28
  5048. OpReturnValue %29
  5049. OpFunctionEnd
  5050. )";
  5051. CompileSuccessfully(spirv);
  5052. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5053. EXPECT_THAT(getDiagnosticString(),
  5054. HasSubstr("OpSampledImage instruction must not appear as operand "
  5055. "for OpReturnValue"));
  5056. }
  5057. TEST_F(ValidateImage, SignExtendV13Bad) {
  5058. const std::string body = R"(
  5059. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  5060. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
  5061. )";
  5062. CompileSuccessfully(
  5063. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
  5064. ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
  5065. EXPECT_THAT(
  5066. getDiagnosticString(),
  5067. HasSubstr("SignExtend(4096) requires SPIR-V version 1.4 or later"));
  5068. }
  5069. TEST_F(ValidateImage, ZeroExtendV13Bad) {
  5070. const std::string body = R"(
  5071. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  5072. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
  5073. )";
  5074. CompileSuccessfully(
  5075. GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
  5076. ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
  5077. EXPECT_THAT(
  5078. getDiagnosticString(),
  5079. HasSubstr("ZeroExtend(8192) requires SPIR-V version 1.4 or later"));
  5080. }
  5081. TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
  5082. // Unsigned int sampled type
  5083. const std::string body = R"(
  5084. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  5085. %res1 = OpImageRead %u32 %img %u32vec2_01 SignExtend
  5086. )";
  5087. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5088. CompileSuccessfully(
  5089. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  5090. SPV_ENV_UNIVERSAL_1_4);
  5091. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5092. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5093. }
  5094. TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) {
  5095. // Signed int sampled type
  5096. const std::string body = R"(
  5097. %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
  5098. %res1 = OpImageRead %s32 %img %u32vec2_01 SignExtend
  5099. )";
  5100. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5101. CompileSuccessfully(
  5102. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  5103. SPV_ENV_UNIVERSAL_1_4);
  5104. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5105. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5106. }
  5107. TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) {
  5108. const std::string body = R"(
  5109. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  5110. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
  5111. )";
  5112. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5113. CompileSuccessfully(
  5114. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  5115. SPV_ENV_UNIVERSAL_1_4);
  5116. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5117. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5118. }
  5119. TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) {
  5120. const std::string body = R"(
  5121. %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
  5122. %res1 = OpImageRead %s32vec4 %img %u32vec2_01 SignExtend
  5123. )";
  5124. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5125. CompileSuccessfully(
  5126. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  5127. SPV_ENV_UNIVERSAL_1_4);
  5128. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5129. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5130. }
  5131. // No negative tests for SignExtend since we don't truly know the
  5132. // texel format.
  5133. TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) {
  5134. // Unsigned int sampled type
  5135. const std::string body = R"(
  5136. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  5137. %res1 = OpImageRead %u32 %img %u32vec2_01 ZeroExtend
  5138. )";
  5139. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5140. CompileSuccessfully(
  5141. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  5142. SPV_ENV_UNIVERSAL_1_4);
  5143. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5144. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5145. }
  5146. TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) {
  5147. // Zeroed int sampled type
  5148. const std::string body = R"(
  5149. %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
  5150. %res1 = OpImageRead %s32 %img %u32vec2_01 ZeroExtend
  5151. )";
  5152. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5153. CompileSuccessfully(
  5154. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  5155. SPV_ENV_UNIVERSAL_1_4);
  5156. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5157. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5158. }
  5159. TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) {
  5160. const std::string body = R"(
  5161. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  5162. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
  5163. )";
  5164. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5165. CompileSuccessfully(
  5166. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  5167. SPV_ENV_UNIVERSAL_1_4);
  5168. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5169. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5170. }
  5171. TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) {
  5172. const std::string body = R"(
  5173. %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
  5174. %res1 = OpImageRead %s32vec4 %img %u32vec2_01 ZeroExtend
  5175. )";
  5176. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5177. CompileSuccessfully(
  5178. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
  5179. SPV_ENV_UNIVERSAL_1_4);
  5180. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5181. EXPECT_THAT(getDiagnosticString(), Eq(""));
  5182. }
  5183. TEST_F(ValidateImage, ReadLodAMDSuccess1) {
  5184. const std::string body = R"(
  5185. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  5186. %res1 = OpImageRead %u32vec4 %img %u32vec2_01 Lod %u32_0
  5187. )";
  5188. const std::string extra =
  5189. "\nOpCapability StorageImageReadWithoutFormat\n"
  5190. "OpCapability ImageReadWriteLodAMD\n"
  5191. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  5192. CompileSuccessfully(
  5193. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5194. SPV_ENV_UNIVERSAL_1_1);
  5195. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5196. }
  5197. TEST_F(ValidateImage, ReadLodAMDSuccess2) {
  5198. const std::string body = R"(
  5199. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  5200. %res1 = OpImageRead %f32vec4 %img %u32vec2_01 Lod %u32_0
  5201. )";
  5202. const std::string extra =
  5203. "\nOpCapability Image1D\n"
  5204. "OpCapability ImageReadWriteLodAMD\n"
  5205. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  5206. CompileSuccessfully(
  5207. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5208. SPV_ENV_UNIVERSAL_1_1);
  5209. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5210. }
  5211. TEST_F(ValidateImage, ReadLodAMDSuccess3) {
  5212. const std::string body = R"(
  5213. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  5214. %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
  5215. )";
  5216. const std::string extra =
  5217. "\nOpCapability ImageCubeArray\n"
  5218. "OpCapability ImageReadWriteLodAMD\n"
  5219. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  5220. CompileSuccessfully(
  5221. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5222. SPV_ENV_UNIVERSAL_1_1);
  5223. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5224. }
  5225. TEST_F(ValidateImage, ReadLodAMDNeedCapability) {
  5226. const std::string body = R"(
  5227. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  5228. %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
  5229. )";
  5230. const std::string extra = "\nOpCapability ImageCubeArray\n";
  5231. CompileSuccessfully(
  5232. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5233. SPV_ENV_UNIVERSAL_1_1);
  5234. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  5235. ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5236. EXPECT_THAT(getDiagnosticString(),
  5237. HasSubstr("Image Operand Lod can only be used with ExplicitLod "
  5238. "opcodes and OpImageFetch"));
  5239. }
  5240. TEST_F(ValidateImage, WriteLodAMDSuccess1) {
  5241. const std::string body = R"(
  5242. %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
  5243. OpImageWrite %img %u32vec2_01 %u32vec4_0123 Lod %u32_0
  5244. )";
  5245. const std::string extra =
  5246. "\nOpCapability StorageImageWriteWithoutFormat\n"
  5247. "OpCapability ImageReadWriteLodAMD\n"
  5248. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  5249. CompileSuccessfully(
  5250. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5251. SPV_ENV_UNIVERSAL_1_1);
  5252. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5253. }
  5254. TEST_F(ValidateImage, WriteLodAMDSuccess2) {
  5255. const std::string body = R"(
  5256. %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
  5257. OpImageWrite %img %u32_1 %f32vec4_0000 Lod %u32_0
  5258. )";
  5259. const std::string extra =
  5260. "\nOpCapability Image1D\n"
  5261. "OpCapability ImageReadWriteLodAMD\n"
  5262. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  5263. CompileSuccessfully(
  5264. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5265. SPV_ENV_UNIVERSAL_1_1);
  5266. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5267. }
  5268. TEST_F(ValidateImage, WriteLodAMDSuccess3) {
  5269. const std::string body = R"(
  5270. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  5271. OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
  5272. )";
  5273. const std::string extra =
  5274. "\nOpCapability ImageCubeArray\n"
  5275. "OpCapability ImageReadWriteLodAMD\n"
  5276. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  5277. CompileSuccessfully(
  5278. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5279. SPV_ENV_UNIVERSAL_1_1);
  5280. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5281. }
  5282. TEST_F(ValidateImage, WriteLodAMDNeedCapability) {
  5283. const std::string body = R"(
  5284. %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
  5285. OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
  5286. )";
  5287. const std::string extra = "\nOpCapability ImageCubeArray\n";
  5288. CompileSuccessfully(
  5289. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5290. SPV_ENV_UNIVERSAL_1_1);
  5291. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  5292. ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5293. EXPECT_THAT(getDiagnosticString(),
  5294. HasSubstr("Image Operand Lod can only be used with ExplicitLod "
  5295. "opcodes and OpImageFetch"));
  5296. }
  5297. TEST_F(ValidateImage, SparseReadLodAMDSuccess) {
  5298. const std::string body = R"(
  5299. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  5300. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
  5301. )";
  5302. const std::string extra =
  5303. "\nOpCapability StorageImageReadWithoutFormat\n"
  5304. "OpCapability ImageReadWriteLodAMD\n"
  5305. "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
  5306. CompileSuccessfully(
  5307. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5308. SPV_ENV_UNIVERSAL_1_1);
  5309. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5310. }
  5311. TEST_F(ValidateImage, SparseReadLodAMDNeedCapability) {
  5312. const std::string body = R"(
  5313. %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
  5314. %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
  5315. )";
  5316. const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
  5317. CompileSuccessfully(
  5318. GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
  5319. SPV_ENV_UNIVERSAL_1_1);
  5320. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  5321. ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
  5322. EXPECT_THAT(getDiagnosticString(),
  5323. HasSubstr("Image Operand Lod can only be used with ExplicitLod "
  5324. "opcodes and OpImageFetch"));
  5325. }
  5326. TEST_F(ValidateImage, GatherBiasAMDSuccess) {
  5327. const std::string body = R"(
  5328. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  5329. %sampler = OpLoad %type_sampler %uniform_sampler
  5330. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  5331. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
  5332. )";
  5333. const std::string extra = R"(
  5334. OpCapability ImageGatherBiasLodAMD
  5335. OpExtension "SPV_AMD_texture_gather_bias_lod"
  5336. )";
  5337. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  5338. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5339. }
  5340. TEST_F(ValidateImage, GatherLodAMDSuccess) {
  5341. const std::string body = R"(
  5342. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  5343. %sampler = OpLoad %type_sampler %uniform_sampler
  5344. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  5345. %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
  5346. )";
  5347. const std::string extra = R"(
  5348. OpCapability ImageGatherBiasLodAMD
  5349. OpExtension "SPV_AMD_texture_gather_bias_lod"
  5350. )";
  5351. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  5352. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5353. }
  5354. TEST_F(ValidateImage, SparseGatherBiasAMDSuccess) {
  5355. const std::string body = R"(
  5356. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  5357. %sampler = OpLoad %type_sampler %uniform_sampler
  5358. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  5359. %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
  5360. )";
  5361. const std::string extra = R"(
  5362. OpCapability ImageGatherBiasLodAMD
  5363. OpExtension "SPV_AMD_texture_gather_bias_lod"
  5364. )";
  5365. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  5366. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5367. }
  5368. TEST_F(ValidateImage, SparseGatherLodAMDSuccess) {
  5369. const std::string body = R"(
  5370. %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
  5371. %sampler = OpLoad %type_sampler %uniform_sampler
  5372. %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
  5373. %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
  5374. )";
  5375. const std::string extra = R"(
  5376. OpCapability ImageGatherBiasLodAMD
  5377. OpExtension "SPV_AMD_texture_gather_bias_lod"
  5378. )";
  5379. CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
  5380. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5381. }
  5382. // No negative tests for ZeroExtend since we don't truly know the
  5383. // texel format.
  5384. // Tests for 64-bit images
  5385. static const std::string capabilities_and_extensions_image64 = R"(
  5386. OpCapability Int64ImageEXT
  5387. OpExtension "SPV_EXT_shader_image_int64"
  5388. )";
  5389. static const std::string capabilities_and_extensions_image64_atomic = R"(
  5390. OpCapability Int64Atomics
  5391. OpCapability Int64ImageEXT
  5392. OpExtension "SPV_EXT_shader_image_int64"
  5393. )";
  5394. static const std::string declarations_image64 = R"(
  5395. %type_image_u64_buffer_0002_r64ui = OpTypeImage %u64 Buffer 0 0 0 2 R64ui
  5396. %ptr_Image_u64 = OpTypePointer Image %u64
  5397. %ptr_image_u64_buffer_0002_r64ui = OpTypePointer Private %type_image_u64_buffer_0002_r64ui
  5398. %private_image_u64_buffer_0002_r64ui = OpVariable %ptr_image_u64_buffer_0002_r64ui Private
  5399. )";
  5400. static const std::string declarations_image64i = R"(
  5401. %type_image_s64_buffer_0002_r64i = OpTypeImage %s64 Buffer 0 0 0 2 R64i
  5402. %ptr_Image_s64 = OpTypePointer Image %s64
  5403. %ptr_image_s64_buffer_0002_r64i = OpTypePointer Private %type_image_s64_buffer_0002_r64i
  5404. %private_image_s64_buffer_0002_r64i = OpVariable %ptr_image_s64_buffer_0002_r64i Private
  5405. )";
  5406. TEST_F(ValidateImage, Image64MissingCapability) {
  5407. CompileSuccessfully(GenerateShaderCode("", "", "Fragment", "",
  5408. SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5409. declarations_image64)
  5410. .c_str());
  5411. ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
  5412. }
  5413. TEST_F(ValidateImage, Image64MissingExtension) {
  5414. const std::string extra = R"(
  5415. OpCapability Int64ImageEXT
  5416. )";
  5417. CompileSuccessfully(GenerateShaderCode("", extra, "Fragment", "",
  5418. SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5419. declarations_image64)
  5420. .c_str());
  5421. ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
  5422. }
  5423. TEST_F(ValidateImage, ImageTexelPointer64Success) {
  5424. const std::string body = R"(
  5425. %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
  5426. %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
  5427. )";
  5428. CompileSuccessfully(
  5429. GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
  5430. "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5431. declarations_image64)
  5432. .c_str());
  5433. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5434. }
  5435. TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotPointer) {
  5436. const std::string body = R"(
  5437. %texel_ptr = OpImageTexelPointer %type_image_u64_buffer_0002_r64ui %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
  5438. %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
  5439. )";
  5440. CompileSuccessfully(
  5441. GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
  5442. "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5443. declarations_image64)
  5444. .c_str());
  5445. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5446. EXPECT_THAT(getDiagnosticString(),
  5447. HasSubstr("Expected Result Type to be a pointer"));
  5448. }
  5449. TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotImageClass) {
  5450. const std::string body = R"(
  5451. %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
  5452. %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
  5453. )";
  5454. CompileSuccessfully(
  5455. GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
  5456. "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5457. declarations_image64)
  5458. .c_str());
  5459. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5460. EXPECT_THAT(getDiagnosticString(),
  5461. HasSubstr("Expected Result Type to be a pointer whose "
  5462. "Storage Class operand is Image"));
  5463. }
  5464. TEST_F(ValidateImage, ImageTexelPointer64SampleNotZeroForImageWithMSZero) {
  5465. const std::string body = R"(
  5466. %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_1
  5467. %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
  5468. )";
  5469. CompileSuccessfully(
  5470. GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
  5471. "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
  5472. declarations_image64)
  5473. .c_str());
  5474. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5475. EXPECT_THAT(getDiagnosticString(),
  5476. HasSubstr("Expected Sample for Image with MS 0 to be a valid "
  5477. "<id> for the value 0"));
  5478. }
  5479. TEST_F(ValidateImage, ImageTexelPointerR32uiSuccessVulkan) {
  5480. const std::string body = R"(
  5481. %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
  5482. )";
  5483. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5484. CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
  5485. env);
  5486. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5487. }
  5488. TEST_F(ValidateImage, ImageTexelPointerR32iSuccessVulkan) {
  5489. const std::string& declarations = R"(
  5490. %type_image_s32_buffer_0002_r32i = OpTypeImage %s32 Buffer 0 0 0 2 R32i
  5491. %ptr_Image_s32 = OpTypePointer Image %s32
  5492. %ptr_image_s32_buffer_0002_r32i = OpTypePointer Private %type_image_s32_buffer_0002_r32i
  5493. %private_image_s32_buffer_0002_r32i = OpVariable %ptr_image_s32_buffer_0002_r32i Private
  5494. )";
  5495. const std::string body = R"(
  5496. %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_r32i %u32_0 %u32_0
  5497. )";
  5498. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5499. CompileSuccessfully(
  5500. GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
  5501. .c_str(),
  5502. env);
  5503. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5504. }
  5505. TEST_F(ValidateImage, ImageTexelPointerR64uiSuccessVulkan) {
  5506. const std::string body = R"(
  5507. %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
  5508. )";
  5509. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5510. CompileSuccessfully(
  5511. GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
  5512. "", env, "GLSL450", declarations_image64)
  5513. .c_str(),
  5514. env);
  5515. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5516. }
  5517. TEST_F(ValidateImage, ImageTexelPointerR64iSuccessVulkan) {
  5518. const std::string body = R"(
  5519. %texel_ptr = OpImageTexelPointer %ptr_Image_s64 %private_image_s64_buffer_0002_r64i %u32_0 %u32_0
  5520. )";
  5521. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5522. CompileSuccessfully(
  5523. GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
  5524. "", env, "GLSL450", declarations_image64i)
  5525. .c_str(),
  5526. env);
  5527. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5528. }
  5529. TEST_F(ValidateImage, ImageTexelPointerR32fSuccessVulkan) {
  5530. const std::string& declarations = R"(
  5531. %type_image_f32_buffer_0002_r32f = OpTypeImage %f32 Buffer 0 0 0 2 R32f
  5532. %ptr_image_f32_buffer_0002_r32f = OpTypePointer Private %type_image_f32_buffer_0002_r32f
  5533. %private_image_f32_buffer_0002_r32f = OpVariable %ptr_image_f32_buffer_0002_r32f Private
  5534. )";
  5535. const std::string body = R"(
  5536. %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32f %u32_0 %u32_0
  5537. )";
  5538. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5539. CompileSuccessfully(
  5540. GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
  5541. .c_str(),
  5542. env);
  5543. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  5544. }
  5545. TEST_F(ValidateImage, ImageTexelPointerRgba32iVulkan) {
  5546. const std::string& declarations = R"(
  5547. %type_image_s32_buffer_0002_rgba32i = OpTypeImage %s32 Buffer 0 0 0 2 Rgba32i
  5548. %ptr_Image_s32 = OpTypePointer Image %s32
  5549. %ptr_image_s32_buffer_0002_rgba32i = OpTypePointer Private %type_image_s32_buffer_0002_rgba32i
  5550. %private_image_s32_buffer_0002_rgba32i = OpVariable %ptr_image_s32_buffer_0002_rgba32i Private
  5551. )";
  5552. const std::string body = R"(
  5553. %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba32i %u32_0 %u32_0
  5554. )";
  5555. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5556. CompileSuccessfully(
  5557. GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
  5558. .c_str(),
  5559. env);
  5560. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  5561. EXPECT_THAT(getDiagnosticString(),
  5562. AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
  5563. EXPECT_THAT(getDiagnosticString(),
  5564. HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
  5565. "R32f, R32i, or R32ui for Vulkan environment"));
  5566. }
  5567. TEST_F(ValidateImage, ImageTexelPointerRgba16fVulkan) {
  5568. const std::string& declarations = R"(
  5569. %type_image_s32_buffer_0002_rgba16f = OpTypeImage %s32 Buffer 0 0 0 2 Rgba16f
  5570. %ptr_Image_s32 = OpTypePointer Image %s32
  5571. %ptr_image_s32_buffer_0002_rgba16f = OpTypePointer Private %type_image_s32_buffer_0002_rgba16f
  5572. %private_image_s32_buffer_0002_rgba16f = OpVariable %ptr_image_s32_buffer_0002_rgba16f Private
  5573. )";
  5574. const std::string body = R"(
  5575. %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba16f %u32_0 %u32_0
  5576. )";
  5577. spv_target_env env = SPV_ENV_VULKAN_1_0;
  5578. CompileSuccessfully(
  5579. GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
  5580. .c_str(),
  5581. env);
  5582. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  5583. EXPECT_THAT(getDiagnosticString(),
  5584. AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
  5585. EXPECT_THAT(getDiagnosticString(),
  5586. HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
  5587. "R32f, R32i, or R32ui for Vulkan environment"));
  5588. }
  5589. TEST_F(ValidateImage, ImageExecutionModeLimitationNoMode) {
  5590. const std::string text = R"(
  5591. OpCapability Shader
  5592. OpMemoryModel Logical GLSL450
  5593. OpEntryPoint GLCompute %2 " " %4
  5594. %void = OpTypeVoid
  5595. %8 = OpTypeFunction %void
  5596. %float = OpTypeFloat 32
  5597. %v4float = OpTypeVector %float 4
  5598. %12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
  5599. %13 = OpTypeSampledImage %12
  5600. %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
  5601. %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
  5602. %_ptr_Input_v4float = OpTypePointer Input %v4float
  5603. %4 = OpVariable %_ptr_Input_v4float Input
  5604. %v2float = OpTypeVector %float 2
  5605. %float_1_35631564en19 = OpConstant %float 1.35631564e-19
  5606. %2 = OpFunction %void None %8
  5607. %8224 = OpLabel
  5608. %6 = OpLoad %13 %5
  5609. %19 = OpLoad %v4float %4
  5610. %20 = OpVectorShuffle %v2float %19 %19 0 1
  5611. %21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
  5612. %65312 = OpImageSampleImplicitLod %v4float %6 %21
  5613. OpUnreachable
  5614. OpFunctionEnd
  5615. )";
  5616. CompileSuccessfully(text);
  5617. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5618. EXPECT_THAT(getDiagnosticString(),
  5619. HasSubstr("ImplicitLod instructions require "
  5620. "DerivativeGroupQuadsKHR or DerivativeGroupLinearKHR "
  5621. "execution mode for GLCompute, MeshEXT or TaskEXT "
  5622. "execution model"));
  5623. }
  5624. TEST_F(ValidateImage, TypeSampledImageNotBufferPost1p6) {
  5625. const std::string text = R"(
  5626. OpCapability Shader
  5627. OpCapability Linkage
  5628. OpCapability SampledBuffer
  5629. OpMemoryModel Logical GLSL450
  5630. %float = OpTypeFloat 32
  5631. %image = OpTypeImage %float Buffer 0 0 0 1 Unknown
  5632. %sampled = OpTypeSampledImage %image
  5633. )";
  5634. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
  5635. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
  5636. EXPECT_THAT(getDiagnosticString(),
  5637. HasSubstr("In SPIR-V 1.6 or later, sampled image dimension must "
  5638. "not be Buffer"));
  5639. }
  5640. TEST_F(ValidateImage, NonTemporalImage) {
  5641. const std::string text = R"(
  5642. OpCapability Shader
  5643. OpMemoryModel Logical GLSL450
  5644. OpEntryPoint Fragment %2 " " %4 %5
  5645. OpExecutionMode %2 OriginUpperLeft
  5646. %void = OpTypeVoid
  5647. %8 = OpTypeFunction %void
  5648. %float = OpTypeFloat 32
  5649. %v4float = OpTypeVector %float 4
  5650. %12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
  5651. %13 = OpTypeSampledImage %12
  5652. %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
  5653. %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
  5654. %_ptr_Input_v4float = OpTypePointer Input %v4float
  5655. %4 = OpVariable %_ptr_Input_v4float Input
  5656. %v2float = OpTypeVector %float 2
  5657. %float_1_35631564en19 = OpConstant %float 1.35631564e-19
  5658. %2 = OpFunction %void None %8
  5659. %8224 = OpLabel
  5660. %6 = OpLoad %13 %5
  5661. %19 = OpLoad %v4float %4
  5662. %20 = OpVectorShuffle %v2float %19 %19 0 1
  5663. %21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
  5664. %65312 = OpImageSampleImplicitLod %v4float %6 %21 Nontemporal
  5665. OpReturn
  5666. OpFunctionEnd
  5667. )";
  5668. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
  5669. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
  5670. }
  5671. TEST_F(ValidateImage, NVBindlessSamplerBuiltins) {
  5672. const std::string text = R"(
  5673. OpCapability Shader
  5674. OpCapability Int64
  5675. OpCapability Image1D
  5676. OpCapability BindlessTextureNV
  5677. OpExtension "SPV_NV_bindless_texture"
  5678. %1 = OpExtInstImport "GLSL.std.450"
  5679. OpMemoryModel Logical GLSL450
  5680. OpSamplerImageAddressingModeNV 64
  5681. OpEntryPoint Fragment %main "main"
  5682. OpExecutionMode %main OriginUpperLeft
  5683. OpSource GLSL 450
  5684. OpName %main "main"
  5685. OpName %s2D "s2D"
  5686. OpName %textureHandle "textureHandle"
  5687. OpName %i1D "i1D"
  5688. OpName %s "s"
  5689. OpName %temp "temp"
  5690. %void = OpTypeVoid
  5691. %3 = OpTypeFunction %void
  5692. %float = OpTypeFloat 32
  5693. %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
  5694. %8 = OpTypeSampledImage %7
  5695. %_ptr_Function_8 = OpTypePointer Function %8
  5696. %ulong = OpTypeInt 64 0
  5697. %_ptr_Private_ulong = OpTypePointer Private %ulong
  5698. %textureHandle = OpVariable %_ptr_Private_ulong Private
  5699. %16 = OpTypeImage %float 1D 0 0 0 2 Rgba32f
  5700. %_ptr_Function_16 = OpTypePointer Function %16
  5701. %21 = OpTypeSampler
  5702. %_ptr_Function_21 = OpTypePointer Function %21
  5703. %_ptr_Function_ulong = OpTypePointer Function %ulong
  5704. %main = OpFunction %void None %3
  5705. %5 = OpLabel
  5706. %s2D = OpVariable %_ptr_Function_8 Function
  5707. %i1D = OpVariable %_ptr_Function_16 Function
  5708. %s = OpVariable %_ptr_Function_21 Function
  5709. %temp = OpVariable %_ptr_Function_ulong Function
  5710. %14 = OpLoad %ulong %textureHandle
  5711. %15 = OpConvertUToSampledImageNV %8 %14
  5712. OpStore %s2D %15
  5713. %19 = OpLoad %ulong %textureHandle
  5714. %20 = OpConvertUToImageNV %16 %19
  5715. OpStore %i1D %20
  5716. %24 = OpLoad %ulong %textureHandle
  5717. %25 = OpConvertUToSamplerNV %21 %24
  5718. OpStore %s %25
  5719. %28 = OpLoad %8 %s2D
  5720. %29 = OpConvertSampledImageToUNV %ulong %28
  5721. OpStore %temp %29
  5722. %30 = OpLoad %16 %i1D
  5723. %31 = OpConvertImageToUNV %ulong %30
  5724. OpStore %temp %31
  5725. %32 = OpLoad %21 %s
  5726. %33 = OpConvertSamplerToUNV %ulong %32
  5727. OpStore %temp %33
  5728. OpReturn
  5729. OpFunctionEnd
  5730. )";
  5731. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  5732. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5733. }
  5734. TEST_F(ValidateImage, NVBindlessAddressingMode64) {
  5735. std::string text = R"(
  5736. OpCapability Shader
  5737. OpCapability BindlessTextureNV
  5738. OpExtension "SPV_NV_bindless_texture"
  5739. OpMemoryModel Logical GLSL450
  5740. OpSamplerImageAddressingModeNV 64
  5741. OpEntryPoint GLCompute %func "main"
  5742. %voidt = OpTypeVoid
  5743. %uintt = OpTypeInt 32 0
  5744. %funct = OpTypeFunction %voidt
  5745. %func = OpFunction %voidt None %funct
  5746. %entry = OpLabel
  5747. %udef = OpUndef %uintt
  5748. OpReturn
  5749. OpFunctionEnd
  5750. )";
  5751. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  5752. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5753. }
  5754. TEST_F(ValidateImage, NVBindlessAddressingMode32) {
  5755. std::string text = R"(
  5756. OpCapability Shader
  5757. OpCapability BindlessTextureNV
  5758. OpExtension "SPV_NV_bindless_texture"
  5759. OpMemoryModel Logical GLSL450
  5760. OpSamplerImageAddressingModeNV 32
  5761. OpEntryPoint GLCompute %func "main"
  5762. %voidt = OpTypeVoid
  5763. %uintt = OpTypeInt 32 0
  5764. %funct = OpTypeFunction %voidt
  5765. %func = OpFunction %voidt None %funct
  5766. %entry = OpLabel
  5767. %udef = OpUndef %uintt
  5768. OpReturn
  5769. OpFunctionEnd
  5770. )";
  5771. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  5772. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5773. }
  5774. TEST_F(ValidateImage, NVBindlessInvalidAddressingMode) {
  5775. std::string text = R"(
  5776. OpCapability Shader
  5777. OpCapability BindlessTextureNV
  5778. OpExtension "SPV_NV_bindless_texture"
  5779. OpMemoryModel Logical GLSL450
  5780. OpSamplerImageAddressingModeNV 0
  5781. OpEntryPoint GLCompute %func "main"
  5782. %voidt = OpTypeVoid
  5783. %uintt = OpTypeInt 32 0
  5784. %funct = OpTypeFunction %voidt
  5785. %func = OpFunction %voidt None %funct
  5786. %entry = OpLabel
  5787. %udef = OpUndef %uintt
  5788. OpReturn
  5789. OpFunctionEnd
  5790. )";
  5791. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  5792. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  5793. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5794. EXPECT_THAT(
  5795. getDiagnosticString(),
  5796. HasSubstr("OpSamplerImageAddressingModeNV bitwidth should be 64 or 32"));
  5797. }
  5798. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationA) {
  5799. std::string text = R"(
  5800. OpCapability Shader
  5801. OpCapability TextureBlockMatchQCOM
  5802. OpExtension "SPV_QCOM_image_processing"
  5803. %1 = OpExtInstImport "GLSL.std.450"
  5804. OpMemoryModel Logical GLSL450
  5805. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  5806. OpExecutionMode %2 OriginUpperLeft
  5807. OpDecorate %3 Location 0
  5808. OpDecorate %4 DescriptorSet 0
  5809. OpDecorate %4 Binding 1
  5810. OpDecorate %5 DescriptorSet 0
  5811. OpDecorate %5 Binding 3
  5812. OpDecorate %6 DescriptorSet 0
  5813. OpDecorate %6 Binding 2
  5814. OpDecorate %6 BlockMatchTextureQCOM
  5815. %void = OpTypeVoid
  5816. %8 = OpTypeFunction %void
  5817. %uint = OpTypeInt 32 0
  5818. %v2uint = OpTypeVector %uint 2
  5819. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  5820. %float = OpTypeFloat 32
  5821. %v4float = OpTypeVector %float 4
  5822. %_ptr_Input_float = OpTypePointer Input %float
  5823. %_ptr_Function_uint = OpTypePointer Function %uint
  5824. %uint_4 = OpConstant %uint 4
  5825. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  5826. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5827. %3 = OpVariable %_ptr_Output_v4float Output
  5828. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  5829. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  5830. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  5831. %21 = OpTypeSampler
  5832. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  5833. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  5834. %23 = OpTypeSampledImage %19
  5835. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  5836. %2 = OpFunction %void None %8
  5837. %24 = OpLabel
  5838. %25 = OpVariable %_ptr_Function_v2uint Function
  5839. %26 = OpLoad %19 %4
  5840. %27 = OpLoad %21 %5
  5841. %28 = OpSampledImage %23 %26 %27
  5842. %29 = OpLoad %v2uint %25
  5843. %30 = OpLoad %19 %6
  5844. %31 = OpLoad %21 %5
  5845. %32 = OpSampledImage %23 %30 %31
  5846. %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
  5847. OpStore %3 %33
  5848. OpReturn
  5849. OpFunctionEnd
  5850. )";
  5851. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  5852. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  5853. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5854. EXPECT_THAT(getDiagnosticString(),
  5855. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  5856. }
  5857. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationB) {
  5858. std::string text = R"(
  5859. OpCapability Shader
  5860. OpCapability TextureBlockMatchQCOM
  5861. OpExtension "SPV_QCOM_image_processing"
  5862. %1 = OpExtInstImport "GLSL.std.450"
  5863. OpMemoryModel Logical GLSL450
  5864. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  5865. OpExecutionMode %2 OriginUpperLeft
  5866. OpDecorate %3 Location 0
  5867. OpDecorate %4 DescriptorSet 0
  5868. OpDecorate %4 Binding 1
  5869. OpDecorate %5 DescriptorSet 0
  5870. OpDecorate %5 Binding 3
  5871. OpDecorate %5 BlockMatchTextureQCOM
  5872. OpDecorate %6 DescriptorSet 0
  5873. OpDecorate %6 Binding 2
  5874. %void = OpTypeVoid
  5875. %8 = OpTypeFunction %void
  5876. %uint = OpTypeInt 32 0
  5877. %v2uint = OpTypeVector %uint 2
  5878. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  5879. %float = OpTypeFloat 32
  5880. %v4float = OpTypeVector %float 4
  5881. %_ptr_Input_float = OpTypePointer Input %float
  5882. %_ptr_Function_uint = OpTypePointer Function %uint
  5883. %uint_4 = OpConstant %uint 4
  5884. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  5885. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5886. %3 = OpVariable %_ptr_Output_v4float Output
  5887. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  5888. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  5889. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  5890. %21 = OpTypeSampler
  5891. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  5892. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  5893. %23 = OpTypeSampledImage %19
  5894. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  5895. %2 = OpFunction %void None %8
  5896. %24 = OpLabel
  5897. %25 = OpVariable %_ptr_Function_v2uint Function
  5898. %26 = OpLoad %19 %4
  5899. %27 = OpLoad %21 %5
  5900. %28 = OpSampledImage %23 %26 %27
  5901. %29 = OpLoad %v2uint %25
  5902. %30 = OpLoad %19 %6
  5903. %31 = OpLoad %21 %5
  5904. %32 = OpSampledImage %23 %30 %31
  5905. %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
  5906. OpStore %3 %33
  5907. OpReturn
  5908. OpFunctionEnd
  5909. )";
  5910. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  5911. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  5912. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5913. EXPECT_THAT(getDiagnosticString(),
  5914. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  5915. }
  5916. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationC) {
  5917. std::string text = R"(
  5918. OpCapability Shader
  5919. OpCapability TextureBlockMatchQCOM
  5920. OpExtension "SPV_QCOM_image_processing"
  5921. %1 = OpExtInstImport "GLSL.std.450"
  5922. OpMemoryModel Logical GLSL450
  5923. OpEntryPoint Fragment %2 "main" %3 %4 %5
  5924. OpExecutionMode %2 OriginUpperLeft
  5925. OpDecorate %3 Location 0
  5926. OpDecorate %4 DescriptorSet 0
  5927. OpDecorate %4 Binding 4
  5928. OpDecorate %5 DescriptorSet 0
  5929. OpDecorate %5 Binding 5
  5930. OpDecorate %5 BlockMatchTextureQCOM
  5931. %void = OpTypeVoid
  5932. %7 = OpTypeFunction %void
  5933. %uint = OpTypeInt 32 0
  5934. %v2uint = OpTypeVector %uint 2
  5935. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  5936. %float = OpTypeFloat 32
  5937. %v4float = OpTypeVector %float 4
  5938. %_ptr_Input_v4float = OpTypePointer Input %v4float
  5939. %_ptr_Input_float = OpTypePointer Input %float
  5940. %_ptr_Function_uint = OpTypePointer Function %uint
  5941. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5942. %3 = OpVariable %_ptr_Output_v4float Output
  5943. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  5944. %19 = OpTypeSampledImage %18
  5945. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  5946. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  5947. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  5948. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  5949. %2 = OpFunction %void None %7
  5950. %22 = OpLabel
  5951. %23 = OpVariable %_ptr_Function_v2uint Function
  5952. %24 = OpLoad %19 %4
  5953. %25 = OpLoad %v2uint %23
  5954. %26 = OpLoad %19 %5
  5955. %27 = OpLoad %v2uint %23
  5956. %28 = OpLoad %v2uint %23
  5957. %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
  5958. OpStore %3 %29
  5959. OpReturn
  5960. OpFunctionEnd
  5961. )";
  5962. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  5963. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  5964. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  5965. EXPECT_THAT(getDiagnosticString(),
  5966. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  5967. }
  5968. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationD) {
  5969. std::string text = R"(
  5970. OpCapability Shader
  5971. OpCapability TextureBlockMatchQCOM
  5972. OpExtension "SPV_QCOM_image_processing"
  5973. %1 = OpExtInstImport "GLSL.std.450"
  5974. OpMemoryModel Logical GLSL450
  5975. OpEntryPoint Fragment %2 "main" %3 %4 %5
  5976. OpExecutionMode %2 OriginUpperLeft
  5977. OpDecorate %3 Location 0
  5978. OpDecorate %4 DescriptorSet 0
  5979. OpDecorate %4 Binding 4
  5980. OpDecorate %4 BlockMatchTextureQCOM
  5981. OpDecorate %5 DescriptorSet 0
  5982. OpDecorate %5 Binding 5
  5983. %void = OpTypeVoid
  5984. %7 = OpTypeFunction %void
  5985. %uint = OpTypeInt 32 0
  5986. %v2uint = OpTypeVector %uint 2
  5987. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  5988. %float = OpTypeFloat 32
  5989. %v4float = OpTypeVector %float 4
  5990. %_ptr_Input_v4float = OpTypePointer Input %v4float
  5991. %_ptr_Input_float = OpTypePointer Input %float
  5992. %_ptr_Function_uint = OpTypePointer Function %uint
  5993. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5994. %3 = OpVariable %_ptr_Output_v4float Output
  5995. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  5996. %19 = OpTypeSampledImage %18
  5997. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  5998. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  5999. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6000. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6001. %2 = OpFunction %void None %7
  6002. %22 = OpLabel
  6003. %23 = OpVariable %_ptr_Function_v2uint Function
  6004. %24 = OpLoad %19 %4
  6005. %25 = OpLoad %v2uint %23
  6006. %26 = OpLoad %19 %5
  6007. %27 = OpLoad %v2uint %23
  6008. %28 = OpLoad %v2uint %23
  6009. %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
  6010. OpStore %3 %29
  6011. OpReturn
  6012. OpFunctionEnd
  6013. )";
  6014. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6015. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6016. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6017. EXPECT_THAT(getDiagnosticString(),
  6018. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  6019. }
  6020. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationA) {
  6021. std::string text = R"(
  6022. OpCapability Shader
  6023. OpCapability TextureBlockMatchQCOM
  6024. OpExtension "SPV_QCOM_image_processing"
  6025. %1 = OpExtInstImport "GLSL.std.450"
  6026. OpMemoryModel Logical GLSL450
  6027. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  6028. OpExecutionMode %2 OriginUpperLeft
  6029. OpDecorate %3 Location 0
  6030. OpDecorate %4 DescriptorSet 0
  6031. OpDecorate %4 Binding 1
  6032. OpDecorate %5 DescriptorSet 0
  6033. OpDecorate %5 Binding 3
  6034. OpDecorate %6 DescriptorSet 0
  6035. OpDecorate %6 Binding 2
  6036. OpDecorate %6 BlockMatchTextureQCOM
  6037. %void = OpTypeVoid
  6038. %8 = OpTypeFunction %void
  6039. %uint = OpTypeInt 32 0
  6040. %v2uint = OpTypeVector %uint 2
  6041. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6042. %float = OpTypeFloat 32
  6043. %v4float = OpTypeVector %float 4
  6044. %_ptr_Input_float = OpTypePointer Input %float
  6045. %_ptr_Function_uint = OpTypePointer Function %uint
  6046. %uint_4 = OpConstant %uint 4
  6047. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  6048. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6049. %3 = OpVariable %_ptr_Output_v4float Output
  6050. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6051. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  6052. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6053. %21 = OpTypeSampler
  6054. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  6055. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  6056. %23 = OpTypeSampledImage %19
  6057. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6058. %2 = OpFunction %void None %8
  6059. %24 = OpLabel
  6060. %25 = OpVariable %_ptr_Function_v2uint Function
  6061. %26 = OpLoad %19 %4
  6062. %27 = OpLoad %21 %5
  6063. %28 = OpSampledImage %23 %26 %27
  6064. %29 = OpLoad %v2uint %25
  6065. %30 = OpLoad %19 %6
  6066. %31 = OpLoad %21 %5
  6067. %32 = OpSampledImage %23 %30 %31
  6068. %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
  6069. OpStore %3 %33
  6070. OpReturn
  6071. OpFunctionEnd
  6072. )";
  6073. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6074. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6075. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6076. EXPECT_THAT(getDiagnosticString(),
  6077. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  6078. }
  6079. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationB) {
  6080. std::string text = R"(
  6081. OpCapability Shader
  6082. OpCapability TextureBlockMatchQCOM
  6083. OpExtension "SPV_QCOM_image_processing"
  6084. %1 = OpExtInstImport "GLSL.std.450"
  6085. OpMemoryModel Logical GLSL450
  6086. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  6087. OpExecutionMode %2 OriginUpperLeft
  6088. OpDecorate %3 Location 0
  6089. OpDecorate %4 DescriptorSet 0
  6090. OpDecorate %4 Binding 1
  6091. OpDecorate %5 DescriptorSet 0
  6092. OpDecorate %5 Binding 3
  6093. OpDecorate %5 BlockMatchTextureQCOM
  6094. OpDecorate %6 DescriptorSet 0
  6095. OpDecorate %6 Binding 2
  6096. %void = OpTypeVoid
  6097. %8 = OpTypeFunction %void
  6098. %uint = OpTypeInt 32 0
  6099. %v2uint = OpTypeVector %uint 2
  6100. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6101. %float = OpTypeFloat 32
  6102. %v4float = OpTypeVector %float 4
  6103. %_ptr_Input_float = OpTypePointer Input %float
  6104. %_ptr_Function_uint = OpTypePointer Function %uint
  6105. %uint_4 = OpConstant %uint 4
  6106. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  6107. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6108. %3 = OpVariable %_ptr_Output_v4float Output
  6109. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6110. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  6111. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6112. %21 = OpTypeSampler
  6113. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  6114. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  6115. %23 = OpTypeSampledImage %19
  6116. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6117. %2 = OpFunction %void None %8
  6118. %24 = OpLabel
  6119. %25 = OpVariable %_ptr_Function_v2uint Function
  6120. %26 = OpLoad %19 %4
  6121. %27 = OpLoad %21 %5
  6122. %28 = OpSampledImage %23 %26 %27
  6123. %29 = OpLoad %v2uint %25
  6124. %30 = OpLoad %19 %6
  6125. %31 = OpLoad %21 %5
  6126. %32 = OpSampledImage %23 %30 %31
  6127. %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
  6128. OpStore %3 %33
  6129. OpReturn
  6130. OpFunctionEnd
  6131. )";
  6132. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6133. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6134. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6135. EXPECT_THAT(getDiagnosticString(),
  6136. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  6137. }
  6138. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationC) {
  6139. std::string text = R"(
  6140. OpCapability Shader
  6141. OpCapability TextureBlockMatchQCOM
  6142. OpExtension "SPV_QCOM_image_processing"
  6143. %1 = OpExtInstImport "GLSL.std.450"
  6144. OpMemoryModel Logical GLSL450
  6145. OpEntryPoint Fragment %2 "main" %3 %4 %5
  6146. OpExecutionMode %2 OriginUpperLeft
  6147. OpDecorate %3 Location 0
  6148. OpDecorate %4 DescriptorSet 0
  6149. OpDecorate %4 Binding 4
  6150. OpDecorate %5 DescriptorSet 0
  6151. OpDecorate %5 Binding 5
  6152. OpDecorate %5 BlockMatchTextureQCOM
  6153. %void = OpTypeVoid
  6154. %7 = OpTypeFunction %void
  6155. %uint = OpTypeInt 32 0
  6156. %v2uint = OpTypeVector %uint 2
  6157. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6158. %float = OpTypeFloat 32
  6159. %v4float = OpTypeVector %float 4
  6160. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6161. %_ptr_Input_float = OpTypePointer Input %float
  6162. %_ptr_Function_uint = OpTypePointer Function %uint
  6163. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6164. %3 = OpVariable %_ptr_Output_v4float Output
  6165. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6166. %19 = OpTypeSampledImage %18
  6167. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  6168. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6169. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6170. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6171. %2 = OpFunction %void None %7
  6172. %22 = OpLabel
  6173. %23 = OpVariable %_ptr_Function_v2uint Function
  6174. %24 = OpLoad %19 %4
  6175. %25 = OpLoad %v2uint %23
  6176. %26 = OpLoad %19 %5
  6177. %27 = OpLoad %v2uint %23
  6178. %28 = OpLoad %v2uint %23
  6179. %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
  6180. OpStore %3 %29
  6181. OpReturn
  6182. OpFunctionEnd
  6183. )";
  6184. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6185. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6186. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6187. EXPECT_THAT(getDiagnosticString(),
  6188. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  6189. }
  6190. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationD) {
  6191. std::string text = R"(
  6192. OpCapability Shader
  6193. OpCapability TextureBlockMatchQCOM
  6194. OpExtension "SPV_QCOM_image_processing"
  6195. %1 = OpExtInstImport "GLSL.std.450"
  6196. OpMemoryModel Logical GLSL450
  6197. OpEntryPoint Fragment %2 "main" %3 %4 %5
  6198. OpExecutionMode %2 OriginUpperLeft
  6199. OpDecorate %3 Location 0
  6200. OpDecorate %4 DescriptorSet 0
  6201. OpDecorate %4 Binding 4
  6202. OpDecorate %4 BlockMatchTextureQCOM
  6203. OpDecorate %5 DescriptorSet 0
  6204. OpDecorate %5 Binding 5
  6205. %void = OpTypeVoid
  6206. %7 = OpTypeFunction %void
  6207. %uint = OpTypeInt 32 0
  6208. %v2uint = OpTypeVector %uint 2
  6209. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6210. %float = OpTypeFloat 32
  6211. %v4float = OpTypeVector %float 4
  6212. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6213. %_ptr_Input_float = OpTypePointer Input %float
  6214. %_ptr_Function_uint = OpTypePointer Function %uint
  6215. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6216. %3 = OpVariable %_ptr_Output_v4float Output
  6217. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6218. %19 = OpTypeSampledImage %18
  6219. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  6220. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6221. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6222. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6223. %2 = OpFunction %void None %7
  6224. %22 = OpLabel
  6225. %23 = OpVariable %_ptr_Function_v2uint Function
  6226. %24 = OpLoad %19 %4
  6227. %25 = OpLoad %v2uint %23
  6228. %26 = OpLoad %19 %5
  6229. %27 = OpLoad %v2uint %23
  6230. %28 = OpLoad %v2uint %23
  6231. %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
  6232. OpStore %3 %29
  6233. OpReturn
  6234. OpFunctionEnd
  6235. )";
  6236. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6237. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6238. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6239. EXPECT_THAT(getDiagnosticString(),
  6240. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  6241. }
  6242. TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationA) {
  6243. std::string text = R"(
  6244. OpCapability Shader
  6245. OpCapability TextureSampleWeightedQCOM
  6246. OpExtension "SPV_QCOM_image_processing"
  6247. %1 = OpExtInstImport "GLSL.std.450"
  6248. OpMemoryModel Logical GLSL450
  6249. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
  6250. OpExecutionMode %2 OriginUpperLeft
  6251. OpDecorate %3 Location 0
  6252. OpDecorate %4 DescriptorSet 0
  6253. OpDecorate %4 Binding 1
  6254. OpDecorate %5 DescriptorSet 0
  6255. OpDecorate %5 Binding 3
  6256. OpDecorate %6 Location 0
  6257. OpDecorate %7 DescriptorSet 0
  6258. OpDecorate %7 Binding 0
  6259. %void = OpTypeVoid
  6260. %9 = OpTypeFunction %void
  6261. %float = OpTypeFloat 32
  6262. %v4float = OpTypeVector %float 4
  6263. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6264. %3 = OpVariable %_ptr_Output_v4float Output
  6265. %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6266. %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
  6267. %4 = OpVariable %_ptr_UniformConstant_13 UniformConstant
  6268. %15 = OpTypeSampler
  6269. %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
  6270. %5 = OpVariable %_ptr_UniformConstant_15 UniformConstant
  6271. %17 = OpTypeSampledImage %13
  6272. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6273. %6 = OpVariable %_ptr_Input_v4float Input
  6274. %v2float = OpTypeVector %float 2
  6275. %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6276. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  6277. %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  6278. %22 = OpTypeSampledImage %20
  6279. %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
  6280. %2 = OpFunction %void None %9
  6281. %24 = OpLabel
  6282. %25 = OpLoad %13 %4
  6283. %26 = OpLoad %15 %5
  6284. %27 = OpSampledImage %17 %25 %26
  6285. %28 = OpLoad %v4float %6
  6286. %29 = OpVectorShuffle %v2float %28 %28 0 1
  6287. %30 = OpLoad %20 %7
  6288. %31 = OpLoad %15 %5
  6289. %32 = OpSampledImage %22 %30 %31
  6290. %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
  6291. OpStore %3 %33
  6292. OpReturn
  6293. OpFunctionEnd
  6294. )";
  6295. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6296. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6297. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6298. EXPECT_THAT(getDiagnosticString(),
  6299. HasSubstr("Missing decoration WeightTextureQCOM"));
  6300. }
  6301. TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationB) {
  6302. std::string text = R"(
  6303. OpCapability Shader
  6304. OpCapability TextureSampleWeightedQCOM
  6305. OpExtension "SPV_QCOM_image_processing"
  6306. %1 = OpExtInstImport "GLSL.std.450"
  6307. OpMemoryModel Logical GLSL450
  6308. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  6309. OpExecutionMode %2 OriginUpperLeft
  6310. OpDecorate %3 Location 0
  6311. OpDecorate %4 Location 0
  6312. OpDecorate %5 DescriptorSet 0
  6313. OpDecorate %5 Binding 4
  6314. OpDecorate %6 DescriptorSet 0
  6315. OpDecorate %6 Binding 5
  6316. %void = OpTypeVoid
  6317. %8 = OpTypeFunction %void
  6318. %float = OpTypeFloat 32
  6319. %v4float = OpTypeVector %float 4
  6320. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6321. %3 = OpVariable %_ptr_Output_v4float Output
  6322. %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6323. %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
  6324. %14 = OpTypeSampler
  6325. %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
  6326. %16 = OpTypeSampledImage %12
  6327. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6328. %4 = OpVariable %_ptr_Input_v4float Input
  6329. %v2float = OpTypeVector %float 2
  6330. %19 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6331. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  6332. %21 = OpTypeSampledImage %19
  6333. %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
  6334. %5 = OpVariable %_ptr_UniformConstant_16 UniformConstant
  6335. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  6336. %6 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  6337. %2 = OpFunction %void None %8
  6338. %24 = OpLabel
  6339. %25 = OpLoad %16 %5
  6340. %26 = OpLoad %v4float %4
  6341. %27 = OpVectorShuffle %v2float %26 %26 0 1
  6342. %28 = OpLoad %21 %6
  6343. %29 = OpImageSampleWeightedQCOM %v4float %25 %27 %28
  6344. OpStore %3 %29
  6345. OpReturn
  6346. OpFunctionEnd
  6347. )";
  6348. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6349. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6350. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6351. EXPECT_THAT(getDiagnosticString(),
  6352. HasSubstr("Missing decoration WeightTextureQCOM"));
  6353. }
  6354. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchWindowSADInvalidUseA) {
  6355. std::string text = R"(
  6356. ; SPIR-V
  6357. ; Version: 1.0
  6358. ; Generator: Khronos Glslang Reference Front End; 11
  6359. ; Bound: 79
  6360. ; Schema: 0
  6361. OpCapability Shader
  6362. OpCapability TextureBlockMatchQCOM
  6363. OpExtension "SPV_QCOM_image_processing"
  6364. %1 = OpExtInstImport "GLSL.std.450"
  6365. OpMemoryModel Logical GLSL450
  6366. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  6367. OpExecutionMode %main OriginUpperLeft
  6368. OpDecorate %100 Location 0
  6369. OpDecorate %101 Location 0
  6370. OpDecorate %102 DescriptorSet 0
  6371. OpDecorate %102 Binding 1
  6372. OpDecorate %103 DescriptorSet 0
  6373. OpDecorate %103 Binding 3
  6374. OpDecorate %104 DescriptorSet 0
  6375. OpDecorate %104 Binding 2
  6376. OpDecorate %102 BlockMatchTextureQCOM
  6377. OpDecorate %104 BlockMatchTextureQCOM
  6378. %void = OpTypeVoid
  6379. %3 = OpTypeFunction %void
  6380. %uint = OpTypeInt 32 0
  6381. %v2uint = OpTypeVector %uint 2
  6382. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6383. %float = OpTypeFloat 32
  6384. %v4float = OpTypeVector %float 4
  6385. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6386. %100 = OpVariable %_ptr_Input_v4float Input
  6387. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6388. %101 = OpVariable %_ptr_Output_v4float Output
  6389. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6390. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  6391. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  6392. %46 = OpTypeSampler
  6393. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  6394. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  6395. %50 = OpTypeSampledImage %42
  6396. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  6397. %v2float = OpTypeVector %float 2
  6398. %main = OpFunction %void None %3
  6399. %5 = OpLabel
  6400. %15 = OpVariable %_ptr_Function_v2uint Function
  6401. %45 = OpLoad %42 %102
  6402. %49 = OpLoad %46 %103
  6403. %51 = OpSampledImage %50 %45 %49
  6404. %52 = OpLoad %v2uint %15
  6405. %54 = OpLoad %42 %104
  6406. %55 = OpLoad %46 %103
  6407. %56 = OpSampledImage %50 %54 %55
  6408. %57 = OpLoad %v2uint %15
  6409. %58 = OpLoad %v2uint %15
  6410. %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
  6411. OpStore %101 %59
  6412. %69 = OpLoad %42 %102
  6413. %70 = OpLoad %46 %103
  6414. %71 = OpSampledImage %50 %69 %70
  6415. %73 = OpLoad %v4float %100
  6416. %74 = OpVectorShuffle %v2float %73 %73 0 0
  6417. %75 = OpImageSampleImplicitLod %v4float %71 %74
  6418. OpStore %101 %75
  6419. OpReturn
  6420. OpFunctionEnd
  6421. )";
  6422. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6423. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6424. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6425. EXPECT_THAT(
  6426. getDiagnosticString(),
  6427. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  6428. }
  6429. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseB) {
  6430. std::string text = R"(
  6431. ; SPIR-V
  6432. ; Version: 1.0
  6433. ; Generator: Khronos Glslang Reference Front End; 11
  6434. ; Bound: 79
  6435. ; Schema: 0
  6436. OpCapability Shader
  6437. OpCapability TextureBlockMatchQCOM
  6438. OpExtension "SPV_QCOM_image_processing"
  6439. %1 = OpExtInstImport "GLSL.std.450"
  6440. OpMemoryModel Logical GLSL450
  6441. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  6442. OpExecutionMode %main OriginUpperLeft
  6443. OpDecorate %100 Location 0
  6444. OpDecorate %101 Location 0
  6445. OpDecorate %102 DescriptorSet 0
  6446. OpDecorate %102 Binding 1
  6447. OpDecorate %103 DescriptorSet 0
  6448. OpDecorate %103 Binding 3
  6449. OpDecorate %104 DescriptorSet 0
  6450. OpDecorate %104 Binding 2
  6451. OpDecorate %102 BlockMatchTextureQCOM
  6452. OpDecorate %104 BlockMatchTextureQCOM
  6453. %void = OpTypeVoid
  6454. %3 = OpTypeFunction %void
  6455. %uint = OpTypeInt 32 0
  6456. %v2uint = OpTypeVector %uint 2
  6457. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6458. %float = OpTypeFloat 32
  6459. %v4float = OpTypeVector %float 4
  6460. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6461. %100 = OpVariable %_ptr_Input_v4float Input
  6462. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6463. %101 = OpVariable %_ptr_Output_v4float Output
  6464. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6465. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  6466. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  6467. %46 = OpTypeSampler
  6468. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  6469. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  6470. %50 = OpTypeSampledImage %42
  6471. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  6472. %v2float = OpTypeVector %float 2
  6473. %main = OpFunction %void None %3
  6474. %5 = OpLabel
  6475. %15 = OpVariable %_ptr_Function_v2uint Function
  6476. %45 = OpLoad %42 %102
  6477. %49 = OpLoad %46 %103
  6478. %51 = OpSampledImage %50 %45 %49
  6479. %52 = OpLoad %v2uint %15
  6480. %54 = OpLoad %42 %104
  6481. %55 = OpLoad %46 %103
  6482. %56 = OpSampledImage %50 %54 %55
  6483. %57 = OpLoad %v2uint %15
  6484. %58 = OpLoad %v2uint %15
  6485. %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
  6486. OpStore %101 %59
  6487. %69 = OpLoad %42 %104
  6488. %70 = OpLoad %46 %103
  6489. %71 = OpSampledImage %50 %69 %70
  6490. %73 = OpLoad %v4float %100
  6491. %74 = OpVectorShuffle %v2float %73 %73 0 0
  6492. %75 = OpImageSampleImplicitLod %v4float %71 %74
  6493. OpStore %101 %75
  6494. OpReturn
  6495. OpFunctionEnd
  6496. )";
  6497. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6498. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6499. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6500. EXPECT_THAT(
  6501. getDiagnosticString(),
  6502. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  6503. }
  6504. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseC) {
  6505. std::string text = R"(
  6506. OpCapability Shader
  6507. OpCapability TextureBlockMatchQCOM
  6508. OpExtension "SPV_QCOM_image_processing"
  6509. %1 = OpExtInstImport "GLSL.std.450"
  6510. OpMemoryModel Logical GLSL450
  6511. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  6512. OpExecutionMode %2 OriginUpperLeft
  6513. OpDecorate %3 Location 0
  6514. OpDecorate %4 Location 0
  6515. OpDecorate %5 DescriptorSet 0
  6516. OpDecorate %5 Binding 4
  6517. OpDecorate %6 DescriptorSet 0
  6518. OpDecorate %6 Binding 5
  6519. OpDecorate %5 BlockMatchTextureQCOM
  6520. OpDecorate %6 BlockMatchTextureQCOM
  6521. %void = OpTypeVoid
  6522. %8 = OpTypeFunction %void
  6523. %uint = OpTypeInt 32 0
  6524. %v2uint = OpTypeVector %uint 2
  6525. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6526. %float = OpTypeFloat 32
  6527. %v4float = OpTypeVector %float 4
  6528. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6529. %3 = OpVariable %_ptr_Input_v4float Input
  6530. %uint_4 = OpConstant %uint 4
  6531. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  6532. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6533. %4 = OpVariable %_ptr_Output_v4float Output
  6534. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6535. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  6536. %20 = OpTypeSampledImage %18
  6537. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  6538. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  6539. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  6540. %v2float = OpTypeVector %float 2
  6541. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6542. %2 = OpFunction %void None %8
  6543. %24 = OpLabel
  6544. %25 = OpVariable %_ptr_Function_v2uint Function
  6545. OpStore %25 %16
  6546. %26 = OpLoad %20 %5
  6547. %27 = OpLoad %v2uint %25
  6548. %28 = OpLoad %20 %6
  6549. %29 = OpLoad %v2uint %25
  6550. %30 = OpLoad %v2uint %25
  6551. %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
  6552. OpStore %4 %31
  6553. %32 = OpLoad %20 %5
  6554. %33 = OpLoad %v4float %3
  6555. %34 = OpVectorShuffle %v2float %33 %33 0 2
  6556. %35 = OpImageSampleImplicitLod %v4float %32 %34
  6557. OpStore %4 %35
  6558. OpReturn
  6559. OpFunctionEnd
  6560. )";
  6561. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6562. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6563. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6564. EXPECT_THAT(
  6565. getDiagnosticString(),
  6566. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  6567. }
  6568. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseD) {
  6569. std::string text = R"(
  6570. OpCapability Shader
  6571. OpCapability TextureBlockMatchQCOM
  6572. OpExtension "SPV_QCOM_image_processing"
  6573. %1 = OpExtInstImport "GLSL.std.450"
  6574. OpMemoryModel Logical GLSL450
  6575. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  6576. OpExecutionMode %2 OriginUpperLeft
  6577. OpDecorate %3 Location 0
  6578. OpDecorate %4 Location 0
  6579. OpDecorate %5 DescriptorSet 0
  6580. OpDecorate %5 Binding 4
  6581. OpDecorate %6 DescriptorSet 0
  6582. OpDecorate %6 Binding 5
  6583. OpDecorate %5 BlockMatchTextureQCOM
  6584. OpDecorate %6 BlockMatchTextureQCOM
  6585. %void = OpTypeVoid
  6586. %8 = OpTypeFunction %void
  6587. %uint = OpTypeInt 32 0
  6588. %v2uint = OpTypeVector %uint 2
  6589. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6590. %float = OpTypeFloat 32
  6591. %v4float = OpTypeVector %float 4
  6592. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6593. %3 = OpVariable %_ptr_Input_v4float Input
  6594. %uint_4 = OpConstant %uint 4
  6595. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  6596. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6597. %4 = OpVariable %_ptr_Output_v4float Output
  6598. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6599. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  6600. %20 = OpTypeSampledImage %18
  6601. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  6602. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  6603. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  6604. %v2float = OpTypeVector %float 2
  6605. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6606. %2 = OpFunction %void None %8
  6607. %24 = OpLabel
  6608. %25 = OpVariable %_ptr_Function_v2uint Function
  6609. OpStore %25 %16
  6610. %26 = OpLoad %20 %5
  6611. %27 = OpLoad %v2uint %25
  6612. %28 = OpLoad %20 %6
  6613. %29 = OpLoad %v2uint %25
  6614. %30 = OpLoad %v2uint %25
  6615. %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
  6616. OpStore %4 %31
  6617. %32 = OpLoad %20 %6
  6618. %33 = OpLoad %v4float %3
  6619. %34 = OpVectorShuffle %v2float %33 %33 0 2
  6620. %35 = OpImageSampleImplicitLod %v4float %32 %34
  6621. OpStore %4 %35
  6622. OpReturn
  6623. OpFunctionEnd
  6624. )";
  6625. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6626. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6627. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6628. EXPECT_THAT(
  6629. getDiagnosticString(),
  6630. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  6631. }
  6632. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseA) {
  6633. std::string text = R"(
  6634. ; SPIR-V
  6635. ; Version: 1.0
  6636. ; Generator: Khronos Glslang Reference Front End; 11
  6637. ; Bound: 79
  6638. ; Schema: 0
  6639. OpCapability Shader
  6640. OpCapability TextureBlockMatchQCOM
  6641. OpExtension "SPV_QCOM_image_processing"
  6642. %1 = OpExtInstImport "GLSL.std.450"
  6643. OpMemoryModel Logical GLSL450
  6644. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  6645. OpExecutionMode %main OriginUpperLeft
  6646. OpDecorate %100 Location 0
  6647. OpDecorate %101 Location 0
  6648. OpDecorate %102 DescriptorSet 0
  6649. OpDecorate %102 Binding 1
  6650. OpDecorate %103 DescriptorSet 0
  6651. OpDecorate %103 Binding 3
  6652. OpDecorate %104 DescriptorSet 0
  6653. OpDecorate %104 Binding 2
  6654. OpDecorate %102 BlockMatchTextureQCOM
  6655. OpDecorate %104 BlockMatchTextureQCOM
  6656. %void = OpTypeVoid
  6657. %3 = OpTypeFunction %void
  6658. %uint = OpTypeInt 32 0
  6659. %v2uint = OpTypeVector %uint 2
  6660. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6661. %float = OpTypeFloat 32
  6662. %v4float = OpTypeVector %float 4
  6663. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6664. %100 = OpVariable %_ptr_Input_v4float Input
  6665. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6666. %101 = OpVariable %_ptr_Output_v4float Output
  6667. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6668. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  6669. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  6670. %46 = OpTypeSampler
  6671. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  6672. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  6673. %50 = OpTypeSampledImage %42
  6674. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  6675. %v2float = OpTypeVector %float 2
  6676. %main = OpFunction %void None %3
  6677. %5 = OpLabel
  6678. %15 = OpVariable %_ptr_Function_v2uint Function
  6679. %45 = OpLoad %42 %102
  6680. %49 = OpLoad %46 %103
  6681. %51 = OpSampledImage %50 %45 %49
  6682. %52 = OpLoad %v2uint %15
  6683. %54 = OpLoad %42 %104
  6684. %55 = OpLoad %46 %103
  6685. %56 = OpSampledImage %50 %54 %55
  6686. %57 = OpLoad %v2uint %15
  6687. %58 = OpLoad %v2uint %15
  6688. %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
  6689. OpStore %101 %59
  6690. %69 = OpLoad %42 %102
  6691. %70 = OpLoad %46 %103
  6692. %71 = OpSampledImage %50 %69 %70
  6693. %73 = OpLoad %v4float %100
  6694. %74 = OpVectorShuffle %v2float %73 %73 0 0
  6695. %75 = OpImageSampleImplicitLod %v4float %71 %74
  6696. OpStore %101 %75
  6697. OpReturn
  6698. OpFunctionEnd
  6699. )";
  6700. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6701. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6702. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6703. EXPECT_THAT(
  6704. getDiagnosticString(),
  6705. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  6706. }
  6707. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseB) {
  6708. std::string text = R"(
  6709. ; SPIR-V
  6710. ; Version: 1.0
  6711. ; Generator: Khronos Glslang Reference Front End; 11
  6712. ; Bound: 79
  6713. ; Schema: 0
  6714. OpCapability Shader
  6715. OpCapability TextureBlockMatchQCOM
  6716. OpExtension "SPV_QCOM_image_processing"
  6717. %1 = OpExtInstImport "GLSL.std.450"
  6718. OpMemoryModel Logical GLSL450
  6719. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  6720. OpExecutionMode %main OriginUpperLeft
  6721. OpDecorate %100 Location 0
  6722. OpDecorate %101 Location 0
  6723. OpDecorate %102 DescriptorSet 0
  6724. OpDecorate %102 Binding 1
  6725. OpDecorate %103 DescriptorSet 0
  6726. OpDecorate %103 Binding 3
  6727. OpDecorate %104 DescriptorSet 0
  6728. OpDecorate %104 Binding 2
  6729. OpDecorate %102 BlockMatchTextureQCOM
  6730. OpDecorate %104 BlockMatchTextureQCOM
  6731. %void = OpTypeVoid
  6732. %3 = OpTypeFunction %void
  6733. %uint = OpTypeInt 32 0
  6734. %v2uint = OpTypeVector %uint 2
  6735. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6736. %float = OpTypeFloat 32
  6737. %v4float = OpTypeVector %float 4
  6738. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6739. %100 = OpVariable %_ptr_Input_v4float Input
  6740. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6741. %101 = OpVariable %_ptr_Output_v4float Output
  6742. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6743. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  6744. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  6745. %46 = OpTypeSampler
  6746. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  6747. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  6748. %50 = OpTypeSampledImage %42
  6749. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  6750. %v2float = OpTypeVector %float 2
  6751. %main = OpFunction %void None %3
  6752. %5 = OpLabel
  6753. %15 = OpVariable %_ptr_Function_v2uint Function
  6754. %45 = OpLoad %42 %102
  6755. %49 = OpLoad %46 %103
  6756. %51 = OpSampledImage %50 %45 %49
  6757. %52 = OpLoad %v2uint %15
  6758. %54 = OpLoad %42 %104
  6759. %55 = OpLoad %46 %103
  6760. %56 = OpSampledImage %50 %54 %55
  6761. %57 = OpLoad %v2uint %15
  6762. %58 = OpLoad %v2uint %15
  6763. %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
  6764. OpStore %101 %59
  6765. %69 = OpLoad %42 %104
  6766. %70 = OpLoad %46 %103
  6767. %71 = OpSampledImage %50 %69 %70
  6768. %73 = OpLoad %v4float %100
  6769. %74 = OpVectorShuffle %v2float %73 %73 0 0
  6770. %75 = OpImageSampleImplicitLod %v4float %71 %74
  6771. OpStore %101 %75
  6772. OpReturn
  6773. OpFunctionEnd
  6774. )";
  6775. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6776. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6777. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6778. EXPECT_THAT(
  6779. getDiagnosticString(),
  6780. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  6781. }
  6782. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseC) {
  6783. std::string text = R"(
  6784. OpCapability Shader
  6785. OpCapability TextureBlockMatchQCOM
  6786. OpExtension "SPV_QCOM_image_processing"
  6787. %1 = OpExtInstImport "GLSL.std.450"
  6788. OpMemoryModel Logical GLSL450
  6789. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  6790. OpExecutionMode %2 OriginUpperLeft
  6791. OpDecorate %3 Location 0
  6792. OpDecorate %4 Location 0
  6793. OpDecorate %5 DescriptorSet 0
  6794. OpDecorate %5 Binding 4
  6795. OpDecorate %6 DescriptorSet 0
  6796. OpDecorate %6 Binding 5
  6797. OpDecorate %5 BlockMatchTextureQCOM
  6798. OpDecorate %6 BlockMatchTextureQCOM
  6799. %void = OpTypeVoid
  6800. %8 = OpTypeFunction %void
  6801. %uint = OpTypeInt 32 0
  6802. %v2uint = OpTypeVector %uint 2
  6803. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6804. %float = OpTypeFloat 32
  6805. %v4float = OpTypeVector %float 4
  6806. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6807. %3 = OpVariable %_ptr_Input_v4float Input
  6808. %uint_4 = OpConstant %uint 4
  6809. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  6810. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6811. %4 = OpVariable %_ptr_Output_v4float Output
  6812. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6813. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  6814. %20 = OpTypeSampledImage %18
  6815. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  6816. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  6817. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  6818. %v2float = OpTypeVector %float 2
  6819. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6820. %2 = OpFunction %void None %8
  6821. %24 = OpLabel
  6822. %25 = OpVariable %_ptr_Function_v2uint Function
  6823. OpStore %25 %16
  6824. %26 = OpLoad %20 %5
  6825. %27 = OpLoad %v2uint %25
  6826. %28 = OpLoad %20 %6
  6827. %29 = OpLoad %v2uint %25
  6828. %30 = OpLoad %v2uint %25
  6829. %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
  6830. OpStore %4 %31
  6831. %32 = OpLoad %20 %5
  6832. %33 = OpLoad %v4float %3
  6833. %34 = OpVectorShuffle %v2float %33 %33 0 2
  6834. %35 = OpImageSampleImplicitLod %v4float %32 %34
  6835. OpStore %4 %35
  6836. OpReturn
  6837. OpFunctionEnd
  6838. )";
  6839. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6840. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6841. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6842. EXPECT_THAT(
  6843. getDiagnosticString(),
  6844. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  6845. }
  6846. TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseD) {
  6847. std::string text = R"(
  6848. OpCapability Shader
  6849. OpCapability TextureBlockMatchQCOM
  6850. OpExtension "SPV_QCOM_image_processing"
  6851. %1 = OpExtInstImport "GLSL.std.450"
  6852. OpMemoryModel Logical GLSL450
  6853. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  6854. OpExecutionMode %2 OriginUpperLeft
  6855. OpDecorate %3 Location 0
  6856. OpDecorate %4 Location 0
  6857. OpDecorate %5 DescriptorSet 0
  6858. OpDecorate %5 Binding 4
  6859. OpDecorate %6 DescriptorSet 0
  6860. OpDecorate %6 Binding 5
  6861. OpDecorate %5 BlockMatchTextureQCOM
  6862. OpDecorate %6 BlockMatchTextureQCOM
  6863. %void = OpTypeVoid
  6864. %8 = OpTypeFunction %void
  6865. %uint = OpTypeInt 32 0
  6866. %v2uint = OpTypeVector %uint 2
  6867. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  6868. %float = OpTypeFloat 32
  6869. %v4float = OpTypeVector %float 4
  6870. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6871. %3 = OpVariable %_ptr_Input_v4float Input
  6872. %uint_4 = OpConstant %uint 4
  6873. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  6874. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6875. %4 = OpVariable %_ptr_Output_v4float Output
  6876. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6877. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  6878. %20 = OpTypeSampledImage %18
  6879. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  6880. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  6881. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  6882. %v2float = OpTypeVector %float 2
  6883. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6884. %2 = OpFunction %void None %8
  6885. %24 = OpLabel
  6886. %25 = OpVariable %_ptr_Function_v2uint Function
  6887. OpStore %25 %16
  6888. %26 = OpLoad %20 %5
  6889. %27 = OpLoad %v2uint %25
  6890. %28 = OpLoad %20 %6
  6891. %29 = OpLoad %v2uint %25
  6892. %30 = OpLoad %v2uint %25
  6893. %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
  6894. OpStore %4 %31
  6895. %32 = OpLoad %20 %6
  6896. %33 = OpLoad %v4float %3
  6897. %34 = OpVectorShuffle %v2float %33 %33 0 2
  6898. %35 = OpImageSampleImplicitLod %v4float %32 %34
  6899. OpStore %4 %35
  6900. OpReturn
  6901. OpFunctionEnd
  6902. )";
  6903. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6904. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6905. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6906. EXPECT_THAT(
  6907. getDiagnosticString(),
  6908. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  6909. }
  6910. TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseA) {
  6911. std::string text = R"(
  6912. OpCapability Shader
  6913. OpCapability TextureSampleWeightedQCOM
  6914. OpExtension "SPV_QCOM_image_processing"
  6915. %1 = OpExtInstImport "GLSL.std.450"
  6916. OpMemoryModel Logical GLSL450
  6917. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  6918. OpExecutionMode %2 OriginUpperLeft
  6919. OpDecorate %3 Location 0
  6920. OpDecorate %4 Location 0
  6921. OpDecorate %5 DescriptorSet 0
  6922. OpDecorate %5 Binding 4
  6923. OpDecorate %6 DescriptorSet 0
  6924. OpDecorate %6 Binding 5
  6925. OpDecorate %6 WeightTextureQCOM
  6926. %void = OpTypeVoid
  6927. %8 = OpTypeFunction %void
  6928. %float = OpTypeFloat 32
  6929. %v4float = OpTypeVector %float 4
  6930. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6931. %3 = OpVariable %_ptr_Output_v4float Output
  6932. %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
  6933. %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
  6934. %14 = OpTypeSampledImage %12
  6935. %_ptr_Input_v4float = OpTypePointer Input %v4float
  6936. %4 = OpVariable %_ptr_Input_v4float Input
  6937. %v2float = OpTypeVector %float 2
  6938. %17 = OpTypeImage %float 2D 0 1 0 1 Unknown
  6939. %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
  6940. %19 = OpTypeSampledImage %17
  6941. %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
  6942. %5 = OpVariable %_ptr_UniformConstant_14 UniformConstant
  6943. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  6944. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  6945. %v3float = OpTypeVector %float 3
  6946. %2 = OpFunction %void None %8
  6947. %23 = OpLabel
  6948. %24 = OpLoad %v4float %4
  6949. %25 = OpVectorShuffle %v2float %24 %24 0 1
  6950. %26 = OpLoad %14 %5
  6951. %27 = OpLoad %v4float %4
  6952. %28 = OpVectorShuffle %v2float %27 %27 0 1
  6953. %29 = OpLoad %19 %6
  6954. %30 = OpImageSampleWeightedQCOM %v4float %26 %28 %29
  6955. OpStore %3 %30
  6956. %31 = OpLoad %19 %6
  6957. %32 = OpLoad %v4float %4
  6958. %33 = OpVectorShuffle %v3float %32 %32 0 1 0
  6959. %34 = OpCompositeExtract %float %33 0
  6960. %35 = OpCompositeExtract %float %33 1
  6961. %36 = OpCompositeExtract %float %33 2
  6962. %37 = OpCompositeConstruct %v3float %34 %35 %36
  6963. %38 = OpImageSampleImplicitLod %v4float %31 %37
  6964. OpStore %3 %38
  6965. OpReturn
  6966. OpFunctionEnd
  6967. )";
  6968. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  6969. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  6970. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6971. EXPECT_THAT(
  6972. getDiagnosticString(),
  6973. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  6974. }
  6975. TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseB) {
  6976. std::string text = R"(
  6977. OpCapability Shader
  6978. OpCapability TextureSampleWeightedQCOM
  6979. OpExtension "SPV_QCOM_image_processing"
  6980. %1 = OpExtInstImport "GLSL.std.450"
  6981. OpMemoryModel Logical GLSL450
  6982. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
  6983. OpExecutionMode %2 OriginUpperLeft
  6984. OpDecorate %3 Location 0
  6985. OpDecorate %5 DescriptorSet 0
  6986. OpDecorate %5 Binding 1
  6987. OpDecorate %6 DescriptorSet 0
  6988. OpDecorate %6 Binding 3
  6989. OpDecorate %4 Location 0
  6990. OpDecorate %7 DescriptorSet 0
  6991. OpDecorate %7 Binding 0
  6992. OpDecorate %7 WeightTextureQCOM
  6993. %void = OpTypeVoid
  6994. %9 = OpTypeFunction %void
  6995. %float = OpTypeFloat 32
  6996. %v4float = OpTypeVector %float 4
  6997. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6998. %3 = OpVariable %_ptr_Output_v4float Output
  6999. %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7000. %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
  7001. %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
  7002. %15 = OpTypeSampler
  7003. %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
  7004. %6 = OpVariable %_ptr_UniformConstant_15 UniformConstant
  7005. %17 = OpTypeSampledImage %13
  7006. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7007. %4 = OpVariable %_ptr_Input_v4float Input
  7008. %v2float = OpTypeVector %float 2
  7009. %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
  7010. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  7011. %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  7012. %22 = OpTypeSampledImage %20
  7013. %v3float = OpTypeVector %float 3
  7014. %2 = OpFunction %void None %9
  7015. %24 = OpLabel
  7016. %25 = OpLoad %13 %5
  7017. %26 = OpLoad %15 %6
  7018. %27 = OpSampledImage %17 %25 %26
  7019. %28 = OpLoad %v4float %4
  7020. %29 = OpVectorShuffle %v2float %28 %28 0 1
  7021. %30 = OpLoad %20 %7
  7022. %31 = OpLoad %15 %6
  7023. %32 = OpSampledImage %22 %30 %31
  7024. %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
  7025. OpStore %3 %33
  7026. %34 = OpLoad %20 %7
  7027. %35 = OpLoad %15 %6
  7028. %36 = OpSampledImage %22 %34 %35
  7029. %37 = OpLoad %v4float %4
  7030. %38 = OpVectorShuffle %v3float %37 %37 0 1 0
  7031. %39 = OpCompositeExtract %float %38 0
  7032. %40 = OpCompositeExtract %float %38 1
  7033. %41 = OpCompositeExtract %float %38 2
  7034. %42 = OpCompositeConstruct %v3float %39 %40 %41
  7035. %43 = OpImageSampleImplicitLod %v4float %36 %42
  7036. OpStore %3 %43
  7037. OpReturn
  7038. OpFunctionEnd
  7039. )";
  7040. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7041. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7042. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7043. EXPECT_THAT(
  7044. getDiagnosticString(),
  7045. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  7046. }
  7047. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIT) {
  7048. const std::string text = R"(
  7049. OpCapability Shader
  7050. OpCapability TextureBlockMatchQCOM
  7051. OpCapability TextureBlockMatch2QCOM
  7052. OpExtension "SPV_QCOM_image_processing"
  7053. OpExtension "SPV_QCOM_image_processing2"
  7054. %1 = OpExtInstImport "GLSL.std.450"
  7055. OpMemoryModel Logical GLSL450
  7056. OpEntryPoint Fragment %2 "main" %3 %4 %5
  7057. OpExecutionMode %2 OriginUpperLeft
  7058. OpDecorate %3 Location 0
  7059. OpDecorate %4 DescriptorSet 0
  7060. OpDecorate %4 Binding 4
  7061. OpDecorate %4 BlockMatchSamplerQCOM
  7062. OpDecorate %5 DescriptorSet 0
  7063. OpDecorate %5 Binding 5
  7064. OpDecorate %5 BlockMatchTextureQCOM
  7065. OpDecorate %5 BlockMatchSamplerQCOM
  7066. %void = OpTypeVoid
  7067. %7 = OpTypeFunction %void
  7068. %uint = OpTypeInt 32 0
  7069. %v2uint = OpTypeVector %uint 2
  7070. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7071. %float = OpTypeFloat 32
  7072. %v4float = OpTypeVector %float 4
  7073. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7074. %_ptr_Input_float = OpTypePointer Input %float
  7075. %_ptr_Function_uint = OpTypePointer Function %uint
  7076. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7077. %3 = OpVariable %_ptr_Output_v4float Output
  7078. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7079. %19 = OpTypeSampledImage %18
  7080. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7081. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7082. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7083. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  7084. %2 = OpFunction %void None %7
  7085. %22 = OpLabel
  7086. %23 = OpVariable %_ptr_Function_v2uint Function
  7087. %24 = OpLoad %19 %4
  7088. %25 = OpLoad %v2uint %23
  7089. %26 = OpLoad %19 %5
  7090. %27 = OpLoad %v2uint %23
  7091. %28 = OpLoad %v2uint %23
  7092. %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
  7093. OpStore %3 %29
  7094. OpReturn
  7095. OpFunctionEnd
  7096. )";
  7097. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7098. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7099. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7100. EXPECT_THAT(getDiagnosticString(),
  7101. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  7102. }
  7103. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIS) {
  7104. const std::string text = R"(
  7105. OpCapability Shader
  7106. OpCapability TextureBlockMatchQCOM
  7107. OpCapability TextureBlockMatch2QCOM
  7108. OpExtension "SPV_QCOM_image_processing"
  7109. OpExtension "SPV_QCOM_image_processing2"
  7110. %1 = OpExtInstImport "GLSL.std.450"
  7111. OpMemoryModel Logical GLSL450
  7112. OpEntryPoint Fragment %2 "main" %3 %4 %5
  7113. OpExecutionMode %2 OriginUpperLeft
  7114. OpDecorate %3 Location 0
  7115. OpDecorate %4 DescriptorSet 0
  7116. OpDecorate %4 Binding 4
  7117. OpDecorate %4 BlockMatchTextureQCOM
  7118. OpDecorate %5 DescriptorSet 0
  7119. OpDecorate %5 Binding 5
  7120. OpDecorate %5 BlockMatchTextureQCOM
  7121. OpDecorate %5 BlockMatchSamplerQCOM
  7122. %void = OpTypeVoid
  7123. %7 = OpTypeFunction %void
  7124. %uint = OpTypeInt 32 0
  7125. %v2uint = OpTypeVector %uint 2
  7126. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7127. %float = OpTypeFloat 32
  7128. %v4float = OpTypeVector %float 4
  7129. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7130. %_ptr_Input_float = OpTypePointer Input %float
  7131. %_ptr_Function_uint = OpTypePointer Function %uint
  7132. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7133. %3 = OpVariable %_ptr_Output_v4float Output
  7134. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7135. %19 = OpTypeSampledImage %18
  7136. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7137. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7138. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7139. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  7140. %2 = OpFunction %void None %7
  7141. %22 = OpLabel
  7142. %23 = OpVariable %_ptr_Function_v2uint Function
  7143. %24 = OpLoad %19 %4
  7144. %25 = OpLoad %v2uint %23
  7145. %26 = OpLoad %19 %5
  7146. %27 = OpLoad %v2uint %23
  7147. %28 = OpLoad %v2uint %23
  7148. %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
  7149. OpStore %3 %29
  7150. OpReturn
  7151. OpFunctionEnd
  7152. )";
  7153. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7154. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7155. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7156. EXPECT_THAT(getDiagnosticString(),
  7157. HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
  7158. }
  7159. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIT) {
  7160. const std::string text = R"(
  7161. OpCapability Shader
  7162. OpCapability TextureBlockMatchQCOM
  7163. OpCapability TextureBlockMatch2QCOM
  7164. OpExtension "SPV_QCOM_image_processing"
  7165. OpExtension "SPV_QCOM_image_processing2"
  7166. %1 = OpExtInstImport "GLSL.std.450"
  7167. OpMemoryModel Logical GLSL450
  7168. OpEntryPoint Fragment %2 "main" %3 %4 %5
  7169. OpExecutionMode %2 OriginUpperLeft
  7170. OpDecorate %3 Location 0
  7171. OpDecorate %4 DescriptorSet 0
  7172. OpDecorate %4 Binding 4
  7173. OpDecorate %4 BlockMatchTextureQCOM
  7174. OpDecorate %4 BlockMatchSamplerQCOM
  7175. OpDecorate %5 DescriptorSet 0
  7176. OpDecorate %5 Binding 5
  7177. OpDecorate %5 BlockMatchSamplerQCOM
  7178. %void = OpTypeVoid
  7179. %7 = OpTypeFunction %void
  7180. %uint = OpTypeInt 32 0
  7181. %v2uint = OpTypeVector %uint 2
  7182. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7183. %float = OpTypeFloat 32
  7184. %v4float = OpTypeVector %float 4
  7185. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7186. %_ptr_Input_float = OpTypePointer Input %float
  7187. %_ptr_Function_uint = OpTypePointer Function %uint
  7188. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7189. %3 = OpVariable %_ptr_Output_v4float Output
  7190. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7191. %19 = OpTypeSampledImage %18
  7192. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7193. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7194. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7195. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  7196. %2 = OpFunction %void None %7
  7197. %22 = OpLabel
  7198. %23 = OpVariable %_ptr_Function_v2uint Function
  7199. %24 = OpLoad %19 %4
  7200. %25 = OpLoad %v2uint %23
  7201. %26 = OpLoad %19 %5
  7202. %27 = OpLoad %v2uint %23
  7203. %28 = OpLoad %v2uint %23
  7204. %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
  7205. OpStore %3 %29
  7206. OpReturn
  7207. OpFunctionEnd
  7208. )";
  7209. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7210. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7211. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7212. EXPECT_THAT(getDiagnosticString(),
  7213. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  7214. }
  7215. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIS) {
  7216. const std::string text = R"(
  7217. OpCapability Shader
  7218. OpCapability TextureBlockMatchQCOM
  7219. OpCapability TextureBlockMatch2QCOM
  7220. OpExtension "SPV_QCOM_image_processing"
  7221. OpExtension "SPV_QCOM_image_processing2"
  7222. %1 = OpExtInstImport "GLSL.std.450"
  7223. OpMemoryModel Logical GLSL450
  7224. OpEntryPoint Fragment %2 "main" %3 %4 %5
  7225. OpExecutionMode %2 OriginUpperLeft
  7226. OpDecorate %3 Location 0
  7227. OpDecorate %4 DescriptorSet 0
  7228. OpDecorate %4 Binding 4
  7229. OpDecorate %4 BlockMatchTextureQCOM
  7230. OpDecorate %4 BlockMatchSamplerQCOM
  7231. OpDecorate %5 DescriptorSet 0
  7232. OpDecorate %5 Binding 5
  7233. OpDecorate %5 BlockMatchTextureQCOM
  7234. %void = OpTypeVoid
  7235. %7 = OpTypeFunction %void
  7236. %uint = OpTypeInt 32 0
  7237. %v2uint = OpTypeVector %uint 2
  7238. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7239. %float = OpTypeFloat 32
  7240. %v4float = OpTypeVector %float 4
  7241. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7242. %_ptr_Input_float = OpTypePointer Input %float
  7243. %_ptr_Function_uint = OpTypePointer Function %uint
  7244. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7245. %3 = OpVariable %_ptr_Output_v4float Output
  7246. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7247. %19 = OpTypeSampledImage %18
  7248. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7249. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7250. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7251. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  7252. %2 = OpFunction %void None %7
  7253. %22 = OpLabel
  7254. %23 = OpVariable %_ptr_Function_v2uint Function
  7255. %24 = OpLoad %19 %4
  7256. %25 = OpLoad %v2uint %23
  7257. %26 = OpLoad %19 %5
  7258. %27 = OpLoad %v2uint %23
  7259. %28 = OpLoad %v2uint %23
  7260. %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
  7261. OpStore %3 %29
  7262. OpReturn
  7263. OpFunctionEnd
  7264. )";
  7265. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7266. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7267. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7268. EXPECT_THAT(getDiagnosticString(),
  7269. HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
  7270. }
  7271. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIT) {
  7272. const std::string text = R"(
  7273. OpCapability Shader
  7274. OpCapability TextureBlockMatchQCOM
  7275. OpCapability TextureBlockMatch2QCOM
  7276. OpExtension "SPV_QCOM_image_processing"
  7277. OpExtension "SPV_QCOM_image_processing2"
  7278. %1 = OpExtInstImport "GLSL.std.450"
  7279. OpMemoryModel Logical GLSL450
  7280. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  7281. OpExecutionMode %2 OriginUpperLeft
  7282. OpDecorate %3 Location 0
  7283. OpDecorate %4 DescriptorSet 0
  7284. OpDecorate %4 Binding 1
  7285. OpDecorate %4 BlockMatchSamplerQCOM
  7286. OpDecorate %5 DescriptorSet 0
  7287. OpDecorate %5 Binding 3
  7288. OpDecorate %6 DescriptorSet 0
  7289. OpDecorate %6 Binding 2
  7290. OpDecorate %6 BlockMatchTextureQCOM
  7291. OpDecorate %6 BlockMatchSamplerQCOM
  7292. %void = OpTypeVoid
  7293. %8 = OpTypeFunction %void
  7294. %uint = OpTypeInt 32 0
  7295. %v2uint = OpTypeVector %uint 2
  7296. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7297. %float = OpTypeFloat 32
  7298. %v4float = OpTypeVector %float 4
  7299. %_ptr_Input_float = OpTypePointer Input %float
  7300. %_ptr_Function_uint = OpTypePointer Function %uint
  7301. %uint_4 = OpConstant %uint 4
  7302. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  7303. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7304. %3 = OpVariable %_ptr_Output_v4float Output
  7305. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7306. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7307. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7308. %21 = OpTypeSampler
  7309. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  7310. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  7311. %23 = OpTypeSampledImage %19
  7312. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7313. %2 = OpFunction %void None %8
  7314. %24 = OpLabel
  7315. %25 = OpVariable %_ptr_Function_v2uint Function
  7316. %26 = OpLoad %19 %4
  7317. %27 = OpLoad %21 %5
  7318. %28 = OpSampledImage %23 %26 %27
  7319. %29 = OpLoad %v2uint %25
  7320. %30 = OpLoad %19 %6
  7321. %31 = OpLoad %21 %5
  7322. %32 = OpSampledImage %23 %30 %31
  7323. %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
  7324. OpStore %3 %33
  7325. OpReturn
  7326. OpFunctionEnd
  7327. )";
  7328. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7329. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7330. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7331. EXPECT_THAT(getDiagnosticString(),
  7332. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  7333. }
  7334. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIS) {
  7335. const std::string text = R"(
  7336. OpCapability Shader
  7337. OpCapability TextureBlockMatchQCOM
  7338. OpCapability TextureBlockMatch2QCOM
  7339. OpExtension "SPV_QCOM_image_processing"
  7340. OpExtension "SPV_QCOM_image_processing2"
  7341. %1 = OpExtInstImport "GLSL.std.450"
  7342. OpMemoryModel Logical GLSL450
  7343. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  7344. OpExecutionMode %2 OriginUpperLeft
  7345. OpDecorate %3 Location 0
  7346. OpDecorate %4 DescriptorSet 0
  7347. OpDecorate %4 Binding 1
  7348. OpDecorate %4 BlockMatchTextureQCOM
  7349. OpDecorate %5 DescriptorSet 0
  7350. OpDecorate %5 Binding 3
  7351. OpDecorate %6 DescriptorSet 0
  7352. OpDecorate %6 Binding 2
  7353. OpDecorate %6 BlockMatchTextureQCOM
  7354. OpDecorate %6 BlockMatchSamplerQCOM
  7355. %void = OpTypeVoid
  7356. %8 = OpTypeFunction %void
  7357. %uint = OpTypeInt 32 0
  7358. %v2uint = OpTypeVector %uint 2
  7359. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7360. %float = OpTypeFloat 32
  7361. %v4float = OpTypeVector %float 4
  7362. %_ptr_Input_float = OpTypePointer Input %float
  7363. %_ptr_Function_uint = OpTypePointer Function %uint
  7364. %uint_4 = OpConstant %uint 4
  7365. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  7366. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7367. %3 = OpVariable %_ptr_Output_v4float Output
  7368. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7369. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7370. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7371. %21 = OpTypeSampler
  7372. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  7373. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  7374. %23 = OpTypeSampledImage %19
  7375. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7376. %2 = OpFunction %void None %8
  7377. %24 = OpLabel
  7378. %25 = OpVariable %_ptr_Function_v2uint Function
  7379. %26 = OpLoad %19 %4
  7380. %27 = OpLoad %21 %5
  7381. %28 = OpSampledImage %23 %26 %27
  7382. %29 = OpLoad %v2uint %25
  7383. %30 = OpLoad %19 %6
  7384. %31 = OpLoad %21 %5
  7385. %32 = OpSampledImage %23 %30 %31
  7386. %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
  7387. OpStore %3 %33
  7388. OpReturn
  7389. OpFunctionEnd
  7390. )";
  7391. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7392. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7393. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7394. EXPECT_THAT(getDiagnosticString(),
  7395. HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
  7396. }
  7397. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIT) {
  7398. const std::string text = R"(
  7399. OpCapability Shader
  7400. OpCapability TextureBlockMatchQCOM
  7401. OpCapability TextureBlockMatch2QCOM
  7402. OpExtension "SPV_QCOM_image_processing"
  7403. OpExtension "SPV_QCOM_image_processing2"
  7404. %1 = OpExtInstImport "GLSL.std.450"
  7405. OpMemoryModel Logical GLSL450
  7406. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  7407. OpExecutionMode %2 OriginUpperLeft
  7408. OpDecorate %3 Location 0
  7409. OpDecorate %4 DescriptorSet 0
  7410. OpDecorate %4 Binding 1
  7411. OpDecorate %4 BlockMatchTextureQCOM
  7412. OpDecorate %5 DescriptorSet 0
  7413. OpDecorate %5 Binding 3
  7414. OpDecorate %5 BlockMatchSamplerQCOM
  7415. OpDecorate %6 DescriptorSet 0
  7416. OpDecorate %6 Binding 2
  7417. OpDecorate %6 BlockMatchSamplerQCOM
  7418. %void = OpTypeVoid
  7419. %8 = OpTypeFunction %void
  7420. %uint = OpTypeInt 32 0
  7421. %v2uint = OpTypeVector %uint 2
  7422. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7423. %float = OpTypeFloat 32
  7424. %v4float = OpTypeVector %float 4
  7425. %_ptr_Input_float = OpTypePointer Input %float
  7426. %_ptr_Function_uint = OpTypePointer Function %uint
  7427. %uint_4 = OpConstant %uint 4
  7428. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  7429. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7430. %3 = OpVariable %_ptr_Output_v4float Output
  7431. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7432. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7433. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7434. %21 = OpTypeSampler
  7435. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  7436. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  7437. %23 = OpTypeSampledImage %19
  7438. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7439. %2 = OpFunction %void None %8
  7440. %24 = OpLabel
  7441. %25 = OpVariable %_ptr_Function_v2uint Function
  7442. %26 = OpLoad %19 %4
  7443. %27 = OpLoad %21 %5
  7444. %28 = OpSampledImage %23 %26 %27
  7445. %29 = OpLoad %v2uint %25
  7446. %30 = OpLoad %19 %6
  7447. %31 = OpLoad %21 %5
  7448. %32 = OpSampledImage %23 %30 %31
  7449. %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
  7450. OpStore %3 %33
  7451. OpReturn
  7452. OpFunctionEnd
  7453. )";
  7454. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7455. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7456. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7457. EXPECT_THAT(getDiagnosticString(),
  7458. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  7459. }
  7460. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIS) {
  7461. const std::string text = R"(
  7462. OpCapability Shader
  7463. OpCapability TextureBlockMatchQCOM
  7464. OpCapability TextureBlockMatch2QCOM
  7465. OpExtension "SPV_QCOM_image_processing"
  7466. OpExtension "SPV_QCOM_image_processing2"
  7467. %1 = OpExtInstImport "GLSL.std.450"
  7468. OpMemoryModel Logical GLSL450
  7469. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  7470. OpExecutionMode %2 OriginUpperLeft
  7471. OpDecorate %3 Location 0
  7472. OpDecorate %4 DescriptorSet 0
  7473. OpDecorate %4 Binding 1
  7474. OpDecorate %4 BlockMatchTextureQCOM
  7475. OpDecorate %4 BlockMatchSamplerQCOM
  7476. OpDecorate %5 DescriptorSet 0
  7477. OpDecorate %5 Binding 3
  7478. OpDecorate %6 DescriptorSet 0
  7479. OpDecorate %6 Binding 2
  7480. OpDecorate %6 BlockMatchTextureQCOM
  7481. %void = OpTypeVoid
  7482. %8 = OpTypeFunction %void
  7483. %uint = OpTypeInt 32 0
  7484. %v2uint = OpTypeVector %uint 2
  7485. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7486. %float = OpTypeFloat 32
  7487. %v4float = OpTypeVector %float 4
  7488. %_ptr_Input_float = OpTypePointer Input %float
  7489. %_ptr_Function_uint = OpTypePointer Function %uint
  7490. %uint_4 = OpConstant %uint 4
  7491. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  7492. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7493. %3 = OpVariable %_ptr_Output_v4float Output
  7494. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7495. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7496. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7497. %21 = OpTypeSampler
  7498. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  7499. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  7500. %23 = OpTypeSampledImage %19
  7501. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7502. %2 = OpFunction %void None %8
  7503. %24 = OpLabel
  7504. %25 = OpVariable %_ptr_Function_v2uint Function
  7505. %26 = OpLoad %19 %4
  7506. %27 = OpLoad %21 %5
  7507. %28 = OpSampledImage %23 %26 %27
  7508. %29 = OpLoad %v2uint %25
  7509. %30 = OpLoad %19 %6
  7510. %31 = OpLoad %21 %5
  7511. %32 = OpSampledImage %23 %30 %31
  7512. %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
  7513. OpStore %3 %33
  7514. OpReturn
  7515. OpFunctionEnd
  7516. )";
  7517. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7518. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7519. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7520. EXPECT_THAT(getDiagnosticString(),
  7521. HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
  7522. }
  7523. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIT) {
  7524. const std::string text = R"(
  7525. OpCapability Shader
  7526. OpCapability TextureBlockMatchQCOM
  7527. OpCapability TextureBlockMatch2QCOM
  7528. OpExtension "SPV_QCOM_image_processing"
  7529. OpExtension "SPV_QCOM_image_processing2"
  7530. %1 = OpExtInstImport "GLSL.std.450"
  7531. OpMemoryModel Logical GLSL450
  7532. OpEntryPoint Fragment %2 "main" %3 %4 %5
  7533. OpExecutionMode %2 OriginUpperLeft
  7534. OpDecorate %3 Location 0
  7535. OpDecorate %4 DescriptorSet 0
  7536. OpDecorate %4 Binding 4
  7537. OpDecorate %4 BlockMatchSamplerQCOM
  7538. OpDecorate %5 DescriptorSet 0
  7539. OpDecorate %5 Binding 5
  7540. OpDecorate %5 BlockMatchTextureQCOM
  7541. OpDecorate %5 BlockMatchSamplerQCOM
  7542. %void = OpTypeVoid
  7543. %7 = OpTypeFunction %void
  7544. %uint = OpTypeInt 32 0
  7545. %v2uint = OpTypeVector %uint 2
  7546. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7547. %float = OpTypeFloat 32
  7548. %v4float = OpTypeVector %float 4
  7549. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7550. %_ptr_Input_float = OpTypePointer Input %float
  7551. %_ptr_Function_uint = OpTypePointer Function %uint
  7552. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7553. %3 = OpVariable %_ptr_Output_v4float Output
  7554. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7555. %19 = OpTypeSampledImage %18
  7556. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7557. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7558. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7559. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  7560. %2 = OpFunction %void None %7
  7561. %22 = OpLabel
  7562. %23 = OpVariable %_ptr_Function_v2uint Function
  7563. %24 = OpLoad %19 %4
  7564. %25 = OpLoad %v2uint %23
  7565. %26 = OpLoad %19 %5
  7566. %27 = OpLoad %v2uint %23
  7567. %28 = OpLoad %v2uint %23
  7568. %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
  7569. OpStore %3 %29
  7570. OpReturn
  7571. OpFunctionEnd
  7572. )";
  7573. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7574. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7575. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7576. EXPECT_THAT(getDiagnosticString(),
  7577. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  7578. }
  7579. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIS) {
  7580. const std::string text = R"(
  7581. OpCapability Shader
  7582. OpCapability TextureBlockMatchQCOM
  7583. OpCapability TextureBlockMatch2QCOM
  7584. OpExtension "SPV_QCOM_image_processing"
  7585. OpExtension "SPV_QCOM_image_processing2"
  7586. %1 = OpExtInstImport "GLSL.std.450"
  7587. OpMemoryModel Logical GLSL450
  7588. OpEntryPoint Fragment %2 "main" %3 %4 %5
  7589. OpExecutionMode %2 OriginUpperLeft
  7590. OpDecorate %3 Location 0
  7591. OpDecorate %4 DescriptorSet 0
  7592. OpDecorate %4 Binding 4
  7593. OpDecorate %4 BlockMatchTextureQCOM
  7594. OpDecorate %5 DescriptorSet 0
  7595. OpDecorate %5 Binding 5
  7596. OpDecorate %5 BlockMatchTextureQCOM
  7597. OpDecorate %5 BlockMatchSamplerQCOM
  7598. %void = OpTypeVoid
  7599. %7 = OpTypeFunction %void
  7600. %uint = OpTypeInt 32 0
  7601. %v2uint = OpTypeVector %uint 2
  7602. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7603. %float = OpTypeFloat 32
  7604. %v4float = OpTypeVector %float 4
  7605. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7606. %_ptr_Input_float = OpTypePointer Input %float
  7607. %_ptr_Function_uint = OpTypePointer Function %uint
  7608. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7609. %3 = OpVariable %_ptr_Output_v4float Output
  7610. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7611. %19 = OpTypeSampledImage %18
  7612. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7613. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7614. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7615. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  7616. %2 = OpFunction %void None %7
  7617. %22 = OpLabel
  7618. %23 = OpVariable %_ptr_Function_v2uint Function
  7619. %24 = OpLoad %19 %4
  7620. %25 = OpLoad %v2uint %23
  7621. %26 = OpLoad %19 %5
  7622. %27 = OpLoad %v2uint %23
  7623. %28 = OpLoad %v2uint %23
  7624. %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
  7625. OpStore %3 %29
  7626. OpReturn
  7627. OpFunctionEnd
  7628. )";
  7629. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7630. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7631. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7632. EXPECT_THAT(getDiagnosticString(),
  7633. HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
  7634. }
  7635. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIT) {
  7636. const std::string text = R"(
  7637. OpCapability Shader
  7638. OpCapability TextureBlockMatchQCOM
  7639. OpCapability TextureBlockMatch2QCOM
  7640. OpExtension "SPV_QCOM_image_processing"
  7641. OpExtension "SPV_QCOM_image_processing2"
  7642. %1 = OpExtInstImport "GLSL.std.450"
  7643. OpMemoryModel Logical GLSL450
  7644. OpEntryPoint Fragment %2 "main" %3 %4 %5
  7645. OpExecutionMode %2 OriginUpperLeft
  7646. OpDecorate %3 Location 0
  7647. OpDecorate %4 DescriptorSet 0
  7648. OpDecorate %4 Binding 4
  7649. OpDecorate %4 BlockMatchTextureQCOM
  7650. OpDecorate %4 BlockMatchSamplerQCOM
  7651. OpDecorate %5 DescriptorSet 0
  7652. OpDecorate %5 Binding 5
  7653. OpDecorate %5 BlockMatchSamplerQCOM
  7654. %void = OpTypeVoid
  7655. %7 = OpTypeFunction %void
  7656. %uint = OpTypeInt 32 0
  7657. %v2uint = OpTypeVector %uint 2
  7658. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7659. %float = OpTypeFloat 32
  7660. %v4float = OpTypeVector %float 4
  7661. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7662. %_ptr_Input_float = OpTypePointer Input %float
  7663. %_ptr_Function_uint = OpTypePointer Function %uint
  7664. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7665. %3 = OpVariable %_ptr_Output_v4float Output
  7666. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7667. %19 = OpTypeSampledImage %18
  7668. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7669. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7670. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7671. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  7672. %2 = OpFunction %void None %7
  7673. %22 = OpLabel
  7674. %23 = OpVariable %_ptr_Function_v2uint Function
  7675. %24 = OpLoad %19 %4
  7676. %25 = OpLoad %v2uint %23
  7677. %26 = OpLoad %19 %5
  7678. %27 = OpLoad %v2uint %23
  7679. %28 = OpLoad %v2uint %23
  7680. %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
  7681. OpStore %3 %29
  7682. OpReturn
  7683. OpFunctionEnd
  7684. )";
  7685. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7686. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7687. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7688. EXPECT_THAT(getDiagnosticString(),
  7689. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  7690. }
  7691. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIS) {
  7692. const std::string text = R"(
  7693. OpCapability Shader
  7694. OpCapability TextureBlockMatchQCOM
  7695. OpCapability TextureBlockMatch2QCOM
  7696. OpExtension "SPV_QCOM_image_processing"
  7697. OpExtension "SPV_QCOM_image_processing2"
  7698. %1 = OpExtInstImport "GLSL.std.450"
  7699. OpMemoryModel Logical GLSL450
  7700. OpEntryPoint Fragment %2 "main" %3 %4 %5
  7701. OpExecutionMode %2 OriginUpperLeft
  7702. OpDecorate %3 Location 0
  7703. OpDecorate %4 DescriptorSet 0
  7704. OpDecorate %4 Binding 4
  7705. OpDecorate %4 BlockMatchTextureQCOM
  7706. OpDecorate %4 BlockMatchSamplerQCOM
  7707. OpDecorate %5 DescriptorSet 0
  7708. OpDecorate %5 Binding 5
  7709. OpDecorate %5 BlockMatchTextureQCOM
  7710. %void = OpTypeVoid
  7711. %7 = OpTypeFunction %void
  7712. %uint = OpTypeInt 32 0
  7713. %v2uint = OpTypeVector %uint 2
  7714. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7715. %float = OpTypeFloat 32
  7716. %v4float = OpTypeVector %float 4
  7717. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7718. %_ptr_Input_float = OpTypePointer Input %float
  7719. %_ptr_Function_uint = OpTypePointer Function %uint
  7720. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7721. %3 = OpVariable %_ptr_Output_v4float Output
  7722. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7723. %19 = OpTypeSampledImage %18
  7724. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7725. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7726. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7727. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  7728. %2 = OpFunction %void None %7
  7729. %22 = OpLabel
  7730. %23 = OpVariable %_ptr_Function_v2uint Function
  7731. %24 = OpLoad %19 %4
  7732. %25 = OpLoad %v2uint %23
  7733. %26 = OpLoad %19 %5
  7734. %27 = OpLoad %v2uint %23
  7735. %28 = OpLoad %v2uint %23
  7736. %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
  7737. OpStore %3 %29
  7738. OpReturn
  7739. OpFunctionEnd
  7740. )";
  7741. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7742. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7743. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7744. EXPECT_THAT(getDiagnosticString(),
  7745. HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
  7746. }
  7747. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIT) {
  7748. const std::string text = R"(
  7749. OpCapability Shader
  7750. OpCapability TextureBlockMatchQCOM
  7751. OpCapability TextureBlockMatch2QCOM
  7752. OpExtension "SPV_QCOM_image_processing"
  7753. OpExtension "SPV_QCOM_image_processing2"
  7754. %1 = OpExtInstImport "GLSL.std.450"
  7755. OpMemoryModel Logical GLSL450
  7756. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  7757. OpExecutionMode %2 OriginUpperLeft
  7758. OpDecorate %3 Location 0
  7759. OpDecorate %4 DescriptorSet 0
  7760. OpDecorate %4 Binding 1
  7761. OpDecorate %4 BlockMatchSamplerQCOM
  7762. OpDecorate %5 DescriptorSet 0
  7763. OpDecorate %5 Binding 3
  7764. OpDecorate %6 DescriptorSet 0
  7765. OpDecorate %6 Binding 2
  7766. OpDecorate %6 BlockMatchTextureQCOM
  7767. OpDecorate %6 BlockMatchSamplerQCOM
  7768. %void = OpTypeVoid
  7769. %8 = OpTypeFunction %void
  7770. %uint = OpTypeInt 32 0
  7771. %v2uint = OpTypeVector %uint 2
  7772. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7773. %float = OpTypeFloat 32
  7774. %v4float = OpTypeVector %float 4
  7775. %_ptr_Input_float = OpTypePointer Input %float
  7776. %_ptr_Function_uint = OpTypePointer Function %uint
  7777. %uint_4 = OpConstant %uint 4
  7778. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  7779. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7780. %3 = OpVariable %_ptr_Output_v4float Output
  7781. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7782. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7783. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7784. %21 = OpTypeSampler
  7785. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  7786. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  7787. %23 = OpTypeSampledImage %19
  7788. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7789. %2 = OpFunction %void None %8
  7790. %24 = OpLabel
  7791. %25 = OpVariable %_ptr_Function_v2uint Function
  7792. %26 = OpLoad %19 %4
  7793. %27 = OpLoad %21 %5
  7794. %28 = OpSampledImage %23 %26 %27
  7795. %29 = OpLoad %v2uint %25
  7796. %30 = OpLoad %19 %6
  7797. %31 = OpLoad %21 %5
  7798. %32 = OpSampledImage %23 %30 %31
  7799. %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
  7800. OpStore %3 %33
  7801. OpReturn
  7802. OpFunctionEnd
  7803. )";
  7804. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7805. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7806. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7807. EXPECT_THAT(getDiagnosticString(),
  7808. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  7809. }
  7810. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIS) {
  7811. const std::string text = R"(
  7812. OpCapability Shader
  7813. OpCapability TextureBlockMatchQCOM
  7814. OpCapability TextureBlockMatch2QCOM
  7815. OpExtension "SPV_QCOM_image_processing"
  7816. OpExtension "SPV_QCOM_image_processing2"
  7817. %1 = OpExtInstImport "GLSL.std.450"
  7818. OpMemoryModel Logical GLSL450
  7819. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  7820. OpExecutionMode %2 OriginUpperLeft
  7821. OpDecorate %3 Location 0
  7822. OpDecorate %4 DescriptorSet 0
  7823. OpDecorate %4 Binding 1
  7824. OpDecorate %4 BlockMatchTextureQCOM
  7825. OpDecorate %5 DescriptorSet 0
  7826. OpDecorate %5 Binding 3
  7827. OpDecorate %6 DescriptorSet 0
  7828. OpDecorate %6 Binding 2
  7829. OpDecorate %6 BlockMatchTextureQCOM
  7830. OpDecorate %6 BlockMatchSamplerQCOM
  7831. %void = OpTypeVoid
  7832. %8 = OpTypeFunction %void
  7833. %uint = OpTypeInt 32 0
  7834. %v2uint = OpTypeVector %uint 2
  7835. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7836. %float = OpTypeFloat 32
  7837. %v4float = OpTypeVector %float 4
  7838. %_ptr_Input_float = OpTypePointer Input %float
  7839. %_ptr_Function_uint = OpTypePointer Function %uint
  7840. %uint_4 = OpConstant %uint 4
  7841. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  7842. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7843. %3 = OpVariable %_ptr_Output_v4float Output
  7844. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7845. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7846. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7847. %21 = OpTypeSampler
  7848. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  7849. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  7850. %23 = OpTypeSampledImage %19
  7851. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7852. %2 = OpFunction %void None %8
  7853. %24 = OpLabel
  7854. %25 = OpVariable %_ptr_Function_v2uint Function
  7855. %26 = OpLoad %19 %4
  7856. %27 = OpLoad %21 %5
  7857. %28 = OpSampledImage %23 %26 %27
  7858. %29 = OpLoad %v2uint %25
  7859. %30 = OpLoad %19 %6
  7860. %31 = OpLoad %21 %5
  7861. %32 = OpSampledImage %23 %30 %31
  7862. %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
  7863. OpStore %3 %33
  7864. OpReturn
  7865. OpFunctionEnd
  7866. )";
  7867. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7868. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7869. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7870. EXPECT_THAT(getDiagnosticString(),
  7871. HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
  7872. }
  7873. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIT) {
  7874. const std::string text = R"(
  7875. OpCapability Shader
  7876. OpCapability TextureBlockMatchQCOM
  7877. OpCapability TextureBlockMatch2QCOM
  7878. OpExtension "SPV_QCOM_image_processing"
  7879. OpExtension "SPV_QCOM_image_processing2"
  7880. %1 = OpExtInstImport "GLSL.std.450"
  7881. OpMemoryModel Logical GLSL450
  7882. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  7883. OpExecutionMode %2 OriginUpperLeft
  7884. OpDecorate %3 Location 0
  7885. OpDecorate %4 DescriptorSet 0
  7886. OpDecorate %4 Binding 1
  7887. OpDecorate %4 BlockMatchTextureQCOM
  7888. OpDecorate %5 DescriptorSet 0
  7889. OpDecorate %5 Binding 3
  7890. OpDecorate %5 BlockMatchSamplerQCOM
  7891. OpDecorate %6 DescriptorSet 0
  7892. OpDecorate %6 Binding 2
  7893. OpDecorate %6 BlockMatchSamplerQCOM
  7894. %void = OpTypeVoid
  7895. %8 = OpTypeFunction %void
  7896. %uint = OpTypeInt 32 0
  7897. %v2uint = OpTypeVector %uint 2
  7898. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7899. %float = OpTypeFloat 32
  7900. %v4float = OpTypeVector %float 4
  7901. %_ptr_Input_float = OpTypePointer Input %float
  7902. %_ptr_Function_uint = OpTypePointer Function %uint
  7903. %uint_4 = OpConstant %uint 4
  7904. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  7905. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7906. %3 = OpVariable %_ptr_Output_v4float Output
  7907. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7908. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7909. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7910. %21 = OpTypeSampler
  7911. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  7912. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  7913. %23 = OpTypeSampledImage %19
  7914. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7915. %2 = OpFunction %void None %8
  7916. %24 = OpLabel
  7917. %25 = OpVariable %_ptr_Function_v2uint Function
  7918. %26 = OpLoad %19 %4
  7919. %27 = OpLoad %21 %5
  7920. %28 = OpSampledImage %23 %26 %27
  7921. %29 = OpLoad %v2uint %25
  7922. %30 = OpLoad %19 %6
  7923. %31 = OpLoad %21 %5
  7924. %32 = OpSampledImage %23 %30 %31
  7925. %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
  7926. OpStore %3 %33
  7927. OpReturn
  7928. OpFunctionEnd
  7929. )";
  7930. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7931. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7932. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7933. EXPECT_THAT(getDiagnosticString(),
  7934. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  7935. }
  7936. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIS) {
  7937. const std::string text = R"(
  7938. OpCapability Shader
  7939. OpCapability TextureBlockMatchQCOM
  7940. OpCapability TextureBlockMatch2QCOM
  7941. OpExtension "SPV_QCOM_image_processing"
  7942. OpExtension "SPV_QCOM_image_processing2"
  7943. %1 = OpExtInstImport "GLSL.std.450"
  7944. OpMemoryModel Logical GLSL450
  7945. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  7946. OpExecutionMode %2 OriginUpperLeft
  7947. OpDecorate %3 Location 0
  7948. OpDecorate %4 DescriptorSet 0
  7949. OpDecorate %4 Binding 1
  7950. OpDecorate %4 BlockMatchTextureQCOM
  7951. OpDecorate %4 BlockMatchSamplerQCOM
  7952. OpDecorate %5 DescriptorSet 0
  7953. OpDecorate %5 Binding 3
  7954. OpDecorate %6 DescriptorSet 0
  7955. OpDecorate %6 Binding 2
  7956. OpDecorate %6 BlockMatchTextureQCOM
  7957. %void = OpTypeVoid
  7958. %8 = OpTypeFunction %void
  7959. %uint = OpTypeInt 32 0
  7960. %v2uint = OpTypeVector %uint 2
  7961. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  7962. %float = OpTypeFloat 32
  7963. %v4float = OpTypeVector %float 4
  7964. %_ptr_Input_float = OpTypePointer Input %float
  7965. %_ptr_Function_uint = OpTypePointer Function %uint
  7966. %uint_4 = OpConstant %uint 4
  7967. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  7968. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7969. %3 = OpVariable %_ptr_Output_v4float Output
  7970. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  7971. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  7972. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7973. %21 = OpTypeSampler
  7974. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  7975. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  7976. %23 = OpTypeSampledImage %19
  7977. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  7978. %2 = OpFunction %void None %8
  7979. %24 = OpLabel
  7980. %25 = OpVariable %_ptr_Function_v2uint Function
  7981. %26 = OpLoad %19 %4
  7982. %27 = OpLoad %21 %5
  7983. %28 = OpSampledImage %23 %26 %27
  7984. %29 = OpLoad %v2uint %25
  7985. %30 = OpLoad %19 %6
  7986. %31 = OpLoad %21 %5
  7987. %32 = OpSampledImage %23 %30 %31
  7988. %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
  7989. OpStore %3 %33
  7990. OpReturn
  7991. OpFunctionEnd
  7992. )";
  7993. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  7994. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  7995. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  7996. EXPECT_THAT(getDiagnosticString(),
  7997. HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
  7998. }
  7999. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetIT) {
  8000. const std::string text = R"(
  8001. OpCapability Shader
  8002. OpCapability TextureBlockMatchQCOM
  8003. OpCapability TextureBlockMatch2QCOM
  8004. OpExtension "SPV_QCOM_image_processing"
  8005. OpExtension "SPV_QCOM_image_processing2"
  8006. %1 = OpExtInstImport "GLSL.std.450"
  8007. OpMemoryModel Logical GLSL450
  8008. OpEntryPoint Fragment %2 "main" %3 %4 %5
  8009. OpExecutionMode %2 OriginUpperLeft
  8010. OpDecorate %3 Location 0
  8011. OpDecorate %4 DescriptorSet 0
  8012. OpDecorate %4 Binding 4
  8013. OpDecorate %5 DescriptorSet 0
  8014. OpDecorate %5 Binding 5
  8015. OpDecorate %5 BlockMatchTextureQCOM
  8016. %void = OpTypeVoid
  8017. %7 = OpTypeFunction %void
  8018. %uint = OpTypeInt 32 0
  8019. %v2uint = OpTypeVector %uint 2
  8020. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8021. %float = OpTypeFloat 32
  8022. %v4float = OpTypeVector %float 4
  8023. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8024. %_ptr_Input_float = OpTypePointer Input %float
  8025. %_ptr_Function_uint = OpTypePointer Function %uint
  8026. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8027. %3 = OpVariable %_ptr_Output_v4float Output
  8028. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8029. %19 = OpTypeSampledImage %18
  8030. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  8031. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8032. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8033. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  8034. %2 = OpFunction %void None %7
  8035. %22 = OpLabel
  8036. %23 = OpVariable %_ptr_Function_v2uint Function
  8037. %24 = OpLoad %19 %4
  8038. %25 = OpLoad %v2uint %23
  8039. %26 = OpLoad %19 %5
  8040. %27 = OpLoad %v2uint %23
  8041. %28 = OpLoad %v2uint %23
  8042. %29 = OpImageBlockMatchGatherSADQCOM %v4float %24 %25 %26 %27 %28
  8043. OpStore %3 %29
  8044. OpReturn
  8045. OpFunctionEnd
  8046. )";
  8047. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8048. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8049. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8050. EXPECT_THAT(getDiagnosticString(),
  8051. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  8052. }
  8053. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorRefIT) {
  8054. const std::string text = R"(
  8055. OpCapability Shader
  8056. OpCapability TextureBlockMatchQCOM
  8057. OpCapability TextureBlockMatch2QCOM
  8058. OpExtension "SPV_QCOM_image_processing"
  8059. OpExtension "SPV_QCOM_image_processing2"
  8060. %1 = OpExtInstImport "GLSL.std.450"
  8061. OpMemoryModel Logical GLSL450
  8062. OpEntryPoint Fragment %2 "main" %3 %4 %5
  8063. OpExecutionMode %2 OriginUpperLeft
  8064. OpDecorate %3 Location 0
  8065. OpDecorate %4 DescriptorSet 0
  8066. OpDecorate %4 Binding 4
  8067. OpDecorate %4 BlockMatchTextureQCOM
  8068. OpDecorate %5 DescriptorSet 0
  8069. OpDecorate %5 Binding 5
  8070. %void = OpTypeVoid
  8071. %7 = OpTypeFunction %void
  8072. %uint = OpTypeInt 32 0
  8073. %v2uint = OpTypeVector %uint 2
  8074. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8075. %float = OpTypeFloat 32
  8076. %v4float = OpTypeVector %float 4
  8077. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8078. %_ptr_Input_float = OpTypePointer Input %float
  8079. %_ptr_Function_uint = OpTypePointer Function %uint
  8080. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8081. %3 = OpVariable %_ptr_Output_v4float Output
  8082. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8083. %19 = OpTypeSampledImage %18
  8084. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  8085. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8086. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8087. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  8088. %2 = OpFunction %void None %7
  8089. %22 = OpLabel
  8090. %23 = OpVariable %_ptr_Function_v2uint Function
  8091. %24 = OpLoad %19 %4
  8092. %25 = OpLoad %v2uint %23
  8093. %26 = OpLoad %19 %5
  8094. %27 = OpLoad %v2uint %23
  8095. %28 = OpLoad %v2uint %23
  8096. %29 = OpImageBlockMatchGatherSADQCOM %v4float %24 %25 %26 %27 %28
  8097. OpStore %3 %29
  8098. OpReturn
  8099. OpFunctionEnd
  8100. )";
  8101. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8102. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8103. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8104. EXPECT_THAT(getDiagnosticString(),
  8105. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  8106. }
  8107. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetNIT) {
  8108. const std::string text = R"(
  8109. OpCapability Shader
  8110. OpCapability TextureBlockMatchQCOM
  8111. OpCapability TextureBlockMatch2QCOM
  8112. OpExtension "SPV_QCOM_image_processing"
  8113. OpExtension "SPV_QCOM_image_processing2"
  8114. %1 = OpExtInstImport "GLSL.std.450"
  8115. OpMemoryModel Logical GLSL450
  8116. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  8117. OpExecutionMode %2 OriginUpperLeft
  8118. OpDecorate %3 Location 0
  8119. OpDecorate %4 DescriptorSet 0
  8120. OpDecorate %4 Binding 1
  8121. OpDecorate %5 DescriptorSet 0
  8122. OpDecorate %5 Binding 3
  8123. OpDecorate %6 DescriptorSet 0
  8124. OpDecorate %6 Binding 2
  8125. OpDecorate %6 BlockMatchTextureQCOM
  8126. %void = OpTypeVoid
  8127. %8 = OpTypeFunction %void
  8128. %uint = OpTypeInt 32 0
  8129. %v2uint = OpTypeVector %uint 2
  8130. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8131. %float = OpTypeFloat 32
  8132. %v4float = OpTypeVector %float 4
  8133. %_ptr_Input_float = OpTypePointer Input %float
  8134. %_ptr_Function_uint = OpTypePointer Function %uint
  8135. %uint_4 = OpConstant %uint 4
  8136. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  8137. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8138. %3 = OpVariable %_ptr_Output_v4float Output
  8139. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8140. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  8141. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8142. %21 = OpTypeSampler
  8143. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  8144. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  8145. %23 = OpTypeSampledImage %19
  8146. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8147. %2 = OpFunction %void None %8
  8148. %24 = OpLabel
  8149. %25 = OpVariable %_ptr_Function_v2uint Function
  8150. %26 = OpLoad %19 %4
  8151. %27 = OpLoad %21 %5
  8152. %28 = OpSampledImage %23 %26 %27
  8153. %29 = OpLoad %v2uint %25
  8154. %30 = OpLoad %19 %6
  8155. %31 = OpLoad %21 %5
  8156. %32 = OpSampledImage %23 %30 %31
  8157. %33 = OpImageBlockMatchGatherSADQCOM %v4float %28 %29 %32 %29 %29
  8158. OpStore %3 %33
  8159. OpReturn
  8160. OpFunctionEnd
  8161. )";
  8162. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8163. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8164. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8165. EXPECT_THAT(getDiagnosticString(),
  8166. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  8167. }
  8168. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorRefNIT) {
  8169. const std::string text = R"(
  8170. OpCapability Shader
  8171. OpCapability TextureBlockMatchQCOM
  8172. OpCapability TextureBlockMatch2QCOM
  8173. OpExtension "SPV_QCOM_image_processing"
  8174. OpExtension "SPV_QCOM_image_processing2"
  8175. %1 = OpExtInstImport "GLSL.std.450"
  8176. OpMemoryModel Logical GLSL450
  8177. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  8178. OpExecutionMode %2 OriginUpperLeft
  8179. OpDecorate %3 Location 0
  8180. OpDecorate %4 DescriptorSet 0
  8181. OpDecorate %4 Binding 1
  8182. OpDecorate %4 BlockMatchTextureQCOM
  8183. OpDecorate %5 DescriptorSet 0
  8184. OpDecorate %5 Binding 3
  8185. OpDecorate %6 DescriptorSet 0
  8186. OpDecorate %6 Binding 2
  8187. %void = OpTypeVoid
  8188. %8 = OpTypeFunction %void
  8189. %uint = OpTypeInt 32 0
  8190. %v2uint = OpTypeVector %uint 2
  8191. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8192. %float = OpTypeFloat 32
  8193. %v4float = OpTypeVector %float 4
  8194. %_ptr_Input_float = OpTypePointer Input %float
  8195. %_ptr_Function_uint = OpTypePointer Function %uint
  8196. %uint_4 = OpConstant %uint 4
  8197. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  8198. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8199. %3 = OpVariable %_ptr_Output_v4float Output
  8200. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8201. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  8202. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8203. %21 = OpTypeSampler
  8204. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  8205. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  8206. %23 = OpTypeSampledImage %19
  8207. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8208. %2 = OpFunction %void None %8
  8209. %24 = OpLabel
  8210. %25 = OpVariable %_ptr_Function_v2uint Function
  8211. %26 = OpLoad %19 %4
  8212. %27 = OpLoad %21 %5
  8213. %28 = OpSampledImage %23 %26 %27
  8214. %29 = OpLoad %v2uint %25
  8215. %30 = OpLoad %19 %6
  8216. %31 = OpLoad %21 %5
  8217. %32 = OpSampledImage %23 %30 %31
  8218. %33 = OpImageBlockMatchGatherSADQCOM %v4float %28 %29 %32 %29 %29
  8219. OpStore %3 %33
  8220. OpReturn
  8221. OpFunctionEnd
  8222. )";
  8223. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8224. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8225. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8226. EXPECT_THAT(getDiagnosticString(),
  8227. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  8228. }
  8229. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetIT) {
  8230. const std::string text = R"(
  8231. OpCapability Shader
  8232. OpCapability TextureBlockMatchQCOM
  8233. OpCapability TextureBlockMatch2QCOM
  8234. OpExtension "SPV_QCOM_image_processing"
  8235. OpExtension "SPV_QCOM_image_processing2"
  8236. %1 = OpExtInstImport "GLSL.std.450"
  8237. OpMemoryModel Logical GLSL450
  8238. OpEntryPoint Fragment %2 "main" %3 %4 %5
  8239. OpExecutionMode %2 OriginUpperLeft
  8240. OpDecorate %3 Location 0
  8241. OpDecorate %4 DescriptorSet 0
  8242. OpDecorate %4 Binding 4
  8243. OpDecorate %5 DescriptorSet 0
  8244. OpDecorate %5 Binding 5
  8245. OpDecorate %5 BlockMatchTextureQCOM
  8246. %void = OpTypeVoid
  8247. %7 = OpTypeFunction %void
  8248. %uint = OpTypeInt 32 0
  8249. %v2uint = OpTypeVector %uint 2
  8250. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8251. %float = OpTypeFloat 32
  8252. %v4float = OpTypeVector %float 4
  8253. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8254. %_ptr_Input_float = OpTypePointer Input %float
  8255. %_ptr_Function_uint = OpTypePointer Function %uint
  8256. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8257. %3 = OpVariable %_ptr_Output_v4float Output
  8258. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8259. %19 = OpTypeSampledImage %18
  8260. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  8261. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8262. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8263. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  8264. %2 = OpFunction %void None %7
  8265. %22 = OpLabel
  8266. %23 = OpVariable %_ptr_Function_v2uint Function
  8267. %24 = OpLoad %19 %4
  8268. %25 = OpLoad %v2uint %23
  8269. %26 = OpLoad %19 %5
  8270. %27 = OpLoad %v2uint %23
  8271. %28 = OpLoad %v2uint %23
  8272. %29 = OpImageBlockMatchGatherSSDQCOM %v4float %24 %25 %26 %27 %28
  8273. OpStore %3 %29
  8274. OpReturn
  8275. OpFunctionEnd
  8276. )";
  8277. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8278. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8279. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8280. EXPECT_THAT(getDiagnosticString(),
  8281. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  8282. }
  8283. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefIT) {
  8284. const std::string text = R"(
  8285. OpCapability Shader
  8286. OpCapability TextureBlockMatchQCOM
  8287. OpCapability TextureBlockMatch2QCOM
  8288. OpExtension "SPV_QCOM_image_processing"
  8289. OpExtension "SPV_QCOM_image_processing2"
  8290. %1 = OpExtInstImport "GLSL.std.450"
  8291. OpMemoryModel Logical GLSL450
  8292. OpEntryPoint Fragment %2 "main" %3 %4 %5
  8293. OpExecutionMode %2 OriginUpperLeft
  8294. OpDecorate %3 Location 0
  8295. OpDecorate %4 DescriptorSet 0
  8296. OpDecorate %4 Binding 4
  8297. OpDecorate %4 BlockMatchTextureQCOM
  8298. OpDecorate %5 DescriptorSet 0
  8299. OpDecorate %5 Binding 5
  8300. %void = OpTypeVoid
  8301. %7 = OpTypeFunction %void
  8302. %uint = OpTypeInt 32 0
  8303. %v2uint = OpTypeVector %uint 2
  8304. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8305. %float = OpTypeFloat 32
  8306. %v4float = OpTypeVector %float 4
  8307. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8308. %_ptr_Input_float = OpTypePointer Input %float
  8309. %_ptr_Function_uint = OpTypePointer Function %uint
  8310. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8311. %3 = OpVariable %_ptr_Output_v4float Output
  8312. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8313. %19 = OpTypeSampledImage %18
  8314. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  8315. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8316. %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8317. %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
  8318. %2 = OpFunction %void None %7
  8319. %22 = OpLabel
  8320. %23 = OpVariable %_ptr_Function_v2uint Function
  8321. %24 = OpLoad %19 %4
  8322. %25 = OpLoad %v2uint %23
  8323. %26 = OpLoad %19 %5
  8324. %27 = OpLoad %v2uint %23
  8325. %28 = OpLoad %v2uint %23
  8326. %29 = OpImageBlockMatchGatherSSDQCOM %v4float %24 %25 %26 %27 %28
  8327. OpStore %3 %29
  8328. OpReturn
  8329. OpFunctionEnd
  8330. )";
  8331. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8332. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8333. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8334. EXPECT_THAT(getDiagnosticString(),
  8335. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  8336. }
  8337. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetNIT) {
  8338. const std::string text = R"(
  8339. OpCapability Shader
  8340. OpCapability TextureBlockMatchQCOM
  8341. OpCapability TextureBlockMatch2QCOM
  8342. OpExtension "SPV_QCOM_image_processing"
  8343. OpExtension "SPV_QCOM_image_processing2"
  8344. %1 = OpExtInstImport "GLSL.std.450"
  8345. OpMemoryModel Logical GLSL450
  8346. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  8347. OpExecutionMode %2 OriginUpperLeft
  8348. OpDecorate %3 Location 0
  8349. OpDecorate %4 DescriptorSet 0
  8350. OpDecorate %4 Binding 1
  8351. OpDecorate %5 DescriptorSet 0
  8352. OpDecorate %5 Binding 3
  8353. OpDecorate %6 DescriptorSet 0
  8354. OpDecorate %6 Binding 2
  8355. OpDecorate %6 BlockMatchTextureQCOM
  8356. %void = OpTypeVoid
  8357. %8 = OpTypeFunction %void
  8358. %uint = OpTypeInt 32 0
  8359. %v2uint = OpTypeVector %uint 2
  8360. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8361. %float = OpTypeFloat 32
  8362. %v4float = OpTypeVector %float 4
  8363. %_ptr_Input_float = OpTypePointer Input %float
  8364. %_ptr_Function_uint = OpTypePointer Function %uint
  8365. %uint_4 = OpConstant %uint 4
  8366. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  8367. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8368. %3 = OpVariable %_ptr_Output_v4float Output
  8369. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8370. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  8371. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8372. %21 = OpTypeSampler
  8373. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  8374. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  8375. %23 = OpTypeSampledImage %19
  8376. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8377. %2 = OpFunction %void None %8
  8378. %24 = OpLabel
  8379. %25 = OpVariable %_ptr_Function_v2uint Function
  8380. %26 = OpLoad %19 %4
  8381. %27 = OpLoad %21 %5
  8382. %28 = OpSampledImage %23 %26 %27
  8383. %29 = OpLoad %v2uint %25
  8384. %30 = OpLoad %19 %6
  8385. %31 = OpLoad %21 %5
  8386. %32 = OpSampledImage %23 %30 %31
  8387. %33 = OpImageBlockMatchGatherSSDQCOM %v4float %28 %29 %32 %29 %29
  8388. OpStore %3 %33
  8389. OpReturn
  8390. OpFunctionEnd
  8391. )";
  8392. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8393. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8394. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8395. EXPECT_THAT(getDiagnosticString(),
  8396. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  8397. }
  8398. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefNIT) {
  8399. const std::string text = R"(
  8400. OpCapability Shader
  8401. OpCapability TextureBlockMatchQCOM
  8402. OpCapability TextureBlockMatch2QCOM
  8403. OpExtension "SPV_QCOM_image_processing"
  8404. OpExtension "SPV_QCOM_image_processing2"
  8405. %1 = OpExtInstImport "GLSL.std.450"
  8406. OpMemoryModel Logical GLSL450
  8407. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  8408. OpExecutionMode %2 OriginUpperLeft
  8409. OpDecorate %3 Location 0
  8410. OpDecorate %4 DescriptorSet 0
  8411. OpDecorate %4 Binding 1
  8412. OpDecorate %4 BlockMatchTextureQCOM
  8413. OpDecorate %5 DescriptorSet 0
  8414. OpDecorate %5 Binding 3
  8415. OpDecorate %6 DescriptorSet 0
  8416. OpDecorate %6 Binding 2
  8417. %void = OpTypeVoid
  8418. %8 = OpTypeFunction %void
  8419. %uint = OpTypeInt 32 0
  8420. %v2uint = OpTypeVector %uint 2
  8421. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8422. %float = OpTypeFloat 32
  8423. %v4float = OpTypeVector %float 4
  8424. %_ptr_Input_float = OpTypePointer Input %float
  8425. %_ptr_Function_uint = OpTypePointer Function %uint
  8426. %uint_4 = OpConstant %uint 4
  8427. %17 = OpConstantComposite %v2uint %uint_4 %uint_4
  8428. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8429. %3 = OpVariable %_ptr_Output_v4float Output
  8430. %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8431. %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  8432. %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8433. %21 = OpTypeSampler
  8434. %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
  8435. %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
  8436. %23 = OpTypeSampledImage %19
  8437. %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
  8438. %2 = OpFunction %void None %8
  8439. %24 = OpLabel
  8440. %25 = OpVariable %_ptr_Function_v2uint Function
  8441. %26 = OpLoad %19 %4
  8442. %27 = OpLoad %21 %5
  8443. %28 = OpSampledImage %23 %26 %27
  8444. %29 = OpLoad %v2uint %25
  8445. %30 = OpLoad %19 %6
  8446. %31 = OpLoad %21 %5
  8447. %32 = OpSampledImage %23 %30 %31
  8448. %33 = OpImageBlockMatchGatherSSDQCOM %v4float %28 %29 %32 %29 %29
  8449. OpStore %3 %33
  8450. OpReturn
  8451. OpFunctionEnd
  8452. )";
  8453. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8454. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8455. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8456. EXPECT_THAT(getDiagnosticString(),
  8457. HasSubstr("Missing decoration BlockMatchTextureQCOM"));
  8458. }
  8459. TEST_F(ValidateImage,
  8460. QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetI) {
  8461. const std::string text = R"(
  8462. OpCapability Shader
  8463. OpCapability TextureBlockMatchQCOM
  8464. OpCapability TextureBlockMatch2QCOM
  8465. OpExtension "SPV_QCOM_image_processing"
  8466. OpExtension "SPV_QCOM_image_processing2"
  8467. %1 = OpExtInstImport "GLSL.std.450"
  8468. OpMemoryModel Logical GLSL450
  8469. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  8470. OpExecutionMode %2 OriginUpperLeft
  8471. OpDecorate %3 Location 0
  8472. OpDecorate %4 Location 0
  8473. OpDecorate %5 DescriptorSet 0
  8474. OpDecorate %5 Binding 4
  8475. OpDecorate %6 DescriptorSet 0
  8476. OpDecorate %6 Binding 5
  8477. OpDecorate %5 BlockMatchTextureQCOM
  8478. OpDecorate %5 BlockMatchSamplerQCOM
  8479. OpDecorate %6 BlockMatchTextureQCOM
  8480. OpDecorate %6 BlockMatchSamplerQCOM
  8481. %void = OpTypeVoid
  8482. %8 = OpTypeFunction %void
  8483. %uint = OpTypeInt 32 0
  8484. %v2uint = OpTypeVector %uint 2
  8485. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8486. %float = OpTypeFloat 32
  8487. %v4float = OpTypeVector %float 4
  8488. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8489. %3 = OpVariable %_ptr_Input_v4float Input
  8490. %uint_4 = OpConstant %uint 4
  8491. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  8492. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8493. %4 = OpVariable %_ptr_Output_v4float Output
  8494. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8495. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  8496. %20 = OpTypeSampledImage %18
  8497. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  8498. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  8499. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  8500. %v2float = OpTypeVector %float 2
  8501. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  8502. %2 = OpFunction %void None %8
  8503. %24 = OpLabel
  8504. %25 = OpVariable %_ptr_Function_v2uint Function
  8505. OpStore %25 %16
  8506. %26 = OpLoad %20 %5
  8507. %27 = OpLoad %v2uint %25
  8508. %28 = OpLoad %20 %6
  8509. %29 = OpLoad %v2uint %25
  8510. %30 = OpLoad %v2uint %25
  8511. %31 = OpImageBlockMatchWindowSADQCOM %v4float %26 %27 %28 %29 %30
  8512. OpStore %4 %31
  8513. %32 = OpLoad %20 %5
  8514. %33 = OpLoad %v4float %3
  8515. %34 = OpVectorShuffle %v2float %33 %33 0 2
  8516. %35 = OpImageSampleImplicitLod %v4float %32 %34
  8517. OpStore %4 %35
  8518. OpReturn
  8519. OpFunctionEnd
  8520. )";
  8521. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8522. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8523. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8524. EXPECT_THAT(
  8525. getDiagnosticString(),
  8526. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  8527. }
  8528. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefI) {
  8529. const std::string text = R"(
  8530. OpCapability Shader
  8531. OpCapability TextureBlockMatchQCOM
  8532. OpCapability TextureBlockMatch2QCOM
  8533. OpExtension "SPV_QCOM_image_processing"
  8534. OpExtension "SPV_QCOM_image_processing2"
  8535. %1 = OpExtInstImport "GLSL.std.450"
  8536. OpMemoryModel Logical GLSL450
  8537. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  8538. OpExecutionMode %2 OriginUpperLeft
  8539. OpDecorate %3 Location 0
  8540. OpDecorate %4 Location 0
  8541. OpDecorate %5 DescriptorSet 0
  8542. OpDecorate %5 Binding 4
  8543. OpDecorate %6 DescriptorSet 0
  8544. OpDecorate %6 Binding 5
  8545. OpDecorate %5 BlockMatchTextureQCOM
  8546. OpDecorate %5 BlockMatchSamplerQCOM
  8547. OpDecorate %6 BlockMatchTextureQCOM
  8548. OpDecorate %6 BlockMatchSamplerQCOM
  8549. %void = OpTypeVoid
  8550. %8 = OpTypeFunction %void
  8551. %uint = OpTypeInt 32 0
  8552. %v2uint = OpTypeVector %uint 2
  8553. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8554. %float = OpTypeFloat 32
  8555. %v4float = OpTypeVector %float 4
  8556. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8557. %3 = OpVariable %_ptr_Input_v4float Input
  8558. %uint_4 = OpConstant %uint 4
  8559. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  8560. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8561. %4 = OpVariable %_ptr_Output_v4float Output
  8562. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8563. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  8564. %20 = OpTypeSampledImage %18
  8565. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  8566. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  8567. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  8568. %v2float = OpTypeVector %float 2
  8569. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  8570. %2 = OpFunction %void None %8
  8571. %24 = OpLabel
  8572. %25 = OpVariable %_ptr_Function_v2uint Function
  8573. OpStore %25 %16
  8574. %26 = OpLoad %20 %5
  8575. %27 = OpLoad %v2uint %25
  8576. %28 = OpLoad %20 %6
  8577. %29 = OpLoad %v2uint %25
  8578. %30 = OpLoad %v2uint %25
  8579. %31 = OpImageBlockMatchWindowSADQCOM %v4float %26 %27 %28 %29 %30
  8580. OpStore %4 %31
  8581. %32 = OpLoad %20 %6
  8582. %33 = OpLoad %v4float %3
  8583. %34 = OpVectorShuffle %v2float %33 %33 0 2
  8584. %35 = OpImageSampleImplicitLod %v4float %32 %34
  8585. OpStore %4 %35
  8586. OpReturn
  8587. OpFunctionEnd
  8588. )";
  8589. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8590. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8591. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8592. EXPECT_THAT(
  8593. getDiagnosticString(),
  8594. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  8595. }
  8596. TEST_F(ValidateImage,
  8597. QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetNI) {
  8598. const std::string text = R"(
  8599. OpCapability Shader
  8600. OpCapability TextureBlockMatchQCOM
  8601. OpCapability TextureBlockMatch2QCOM
  8602. OpExtension "SPV_QCOM_image_processing"
  8603. OpExtension "SPV_QCOM_image_processing2"
  8604. %1 = OpExtInstImport "GLSL.std.450"
  8605. OpMemoryModel Logical GLSL450
  8606. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  8607. OpExecutionMode %main OriginUpperLeft
  8608. OpDecorate %100 Location 0
  8609. OpDecorate %101 Location 0
  8610. OpDecorate %102 DescriptorSet 0
  8611. OpDecorate %102 Binding 1
  8612. OpDecorate %103 DescriptorSet 0
  8613. OpDecorate %103 Binding 3
  8614. OpDecorate %104 DescriptorSet 0
  8615. OpDecorate %104 Binding 2
  8616. OpDecorate %102 BlockMatchTextureQCOM
  8617. OpDecorate %103 BlockMatchSamplerQCOM
  8618. OpDecorate %104 BlockMatchTextureQCOM
  8619. %void = OpTypeVoid
  8620. %3 = OpTypeFunction %void
  8621. %uint = OpTypeInt 32 0
  8622. %v2uint = OpTypeVector %uint 2
  8623. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8624. %float = OpTypeFloat 32
  8625. %v4float = OpTypeVector %float 4
  8626. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8627. %100 = OpVariable %_ptr_Input_v4float Input
  8628. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8629. %101 = OpVariable %_ptr_Output_v4float Output
  8630. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8631. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  8632. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  8633. %46 = OpTypeSampler
  8634. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  8635. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  8636. %50 = OpTypeSampledImage %42
  8637. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  8638. %v2float = OpTypeVector %float 2
  8639. %main = OpFunction %void None %3
  8640. %5 = OpLabel
  8641. %15 = OpVariable %_ptr_Function_v2uint Function
  8642. %45 = OpLoad %42 %102
  8643. %49 = OpLoad %46 %103
  8644. %51 = OpSampledImage %50 %45 %49
  8645. %52 = OpLoad %v2uint %15
  8646. %54 = OpLoad %42 %104
  8647. %55 = OpLoad %46 %103
  8648. %56 = OpSampledImage %50 %54 %55
  8649. %57 = OpLoad %v2uint %15
  8650. %58 = OpLoad %v2uint %15
  8651. %59 = OpImageBlockMatchWindowSADQCOM %v4float %51 %52 %56 %57 %58
  8652. OpStore %101 %59
  8653. %69 = OpLoad %42 %102
  8654. %70 = OpLoad %46 %103
  8655. %71 = OpSampledImage %50 %69 %70
  8656. %73 = OpLoad %v4float %100
  8657. %74 = OpVectorShuffle %v2float %73 %73 0 0
  8658. %75 = OpImageSampleImplicitLod %v4float %71 %74
  8659. OpStore %101 %75
  8660. OpReturn
  8661. OpFunctionEnd
  8662. )";
  8663. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8664. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8665. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8666. EXPECT_THAT(
  8667. getDiagnosticString(),
  8668. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  8669. }
  8670. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefNI) {
  8671. const std::string text = R"(
  8672. OpCapability Shader
  8673. OpCapability TextureBlockMatchQCOM
  8674. OpCapability TextureBlockMatch2QCOM
  8675. OpExtension "SPV_QCOM_image_processing"
  8676. OpExtension "SPV_QCOM_image_processing2"
  8677. %1 = OpExtInstImport "GLSL.std.450"
  8678. OpMemoryModel Logical GLSL450
  8679. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  8680. OpExecutionMode %main OriginUpperLeft
  8681. OpDecorate %100 Location 0
  8682. OpDecorate %101 Location 0
  8683. OpDecorate %102 DescriptorSet 0
  8684. OpDecorate %102 Binding 1
  8685. OpDecorate %103 DescriptorSet 0
  8686. OpDecorate %103 Binding 3
  8687. OpDecorate %104 DescriptorSet 0
  8688. OpDecorate %104 Binding 2
  8689. OpDecorate %102 BlockMatchTextureQCOM
  8690. OpDecorate %103 BlockMatchSamplerQCOM
  8691. OpDecorate %104 BlockMatchTextureQCOM
  8692. %void = OpTypeVoid
  8693. %3 = OpTypeFunction %void
  8694. %uint = OpTypeInt 32 0
  8695. %v2uint = OpTypeVector %uint 2
  8696. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8697. %float = OpTypeFloat 32
  8698. %v4float = OpTypeVector %float 4
  8699. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8700. %100 = OpVariable %_ptr_Input_v4float Input
  8701. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8702. %101 = OpVariable %_ptr_Output_v4float Output
  8703. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8704. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  8705. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  8706. %46 = OpTypeSampler
  8707. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  8708. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  8709. %50 = OpTypeSampledImage %42
  8710. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  8711. %v2float = OpTypeVector %float 2
  8712. %main = OpFunction %void None %3
  8713. %5 = OpLabel
  8714. %15 = OpVariable %_ptr_Function_v2uint Function
  8715. %45 = OpLoad %42 %102
  8716. %49 = OpLoad %46 %103
  8717. %51 = OpSampledImage %50 %45 %49
  8718. %52 = OpLoad %v2uint %15
  8719. %54 = OpLoad %42 %104
  8720. %55 = OpLoad %46 %103
  8721. %56 = OpSampledImage %50 %54 %55
  8722. %57 = OpLoad %v2uint %15
  8723. %58 = OpLoad %v2uint %15
  8724. %59 = OpImageBlockMatchWindowSADQCOM %v4float %51 %52 %56 %57 %58
  8725. OpStore %101 %59
  8726. %69 = OpLoad %42 %104
  8727. %70 = OpLoad %46 %103
  8728. %71 = OpSampledImage %50 %69 %70
  8729. %73 = OpLoad %v4float %100
  8730. %74 = OpVectorShuffle %v2float %73 %73 0 0
  8731. %75 = OpImageSampleImplicitLod %v4float %71 %74
  8732. OpStore %101 %75
  8733. OpReturn
  8734. OpFunctionEnd
  8735. )";
  8736. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8737. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8738. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8739. EXPECT_THAT(
  8740. getDiagnosticString(),
  8741. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  8742. }
  8743. TEST_F(ValidateImage,
  8744. QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetI) {
  8745. const std::string text = R"(
  8746. OpCapability Shader
  8747. OpCapability TextureBlockMatchQCOM
  8748. OpCapability TextureBlockMatch2QCOM
  8749. OpExtension "SPV_QCOM_image_processing"
  8750. OpExtension "SPV_QCOM_image_processing2"
  8751. %1 = OpExtInstImport "GLSL.std.450"
  8752. OpMemoryModel Logical GLSL450
  8753. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  8754. OpExecutionMode %2 OriginUpperLeft
  8755. OpDecorate %3 Location 0
  8756. OpDecorate %4 Location 0
  8757. OpDecorate %5 DescriptorSet 0
  8758. OpDecorate %5 Binding 4
  8759. OpDecorate %6 DescriptorSet 0
  8760. OpDecorate %6 Binding 5
  8761. OpDecorate %5 BlockMatchTextureQCOM
  8762. OpDecorate %5 BlockMatchSamplerQCOM
  8763. OpDecorate %6 BlockMatchTextureQCOM
  8764. OpDecorate %6 BlockMatchSamplerQCOM
  8765. %void = OpTypeVoid
  8766. %8 = OpTypeFunction %void
  8767. %uint = OpTypeInt 32 0
  8768. %v2uint = OpTypeVector %uint 2
  8769. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8770. %float = OpTypeFloat 32
  8771. %v4float = OpTypeVector %float 4
  8772. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8773. %3 = OpVariable %_ptr_Input_v4float Input
  8774. %uint_4 = OpConstant %uint 4
  8775. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  8776. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8777. %4 = OpVariable %_ptr_Output_v4float Output
  8778. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8779. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  8780. %20 = OpTypeSampledImage %18
  8781. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  8782. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  8783. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  8784. %v2float = OpTypeVector %float 2
  8785. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  8786. %2 = OpFunction %void None %8
  8787. %24 = OpLabel
  8788. %25 = OpVariable %_ptr_Function_v2uint Function
  8789. OpStore %25 %16
  8790. %26 = OpLoad %20 %5
  8791. %27 = OpLoad %v2uint %25
  8792. %28 = OpLoad %20 %6
  8793. %29 = OpLoad %v2uint %25
  8794. %30 = OpLoad %v2uint %25
  8795. %31 = OpImageBlockMatchWindowSSDQCOM %v4float %26 %27 %28 %29 %30
  8796. OpStore %4 %31
  8797. %32 = OpLoad %20 %5
  8798. %33 = OpLoad %v4float %3
  8799. %34 = OpVectorShuffle %v2float %33 %33 0 2
  8800. %35 = OpImageSampleImplicitLod %v4float %32 %34
  8801. OpStore %4 %35
  8802. OpReturn
  8803. OpFunctionEnd
  8804. )";
  8805. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8806. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8807. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8808. EXPECT_THAT(
  8809. getDiagnosticString(),
  8810. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  8811. }
  8812. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefI) {
  8813. const std::string text = R"(
  8814. OpCapability Shader
  8815. OpCapability TextureBlockMatchQCOM
  8816. OpCapability TextureBlockMatch2QCOM
  8817. OpExtension "SPV_QCOM_image_processing"
  8818. OpExtension "SPV_QCOM_image_processing2"
  8819. %1 = OpExtInstImport "GLSL.std.450"
  8820. OpMemoryModel Logical GLSL450
  8821. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  8822. OpExecutionMode %2 OriginUpperLeft
  8823. OpDecorate %3 Location 0
  8824. OpDecorate %4 Location 0
  8825. OpDecorate %5 DescriptorSet 0
  8826. OpDecorate %5 Binding 4
  8827. OpDecorate %6 DescriptorSet 0
  8828. OpDecorate %6 Binding 5
  8829. OpDecorate %5 BlockMatchTextureQCOM
  8830. OpDecorate %5 BlockMatchSamplerQCOM
  8831. OpDecorate %6 BlockMatchTextureQCOM
  8832. OpDecorate %6 BlockMatchSamplerQCOM
  8833. %void = OpTypeVoid
  8834. %8 = OpTypeFunction %void
  8835. %uint = OpTypeInt 32 0
  8836. %v2uint = OpTypeVector %uint 2
  8837. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8838. %float = OpTypeFloat 32
  8839. %v4float = OpTypeVector %float 4
  8840. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8841. %3 = OpVariable %_ptr_Input_v4float Input
  8842. %uint_4 = OpConstant %uint 4
  8843. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  8844. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8845. %4 = OpVariable %_ptr_Output_v4float Output
  8846. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8847. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  8848. %20 = OpTypeSampledImage %18
  8849. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  8850. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  8851. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  8852. %v2float = OpTypeVector %float 2
  8853. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  8854. %2 = OpFunction %void None %8
  8855. %24 = OpLabel
  8856. %25 = OpVariable %_ptr_Function_v2uint Function
  8857. OpStore %25 %16
  8858. %26 = OpLoad %20 %5
  8859. %27 = OpLoad %v2uint %25
  8860. %28 = OpLoad %20 %6
  8861. %29 = OpLoad %v2uint %25
  8862. %30 = OpLoad %v2uint %25
  8863. %31 = OpImageBlockMatchWindowSSDQCOM %v4float %26 %27 %28 %29 %30
  8864. OpStore %4 %31
  8865. %32 = OpLoad %20 %6
  8866. %33 = OpLoad %v4float %3
  8867. %34 = OpVectorShuffle %v2float %33 %33 0 2
  8868. %35 = OpImageSampleImplicitLod %v4float %32 %34
  8869. OpStore %4 %35
  8870. OpReturn
  8871. OpFunctionEnd
  8872. )";
  8873. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8874. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8875. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8876. EXPECT_THAT(
  8877. getDiagnosticString(),
  8878. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  8879. }
  8880. TEST_F(ValidateImage,
  8881. QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetNI) {
  8882. const std::string text = R"(
  8883. OpCapability Shader
  8884. OpCapability TextureBlockMatchQCOM
  8885. OpCapability TextureBlockMatch2QCOM
  8886. OpExtension "SPV_QCOM_image_processing"
  8887. OpExtension "SPV_QCOM_image_processing2"
  8888. %1 = OpExtInstImport "GLSL.std.450"
  8889. OpMemoryModel Logical GLSL450
  8890. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  8891. OpExecutionMode %main OriginUpperLeft
  8892. OpDecorate %100 Location 0
  8893. OpDecorate %101 Location 0
  8894. OpDecorate %102 DescriptorSet 0
  8895. OpDecorate %102 Binding 1
  8896. OpDecorate %103 DescriptorSet 0
  8897. OpDecorate %103 Binding 3
  8898. OpDecorate %104 DescriptorSet 0
  8899. OpDecorate %104 Binding 2
  8900. OpDecorate %102 BlockMatchTextureQCOM
  8901. OpDecorate %103 BlockMatchSamplerQCOM
  8902. OpDecorate %104 BlockMatchTextureQCOM
  8903. %void = OpTypeVoid
  8904. %3 = OpTypeFunction %void
  8905. %uint = OpTypeInt 32 0
  8906. %v2uint = OpTypeVector %uint 2
  8907. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8908. %float = OpTypeFloat 32
  8909. %v4float = OpTypeVector %float 4
  8910. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8911. %100 = OpVariable %_ptr_Input_v4float Input
  8912. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8913. %101 = OpVariable %_ptr_Output_v4float Output
  8914. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8915. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  8916. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  8917. %46 = OpTypeSampler
  8918. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  8919. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  8920. %50 = OpTypeSampledImage %42
  8921. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  8922. %v2float = OpTypeVector %float 2
  8923. %main = OpFunction %void None %3
  8924. %5 = OpLabel
  8925. %15 = OpVariable %_ptr_Function_v2uint Function
  8926. %45 = OpLoad %42 %102
  8927. %49 = OpLoad %46 %103
  8928. %51 = OpSampledImage %50 %45 %49
  8929. %52 = OpLoad %v2uint %15
  8930. %54 = OpLoad %42 %104
  8931. %55 = OpLoad %46 %103
  8932. %56 = OpSampledImage %50 %54 %55
  8933. %57 = OpLoad %v2uint %15
  8934. %58 = OpLoad %v2uint %15
  8935. %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
  8936. OpStore %101 %59
  8937. %69 = OpLoad %42 %102
  8938. %70 = OpLoad %46 %103
  8939. %71 = OpSampledImage %50 %69 %70
  8940. %73 = OpLoad %v4float %100
  8941. %74 = OpVectorShuffle %v2float %73 %73 0 0
  8942. %75 = OpImageSampleImplicitLod %v4float %71 %74
  8943. OpStore %101 %75
  8944. OpReturn
  8945. OpFunctionEnd
  8946. )";
  8947. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  8948. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  8949. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  8950. EXPECT_THAT(
  8951. getDiagnosticString(),
  8952. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  8953. }
  8954. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefNI) {
  8955. const std::string text = R"(
  8956. OpCapability Shader
  8957. OpCapability TextureBlockMatchQCOM
  8958. OpCapability TextureBlockMatch2QCOM
  8959. OpExtension "SPV_QCOM_image_processing"
  8960. OpExtension "SPV_QCOM_image_processing2"
  8961. %1 = OpExtInstImport "GLSL.std.450"
  8962. OpMemoryModel Logical GLSL450
  8963. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  8964. OpExecutionMode %main OriginUpperLeft
  8965. OpDecorate %100 Location 0
  8966. OpDecorate %101 Location 0
  8967. OpDecorate %102 DescriptorSet 0
  8968. OpDecorate %102 Binding 1
  8969. OpDecorate %103 DescriptorSet 0
  8970. OpDecorate %103 Binding 3
  8971. OpDecorate %104 DescriptorSet 0
  8972. OpDecorate %104 Binding 2
  8973. OpDecorate %102 BlockMatchTextureQCOM
  8974. OpDecorate %103 BlockMatchSamplerQCOM
  8975. OpDecorate %104 BlockMatchTextureQCOM
  8976. %void = OpTypeVoid
  8977. %3 = OpTypeFunction %void
  8978. %uint = OpTypeInt 32 0
  8979. %v2uint = OpTypeVector %uint 2
  8980. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  8981. %float = OpTypeFloat 32
  8982. %v4float = OpTypeVector %float 4
  8983. %_ptr_Input_v4float = OpTypePointer Input %v4float
  8984. %100 = OpVariable %_ptr_Input_v4float Input
  8985. %_ptr_Output_v4float = OpTypePointer Output %v4float
  8986. %101 = OpVariable %_ptr_Output_v4float Output
  8987. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  8988. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  8989. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  8990. %46 = OpTypeSampler
  8991. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  8992. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  8993. %50 = OpTypeSampledImage %42
  8994. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  8995. %v2float = OpTypeVector %float 2
  8996. %main = OpFunction %void None %3
  8997. %5 = OpLabel
  8998. %15 = OpVariable %_ptr_Function_v2uint Function
  8999. %45 = OpLoad %42 %102
  9000. %49 = OpLoad %46 %103
  9001. %51 = OpSampledImage %50 %45 %49
  9002. %52 = OpLoad %v2uint %15
  9003. %54 = OpLoad %42 %104
  9004. %55 = OpLoad %46 %103
  9005. %56 = OpSampledImage %50 %54 %55
  9006. %57 = OpLoad %v2uint %15
  9007. %58 = OpLoad %v2uint %15
  9008. %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
  9009. OpStore %101 %59
  9010. %69 = OpLoad %42 %104
  9011. %70 = OpLoad %46 %103
  9012. %71 = OpSampledImage %50 %69 %70
  9013. %73 = OpLoad %v4float %100
  9014. %74 = OpVectorShuffle %v2float %73 %73 0 0
  9015. %75 = OpImageSampleImplicitLod %v4float %71 %74
  9016. OpStore %101 %75
  9017. OpReturn
  9018. OpFunctionEnd
  9019. )";
  9020. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  9021. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  9022. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9023. EXPECT_THAT(
  9024. getDiagnosticString(),
  9025. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  9026. }
  9027. TEST_F(ValidateImage,
  9028. QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetI) {
  9029. const std::string text = R"(
  9030. OpCapability Shader
  9031. OpCapability TextureBlockMatchQCOM
  9032. OpCapability TextureBlockMatch2QCOM
  9033. OpExtension "SPV_QCOM_image_processing"
  9034. OpExtension "SPV_QCOM_image_processing2"
  9035. %1 = OpExtInstImport "GLSL.std.450"
  9036. OpMemoryModel Logical GLSL450
  9037. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  9038. OpExecutionMode %2 OriginUpperLeft
  9039. OpDecorate %3 Location 0
  9040. OpDecorate %4 Location 0
  9041. OpDecorate %5 DescriptorSet 0
  9042. OpDecorate %5 Binding 4
  9043. OpDecorate %6 DescriptorSet 0
  9044. OpDecorate %6 Binding 5
  9045. OpDecorate %5 BlockMatchTextureQCOM
  9046. OpDecorate %6 BlockMatchTextureQCOM
  9047. %void = OpTypeVoid
  9048. %8 = OpTypeFunction %void
  9049. %uint = OpTypeInt 32 0
  9050. %v2uint = OpTypeVector %uint 2
  9051. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  9052. %float = OpTypeFloat 32
  9053. %v4float = OpTypeVector %float 4
  9054. %_ptr_Input_v4float = OpTypePointer Input %v4float
  9055. %3 = OpVariable %_ptr_Input_v4float Input
  9056. %uint_4 = OpConstant %uint 4
  9057. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  9058. %_ptr_Output_v4float = OpTypePointer Output %v4float
  9059. %4 = OpVariable %_ptr_Output_v4float Output
  9060. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  9061. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  9062. %20 = OpTypeSampledImage %18
  9063. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  9064. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  9065. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  9066. %v2float = OpTypeVector %float 2
  9067. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  9068. %2 = OpFunction %void None %8
  9069. %24 = OpLabel
  9070. %25 = OpVariable %_ptr_Function_v2uint Function
  9071. OpStore %25 %16
  9072. %26 = OpLoad %20 %5
  9073. %27 = OpLoad %v2uint %25
  9074. %28 = OpLoad %20 %6
  9075. %29 = OpLoad %v2uint %25
  9076. %30 = OpLoad %v2uint %25
  9077. %31 = OpImageBlockMatchGatherSADQCOM %v4float %26 %27 %28 %29 %30
  9078. OpStore %4 %31
  9079. %32 = OpLoad %20 %5
  9080. %33 = OpLoad %v4float %3
  9081. %34 = OpVectorShuffle %v2float %33 %33 0 2
  9082. %35 = OpImageSampleImplicitLod %v4float %32 %34
  9083. OpStore %4 %35
  9084. OpReturn
  9085. OpFunctionEnd
  9086. )";
  9087. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  9088. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  9089. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9090. EXPECT_THAT(
  9091. getDiagnosticString(),
  9092. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  9093. }
  9094. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefI) {
  9095. const std::string text = R"(
  9096. OpCapability Shader
  9097. OpCapability TextureBlockMatchQCOM
  9098. OpCapability TextureBlockMatch2QCOM
  9099. OpExtension "SPV_QCOM_image_processing"
  9100. OpExtension "SPV_QCOM_image_processing2"
  9101. %1 = OpExtInstImport "GLSL.std.450"
  9102. OpMemoryModel Logical GLSL450
  9103. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  9104. OpExecutionMode %2 OriginUpperLeft
  9105. OpDecorate %3 Location 0
  9106. OpDecorate %4 Location 0
  9107. OpDecorate %5 DescriptorSet 0
  9108. OpDecorate %5 Binding 4
  9109. OpDecorate %6 DescriptorSet 0
  9110. OpDecorate %6 Binding 5
  9111. OpDecorate %5 BlockMatchTextureQCOM
  9112. OpDecorate %6 BlockMatchTextureQCOM
  9113. %void = OpTypeVoid
  9114. %8 = OpTypeFunction %void
  9115. %uint = OpTypeInt 32 0
  9116. %v2uint = OpTypeVector %uint 2
  9117. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  9118. %float = OpTypeFloat 32
  9119. %v4float = OpTypeVector %float 4
  9120. %_ptr_Input_v4float = OpTypePointer Input %v4float
  9121. %3 = OpVariable %_ptr_Input_v4float Input
  9122. %uint_4 = OpConstant %uint 4
  9123. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  9124. %_ptr_Output_v4float = OpTypePointer Output %v4float
  9125. %4 = OpVariable %_ptr_Output_v4float Output
  9126. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  9127. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  9128. %20 = OpTypeSampledImage %18
  9129. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  9130. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  9131. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  9132. %v2float = OpTypeVector %float 2
  9133. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  9134. %2 = OpFunction %void None %8
  9135. %24 = OpLabel
  9136. %25 = OpVariable %_ptr_Function_v2uint Function
  9137. OpStore %25 %16
  9138. %26 = OpLoad %20 %5
  9139. %27 = OpLoad %v2uint %25
  9140. %28 = OpLoad %20 %6
  9141. %29 = OpLoad %v2uint %25
  9142. %30 = OpLoad %v2uint %25
  9143. %31 = OpImageBlockMatchGatherSADQCOM %v4float %26 %27 %28 %29 %30
  9144. OpStore %4 %31
  9145. %32 = OpLoad %20 %6
  9146. %33 = OpLoad %v4float %3
  9147. %34 = OpVectorShuffle %v2float %33 %33 0 2
  9148. %35 = OpImageSampleImplicitLod %v4float %32 %34
  9149. OpStore %4 %35
  9150. OpReturn
  9151. OpFunctionEnd
  9152. )";
  9153. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  9154. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  9155. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9156. EXPECT_THAT(
  9157. getDiagnosticString(),
  9158. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  9159. }
  9160. TEST_F(ValidateImage,
  9161. QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetNI) {
  9162. const std::string text = R"(
  9163. OpCapability Shader
  9164. OpCapability TextureBlockMatchQCOM
  9165. OpCapability TextureBlockMatch2QCOM
  9166. OpExtension "SPV_QCOM_image_processing"
  9167. OpExtension "SPV_QCOM_image_processing2"
  9168. %1 = OpExtInstImport "GLSL.std.450"
  9169. OpMemoryModel Logical GLSL450
  9170. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  9171. OpExecutionMode %main OriginUpperLeft
  9172. OpDecorate %100 Location 0
  9173. OpDecorate %101 Location 0
  9174. OpDecorate %102 DescriptorSet 0
  9175. OpDecorate %102 Binding 1
  9176. OpDecorate %103 DescriptorSet 0
  9177. OpDecorate %103 Binding 3
  9178. OpDecorate %104 DescriptorSet 0
  9179. OpDecorate %104 Binding 2
  9180. OpDecorate %102 BlockMatchTextureQCOM
  9181. OpDecorate %104 BlockMatchTextureQCOM
  9182. %void = OpTypeVoid
  9183. %3 = OpTypeFunction %void
  9184. %uint = OpTypeInt 32 0
  9185. %v2uint = OpTypeVector %uint 2
  9186. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  9187. %float = OpTypeFloat 32
  9188. %v4float = OpTypeVector %float 4
  9189. %_ptr_Input_v4float = OpTypePointer Input %v4float
  9190. %100 = OpVariable %_ptr_Input_v4float Input
  9191. %_ptr_Output_v4float = OpTypePointer Output %v4float
  9192. %101 = OpVariable %_ptr_Output_v4float Output
  9193. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  9194. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  9195. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  9196. %46 = OpTypeSampler
  9197. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  9198. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  9199. %50 = OpTypeSampledImage %42
  9200. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  9201. %v2float = OpTypeVector %float 2
  9202. %main = OpFunction %void None %3
  9203. %5 = OpLabel
  9204. %15 = OpVariable %_ptr_Function_v2uint Function
  9205. %45 = OpLoad %42 %102
  9206. %49 = OpLoad %46 %103
  9207. %51 = OpSampledImage %50 %45 %49
  9208. %52 = OpLoad %v2uint %15
  9209. %54 = OpLoad %42 %104
  9210. %55 = OpLoad %46 %103
  9211. %56 = OpSampledImage %50 %54 %55
  9212. %57 = OpLoad %v2uint %15
  9213. %58 = OpLoad %v2uint %15
  9214. %59 = OpImageBlockMatchGatherSADQCOM %v4float %51 %52 %56 %57 %58
  9215. OpStore %101 %59
  9216. %69 = OpLoad %42 %102
  9217. %70 = OpLoad %46 %103
  9218. %71 = OpSampledImage %50 %69 %70
  9219. %73 = OpLoad %v4float %100
  9220. %74 = OpVectorShuffle %v2float %73 %73 0 0
  9221. %75 = OpImageSampleImplicitLod %v4float %71 %74
  9222. OpStore %101 %75
  9223. OpReturn
  9224. OpFunctionEnd
  9225. )";
  9226. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  9227. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  9228. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9229. EXPECT_THAT(
  9230. getDiagnosticString(),
  9231. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  9232. }
  9233. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefNI) {
  9234. const std::string text = R"(
  9235. OpCapability Shader
  9236. OpCapability TextureBlockMatchQCOM
  9237. OpCapability TextureBlockMatch2QCOM
  9238. OpExtension "SPV_QCOM_image_processing"
  9239. OpExtension "SPV_QCOM_image_processing2"
  9240. %1 = OpExtInstImport "GLSL.std.450"
  9241. OpMemoryModel Logical GLSL450
  9242. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  9243. OpExecutionMode %main OriginUpperLeft
  9244. OpDecorate %100 Location 0
  9245. OpDecorate %101 Location 0
  9246. OpDecorate %102 DescriptorSet 0
  9247. OpDecorate %102 Binding 1
  9248. OpDecorate %103 DescriptorSet 0
  9249. OpDecorate %103 Binding 3
  9250. OpDecorate %104 DescriptorSet 0
  9251. OpDecorate %104 Binding 2
  9252. OpDecorate %102 BlockMatchTextureQCOM
  9253. OpDecorate %104 BlockMatchTextureQCOM
  9254. %void = OpTypeVoid
  9255. %3 = OpTypeFunction %void
  9256. %uint = OpTypeInt 32 0
  9257. %v2uint = OpTypeVector %uint 2
  9258. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  9259. %float = OpTypeFloat 32
  9260. %v4float = OpTypeVector %float 4
  9261. %_ptr_Input_v4float = OpTypePointer Input %v4float
  9262. %100 = OpVariable %_ptr_Input_v4float Input
  9263. %_ptr_Output_v4float = OpTypePointer Output %v4float
  9264. %101 = OpVariable %_ptr_Output_v4float Output
  9265. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  9266. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  9267. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  9268. %46 = OpTypeSampler
  9269. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  9270. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  9271. %50 = OpTypeSampledImage %42
  9272. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  9273. %v2float = OpTypeVector %float 2
  9274. %main = OpFunction %void None %3
  9275. %5 = OpLabel
  9276. %15 = OpVariable %_ptr_Function_v2uint Function
  9277. %45 = OpLoad %42 %102
  9278. %49 = OpLoad %46 %103
  9279. %51 = OpSampledImage %50 %45 %49
  9280. %52 = OpLoad %v2uint %15
  9281. %54 = OpLoad %42 %104
  9282. %55 = OpLoad %46 %103
  9283. %56 = OpSampledImage %50 %54 %55
  9284. %57 = OpLoad %v2uint %15
  9285. %58 = OpLoad %v2uint %15
  9286. %59 = OpImageBlockMatchGatherSADQCOM %v4float %51 %52 %56 %57 %58
  9287. OpStore %101 %59
  9288. %69 = OpLoad %42 %104
  9289. %70 = OpLoad %46 %103
  9290. %71 = OpSampledImage %50 %69 %70
  9291. %73 = OpLoad %v4float %100
  9292. %74 = OpVectorShuffle %v2float %73 %73 0 0
  9293. %75 = OpImageSampleImplicitLod %v4float %71 %74
  9294. OpStore %101 %75
  9295. OpReturn
  9296. OpFunctionEnd
  9297. )";
  9298. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  9299. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  9300. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9301. EXPECT_THAT(
  9302. getDiagnosticString(),
  9303. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  9304. }
  9305. TEST_F(ValidateImage,
  9306. QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetI) {
  9307. const std::string text = R"(
  9308. OpCapability Shader
  9309. OpCapability TextureBlockMatchQCOM
  9310. OpCapability TextureBlockMatch2QCOM
  9311. OpExtension "SPV_QCOM_image_processing"
  9312. OpExtension "SPV_QCOM_image_processing2"
  9313. %1 = OpExtInstImport "GLSL.std.450"
  9314. OpMemoryModel Logical GLSL450
  9315. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  9316. OpExecutionMode %2 OriginUpperLeft
  9317. OpDecorate %3 Location 0
  9318. OpDecorate %4 Location 0
  9319. OpDecorate %5 DescriptorSet 0
  9320. OpDecorate %5 Binding 4
  9321. OpDecorate %6 DescriptorSet 0
  9322. OpDecorate %6 Binding 5
  9323. OpDecorate %5 BlockMatchTextureQCOM
  9324. OpDecorate %6 BlockMatchTextureQCOM
  9325. %void = OpTypeVoid
  9326. %8 = OpTypeFunction %void
  9327. %uint = OpTypeInt 32 0
  9328. %v2uint = OpTypeVector %uint 2
  9329. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  9330. %float = OpTypeFloat 32
  9331. %v4float = OpTypeVector %float 4
  9332. %_ptr_Input_v4float = OpTypePointer Input %v4float
  9333. %3 = OpVariable %_ptr_Input_v4float Input
  9334. %uint_4 = OpConstant %uint 4
  9335. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  9336. %_ptr_Output_v4float = OpTypePointer Output %v4float
  9337. %4 = OpVariable %_ptr_Output_v4float Output
  9338. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  9339. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  9340. %20 = OpTypeSampledImage %18
  9341. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  9342. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  9343. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  9344. %v2float = OpTypeVector %float 2
  9345. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  9346. %2 = OpFunction %void None %8
  9347. %24 = OpLabel
  9348. %25 = OpVariable %_ptr_Function_v2uint Function
  9349. OpStore %25 %16
  9350. %26 = OpLoad %20 %5
  9351. %27 = OpLoad %v2uint %25
  9352. %28 = OpLoad %20 %6
  9353. %29 = OpLoad %v2uint %25
  9354. %30 = OpLoad %v2uint %25
  9355. %31 = OpImageBlockMatchGatherSSDQCOM %v4float %26 %27 %28 %29 %30
  9356. OpStore %4 %31
  9357. %32 = OpLoad %20 %5
  9358. %33 = OpLoad %v4float %3
  9359. %34 = OpVectorShuffle %v2float %33 %33 0 2
  9360. %35 = OpImageSampleImplicitLod %v4float %32 %34
  9361. OpStore %4 %35
  9362. OpReturn
  9363. OpFunctionEnd
  9364. )";
  9365. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  9366. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  9367. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9368. EXPECT_THAT(
  9369. getDiagnosticString(),
  9370. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  9371. }
  9372. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefI) {
  9373. const std::string text = R"(
  9374. OpCapability Shader
  9375. OpCapability TextureBlockMatchQCOM
  9376. OpCapability TextureBlockMatch2QCOM
  9377. OpExtension "SPV_QCOM_image_processing"
  9378. OpExtension "SPV_QCOM_image_processing2"
  9379. %1 = OpExtInstImport "GLSL.std.450"
  9380. OpMemoryModel Logical GLSL450
  9381. OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
  9382. OpExecutionMode %2 OriginUpperLeft
  9383. OpDecorate %3 Location 0
  9384. OpDecorate %4 Location 0
  9385. OpDecorate %5 DescriptorSet 0
  9386. OpDecorate %5 Binding 4
  9387. OpDecorate %6 DescriptorSet 0
  9388. OpDecorate %6 Binding 5
  9389. OpDecorate %5 BlockMatchTextureQCOM
  9390. OpDecorate %6 BlockMatchTextureQCOM
  9391. %void = OpTypeVoid
  9392. %8 = OpTypeFunction %void
  9393. %uint = OpTypeInt 32 0
  9394. %v2uint = OpTypeVector %uint 2
  9395. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  9396. %float = OpTypeFloat 32
  9397. %v4float = OpTypeVector %float 4
  9398. %_ptr_Input_v4float = OpTypePointer Input %v4float
  9399. %3 = OpVariable %_ptr_Input_v4float Input
  9400. %uint_4 = OpConstant %uint 4
  9401. %16 = OpConstantComposite %v2uint %uint_4 %uint_4
  9402. %_ptr_Output_v4float = OpTypePointer Output %v4float
  9403. %4 = OpVariable %_ptr_Output_v4float Output
  9404. %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
  9405. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  9406. %20 = OpTypeSampledImage %18
  9407. %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
  9408. %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  9409. %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
  9410. %v2float = OpTypeVector %float 2
  9411. %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
  9412. %2 = OpFunction %void None %8
  9413. %24 = OpLabel
  9414. %25 = OpVariable %_ptr_Function_v2uint Function
  9415. OpStore %25 %16
  9416. %26 = OpLoad %20 %5
  9417. %27 = OpLoad %v2uint %25
  9418. %28 = OpLoad %20 %6
  9419. %29 = OpLoad %v2uint %25
  9420. %30 = OpLoad %v2uint %25
  9421. %31 = OpImageBlockMatchGatherSSDQCOM %v4float %26 %27 %28 %29 %30
  9422. OpStore %4 %31
  9423. %32 = OpLoad %20 %6
  9424. %33 = OpLoad %v4float %3
  9425. %34 = OpVectorShuffle %v2float %33 %33 0 2
  9426. %35 = OpImageSampleImplicitLod %v4float %32 %34
  9427. OpStore %4 %35
  9428. OpReturn
  9429. OpFunctionEnd
  9430. )";
  9431. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  9432. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  9433. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9434. EXPECT_THAT(
  9435. getDiagnosticString(),
  9436. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  9437. }
  9438. TEST_F(ValidateImage,
  9439. QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetNI) {
  9440. const std::string text = R"(
  9441. OpCapability Shader
  9442. OpCapability TextureBlockMatchQCOM
  9443. OpCapability TextureBlockMatch2QCOM
  9444. OpExtension "SPV_QCOM_image_processing"
  9445. OpExtension "SPV_QCOM_image_processing2"
  9446. %1 = OpExtInstImport "GLSL.std.450"
  9447. OpMemoryModel Logical GLSL450
  9448. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  9449. OpExecutionMode %main OriginUpperLeft
  9450. OpDecorate %100 Location 0
  9451. OpDecorate %101 Location 0
  9452. OpDecorate %102 DescriptorSet 0
  9453. OpDecorate %102 Binding 1
  9454. OpDecorate %103 DescriptorSet 0
  9455. OpDecorate %103 Binding 3
  9456. OpDecorate %104 DescriptorSet 0
  9457. OpDecorate %104 Binding 2
  9458. OpDecorate %102 BlockMatchTextureQCOM
  9459. OpDecorate %104 BlockMatchTextureQCOM
  9460. %void = OpTypeVoid
  9461. %3 = OpTypeFunction %void
  9462. %uint = OpTypeInt 32 0
  9463. %v2uint = OpTypeVector %uint 2
  9464. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  9465. %float = OpTypeFloat 32
  9466. %v4float = OpTypeVector %float 4
  9467. %_ptr_Input_v4float = OpTypePointer Input %v4float
  9468. %100 = OpVariable %_ptr_Input_v4float Input
  9469. %_ptr_Output_v4float = OpTypePointer Output %v4float
  9470. %101 = OpVariable %_ptr_Output_v4float Output
  9471. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  9472. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  9473. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  9474. %46 = OpTypeSampler
  9475. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  9476. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  9477. %50 = OpTypeSampledImage %42
  9478. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  9479. %v2float = OpTypeVector %float 2
  9480. %main = OpFunction %void None %3
  9481. %5 = OpLabel
  9482. %15 = OpVariable %_ptr_Function_v2uint Function
  9483. %45 = OpLoad %42 %102
  9484. %49 = OpLoad %46 %103
  9485. %51 = OpSampledImage %50 %45 %49
  9486. %52 = OpLoad %v2uint %15
  9487. %54 = OpLoad %42 %104
  9488. %55 = OpLoad %46 %103
  9489. %56 = OpSampledImage %50 %54 %55
  9490. %57 = OpLoad %v2uint %15
  9491. %58 = OpLoad %v2uint %15
  9492. %59 = OpImageBlockMatchGatherSSDQCOM %v4float %51 %52 %56 %57 %58
  9493. OpStore %101 %59
  9494. %69 = OpLoad %42 %102
  9495. %70 = OpLoad %46 %103
  9496. %71 = OpSampledImage %50 %69 %70
  9497. %73 = OpLoad %v4float %100
  9498. %74 = OpVectorShuffle %v2float %73 %73 0 0
  9499. %75 = OpImageSampleImplicitLod %v4float %71 %74
  9500. OpStore %101 %75
  9501. OpReturn
  9502. OpFunctionEnd
  9503. )";
  9504. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  9505. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  9506. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9507. EXPECT_THAT(
  9508. getDiagnosticString(),
  9509. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  9510. }
  9511. TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefNI) {
  9512. const std::string text = R"(
  9513. OpCapability Shader
  9514. OpCapability TextureBlockMatchQCOM
  9515. OpCapability TextureBlockMatch2QCOM
  9516. OpExtension "SPV_QCOM_image_processing"
  9517. OpExtension "SPV_QCOM_image_processing2"
  9518. %1 = OpExtInstImport "GLSL.std.450"
  9519. OpMemoryModel Logical GLSL450
  9520. OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
  9521. OpExecutionMode %main OriginUpperLeft
  9522. OpDecorate %100 Location 0
  9523. OpDecorate %101 Location 0
  9524. OpDecorate %102 DescriptorSet 0
  9525. OpDecorate %102 Binding 1
  9526. OpDecorate %103 DescriptorSet 0
  9527. OpDecorate %103 Binding 3
  9528. OpDecorate %104 DescriptorSet 0
  9529. OpDecorate %104 Binding 2
  9530. OpDecorate %102 BlockMatchTextureQCOM
  9531. OpDecorate %104 BlockMatchTextureQCOM
  9532. %void = OpTypeVoid
  9533. %3 = OpTypeFunction %void
  9534. %uint = OpTypeInt 32 0
  9535. %v2uint = OpTypeVector %uint 2
  9536. %_ptr_Function_v2uint = OpTypePointer Function %v2uint
  9537. %float = OpTypeFloat 32
  9538. %v4float = OpTypeVector %float 4
  9539. %_ptr_Input_v4float = OpTypePointer Input %v4float
  9540. %100 = OpVariable %_ptr_Input_v4float Input
  9541. %_ptr_Output_v4float = OpTypePointer Output %v4float
  9542. %101 = OpVariable %_ptr_Output_v4float Output
  9543. %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
  9544. %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
  9545. %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  9546. %46 = OpTypeSampler
  9547. %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
  9548. %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
  9549. %50 = OpTypeSampledImage %42
  9550. %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
  9551. %v2float = OpTypeVector %float 2
  9552. %main = OpFunction %void None %3
  9553. %5 = OpLabel
  9554. %15 = OpVariable %_ptr_Function_v2uint Function
  9555. %45 = OpLoad %42 %102
  9556. %49 = OpLoad %46 %103
  9557. %51 = OpSampledImage %50 %45 %49
  9558. %52 = OpLoad %v2uint %15
  9559. %54 = OpLoad %42 %104
  9560. %55 = OpLoad %46 %103
  9561. %56 = OpSampledImage %50 %54 %55
  9562. %57 = OpLoad %v2uint %15
  9563. %58 = OpLoad %v2uint %15
  9564. %59 = OpImageBlockMatchGatherSSDQCOM %v4float %51 %52 %56 %57 %58
  9565. OpStore %101 %59
  9566. %69 = OpLoad %42 %104
  9567. %70 = OpLoad %46 %103
  9568. %71 = OpSampledImage %50 %69 %70
  9569. %73 = OpLoad %v4float %100
  9570. %74 = OpVectorShuffle %v2float %73 %73 0 0
  9571. %75 = OpImageSampleImplicitLod %v4float %71 %74
  9572. OpStore %101 %75
  9573. OpReturn
  9574. OpFunctionEnd
  9575. )";
  9576. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  9577. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  9578. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  9579. EXPECT_THAT(
  9580. getDiagnosticString(),
  9581. HasSubstr("Illegal use of QCOM image processing decorated texture"));
  9582. }
  9583. TEST_F(ValidateImage, ImageMSArray_ArrayedSampledTypeRequiresCapability) {
  9584. const std::string code = R"(
  9585. OpCapability Shader
  9586. OpCapability StorageImageMultisample
  9587. OpCapability StorageImageReadWithoutFormat
  9588. OpMemoryModel Logical GLSL450
  9589. OpEntryPoint Fragment %main "main"
  9590. OpExecutionMode %main OriginUpperLeft
  9591. OpDecorate %var_image DescriptorSet 0
  9592. OpDecorate %var_image Binding 1
  9593. %void = OpTypeVoid
  9594. %func = OpTypeFunction %void
  9595. %f32 = OpTypeFloat 32
  9596. %u32 = OpTypeInt 32 0
  9597. %uint_2 = OpConstant %u32 2
  9598. %uint_1 = OpConstant %u32 1
  9599. %v2uint = OpTypeVector %u32 2
  9600. %v4float = OpTypeVector %f32 4
  9601. %image = OpTypeImage %f32 2D 2 1 1 2 Unknown
  9602. %ptr_image = OpTypePointer UniformConstant %image
  9603. %10 = OpConstantComposite %v2uint %uint_1 %uint_2
  9604. %var_image = OpVariable %ptr_image UniformConstant
  9605. %main = OpFunction %void None %func
  9606. %main_lab = OpLabel
  9607. %18 = OpLoad %image %var_image
  9608. %19 = OpImageRead %v4float %18 %10 Sample %uint_2
  9609. OpReturn
  9610. OpFunctionEnd
  9611. )";
  9612. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  9613. CompileSuccessfully(code, env);
  9614. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  9615. EXPECT_THAT(
  9616. getDiagnosticString(),
  9617. HasSubstr("Capability ImageMSArray is required to access storage image"));
  9618. }
  9619. TEST_F(ValidateImage, ImageMSArray_SampledTypeDoesNotRequireCapability) {
  9620. const std::string code = R"(
  9621. OpCapability Shader
  9622. OpCapability StorageImageMultisample
  9623. OpCapability StorageImageReadWithoutFormat
  9624. OpMemoryModel Logical GLSL450
  9625. OpEntryPoint Fragment %main "main"
  9626. OpExecutionMode %main OriginUpperLeft
  9627. OpDecorate %var_image DescriptorSet 0
  9628. OpDecorate %var_image Binding 1
  9629. %void = OpTypeVoid
  9630. %func = OpTypeFunction %void
  9631. %f32 = OpTypeFloat 32
  9632. %u32 = OpTypeInt 32 0
  9633. %uint_2 = OpConstant %u32 2
  9634. %uint_1 = OpConstant %u32 1
  9635. %v2uint = OpTypeVector %u32 2
  9636. %v4float = OpTypeVector %f32 4
  9637. %image = OpTypeImage %f32 2D 2 0 1 2 Unknown
  9638. %ptr_image = OpTypePointer UniformConstant %image
  9639. %10 = OpConstantComposite %v2uint %uint_1 %uint_2
  9640. %var_image = OpVariable %ptr_image UniformConstant
  9641. %main = OpFunction %void None %func
  9642. %main_lab = OpLabel
  9643. %18 = OpLoad %image %var_image
  9644. %19 = OpImageRead %v4float %18 %10 Sample %uint_2
  9645. OpReturn
  9646. OpFunctionEnd
  9647. )";
  9648. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  9649. CompileSuccessfully(code, env);
  9650. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  9651. EXPECT_THAT(getDiagnosticString(), Eq(""));
  9652. }
  9653. TEST_F(ValidateImage, ImageMSArray_ArrayedTypeDoesNotRequireCapability) {
  9654. const std::string code = R"(
  9655. OpCapability Shader
  9656. OpCapability StorageImageReadWithoutFormat
  9657. OpMemoryModel Logical GLSL450
  9658. OpEntryPoint Fragment %main "main"
  9659. OpExecutionMode %main OriginUpperLeft
  9660. OpDecorate %var_image DescriptorSet 0
  9661. OpDecorate %var_image Binding 1
  9662. %void = OpTypeVoid
  9663. %func = OpTypeFunction %void
  9664. %f32 = OpTypeFloat 32
  9665. %u32 = OpTypeInt 32 0
  9666. %uint_3 = OpConstant %u32 3
  9667. %uint_2 = OpConstant %u32 2
  9668. %uint_1 = OpConstant %u32 1
  9669. %v3uint = OpTypeVector %u32 3
  9670. %v4float = OpTypeVector %f32 4
  9671. %image = OpTypeImage %f32 2D 2 1 0 2 Unknown
  9672. %ptr_image = OpTypePointer UniformConstant %image
  9673. %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
  9674. %var_image = OpVariable %ptr_image UniformConstant
  9675. %main = OpFunction %void None %func
  9676. %main_lab = OpLabel
  9677. %18 = OpLoad %image %var_image
  9678. %19 = OpImageRead %v4float %18 %10
  9679. OpReturn
  9680. OpFunctionEnd
  9681. )";
  9682. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  9683. CompileSuccessfully(code, env);
  9684. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  9685. EXPECT_THAT(getDiagnosticString(), Eq(""));
  9686. }
  9687. TEST_F(ValidateImage, SampledImageTypeDepthMismatch) {
  9688. const std::string code = R"(
  9689. OpCapability Shader
  9690. OpMemoryModel Logical GLSL450
  9691. OpEntryPoint GLCompute %main "main"
  9692. OpExecutionMode %main LocalSize 1 1 1
  9693. OpDecorate %im_var DescriptorSet 0
  9694. OpDecorate %im_var Binding 0
  9695. OpDecorate %s_var DescriptorSet 1
  9696. OpDecorate %s_var Binding 0
  9697. %void = OpTypeVoid
  9698. %float = OpTypeFloat 32
  9699. %im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
  9700. %im2_ty = OpTypeImage %float 2D 1 0 0 1 Unknown
  9701. %s_ty = OpTypeSampler
  9702. %s_im_ty = OpTypeSampledImage %im2_ty
  9703. %ptr_im = OpTypePointer UniformConstant %im1_ty
  9704. %ptr_s = OpTypePointer UniformConstant %s_ty
  9705. %im_var = OpVariable %ptr_im UniformConstant
  9706. %s_var = OpVariable %ptr_s UniformConstant
  9707. %void_fn = OpTypeFunction %void
  9708. %main = OpFunction %void None %void_fn
  9709. %entry = OpLabel
  9710. %im_ld = OpLoad %im1_ty %im_var
  9711. %s_ld = OpLoad %s_ty %s_var
  9712. %sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
  9713. OpReturn
  9714. OpFunctionEnd
  9715. )";
  9716. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  9717. CompileSuccessfully(code, env);
  9718. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(env));
  9719. }
  9720. TEST_F(ValidateImage, SampledImageTypeArrayedMismatch) {
  9721. const std::string code = R"(
  9722. OpCapability Shader
  9723. OpMemoryModel Logical GLSL450
  9724. OpEntryPoint GLCompute %main "main"
  9725. OpExecutionMode %main LocalSize 1 1 1
  9726. OpDecorate %im_var DescriptorSet 0
  9727. OpDecorate %im_var Binding 0
  9728. OpDecorate %s_var DescriptorSet 1
  9729. OpDecorate %s_var Binding 0
  9730. %void = OpTypeVoid
  9731. %float = OpTypeFloat 32
  9732. %im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
  9733. %im2_ty = OpTypeImage %float 2D 0 1 0 1 Unknown
  9734. %s_ty = OpTypeSampler
  9735. %s_im_ty = OpTypeSampledImage %im2_ty
  9736. %ptr_im = OpTypePointer UniformConstant %im1_ty
  9737. %ptr_s = OpTypePointer UniformConstant %s_ty
  9738. %im_var = OpVariable %ptr_im UniformConstant
  9739. %s_var = OpVariable %ptr_s UniformConstant
  9740. %void_fn = OpTypeFunction %void
  9741. %main = OpFunction %void None %void_fn
  9742. %entry = OpLabel
  9743. %im_ld = OpLoad %im1_ty %im_var
  9744. %s_ld = OpLoad %s_ty %s_var
  9745. %sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
  9746. OpReturn
  9747. OpFunctionEnd
  9748. )";
  9749. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  9750. CompileSuccessfully(code, env);
  9751. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  9752. EXPECT_THAT(
  9753. getDiagnosticString(),
  9754. HasSubstr(
  9755. "Image operands must match result image operands except for depth"));
  9756. }
  9757. TEST_F(ValidateImage, SampledImageTypeMultisampledMismatch) {
  9758. const std::string code = R"(
  9759. OpCapability Shader
  9760. OpMemoryModel Logical GLSL450
  9761. OpEntryPoint GLCompute %main "main"
  9762. OpExecutionMode %main LocalSize 1 1 1
  9763. OpDecorate %im_var DescriptorSet 0
  9764. OpDecorate %im_var Binding 0
  9765. OpDecorate %s_var DescriptorSet 1
  9766. OpDecorate %s_var Binding 0
  9767. %void = OpTypeVoid
  9768. %float = OpTypeFloat 32
  9769. %im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
  9770. %im2_ty = OpTypeImage %float 2D 0 0 1 1 Unknown
  9771. %s_ty = OpTypeSampler
  9772. %s_im_ty = OpTypeSampledImage %im2_ty
  9773. %ptr_im = OpTypePointer UniformConstant %im1_ty
  9774. %ptr_s = OpTypePointer UniformConstant %s_ty
  9775. %im_var = OpVariable %ptr_im UniformConstant
  9776. %s_var = OpVariable %ptr_s UniformConstant
  9777. %void_fn = OpTypeFunction %void
  9778. %main = OpFunction %void None %void_fn
  9779. %entry = OpLabel
  9780. %im_ld = OpLoad %im1_ty %im_var
  9781. %s_ld = OpLoad %s_ty %s_var
  9782. %sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
  9783. OpReturn
  9784. OpFunctionEnd
  9785. )";
  9786. const spv_target_env env = SPV_ENV_VULKAN_1_0;
  9787. CompileSuccessfully(code, env);
  9788. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  9789. EXPECT_THAT(
  9790. getDiagnosticString(),
  9791. HasSubstr(
  9792. "Image operands must match result image operands except for depth"));
  9793. }
  9794. TEST_F(ValidateImage, SampledImageTypeSampledMismatch) {
  9795. const std::string code = R"(
  9796. OpCapability Shader
  9797. OpMemoryModel Logical GLSL450
  9798. OpEntryPoint GLCompute %main "main"
  9799. OpExecutionMode %main LocalSize 1 1 1
  9800. OpDecorate %im_var DescriptorSet 0
  9801. OpDecorate %im_var Binding 0
  9802. OpDecorate %s_var DescriptorSet 1
  9803. OpDecorate %s_var Binding 0
  9804. %void = OpTypeVoid
  9805. %float = OpTypeFloat 32
  9806. %im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
  9807. %im2_ty = OpTypeImage %float 2D 0 0 0 0 Unknown
  9808. %s_ty = OpTypeSampler
  9809. %s_im_ty = OpTypeSampledImage %im2_ty
  9810. %ptr_im = OpTypePointer UniformConstant %im1_ty
  9811. %ptr_s = OpTypePointer UniformConstant %s_ty
  9812. %im_var = OpVariable %ptr_im UniformConstant
  9813. %s_var = OpVariable %ptr_s UniformConstant
  9814. %void_fn = OpTypeFunction %void
  9815. %main = OpFunction %void None %void_fn
  9816. %entry = OpLabel
  9817. %im_ld = OpLoad %im1_ty %im_var
  9818. %s_ld = OpLoad %s_ty %s_var
  9819. %sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
  9820. OpReturn
  9821. OpFunctionEnd
  9822. )";
  9823. const spv_target_env env = SPV_ENV_UNIVERSAL_1_0;
  9824. CompileSuccessfully(code, env);
  9825. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  9826. EXPECT_THAT(
  9827. getDiagnosticString(),
  9828. HasSubstr(
  9829. "Image operands must match result image operands except for depth"));
  9830. }
  9831. TEST_F(ValidateImage, SampledImageTypeFormatMismatch) {
  9832. const std::string code = R"(
  9833. OpCapability Shader
  9834. OpMemoryModel Logical GLSL450
  9835. OpEntryPoint GLCompute %main "main"
  9836. OpExecutionMode %main LocalSize 1 1 1
  9837. OpDecorate %im_var DescriptorSet 0
  9838. OpDecorate %im_var Binding 0
  9839. OpDecorate %s_var DescriptorSet 1
  9840. OpDecorate %s_var Binding 0
  9841. %void = OpTypeVoid
  9842. %float = OpTypeFloat 32
  9843. %im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
  9844. %im2_ty = OpTypeImage %float 2D 0 0 0 1 R32f
  9845. %s_ty = OpTypeSampler
  9846. %s_im_ty = OpTypeSampledImage %im2_ty
  9847. %ptr_im = OpTypePointer UniformConstant %im1_ty
  9848. %ptr_s = OpTypePointer UniformConstant %s_ty
  9849. %im_var = OpVariable %ptr_im UniformConstant
  9850. %s_var = OpVariable %ptr_s UniformConstant
  9851. %void_fn = OpTypeFunction %void
  9852. %main = OpFunction %void None %void_fn
  9853. %entry = OpLabel
  9854. %im_ld = OpLoad %im1_ty %im_var
  9855. %s_ld = OpLoad %s_ty %s_var
  9856. %sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
  9857. OpReturn
  9858. OpFunctionEnd
  9859. )";
  9860. const spv_target_env env = SPV_ENV_UNIVERSAL_1_0;
  9861. CompileSuccessfully(code, env);
  9862. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  9863. EXPECT_THAT(
  9864. getDiagnosticString(),
  9865. HasSubstr(
  9866. "Image operands must match result image operands except for depth"));
  9867. }
  9868. TEST_F(ValidateImage, SampledImageTypeAccessQualifierMismatch) {
  9869. const std::string code = R"(
  9870. OpCapability Kernel
  9871. OpCapability Linkage
  9872. OpMemoryModel Logical OpenCL
  9873. %void = OpTypeVoid
  9874. %float = OpTypeFloat 32
  9875. %im1_ty = OpTypeImage %float 2D 0 0 0 0 Unknown ReadWrite
  9876. %im2_ty = OpTypeImage %float 2D 0 0 0 0 Unknown ReadOnly
  9877. %s_ty = OpTypeSampler
  9878. %s_im_ty = OpTypeSampledImage %im2_ty
  9879. %ptr_im = OpTypePointer UniformConstant %im1_ty
  9880. %ptr_s = OpTypePointer UniformConstant %s_ty
  9881. %im_var = OpVariable %ptr_im UniformConstant
  9882. %s_var = OpVariable %ptr_s UniformConstant
  9883. %void_fn = OpTypeFunction %void
  9884. %main = OpFunction %void None %void_fn
  9885. %entry = OpLabel
  9886. %im_ld = OpLoad %im1_ty %im_var
  9887. %s_ld = OpLoad %s_ty %s_var
  9888. %sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
  9889. OpReturn
  9890. OpFunctionEnd
  9891. )";
  9892. const spv_target_env env = SPV_ENV_UNIVERSAL_1_0;
  9893. CompileSuccessfully(code, env);
  9894. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
  9895. EXPECT_THAT(
  9896. getDiagnosticString(),
  9897. HasSubstr(
  9898. "Image operands must match result image operands except for depth"));
  9899. }
  9900. TEST_F(ValidateImage, ImageTexelPointerNotAPointer) {
  9901. const std::string code = R"(
  9902. OpCapability ClipDistance
  9903. OpMemoryModel Logical Simple
  9904. %void = OpTypeVoid
  9905. %57 = OpTypeFunction %void
  9906. %int = OpTypeInt 32 1
  9907. %int_538976288 = OpConstant %int 538976288
  9908. %int_538976288_0 = OpConstant %int 538976288
  9909. %8224 = OpFunction %void None %57
  9910. %65312 = OpLabel
  9911. %2097184 = OpImageTexelPointer %void %int_538976288 %int_538976288 %int_538976288_0
  9912. OpUnreachable
  9913. OpFunctionEnd
  9914. )";
  9915. CompileSuccessfully(code);
  9916. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  9917. EXPECT_THAT(getDiagnosticString(),
  9918. HasSubstr("Expected Result Type to be a pointer"));
  9919. }
  9920. } // namespace
  9921. } // namespace val
  9922. } // namespace spvtools