val_image_test.cpp 230 KB

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