renderer_vk.cpp 320 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246
  1. /*
  2. * Copyright 2011-2026 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  4. */
  5. #include "bgfx_p.h"
  6. #if BGFX_CONFIG_RENDERER_VULKAN
  7. # include <bx/pixelformat.h>
  8. # include "renderer_vk.h"
  9. # include "shader_spirv.h"
  10. #if BX_PLATFORM_OSX
  11. # import <Cocoa/Cocoa.h>
  12. # import <Foundation/Foundation.h>
  13. # import <QuartzCore/QuartzCore.h>
  14. # import <Metal/Metal.h>
  15. #endif // BX_PLATFORM_OSX
  16. namespace bgfx { namespace vk
  17. {
  18. static char s_viewName[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME];
  19. inline void setViewType(ViewId _view, const bx::StringView _str)
  20. {
  21. if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION || BGFX_CONFIG_PROFILER) )
  22. {
  23. bx::memCopy(&s_viewName[_view][3], _str.getPtr(), _str.getLength() );
  24. }
  25. }
  26. struct PrimInfo
  27. {
  28. VkPrimitiveTopology m_topology;
  29. uint32_t m_min;
  30. uint32_t m_div;
  31. uint32_t m_sub;
  32. };
  33. static const PrimInfo s_primInfo[] =
  34. {
  35. { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 3, 3, 0 },
  36. { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 3, 1, 2 },
  37. { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, 2, 2, 0 },
  38. { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 2, 1, 1 },
  39. { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 1, 1, 0 },
  40. { VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, 0, 0, 0 },
  41. };
  42. static_assert(Topology::Count == BX_COUNTOF(s_primInfo)-1);
  43. static MsaaSamplerVK s_msaa[] =
  44. {
  45. { 1, VK_SAMPLE_COUNT_1_BIT },
  46. { 2, VK_SAMPLE_COUNT_2_BIT },
  47. { 4, VK_SAMPLE_COUNT_4_BIT },
  48. { 8, VK_SAMPLE_COUNT_8_BIT },
  49. { 16, VK_SAMPLE_COUNT_16_BIT },
  50. };
  51. struct ShadingRateVk
  52. {
  53. VkExtent2D fragmentSize;
  54. const VkExtent2D initFragmentSize;
  55. };
  56. static ShadingRateVk s_shadingRate[] =
  57. {
  58. { { 1, 1 }, { 1, 1 } },
  59. { { 1, 2 }, { 1, 2 } },
  60. { { 2, 1 }, { 2, 1 } },
  61. { { 2, 2 }, { 2, 2 } },
  62. { { 2, 4 }, { 2, 4 } },
  63. { { 4, 2 }, { 4, 2 } },
  64. { { 4, 4 }, { 4, 4 } },
  65. };
  66. static_assert(ShadingRate::Count == BX_COUNTOF(s_shadingRate) );
  67. static const VkBlendFactor s_blendFactor[][2] =
  68. {
  69. { VkBlendFactor(0), VkBlendFactor(0) }, // ignored
  70. { VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO }, // ZERO
  71. { VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE }, // ONE
  72. { VK_BLEND_FACTOR_SRC_COLOR, VK_BLEND_FACTOR_SRC_ALPHA }, // SRC_COLOR
  73. { VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA }, // INV_SRC_COLOR
  74. { VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_SRC_ALPHA }, // SRC_ALPHA
  75. { VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA }, // INV_SRC_ALPHA
  76. { VK_BLEND_FACTOR_DST_ALPHA, VK_BLEND_FACTOR_DST_ALPHA }, // DST_ALPHA
  77. { VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA }, // INV_DST_ALPHA
  78. { VK_BLEND_FACTOR_DST_COLOR, VK_BLEND_FACTOR_DST_ALPHA }, // DST_COLOR
  79. { VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA }, // INV_DST_COLOR
  80. { VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE }, // SRC_ALPHA_SAT
  81. { VK_BLEND_FACTOR_CONSTANT_COLOR, VK_BLEND_FACTOR_CONSTANT_COLOR }, // FACTOR
  82. { VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR }, // INV_FACTOR
  83. };
  84. static const VkBlendOp s_blendEquation[] =
  85. {
  86. VK_BLEND_OP_ADD,
  87. VK_BLEND_OP_SUBTRACT,
  88. VK_BLEND_OP_REVERSE_SUBTRACT,
  89. VK_BLEND_OP_MIN,
  90. VK_BLEND_OP_MAX,
  91. };
  92. static const VkCompareOp s_cmpFunc[] =
  93. {
  94. VkCompareOp(0), // ignored
  95. VK_COMPARE_OP_LESS,
  96. VK_COMPARE_OP_LESS_OR_EQUAL,
  97. VK_COMPARE_OP_EQUAL,
  98. VK_COMPARE_OP_GREATER_OR_EQUAL,
  99. VK_COMPARE_OP_GREATER,
  100. VK_COMPARE_OP_NOT_EQUAL,
  101. VK_COMPARE_OP_NEVER,
  102. VK_COMPARE_OP_ALWAYS,
  103. };
  104. static const VkStencilOp s_stencilOp[] =
  105. {
  106. VK_STENCIL_OP_ZERO,
  107. VK_STENCIL_OP_KEEP,
  108. VK_STENCIL_OP_REPLACE,
  109. VK_STENCIL_OP_INCREMENT_AND_WRAP,
  110. VK_STENCIL_OP_INCREMENT_AND_CLAMP,
  111. VK_STENCIL_OP_DECREMENT_AND_WRAP,
  112. VK_STENCIL_OP_DECREMENT_AND_CLAMP,
  113. VK_STENCIL_OP_INVERT,
  114. };
  115. static const VkCullModeFlagBits s_cullMode[] =
  116. {
  117. VK_CULL_MODE_NONE,
  118. VK_CULL_MODE_FRONT_BIT,
  119. VK_CULL_MODE_BACK_BIT,
  120. };
  121. static const VkSamplerAddressMode s_textureAddress[] =
  122. {
  123. VK_SAMPLER_ADDRESS_MODE_REPEAT,
  124. VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,
  125. VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
  126. VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
  127. };
  128. struct PresentMode
  129. {
  130. VkPresentModeKHR mode;
  131. bool vsync;
  132. const char* name;
  133. };
  134. static const PresentMode s_presentMode[] =
  135. {
  136. { VK_PRESENT_MODE_FIFO_KHR, true, "VK_PRESENT_MODE_FIFO_KHR" },
  137. { VK_PRESENT_MODE_FIFO_RELAXED_KHR, true, "VK_PRESENT_MODE_FIFO_RELAXED_KHR" },
  138. { VK_PRESENT_MODE_MAILBOX_KHR, true, "VK_PRESENT_MODE_MAILBOX_KHR" },
  139. { VK_PRESENT_MODE_IMMEDIATE_KHR, false, "VK_PRESENT_MODE_IMMEDIATE_KHR" },
  140. };
  141. #define VK_IMPORT_FUNC(_optional, _func) PFN_##_func _func
  142. #define VK_IMPORT_INSTANCE_FUNC VK_IMPORT_FUNC
  143. #define VK_IMPORT_DEVICE_FUNC VK_IMPORT_FUNC
  144. VK_IMPORT
  145. VK_IMPORT_INSTANCE
  146. VK_IMPORT_DEVICE
  147. #undef VK_IMPORT_DEVICE_FUNC
  148. #undef VK_IMPORT_INSTANCE_FUNC
  149. #undef VK_IMPORT_FUNC
  150. struct TextureFormatInfo
  151. {
  152. VkFormat m_fmt;
  153. VkFormat m_fmtSrv;
  154. VkFormat m_fmtDsv;
  155. VkFormat m_fmtSrgb;
  156. VkComponentMapping m_mapping;
  157. };
  158. static const TextureFormatInfo s_textureFormat[] =
  159. {
  160. #define $_ VK_COMPONENT_SWIZZLE_IDENTITY
  161. #define $0 VK_COMPONENT_SWIZZLE_ZERO
  162. #define $1 VK_COMPONENT_SWIZZLE_ONE
  163. #define $R VK_COMPONENT_SWIZZLE_R
  164. #define $G VK_COMPONENT_SWIZZLE_G
  165. #define $B VK_COMPONENT_SWIZZLE_B
  166. #define $A VK_COMPONENT_SWIZZLE_A
  167. { VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_BC1_RGB_SRGB_BLOCK, { $_, $_, $_, $_ } }, // BC1
  168. { VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_BC2_SRGB_BLOCK, { $_, $_, $_, $_ } }, // BC2
  169. { VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_BC3_SRGB_BLOCK, { $_, $_, $_, $_ } }, // BC3
  170. { VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // BC4
  171. { VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // BC5
  172. { VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // BC6H
  173. { VK_FORMAT_BC7_UNORM_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_BC7_SRGB_BLOCK, { $_, $_, $_, $_ } }, // BC7
  174. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // ETC1
  175. { VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ETC2
  176. { VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ETC2A
  177. { VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ETC2A1
  178. { VK_FORMAT_EAC_R11_UNORM_BLOCK, VK_FORMAT_EAC_R11_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // EACR11
  179. { VK_FORMAT_EAC_R11_SNORM_BLOCK, VK_FORMAT_EAC_R11_SNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // EACR11S
  180. { VK_FORMAT_EAC_R11G11_UNORM_BLOCK, VK_FORMAT_EAC_R11G11_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // EACRG11
  181. { VK_FORMAT_EAC_R11G11_SNORM_BLOCK, VK_FORMAT_EAC_R11G11_SNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // EACRG11S
  182. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // PTC12
  183. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // PTC14
  184. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // PTC12A
  185. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // PTC14A
  186. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // PTC22
  187. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // PTC24
  188. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // ATC
  189. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // ATCE
  190. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // ATCI
  191. { VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_4x4_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC4x4
  192. { VK_FORMAT_ASTC_5x4_UNORM_BLOCK, VK_FORMAT_ASTC_5x4_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_5x4_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC5x4
  193. { VK_FORMAT_ASTC_5x5_UNORM_BLOCK, VK_FORMAT_ASTC_5x5_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_5x5_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC5x5
  194. { VK_FORMAT_ASTC_6x5_UNORM_BLOCK, VK_FORMAT_ASTC_6x5_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_6x5_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC6x5
  195. { VK_FORMAT_ASTC_6x6_UNORM_BLOCK, VK_FORMAT_ASTC_6x6_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_6x6_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC6x6
  196. { VK_FORMAT_ASTC_8x5_UNORM_BLOCK, VK_FORMAT_ASTC_8x5_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_8x5_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC8x5
  197. { VK_FORMAT_ASTC_8x6_UNORM_BLOCK, VK_FORMAT_ASTC_8x6_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_8x6_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC8x6
  198. { VK_FORMAT_ASTC_8x8_UNORM_BLOCK, VK_FORMAT_ASTC_8x8_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_8x8_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC8x8
  199. { VK_FORMAT_ASTC_10x5_UNORM_BLOCK, VK_FORMAT_ASTC_10x5_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_10x5_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC10x5
  200. { VK_FORMAT_ASTC_10x6_UNORM_BLOCK, VK_FORMAT_ASTC_10x6_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_10x6_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC10x6
  201. { VK_FORMAT_ASTC_10x8_UNORM_BLOCK, VK_FORMAT_ASTC_10x8_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_10x8_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC10x8
  202. { VK_FORMAT_ASTC_10x10_UNORM_BLOCK, VK_FORMAT_ASTC_10x10_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_10x10_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC10x10
  203. { VK_FORMAT_ASTC_12x10_UNORM_BLOCK, VK_FORMAT_ASTC_12x10_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_12x10_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC12x10
  204. { VK_FORMAT_ASTC_12x12_UNORM_BLOCK, VK_FORMAT_ASTC_12x12_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_ASTC_12x12_SRGB_BLOCK, { $_, $_, $_, $_ } }, // ASTC12x12
  205. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // Unknown
  206. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R1
  207. { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $0, $0, $0, $R } }, // A8
  208. { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_R8_SRGB, { $_, $_, $_, $_ } }, // R8
  209. { VK_FORMAT_R8_SINT, VK_FORMAT_R8_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R8I
  210. { VK_FORMAT_R8_UINT, VK_FORMAT_R8_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R8U
  211. { VK_FORMAT_R8_SNORM, VK_FORMAT_R8_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R8S
  212. { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R16
  213. { VK_FORMAT_R16_SINT, VK_FORMAT_R16_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R16I
  214. { VK_FORMAT_R16_UINT, VK_FORMAT_R16_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R16U
  215. { VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R16F
  216. { VK_FORMAT_R16_SNORM, VK_FORMAT_R16_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R16S
  217. { VK_FORMAT_R32_SINT, VK_FORMAT_R32_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R32I
  218. { VK_FORMAT_R32_UINT, VK_FORMAT_R32_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R32U
  219. { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R32F
  220. { VK_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8_SRGB, { $_, $_, $_, $_ } }, // RG8
  221. { VK_FORMAT_R8G8_SINT, VK_FORMAT_R8G8_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG8I
  222. { VK_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG8U
  223. { VK_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG8S
  224. { VK_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG16
  225. { VK_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG16I
  226. { VK_FORMAT_R16G16_UINT, VK_FORMAT_R16G16_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG16U
  227. { VK_FORMAT_R16G16_SFLOAT, VK_FORMAT_R16G16_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG16F
  228. { VK_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG16S
  229. { VK_FORMAT_R32G32_SINT, VK_FORMAT_R32G32_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG32I
  230. { VK_FORMAT_R32G32_UINT, VK_FORMAT_R32G32_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG32U
  231. { VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG32F
  232. { VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8_SRGB, { $_, $_, $_, $_ } }, // RGB8
  233. { VK_FORMAT_R8G8B8_SINT, VK_FORMAT_R8G8B8_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8_SRGB, { $_, $_, $_, $_ } }, // RGB8I
  234. { VK_FORMAT_R8G8B8_UINT, VK_FORMAT_R8G8B8_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8_SRGB, { $_, $_, $_, $_ } }, // RGB8U
  235. { VK_FORMAT_R8G8B8_SNORM, VK_FORMAT_R8G8B8_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGB8S
  236. { VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGB9E5F
  237. { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_B8G8R8A8_SRGB, { $_, $_, $_, $_ } }, // BGRA8
  238. { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8A8_SRGB, { $_, $_, $_, $_ } }, // RGBA8
  239. { VK_FORMAT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8A8_SRGB, { $_, $_, $_, $_ } }, // RGBA8I
  240. { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8A8_SRGB, { $_, $_, $_, $_ } }, // RGBA8U
  241. { VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGBA8S
  242. { VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGBA16
  243. { VK_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGBA16I
  244. { VK_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGBA16U
  245. { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGBA16F
  246. { VK_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGBA16S
  247. { VK_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGBA32I
  248. { VK_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGBA32U
  249. { VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGBA32F
  250. { VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // B5G6R5
  251. { VK_FORMAT_B5G6R5_UNORM_PACK16, VK_FORMAT_B5G6R5_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // R5G6B5
  252. { VK_FORMAT_B4G4R4A4_UNORM_PACK16, VK_FORMAT_B4G4R4A4_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $G, $R, $A, $B } }, // BGRA4
  253. { VK_FORMAT_R4G4B4A4_UNORM_PACK16, VK_FORMAT_R4G4B4A4_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $A, $B, $G, $R } }, // RGBA4
  254. { VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // BGR5A1
  255. { VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $B, $G, $R, $A } }, // RGB5A1
  256. { VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RGB10A2
  257. { VK_FORMAT_B10G11R11_UFLOAT_PACK32, VK_FORMAT_B10G11R11_UFLOAT_PACK32, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // RG11B10F
  258. { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // UnknownDepth
  259. { VK_FORMAT_UNDEFINED, VK_FORMAT_R16_UNORM, VK_FORMAT_D16_UNORM, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // D16
  260. { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // D24
  261. { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // D24S8
  262. { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // D32
  263. { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // D16F
  264. { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // D24F
  265. { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // D32F
  266. { VK_FORMAT_UNDEFINED, VK_FORMAT_R8_UINT, VK_FORMAT_S8_UINT, VK_FORMAT_UNDEFINED, { $_, $_, $_, $_ } }, // D0S8
  267. #undef $_
  268. #undef $0
  269. #undef $1
  270. #undef $R
  271. #undef $G
  272. #undef $B
  273. #undef $A
  274. };
  275. static_assert(TextureFormat::Count == BX_COUNTOF(s_textureFormat) );
  276. struct ImageTest
  277. {
  278. VkImageType type;
  279. VkImageUsageFlags usage;
  280. VkImageCreateFlags flags;
  281. uint32_t formatCaps[2];
  282. };
  283. static const ImageTest s_imageTest[] =
  284. {
  285. { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_SAMPLED_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_2D, BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB } },
  286. { VK_IMAGE_TYPE_3D, VK_IMAGE_USAGE_SAMPLED_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_3D, BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB } },
  287. { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, { BGFX_CAPS_FORMAT_TEXTURE_CUBE, BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB } },
  288. { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER, 0 } },
  289. { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER, 0 } },
  290. { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_STORAGE_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ, 0 } },
  291. { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_STORAGE_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE, 0 } },
  292. };
  293. struct LayerInfo
  294. {
  295. bool m_supported;
  296. bool m_initialize;
  297. };
  298. struct Layer
  299. {
  300. enum Enum
  301. {
  302. VK_LAYER_KHRONOS_validation,
  303. VK_LAYER_LUNARG_standard_validation,
  304. Count
  305. };
  306. const char* m_name;
  307. uint32_t m_minVersion;
  308. LayerInfo m_instance;
  309. LayerInfo m_device;
  310. };
  311. // Layer registry
  312. //
  313. static Layer s_layer[] =
  314. {
  315. { "VK_LAYER_KHRONOS_validation", 1, { false, false }, { false, false } },
  316. { "VK_LAYER_LUNARG_standard_validation", 1, { false, false }, { false, false } },
  317. { "", 0, { false, false }, { false, false } },
  318. };
  319. static_assert(Layer::Count == BX_COUNTOF(s_layer)-1);
  320. void updateLayer(const char* _name, uint32_t _version, bool _instanceLayer)
  321. {
  322. bx::StringView layerName(_name);
  323. for (uint32_t ii = 0; ii < Layer::Count; ++ii)
  324. {
  325. Layer& layer = s_layer[ii];
  326. LayerInfo& layerInfo = _instanceLayer
  327. ? layer.m_instance
  328. : layer.m_device
  329. ;
  330. if (!layerInfo.m_supported && layerInfo.m_initialize)
  331. {
  332. if ( 0 == bx::strCmp(layerName, layer.m_name)
  333. && _version >= layer.m_minVersion)
  334. {
  335. layerInfo.m_supported = true;
  336. break;
  337. }
  338. }
  339. }
  340. }
  341. struct Extension
  342. {
  343. enum Enum
  344. {
  345. EXT_conservative_rasterization,
  346. EXT_custom_border_color,
  347. EXT_debug_report,
  348. EXT_debug_utils,
  349. EXT_line_rasterization,
  350. EXT_memory_budget,
  351. EXT_shader_viewport_index_layer,
  352. KHR_draw_indirect_count,
  353. KHR_fragment_shading_rate,
  354. KHR_get_physical_device_properties2,
  355. # if BX_PLATFORM_ANDROID
  356. KHR_android_surface,
  357. # elif BX_PLATFORM_LINUX
  358. KHR_wayland_surface,
  359. KHR_xlib_surface,
  360. KHR_xcb_surface,
  361. # elif BX_PLATFORM_WINDOWS
  362. KHR_win32_surface,
  363. # elif BX_PLATFORM_OSX
  364. MVK_macos_surface,
  365. # elif BX_PLATFORM_NX
  366. NN_vi_surface,
  367. # endif
  368. Count
  369. };
  370. const char* m_name;
  371. uint32_t m_minVersion;
  372. bool m_instanceExt;
  373. bool m_supported;
  374. bool m_initialize;
  375. Layer::Enum m_layer;
  376. };
  377. // Extension registry
  378. //
  379. static Extension s_extension[] =
  380. {
  381. { "VK_EXT_conservative_rasterization", 1, false, false, true, Layer::Count },
  382. { "VK_EXT_custom_border_color", 1, false, false, true, Layer::Count },
  383. { "VK_EXT_debug_report", 1, false, false, false, Layer::Count },
  384. { "VK_EXT_debug_utils", 1, false, false, BGFX_CONFIG_DEBUG_OBJECT_NAME || BGFX_CONFIG_DEBUG_ANNOTATION, Layer::Count },
  385. { "VK_EXT_line_rasterization", 1, false, false, true, Layer::Count },
  386. { "VK_EXT_memory_budget", 1, false, false, true, Layer::Count },
  387. { "VK_EXT_shader_viewport_index_layer", 1, false, false, true, Layer::Count },
  388. { "VK_KHR_draw_indirect_count", 1, false, false, true, Layer::Count },
  389. { "VK_KHR_fragment_shading_rate", 1, false, false, true, Layer::Count },
  390. { "VK_KHR_get_physical_device_properties2", 1, false, false, true, Layer::Count },
  391. # if BX_PLATFORM_ANDROID
  392. { VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count },
  393. # elif BX_PLATFORM_LINUX
  394. { VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count },
  395. { VK_KHR_XLIB_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count },
  396. { VK_KHR_XCB_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count },
  397. # elif BX_PLATFORM_WINDOWS
  398. { VK_KHR_WIN32_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count },
  399. # elif BX_PLATFORM_OSX
  400. { VK_MVK_MACOS_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count },
  401. # elif BX_PLATFORM_NX
  402. { VK_NN_VI_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count },
  403. # endif
  404. };
  405. static_assert(Extension::Count == BX_COUNTOF(s_extension) );
  406. bool updateExtension(const char* _name, uint32_t _version, bool _instanceExt, Extension _extensions[Extension::Count])
  407. {
  408. bool supported = false;
  409. if (BX_ENABLED(BGFX_CONFIG_RENDERER_USE_EXTENSIONS) )
  410. {
  411. const bx::StringView ext(_name);
  412. for (uint32_t ii = 0; ii < Extension::Count; ++ii)
  413. {
  414. Extension& extension = _extensions[ii];
  415. const LayerInfo& layerInfo = _instanceExt
  416. ? s_layer[extension.m_layer].m_instance
  417. : s_layer[extension.m_layer].m_device
  418. ;
  419. if (!extension.m_supported
  420. && extension.m_initialize
  421. && (extension.m_layer == Layer::Count || layerInfo.m_supported) )
  422. {
  423. if ( 0 == bx::strCmp(ext, extension.m_name)
  424. && _version >= extension.m_minVersion)
  425. {
  426. extension.m_supported = true;
  427. extension.m_instanceExt = _instanceExt;
  428. supported = true;
  429. break;
  430. }
  431. }
  432. }
  433. }
  434. return supported;
  435. }
  436. static const VkFormat s_attribType[][4][2] =
  437. {
  438. { // Uint8
  439. { VK_FORMAT_R8_UINT, VK_FORMAT_R8_UNORM },
  440. { VK_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UNORM },
  441. { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UNORM },
  442. { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UNORM },
  443. },
  444. { // Uint10
  445. { VK_FORMAT_A2R10G10B10_UINT_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
  446. { VK_FORMAT_A2R10G10B10_UINT_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
  447. { VK_FORMAT_A2R10G10B10_UINT_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
  448. { VK_FORMAT_A2R10G10B10_UINT_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
  449. },
  450. { // Int16
  451. { VK_FORMAT_R16_SINT, VK_FORMAT_R16_SNORM },
  452. { VK_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SNORM },
  453. { VK_FORMAT_R16G16B16_SINT, VK_FORMAT_R16G16B16_SNORM },
  454. { VK_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SNORM },
  455. },
  456. { // Half
  457. { VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT },
  458. { VK_FORMAT_R16G16_SFLOAT, VK_FORMAT_R16G16_SFLOAT },
  459. { VK_FORMAT_R16G16B16_SFLOAT, VK_FORMAT_R16G16B16_SFLOAT },
  460. { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R16G16B16A16_SFLOAT },
  461. },
  462. { // Float
  463. { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT },
  464. { VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32_SFLOAT },
  465. { VK_FORMAT_R32G32B32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT },
  466. { VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT },
  467. },
  468. };
  469. static_assert(AttribType::Count == BX_COUNTOF(s_attribType) );
  470. void fillVertexLayout(const ShaderVK* _vsh, VkPipelineVertexInputStateCreateInfo& _vertexInputState, const VertexLayout& _layout)
  471. {
  472. uint32_t numBindings = _vertexInputState.vertexBindingDescriptionCount;
  473. uint32_t numAttribs = _vertexInputState.vertexAttributeDescriptionCount;
  474. VkVertexInputBindingDescription* inputBinding = const_cast<VkVertexInputBindingDescription*>(_vertexInputState.pVertexBindingDescriptions + numBindings);
  475. VkVertexInputAttributeDescription* inputAttrib = const_cast<VkVertexInputAttributeDescription*>(_vertexInputState.pVertexAttributeDescriptions + numAttribs);
  476. inputBinding->binding = numBindings;
  477. inputBinding->stride = _layout.m_stride;
  478. inputBinding->inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
  479. for (uint32_t attr = 0; attr < Attrib::Count; ++attr)
  480. {
  481. if (UINT16_MAX != _layout.m_attributes[attr])
  482. {
  483. inputAttrib->location = _vsh->m_attrRemap[attr];
  484. inputAttrib->binding = numBindings;
  485. uint8_t num;
  486. AttribType::Enum type;
  487. bool normalized;
  488. bool asInt;
  489. _layout.decode(Attrib::Enum(attr), num, type, normalized, asInt);
  490. inputAttrib->format = s_attribType[type][num-1][normalized];
  491. inputAttrib->offset = _layout.m_offset[attr];
  492. ++inputAttrib;
  493. ++numAttribs;
  494. }
  495. }
  496. _vertexInputState.vertexBindingDescriptionCount = numBindings + 1;
  497. _vertexInputState.vertexAttributeDescriptionCount = numAttribs;
  498. }
  499. void fillInstanceBinding(const ShaderVK* _vsh, VkPipelineVertexInputStateCreateInfo& _vertexInputState, uint32_t _numInstanceData)
  500. {
  501. BX_UNUSED(_vsh);
  502. uint32_t numBindings = _vertexInputState.vertexBindingDescriptionCount;
  503. uint32_t numAttribs = _vertexInputState.vertexAttributeDescriptionCount;
  504. VkVertexInputBindingDescription* inputBinding = const_cast<VkVertexInputBindingDescription*>(_vertexInputState.pVertexBindingDescriptions + numBindings);
  505. VkVertexInputAttributeDescription* inputAttrib = const_cast<VkVertexInputAttributeDescription*>(_vertexInputState.pVertexAttributeDescriptions + numAttribs);
  506. inputBinding->binding = numBindings;
  507. inputBinding->stride = _numInstanceData * 16;
  508. inputBinding->inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
  509. for (uint32_t inst = 0; inst < _numInstanceData; ++inst)
  510. {
  511. inputAttrib->location = numAttribs;
  512. inputAttrib->binding = numBindings;
  513. inputAttrib->format = VK_FORMAT_R32G32B32A32_SFLOAT;
  514. inputAttrib->offset = inst * 16;
  515. ++numAttribs;
  516. ++inputAttrib;
  517. }
  518. _vertexInputState.vertexBindingDescriptionCount = numBindings + 1;
  519. _vertexInputState.vertexAttributeDescriptionCount = numAttribs;
  520. }
  521. static const char* s_deviceTypeName[] =
  522. {
  523. "Other",
  524. "Integrated GPU",
  525. "Discrete GPU",
  526. "Virtual GPU",
  527. "CPU",
  528. "Unknown?!"
  529. };
  530. const char* getName(VkPhysicalDeviceType _type)
  531. {
  532. return s_deviceTypeName[bx::min<int32_t>(_type, BX_COUNTOF(s_deviceTypeName)-1 )];
  533. }
  534. static const char* s_allocScopeName[] =
  535. {
  536. "vkCommand",
  537. "vkObject",
  538. "vkCache",
  539. "vkDevice",
  540. "vkInstance",
  541. };
  542. static_assert(VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE == BX_COUNTOF(s_allocScopeName)-1);
  543. constexpr size_t kMinAlignment = 16;
  544. static void* VKAPI_PTR allocationFunction(void* _userData, size_t _size, size_t _alignment, VkSystemAllocationScope _allocationScope)
  545. {
  546. bx::AllocatorI* allocator = (bx::AllocatorI*)_userData;
  547. return bx::alignedAlloc(allocator, _size, bx::max(kMinAlignment, _alignment), bx::Location(s_allocScopeName[_allocationScope], 0) );
  548. }
  549. static void* VKAPI_PTR reallocationFunction(void* _userData, void* _ptr, size_t _size, size_t _alignment, VkSystemAllocationScope _allocationScope)
  550. {
  551. bx::AllocatorI* allocator = (bx::AllocatorI*)_userData;
  552. BX_UNUSED(_userData);
  553. if (0 == _size)
  554. {
  555. bx::alignedFree(allocator, _ptr, 0);
  556. return NULL;
  557. }
  558. return bx::alignedRealloc(allocator, _ptr, _size, bx::max(kMinAlignment, _alignment), bx::Location(s_allocScopeName[_allocationScope], 0) );
  559. }
  560. static void VKAPI_PTR freeFunction(void* _userData, void* _ptr)
  561. {
  562. if (NULL == _ptr)
  563. {
  564. return;
  565. }
  566. bx::AllocatorI* allocator = (bx::AllocatorI*)_userData;
  567. bx::alignedFree(allocator, _ptr, kMinAlignment);
  568. }
  569. static void VKAPI_PTR internalAllocationNotification(void* _userData, size_t _size, VkInternalAllocationType _allocationType, VkSystemAllocationScope _allocationScope)
  570. {
  571. BX_UNUSED(_userData, _size, _allocationType, _allocationScope);
  572. }
  573. static void VKAPI_PTR internalFreeNotification(void* _userData, size_t _size, VkInternalAllocationType _allocationType, VkSystemAllocationScope _allocationScope)
  574. {
  575. BX_UNUSED(_userData, _size, _allocationType, _allocationScope);
  576. }
  577. static VkAllocationCallbacks s_allocationCb =
  578. {
  579. NULL,
  580. allocationFunction,
  581. reallocationFunction,
  582. freeFunction,
  583. internalAllocationNotification,
  584. internalFreeNotification,
  585. };
  586. VkResult VKAPI_PTR stubSetDebugUtilsObjectNameEXT(VkDevice _device, const VkDebugUtilsObjectNameInfoEXT* _nameInfo)
  587. {
  588. BX_UNUSED(_device, _nameInfo);
  589. return VK_SUCCESS;
  590. }
  591. void VKAPI_PTR stubCmdInsertDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer, const VkDebugUtilsLabelEXT* _labelInfo)
  592. {
  593. BX_UNUSED(_commandBuffer, _labelInfo);
  594. }
  595. void VKAPI_PTR stubCmdBeginDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer, const VkDebugUtilsLabelEXT* _labelInfo)
  596. {
  597. BX_UNUSED(_commandBuffer, _labelInfo);
  598. }
  599. void VKAPI_PTR stubCmdEndDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer)
  600. {
  601. BX_UNUSED(_commandBuffer);
  602. }
  603. static const char* s_debugReportObjectType[] =
  604. {
  605. "Unknown",
  606. "Instance",
  607. "PhysicalDevice",
  608. "Device",
  609. "Queue",
  610. "Semaphore",
  611. "CommandBuffer",
  612. "Fence",
  613. "DeviceMemory",
  614. "Buffer",
  615. "Image",
  616. "Event",
  617. "QueryPool",
  618. "BufferView",
  619. "ImageView",
  620. "ShaderModule",
  621. "PipelineCache",
  622. "PipelineLayout",
  623. "RenderPass",
  624. "Pipeline",
  625. "DescriptorSetLayout",
  626. "Sampler",
  627. "DescriptorPool",
  628. "DescriptorSet",
  629. "Framebuffer",
  630. "CommandPool",
  631. "SurfaceKHR",
  632. "SwapchainKHR",
  633. "DebugReport",
  634. };
  635. VkBool32 VKAPI_PTR debugReportCb(
  636. VkDebugReportFlagsEXT _flags
  637. , VkDebugReportObjectTypeEXT _objectType
  638. , uint64_t _object
  639. , size_t _location
  640. , int32_t _messageCode
  641. , const char* _layerPrefix
  642. , const char* _message
  643. , void* _userData
  644. )
  645. {
  646. BX_UNUSED(_flags, _objectType, _object, _location, _messageCode, _layerPrefix, _message, _userData, s_debugReportObjectType);
  647. // For more info about 'VUID-VkSwapchainCreateInfoKHR-imageExtent-01274'
  648. // check https://github.com/KhronosGroup/Vulkan-Docs/issues/1144
  649. if (!bx::strFind(_message, "PointSizeMissing").isEmpty()
  650. || !bx::strFind(_message, "SwapchainTooManyImages").isEmpty()
  651. || !bx::strFind(_message, "SwapchainImageNotAcquired").isEmpty()
  652. || !bx::strFind(_message, "VUID-VkSwapchainCreateInfoKHR-imageExtent-01274").isEmpty() )
  653. {
  654. return VK_FALSE;
  655. }
  656. BX_TRACE("%c%c%c%c%c %19s, %s, %d: %s"
  657. , 0 != (_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT ) ? 'I' : '-'
  658. , 0 != (_flags & VK_DEBUG_REPORT_WARNING_BIT_EXT ) ? 'W' : '-'
  659. , 0 != (_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) ? 'P' : '-'
  660. , 0 != (_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT ) ? 'E' : '-'
  661. , 0 != (_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT ) ? 'D' : '-'
  662. , s_debugReportObjectType[_objectType]
  663. , _layerPrefix
  664. , _messageCode
  665. , _message
  666. );
  667. return VK_FALSE;
  668. }
  669. VkResult enumerateLayerProperties(VkPhysicalDevice _physicalDevice, uint32_t* _propertyCount, VkLayerProperties* _properties)
  670. {
  671. return (VK_NULL_HANDLE == _physicalDevice)
  672. ? vkEnumerateInstanceLayerProperties(_propertyCount, _properties)
  673. : vkEnumerateDeviceLayerProperties(_physicalDevice, _propertyCount, _properties)
  674. ;
  675. }
  676. VkResult enumerateExtensionProperties(VkPhysicalDevice _physicalDevice, const char* _layerName, uint32_t* _propertyCount, VkExtensionProperties* _properties)
  677. {
  678. return (VK_NULL_HANDLE == _physicalDevice)
  679. ? vkEnumerateInstanceExtensionProperties(_layerName, _propertyCount, _properties)
  680. : vkEnumerateDeviceExtensionProperties(_physicalDevice, _layerName, _propertyCount, _properties)
  681. ;
  682. }
  683. void dumpExtensions(VkPhysicalDevice _physicalDevice, Extension _extensions[Extension::Count])
  684. {
  685. { // Global extensions.
  686. uint32_t numExtensionProperties;
  687. VkResult result = enumerateExtensionProperties(_physicalDevice
  688. , NULL
  689. , &numExtensionProperties
  690. , NULL
  691. );
  692. if (VK_SUCCESS == result
  693. && 0 < numExtensionProperties)
  694. {
  695. VkExtensionProperties* extensionProperties = (VkExtensionProperties*)bx::alloc(g_allocator, numExtensionProperties * sizeof(VkExtensionProperties) );
  696. result = enumerateExtensionProperties(_physicalDevice
  697. , NULL
  698. , &numExtensionProperties
  699. , extensionProperties
  700. );
  701. BX_TRACE("Global extensions (%d):"
  702. , numExtensionProperties
  703. );
  704. for (uint32_t extension = 0; extension < numExtensionProperties; ++extension)
  705. {
  706. bool supported = updateExtension(
  707. extensionProperties[extension].extensionName
  708. , extensionProperties[extension].specVersion
  709. , VK_NULL_HANDLE == _physicalDevice
  710. , _extensions
  711. );
  712. BX_TRACE("\tv%-3d %s%s"
  713. , extensionProperties[extension].specVersion
  714. , extensionProperties[extension].extensionName
  715. , supported ? " (supported)" : "", extensionProperties[extension].extensionName
  716. );
  717. BX_UNUSED(supported);
  718. }
  719. bx::free(g_allocator, extensionProperties);
  720. }
  721. }
  722. // Layer extensions.
  723. uint32_t numLayerProperties;
  724. VkResult result = enumerateLayerProperties(_physicalDevice, &numLayerProperties, NULL);
  725. if (VK_SUCCESS == result
  726. && 0 < numLayerProperties)
  727. {
  728. VkLayerProperties* layerProperties = (VkLayerProperties*)bx::alloc(g_allocator, numLayerProperties * sizeof(VkLayerProperties) );
  729. result = enumerateLayerProperties(_physicalDevice, &numLayerProperties, layerProperties);
  730. char indent = VK_NULL_HANDLE == _physicalDevice ? '\0' : '\t';
  731. BX_UNUSED(indent);
  732. BX_TRACE("%cLayer extensions (%d):"
  733. , indent
  734. , numLayerProperties
  735. );
  736. for (uint32_t layer = 0; layer < numLayerProperties; ++layer)
  737. {
  738. updateLayer(
  739. layerProperties[layer].layerName
  740. , layerProperties[layer].implementationVersion
  741. , VK_NULL_HANDLE == _physicalDevice
  742. );
  743. BX_TRACE("%c\t%s (s: 0x%08x, i: 0x%08x), %s"
  744. , indent
  745. , layerProperties[layer].layerName
  746. , layerProperties[layer].specVersion
  747. , layerProperties[layer].implementationVersion
  748. , layerProperties[layer].description
  749. );
  750. uint32_t numExtensionProperties;
  751. result = enumerateExtensionProperties(_physicalDevice
  752. , layerProperties[layer].layerName
  753. , &numExtensionProperties
  754. , NULL
  755. );
  756. if (VK_SUCCESS == result
  757. && 0 < numExtensionProperties)
  758. {
  759. VkExtensionProperties* extensionProperties = (VkExtensionProperties*)bx::alloc(g_allocator, numExtensionProperties * sizeof(VkExtensionProperties) );
  760. result = enumerateExtensionProperties(_physicalDevice
  761. , layerProperties[layer].layerName
  762. , &numExtensionProperties
  763. , extensionProperties
  764. );
  765. for (uint32_t extension = 0; extension < numExtensionProperties; ++extension)
  766. {
  767. const bool supported = updateExtension(
  768. extensionProperties[extension].extensionName
  769. , extensionProperties[extension].specVersion
  770. , VK_NULL_HANDLE == _physicalDevice
  771. , _extensions
  772. );
  773. BX_TRACE("%c\t\t%s (s: 0x%08x)"
  774. , indent
  775. , extensionProperties[extension].extensionName
  776. , extensionProperties[extension].specVersion
  777. , supported ? " (supported)" : "", extensionProperties[extension].extensionName
  778. );
  779. BX_UNUSED(supported);
  780. }
  781. bx::free(g_allocator, extensionProperties);
  782. }
  783. }
  784. bx::free(g_allocator, layerProperties);
  785. }
  786. }
  787. const char* getName(VkResult _result)
  788. {
  789. switch (_result)
  790. {
  791. #define VKENUM(_ty) case _ty: return #_ty
  792. VKENUM(VK_SUCCESS);
  793. VKENUM(VK_NOT_READY);
  794. VKENUM(VK_TIMEOUT);
  795. VKENUM(VK_EVENT_SET);
  796. VKENUM(VK_EVENT_RESET);
  797. VKENUM(VK_INCOMPLETE);
  798. VKENUM(VK_ERROR_OUT_OF_HOST_MEMORY);
  799. VKENUM(VK_ERROR_OUT_OF_DEVICE_MEMORY);
  800. VKENUM(VK_ERROR_INITIALIZATION_FAILED);
  801. VKENUM(VK_ERROR_DEVICE_LOST);
  802. VKENUM(VK_ERROR_MEMORY_MAP_FAILED);
  803. VKENUM(VK_ERROR_LAYER_NOT_PRESENT);
  804. VKENUM(VK_ERROR_EXTENSION_NOT_PRESENT);
  805. VKENUM(VK_ERROR_FEATURE_NOT_PRESENT);
  806. VKENUM(VK_ERROR_INCOMPATIBLE_DRIVER);
  807. VKENUM(VK_ERROR_TOO_MANY_OBJECTS);
  808. VKENUM(VK_ERROR_FORMAT_NOT_SUPPORTED);
  809. VKENUM(VK_ERROR_FRAGMENTED_POOL);
  810. VKENUM(VK_ERROR_UNKNOWN);
  811. VKENUM(VK_ERROR_VALIDATION_FAILED);
  812. VKENUM(VK_ERROR_OUT_OF_POOL_MEMORY);
  813. VKENUM(VK_ERROR_INVALID_EXTERNAL_HANDLE);
  814. VKENUM(VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS);
  815. VKENUM(VK_ERROR_FRAGMENTATION);
  816. VKENUM(VK_PIPELINE_COMPILE_REQUIRED);
  817. VKENUM(VK_ERROR_NOT_PERMITTED);
  818. VKENUM(VK_ERROR_SURFACE_LOST_KHR);
  819. VKENUM(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR);
  820. VKENUM(VK_SUBOPTIMAL_KHR);
  821. VKENUM(VK_ERROR_OUT_OF_DATE_KHR);
  822. VKENUM(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR);
  823. #undef VKENUM
  824. default: break;
  825. }
  826. BX_WARN(false, "Unknown VkResult? %x", _result);
  827. return "<VkResult?>";
  828. }
  829. template<typename Ty>
  830. constexpr VkObjectType getType();
  831. template<> constexpr VkObjectType getType<VkBuffer >() { return VK_OBJECT_TYPE_BUFFER; }
  832. template<> constexpr VkObjectType getType<VkCommandPool >() { return VK_OBJECT_TYPE_COMMAND_POOL; }
  833. template<> constexpr VkObjectType getType<VkDescriptorPool >() { return VK_OBJECT_TYPE_DESCRIPTOR_POOL; }
  834. template<> constexpr VkObjectType getType<VkDescriptorSet >() { return VK_OBJECT_TYPE_DESCRIPTOR_SET; }
  835. template<> constexpr VkObjectType getType<VkDescriptorSetLayout>() { return VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT; }
  836. template<> constexpr VkObjectType getType<VkDeviceMemory >() { return VK_OBJECT_TYPE_DEVICE_MEMORY; }
  837. template<> constexpr VkObjectType getType<VkFence >() { return VK_OBJECT_TYPE_FENCE; }
  838. template<> constexpr VkObjectType getType<VkFramebuffer >() { return VK_OBJECT_TYPE_FRAMEBUFFER; }
  839. template<> constexpr VkObjectType getType<VkImage >() { return VK_OBJECT_TYPE_IMAGE; }
  840. template<> constexpr VkObjectType getType<VkImageView >() { return VK_OBJECT_TYPE_IMAGE_VIEW; }
  841. template<> constexpr VkObjectType getType<VkPipeline >() { return VK_OBJECT_TYPE_PIPELINE; }
  842. template<> constexpr VkObjectType getType<VkPipelineCache >() { return VK_OBJECT_TYPE_PIPELINE_CACHE; }
  843. template<> constexpr VkObjectType getType<VkPipelineLayout >() { return VK_OBJECT_TYPE_PIPELINE_LAYOUT; }
  844. template<> constexpr VkObjectType getType<VkQueryPool >() { return VK_OBJECT_TYPE_QUERY_POOL; }
  845. template<> constexpr VkObjectType getType<VkRenderPass >() { return VK_OBJECT_TYPE_RENDER_PASS; }
  846. template<> constexpr VkObjectType getType<VkSampler >() { return VK_OBJECT_TYPE_SAMPLER; }
  847. template<> constexpr VkObjectType getType<VkSemaphore >() { return VK_OBJECT_TYPE_SEMAPHORE; }
  848. template<> constexpr VkObjectType getType<VkShaderModule >() { return VK_OBJECT_TYPE_SHADER_MODULE; }
  849. template<> constexpr VkObjectType getType<VkSurfaceKHR >() { return VK_OBJECT_TYPE_SURFACE_KHR; }
  850. template<> constexpr VkObjectType getType<VkSwapchainKHR >() { return VK_OBJECT_TYPE_SWAPCHAIN_KHR; }
  851. template<typename Ty>
  852. static BX_NO_INLINE void setDebugObjectName(VkDevice _device, Ty _object, const char* _format, ...)
  853. {
  854. if (BX_ENABLED(BGFX_CONFIG_DEBUG_OBJECT_NAME)
  855. && s_extension[Extension::EXT_debug_utils].m_supported)
  856. {
  857. char temp[2048];
  858. va_list argList;
  859. va_start(argList, _format);
  860. int32_t size = bx::min<int32_t>(sizeof(temp)-1, bx::vsnprintf(temp, sizeof(temp), _format, argList) );
  861. va_end(argList);
  862. temp[size] = '\0';
  863. VkDebugUtilsObjectNameInfoEXT ni;
  864. ni.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
  865. ni.pNext = NULL;
  866. ni.objectType = getType<Ty>();
  867. ni.objectHandle = uint64_t(_object.vk);
  868. ni.pObjectName = temp;
  869. VK_CHECK_W(vkSetDebugUtilsObjectNameEXT(_device, &ni) );
  870. }
  871. }
  872. void setMemoryBarrier(
  873. VkCommandBuffer _commandBuffer
  874. , VkPipelineStageFlags _srcStages
  875. , VkPipelineStageFlags _dstStages
  876. )
  877. {
  878. VkMemoryBarrier mb;
  879. mb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
  880. mb.pNext = NULL;
  881. mb.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
  882. mb.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
  883. vkCmdPipelineBarrier(
  884. _commandBuffer
  885. , _srcStages
  886. , _dstStages
  887. , 0
  888. , 1
  889. , &mb
  890. , 0
  891. , NULL
  892. , 0
  893. , NULL
  894. );
  895. }
  896. void setImageMemoryBarrier(
  897. VkCommandBuffer _commandBuffer
  898. , VkImage _image
  899. , VkImageAspectFlags _aspectMask
  900. , VkImageLayout _oldLayout
  901. , VkImageLayout _newLayout
  902. , uint32_t _baseMipLevel = 0
  903. , uint32_t _levelCount = VK_REMAINING_MIP_LEVELS
  904. , uint32_t _baseArrayLayer = 0
  905. , uint32_t _layerCount = VK_REMAINING_ARRAY_LAYERS
  906. )
  907. {
  908. BX_ASSERT(true
  909. && _newLayout != VK_IMAGE_LAYOUT_UNDEFINED
  910. && _newLayout != VK_IMAGE_LAYOUT_PREINITIALIZED
  911. , "_newLayout cannot use VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED."
  912. );
  913. constexpr VkPipelineStageFlags depthStageMask = 0
  914. | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
  915. | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
  916. ;
  917. constexpr VkPipelineStageFlags sampledStageMask = 0
  918. | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
  919. | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
  920. | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
  921. ;
  922. VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
  923. VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  924. VkAccessFlags srcAccessMask = 0;
  925. VkAccessFlags dstAccessMask = 0;
  926. switch (_oldLayout)
  927. {
  928. case VK_IMAGE_LAYOUT_UNDEFINED:
  929. break;
  930. case VK_IMAGE_LAYOUT_GENERAL:
  931. srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
  932. srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
  933. break;
  934. case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
  935. srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  936. srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  937. break;
  938. case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
  939. srcStageMask = depthStageMask;
  940. srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  941. break;
  942. case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
  943. srcStageMask = depthStageMask | sampledStageMask;
  944. break;
  945. case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
  946. srcStageMask = sampledStageMask;
  947. break;
  948. case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
  949. srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
  950. break;
  951. case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
  952. srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
  953. srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
  954. break;
  955. case VK_IMAGE_LAYOUT_PREINITIALIZED:
  956. srcStageMask = VK_PIPELINE_STAGE_HOST_BIT;
  957. srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
  958. break;
  959. case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
  960. break;
  961. default:
  962. BX_ASSERT(false, "Unknown image layout.");
  963. break;
  964. }
  965. switch (_newLayout)
  966. {
  967. case VK_IMAGE_LAYOUT_GENERAL:
  968. dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
  969. dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
  970. break;
  971. case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
  972. dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  973. dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  974. break;
  975. case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
  976. dstStageMask = depthStageMask;
  977. dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  978. break;
  979. case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
  980. dstStageMask = depthStageMask | sampledStageMask;
  981. dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
  982. break;
  983. case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
  984. dstStageMask = sampledStageMask;
  985. dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
  986. break;
  987. case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
  988. dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
  989. dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
  990. break;
  991. case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
  992. dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
  993. dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
  994. break;
  995. case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
  996. // vkQueuePresentKHR performs automatic visibility operations
  997. break;
  998. default:
  999. BX_ASSERT(false, "Unknown image layout.");
  1000. break;
  1001. }
  1002. VkImageMemoryBarrier imb;
  1003. imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
  1004. imb.pNext = NULL;
  1005. imb.srcAccessMask = srcAccessMask;
  1006. imb.dstAccessMask = dstAccessMask;
  1007. imb.oldLayout = _oldLayout;
  1008. imb.newLayout = _newLayout;
  1009. imb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  1010. imb.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  1011. imb.image = _image;
  1012. imb.subresourceRange.aspectMask = _aspectMask;
  1013. imb.subresourceRange.baseMipLevel = _baseMipLevel;
  1014. imb.subresourceRange.levelCount = _levelCount;
  1015. imb.subresourceRange.baseArrayLayer = _baseArrayLayer;
  1016. imb.subresourceRange.layerCount = _layerCount;
  1017. vkCmdPipelineBarrier(
  1018. _commandBuffer
  1019. , srcStageMask
  1020. , dstStageMask
  1021. , 0
  1022. , 0
  1023. , NULL
  1024. , 0
  1025. , NULL
  1026. , 1
  1027. , &imb
  1028. );
  1029. }
  1030. #define MAX_DESCRIPTOR_SETS (BGFX_CONFIG_RENDERER_VULKAN_MAX_DESCRIPTOR_SETS_PER_FRAME * BGFX_CONFIG_MAX_FRAME_LATENCY)
  1031. struct RendererContextVK : public RendererContextI
  1032. {
  1033. RendererContextVK()
  1034. : m_allocatorCb(NULL)
  1035. , m_memoryLru()
  1036. , m_renderDocDll(NULL)
  1037. , m_vulkan1Dll(NULL)
  1038. , m_maxAnisotropy(1.0f)
  1039. , m_depthClamp(false)
  1040. , m_wireframe(false)
  1041. , m_captureBuffer(VK_NULL_HANDLE)
  1042. , m_captureMemory()
  1043. , m_captureSize(0)
  1044. , m_variableRateShadingSupported(false)
  1045. {
  1046. }
  1047. ~RendererContextVK()
  1048. {
  1049. }
  1050. bool init(const Init& _init)
  1051. {
  1052. struct ErrorState
  1053. {
  1054. enum Enum
  1055. {
  1056. Default,
  1057. LoadedVulkan1,
  1058. InstanceCreated,
  1059. DeviceCreated,
  1060. CommandQueueCreated,
  1061. SwapChainCreated,
  1062. DescriptorCreated,
  1063. TimerQueryCreated,
  1064. };
  1065. };
  1066. ErrorState::Enum errorState = ErrorState::Default;
  1067. const bool headless = NULL == g_platformData.nwh;
  1068. const void* nextFeatures = NULL;
  1069. VkPhysicalDeviceLineRasterizationFeaturesEXT lineRasterizationFeatures = {};
  1070. VkPhysicalDeviceCustomBorderColorFeaturesEXT customBorderColorFeatures = {};
  1071. VkPhysicalDeviceFragmentShadingRateFeaturesKHR fragmentShadingRate = {};
  1072. m_fbh = BGFX_INVALID_HANDLE;
  1073. bx::memSet(m_uniforms, 0, sizeof(m_uniforms) );
  1074. bx::memSet(&m_resolution, 0, sizeof(m_resolution) );
  1075. bool imported = true;
  1076. VkResult result;
  1077. m_globalQueueFamily = UINT32_MAX;
  1078. if (_init.debug
  1079. || _init.profile)
  1080. {
  1081. m_renderDocDll = loadRenderDoc();
  1082. }
  1083. setGraphicsDebuggerPresent(false
  1084. || NULL != m_renderDocDll
  1085. || NULL != findModule("Nvda.Graphics.Interception.dll")
  1086. );
  1087. m_vulkan1Dll = bx::dlopen(
  1088. #if BX_PLATFORM_WINDOWS
  1089. "vulkan-1.dll"
  1090. #elif BX_PLATFORM_ANDROID
  1091. "libvulkan.so"
  1092. #elif BX_PLATFORM_OSX
  1093. "libMoltenVK.dylib"
  1094. #else
  1095. "libvulkan.so.1"
  1096. #endif // BX_PLATFORM_*
  1097. );
  1098. if (NULL == m_vulkan1Dll)
  1099. {
  1100. BX_TRACE("Init error: Failed to load vulkan dynamic library.");
  1101. goto error;
  1102. }
  1103. errorState = ErrorState::LoadedVulkan1;
  1104. BX_TRACE("Shared library functions:");
  1105. #define VK_IMPORT_FUNC(_optional, _func) \
  1106. _func = (PFN_##_func)bx::dlsym(m_vulkan1Dll, #_func); \
  1107. BX_TRACE("\t%p " #_func, _func); \
  1108. imported &= _optional || NULL != _func
  1109. VK_IMPORT
  1110. #undef VK_IMPORT_FUNC
  1111. if (!imported)
  1112. {
  1113. BX_TRACE("Init error: Failed to load shared library functions.");
  1114. goto error;
  1115. }
  1116. {
  1117. s_layer[Layer::VK_LAYER_LUNARG_standard_validation].m_device.m_initialize = _init.debug;
  1118. s_layer[Layer::VK_LAYER_LUNARG_standard_validation].m_instance.m_initialize = _init.debug;
  1119. s_layer[Layer::VK_LAYER_KHRONOS_validation ].m_device.m_initialize = _init.debug;
  1120. s_layer[Layer::VK_LAYER_KHRONOS_validation ].m_instance.m_initialize = _init.debug;
  1121. s_extension[Extension::EXT_debug_report].m_initialize = _init.debug;
  1122. s_extension[Extension::EXT_conservative_rasterization ].m_initialize = !!(_init.capabilities & BGFX_CAPS_CONSERVATIVE_RASTER );
  1123. s_extension[Extension::EXT_shader_viewport_index_layer].m_initialize = !!(_init.capabilities & BGFX_CAPS_VIEWPORT_LAYER_ARRAY );
  1124. s_extension[Extension::KHR_draw_indirect_count ].m_initialize = !!(_init.capabilities & BGFX_CAPS_DRAW_INDIRECT_COUNT );
  1125. s_extension[Extension::KHR_fragment_shading_rate ].m_initialize = !!(_init.capabilities & BGFX_CAPS_VARIABLE_RATE_SHADING);
  1126. dumpExtensions(VK_NULL_HANDLE, s_extension);
  1127. if (s_layer[Layer::VK_LAYER_KHRONOS_validation].m_device.m_supported
  1128. || s_layer[Layer::VK_LAYER_KHRONOS_validation].m_instance.m_supported)
  1129. {
  1130. s_layer[Layer::VK_LAYER_LUNARG_standard_validation].m_device.m_supported = false;
  1131. s_layer[Layer::VK_LAYER_LUNARG_standard_validation].m_instance.m_supported = false;
  1132. }
  1133. uint32_t numEnabledLayers = 0;
  1134. const char* enabledLayer[Layer::Count];
  1135. BX_TRACE("Enabled instance layers:");
  1136. for (uint32_t ii = 0; ii < Layer::Count; ++ii)
  1137. {
  1138. const Layer& layer = s_layer[ii];
  1139. if (layer.m_instance.m_supported
  1140. && layer.m_instance.m_initialize)
  1141. {
  1142. enabledLayer[numEnabledLayers++] = layer.m_name;
  1143. BX_TRACE("\t%s", layer.m_name);
  1144. }
  1145. }
  1146. uint32_t numEnabledExtensions = 0;
  1147. const char* enabledExtension[Extension::Count + 1];
  1148. if (!headless)
  1149. {
  1150. enabledExtension[numEnabledExtensions++] = VK_KHR_SURFACE_EXTENSION_NAME;
  1151. }
  1152. for (uint32_t ii = 0; ii < Extension::Count; ++ii)
  1153. {
  1154. const Extension& extension = s_extension[ii];
  1155. const LayerInfo& layerInfo = s_layer[extension.m_layer].m_instance;
  1156. const bool layerEnabled = false
  1157. || extension.m_layer == Layer::Count || (layerInfo.m_supported && layerInfo.m_initialize)
  1158. ;
  1159. if (extension.m_supported
  1160. && extension.m_initialize
  1161. && extension.m_instanceExt
  1162. && layerEnabled)
  1163. {
  1164. enabledExtension[numEnabledExtensions++] = extension.m_name;
  1165. }
  1166. }
  1167. BX_TRACE("Enabled instance extensions:");
  1168. for (uint32_t ii = 0; ii < numEnabledExtensions; ++ii)
  1169. {
  1170. BX_TRACE("\t%s", enabledExtension[ii]);
  1171. }
  1172. uint32_t vulkanApiVersionSelector = 0;
  1173. if (NULL != vkEnumerateInstanceVersion)
  1174. {
  1175. result = vkEnumerateInstanceVersion(&vulkanApiVersionSelector);
  1176. if (VK_SUCCESS != result)
  1177. {
  1178. BX_TRACE(
  1179. "Init error: vkEnumerateInstanceVersion failed %d: %s."
  1180. , result
  1181. , getName(result)
  1182. );
  1183. goto error;
  1184. }
  1185. }
  1186. vulkanApiVersionSelector = bx::max(vulkanApiVersionSelector, VK_API_VERSION_1_2);
  1187. VkApplicationInfo appInfo;
  1188. appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
  1189. appInfo.pNext = NULL;
  1190. appInfo.pApplicationName = "bgfx";
  1191. appInfo.applicationVersion = BGFX_API_VERSION;
  1192. appInfo.pEngineName = "bgfx";
  1193. appInfo.engineVersion = BGFX_API_VERSION;
  1194. appInfo.apiVersion = vulkanApiVersionSelector;
  1195. VkInstanceCreateInfo ici;
  1196. ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  1197. ici.pNext = NULL;
  1198. ici.flags = 0
  1199. | (BX_ENABLED(BX_PLATFORM_OSX) ? VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR : 0)
  1200. ;
  1201. ici.pApplicationInfo = &appInfo;
  1202. ici.enabledLayerCount = numEnabledLayers;
  1203. ici.ppEnabledLayerNames = enabledLayer;
  1204. ici.enabledExtensionCount = numEnabledExtensions;
  1205. ici.ppEnabledExtensionNames = enabledExtension;
  1206. if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
  1207. {
  1208. // Validation layer is calling freeFunction with pointers that are not allocated
  1209. // via callback mechanism. This is bug in validation layer, and work-around
  1210. // would be to keep track of allocated pointers and ignore those that are not
  1211. // allocated by it.
  1212. //
  1213. // Anyhow we just let VK take care of memory, until they fix the issue...
  1214. //
  1215. // s_allocationCb.pUserData = g_allocator;
  1216. // m_allocatorCb = &s_allocationCb;
  1217. BX_UNUSED(s_allocationCb);
  1218. }
  1219. result = vkCreateInstance(
  1220. &ici
  1221. , m_allocatorCb
  1222. , &m_instance
  1223. );
  1224. if (VK_SUCCESS != result)
  1225. {
  1226. BX_TRACE("Init error: vkCreateInstance failed %d: %s.", result, getName(result) );
  1227. goto error;
  1228. }
  1229. m_instanceApiVersion = vulkanApiVersionSelector;
  1230. BX_TRACE("Instance API version: %d.%d.%d"
  1231. , VK_API_VERSION_MAJOR(m_instanceApiVersion)
  1232. , VK_API_VERSION_MINOR(m_instanceApiVersion)
  1233. , VK_API_VERSION_PATCH(m_instanceApiVersion)
  1234. );
  1235. BX_TRACE("Instance variant: %d", VK_API_VERSION_VARIANT(m_instanceApiVersion) );
  1236. }
  1237. errorState = ErrorState::InstanceCreated;
  1238. BX_TRACE("Instance functions:");
  1239. #define VK_IMPORT_INSTANCE_FUNC(_optional, _func) \
  1240. _func = (PFN_##_func)vkGetInstanceProcAddr(m_instance, #_func); \
  1241. BX_TRACE("\t%p " #_func, _func); \
  1242. imported &= _optional || NULL != _func
  1243. VK_IMPORT_INSTANCE
  1244. #undef VK_IMPORT_INSTANCE_FUNC
  1245. if (!imported)
  1246. {
  1247. BX_TRACE("Init error: Failed to load instance functions.");
  1248. goto error;
  1249. }
  1250. m_debugReportCallback = VK_NULL_HANDLE;
  1251. if (s_extension[Extension::EXT_debug_report].m_supported)
  1252. {
  1253. VkDebugReportCallbackCreateInfoEXT drcb;
  1254. drcb.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
  1255. drcb.pNext = NULL;
  1256. drcb.pfnCallback = debugReportCb;
  1257. drcb.pUserData = NULL;
  1258. drcb.flags = 0
  1259. | VK_DEBUG_REPORT_ERROR_BIT_EXT
  1260. | VK_DEBUG_REPORT_WARNING_BIT_EXT
  1261. ;
  1262. result = vkCreateDebugReportCallbackEXT(m_instance
  1263. , &drcb
  1264. , m_allocatorCb
  1265. , &m_debugReportCallback
  1266. );
  1267. BX_WARN(VK_SUCCESS == result, "vkCreateDebugReportCallbackEXT failed %d: %s.", result, getName(result) );
  1268. }
  1269. {
  1270. BX_TRACE("---");
  1271. uint32_t numPhysicalDevices;
  1272. result = vkEnumeratePhysicalDevices(m_instance
  1273. , &numPhysicalDevices
  1274. , NULL
  1275. );
  1276. if (VK_SUCCESS != result)
  1277. {
  1278. BX_TRACE("Init error: vkEnumeratePhysicalDevices failed %d: %s.", result, getName(result) );
  1279. goto error;
  1280. }
  1281. VkPhysicalDevice physicalDevices[4];
  1282. numPhysicalDevices = bx::min<uint32_t>(numPhysicalDevices, BX_COUNTOF(physicalDevices) );
  1283. result = vkEnumeratePhysicalDevices(m_instance
  1284. , &numPhysicalDevices
  1285. , physicalDevices
  1286. );
  1287. if (VK_SUCCESS != result)
  1288. {
  1289. BX_TRACE("Init error: vkEnumeratePhysicalDevices failed %d: %s.", result, getName(result) );
  1290. goto error;
  1291. }
  1292. Extension physicalDeviceExtensions[4][Extension::Count];
  1293. uint32_t physicalDeviceIdx = UINT32_MAX;
  1294. uint32_t fallbackPhysicalDeviceIdx = UINT32_MAX;
  1295. for (uint32_t ii = 0; ii < numPhysicalDevices; ++ii)
  1296. {
  1297. VkPhysicalDeviceProperties2 pdp2;
  1298. pdp2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
  1299. pdp2.pNext = NULL;
  1300. vkGetPhysicalDeviceProperties2(physicalDevices[ii], &pdp2);
  1301. VkPhysicalDeviceProperties& pdp = pdp2.properties;
  1302. BX_TRACE("Physical device %d:", ii);
  1303. BX_TRACE("\t Name: %s", pdp.deviceName);
  1304. BX_TRACE("\t API version: %d.%d.%d"
  1305. , VK_API_VERSION_MAJOR(pdp.apiVersion)
  1306. , VK_API_VERSION_MINOR(pdp.apiVersion)
  1307. , VK_API_VERSION_PATCH(pdp.apiVersion)
  1308. );
  1309. BX_TRACE("\t API variant: %d", VK_API_VERSION_VARIANT(pdp.apiVersion) );
  1310. BX_TRACE("\tDriver version: %x", pdp.driverVersion);
  1311. BX_TRACE("\t VendorId: %x", pdp.vendorID);
  1312. BX_TRACE("\t DeviceId: %x", pdp.deviceID);
  1313. BX_TRACE("\t Type: %d", pdp.deviceType);
  1314. if (VK_PHYSICAL_DEVICE_TYPE_CPU == pdp.deviceType)
  1315. {
  1316. pdp.vendorID = BGFX_PCI_ID_SOFTWARE_RASTERIZER;
  1317. }
  1318. g_caps.gpu[ii].vendorId = uint16_t(pdp.vendorID);
  1319. g_caps.gpu[ii].deviceId = uint16_t(pdp.deviceID);
  1320. ++g_caps.numGPUs;
  1321. if ( (BGFX_PCI_ID_NONE != g_caps.vendorId || 0 != g_caps.deviceId)
  1322. && (BGFX_PCI_ID_NONE == g_caps.vendorId || pdp.vendorID == g_caps.vendorId)
  1323. && ( 0 == g_caps.deviceId || pdp.deviceID == g_caps.deviceId) )
  1324. {
  1325. if (pdp.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
  1326. || pdp.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
  1327. {
  1328. fallbackPhysicalDeviceIdx = ii;
  1329. }
  1330. physicalDeviceIdx = ii;
  1331. }
  1332. else if (UINT32_MAX == physicalDeviceIdx)
  1333. {
  1334. if (pdp.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
  1335. {
  1336. fallbackPhysicalDeviceIdx = ii;
  1337. }
  1338. else if (pdp.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
  1339. {
  1340. physicalDeviceIdx = ii;
  1341. }
  1342. }
  1343. VkPhysicalDeviceMemoryProperties pdmp;
  1344. vkGetPhysicalDeviceMemoryProperties(physicalDevices[ii], &pdmp);
  1345. BX_TRACE("\tMemory type count: %d", pdmp.memoryTypeCount);
  1346. for (uint32_t jj = 0; jj < pdmp.memoryTypeCount; ++jj)
  1347. {
  1348. BX_TRACE("\t%3d: flags 0x%08x, index %d"
  1349. , jj
  1350. , pdmp.memoryTypes[jj].propertyFlags
  1351. , pdmp.memoryTypes[jj].heapIndex
  1352. );
  1353. }
  1354. BX_TRACE("\tMemory heap count: %d", pdmp.memoryHeapCount);
  1355. for (uint32_t jj = 0; jj < pdmp.memoryHeapCount; ++jj)
  1356. {
  1357. char size[16];
  1358. bx::prettify(size, BX_COUNTOF(size), pdmp.memoryHeaps[jj].size);
  1359. BX_TRACE("\t%3d: flags 0x%08x, size %10s"
  1360. , jj
  1361. , pdmp.memoryHeaps[jj].flags
  1362. , size
  1363. );
  1364. }
  1365. bx::memCopy(&physicalDeviceExtensions[ii][0], &s_extension[0], sizeof(s_extension) );
  1366. dumpExtensions(physicalDevices[ii], physicalDeviceExtensions[ii]);
  1367. }
  1368. if (UINT32_MAX == physicalDeviceIdx)
  1369. {
  1370. physicalDeviceIdx = UINT32_MAX == fallbackPhysicalDeviceIdx
  1371. ? 0
  1372. : fallbackPhysicalDeviceIdx
  1373. ;
  1374. }
  1375. m_physicalDevice = physicalDevices[physicalDeviceIdx];
  1376. bx::memCopy(&s_extension[0], &physicalDeviceExtensions[physicalDeviceIdx][0], sizeof(s_extension) );
  1377. m_deviceShadingRateImageProperties = {};
  1378. m_deviceShadingRateImageProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR;
  1379. m_deviceProperties = {};
  1380. m_deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
  1381. m_deviceProperties.pNext = &m_deviceShadingRateImageProperties;
  1382. vkGetPhysicalDeviceProperties2(m_physicalDevice, &m_deviceProperties);
  1383. g_caps.vendorId = uint16_t(m_deviceProperties.properties.vendorID);
  1384. g_caps.deviceId = uint16_t(m_deviceProperties.properties.deviceID);
  1385. BX_TRACE("Using physical device %d: %s", physicalDeviceIdx, m_deviceProperties.properties.deviceName);
  1386. VkPhysicalDeviceFeatures supportedFeatures;
  1387. if (s_extension[Extension::KHR_get_physical_device_properties2].m_supported)
  1388. {
  1389. VkPhysicalDeviceFeatures2KHR deviceFeatures2;
  1390. deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
  1391. deviceFeatures2.pNext = NULL;
  1392. VkBaseOutStructure* next = (VkBaseOutStructure*)&deviceFeatures2;
  1393. if (s_extension[Extension::EXT_line_rasterization].m_supported)
  1394. {
  1395. next->pNext = (VkBaseOutStructure*)&lineRasterizationFeatures;
  1396. next = (VkBaseOutStructure*)&lineRasterizationFeatures;
  1397. lineRasterizationFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT;
  1398. lineRasterizationFeatures.pNext = NULL;
  1399. }
  1400. if (s_extension[Extension::EXT_custom_border_color].m_supported)
  1401. {
  1402. next->pNext = (VkBaseOutStructure*)&customBorderColorFeatures;
  1403. next = (VkBaseOutStructure*)&customBorderColorFeatures;
  1404. customBorderColorFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT;
  1405. customBorderColorFeatures.pNext = NULL;
  1406. }
  1407. nextFeatures = deviceFeatures2.pNext;
  1408. vkGetPhysicalDeviceFeatures2KHR(m_physicalDevice, &deviceFeatures2);
  1409. supportedFeatures = deviceFeatures2.features;
  1410. }
  1411. else
  1412. {
  1413. vkGetPhysicalDeviceFeatures(m_physicalDevice, &supportedFeatures);
  1414. }
  1415. if (s_extension[Extension::KHR_fragment_shading_rate].m_supported)
  1416. {
  1417. VkPhysicalDeviceFeatures2KHR deviceFeatures2;
  1418. deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
  1419. deviceFeatures2.pNext = NULL;
  1420. VkBaseOutStructure* next = (VkBaseOutStructure*)&deviceFeatures2;
  1421. next->pNext = (VkBaseOutStructure*)&fragmentShadingRate;
  1422. fragmentShadingRate.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
  1423. fragmentShadingRate.pNext = NULL;
  1424. vkGetPhysicalDeviceFeatures2KHR(m_physicalDevice, &deviceFeatures2);
  1425. if (!fragmentShadingRate.pipelineFragmentShadingRate
  1426. || !fragmentShadingRate.primitiveFragmentShadingRate)
  1427. {
  1428. s_extension[Extension::KHR_fragment_shading_rate].m_supported = false;
  1429. }
  1430. else
  1431. {
  1432. fragmentShadingRate.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
  1433. fragmentShadingRate.pNext = (VkBaseOutStructure*)nextFeatures;
  1434. fragmentShadingRate.pipelineFragmentShadingRate = VK_TRUE;
  1435. fragmentShadingRate.primitiveFragmentShadingRate = VK_TRUE;
  1436. fragmentShadingRate.attachmentFragmentShadingRate = VK_FALSE;
  1437. nextFeatures = &fragmentShadingRate;
  1438. }
  1439. }
  1440. bx::memSet(&m_deviceFeatures, 0, sizeof(m_deviceFeatures) );
  1441. m_deviceFeatures.fullDrawIndexUint32 = supportedFeatures.fullDrawIndexUint32;
  1442. m_deviceFeatures.imageCubeArray = supportedFeatures.imageCubeArray && (_init.capabilities & BGFX_CAPS_TEXTURE_CUBE_ARRAY);
  1443. m_deviceFeatures.independentBlend = supportedFeatures.independentBlend && (_init.capabilities & BGFX_CAPS_BLEND_INDEPENDENT);
  1444. m_deviceFeatures.multiDrawIndirect = supportedFeatures.multiDrawIndirect && (_init.capabilities & BGFX_CAPS_DRAW_INDIRECT);
  1445. m_deviceFeatures.drawIndirectFirstInstance = supportedFeatures.drawIndirectFirstInstance && (_init.capabilities & BGFX_CAPS_DRAW_INDIRECT);
  1446. m_deviceFeatures.depthClamp = supportedFeatures.depthClamp;
  1447. m_deviceFeatures.fillModeNonSolid = supportedFeatures.fillModeNonSolid;
  1448. m_deviceFeatures.largePoints = supportedFeatures.largePoints;
  1449. m_deviceFeatures.samplerAnisotropy = supportedFeatures.samplerAnisotropy;
  1450. m_deviceFeatures.textureCompressionETC2 = supportedFeatures.textureCompressionETC2;
  1451. m_deviceFeatures.textureCompressionBC = supportedFeatures.textureCompressionBC;
  1452. m_deviceFeatures.vertexPipelineStoresAndAtomics = supportedFeatures.vertexPipelineStoresAndAtomics;
  1453. m_deviceFeatures.fragmentStoresAndAtomics = supportedFeatures.fragmentStoresAndAtomics;
  1454. m_deviceFeatures.shaderImageGatherExtended = supportedFeatures.shaderImageGatherExtended;
  1455. m_deviceFeatures.shaderStorageImageExtendedFormats = supportedFeatures.shaderStorageImageExtendedFormats;
  1456. m_deviceFeatures.shaderClipDistance = supportedFeatures.shaderClipDistance;
  1457. m_deviceFeatures.shaderCullDistance = supportedFeatures.shaderCullDistance;
  1458. m_deviceFeatures.shaderResourceMinLod = supportedFeatures.shaderResourceMinLod;
  1459. m_deviceFeatures.geometryShader = supportedFeatures.geometryShader;
  1460. m_lineAASupport = true
  1461. && s_extension[Extension::EXT_line_rasterization].m_supported
  1462. && lineRasterizationFeatures.smoothLines
  1463. ;
  1464. m_borderColorSupport = true
  1465. && s_extension[Extension::EXT_custom_border_color].m_supported
  1466. && customBorderColorFeatures.customBorderColors
  1467. ;
  1468. m_timerQuerySupport = m_deviceProperties.properties.limits.timestampComputeAndGraphics;
  1469. const bool indirectDrawSupport = true
  1470. && m_deviceFeatures.multiDrawIndirect
  1471. && m_deviceFeatures.drawIndirectFirstInstance
  1472. ;
  1473. g_caps.supported |= ( 0
  1474. | BGFX_CAPS_ALPHA_TO_COVERAGE
  1475. | (m_deviceFeatures.independentBlend ? BGFX_CAPS_BLEND_INDEPENDENT : 0)
  1476. | BGFX_CAPS_COMPUTE
  1477. | (indirectDrawSupport ? BGFX_CAPS_DRAW_INDIRECT : 0)
  1478. | BGFX_CAPS_FRAGMENT_DEPTH
  1479. | BGFX_CAPS_IMAGE_RW
  1480. | (m_deviceFeatures.fullDrawIndexUint32 ? BGFX_CAPS_INDEX32 : 0)
  1481. | BGFX_CAPS_INSTANCING
  1482. | BGFX_CAPS_OCCLUSION_QUERY
  1483. | (!headless ? BGFX_CAPS_SWAP_CHAIN : 0)
  1484. | BGFX_CAPS_TEXTURE_2D_ARRAY
  1485. | BGFX_CAPS_TEXTURE_3D
  1486. | BGFX_CAPS_TEXTURE_BLIT
  1487. | BGFX_CAPS_TEXTURE_COMPARE_ALL
  1488. | (m_deviceFeatures.imageCubeArray ? BGFX_CAPS_TEXTURE_CUBE_ARRAY : 0)
  1489. | BGFX_CAPS_TEXTURE_READ_BACK
  1490. | BGFX_CAPS_VERTEX_ATTRIB_HALF
  1491. | BGFX_CAPS_VERTEX_ATTRIB_UINT10
  1492. | BGFX_CAPS_VERTEX_ID
  1493. | (m_deviceFeatures.geometryShader ? BGFX_CAPS_PRIMITIVE_ID : 0)
  1494. );
  1495. g_caps.supported |= 0
  1496. | (s_extension[Extension::EXT_conservative_rasterization ].m_supported ? BGFX_CAPS_CONSERVATIVE_RASTER : 0)
  1497. | (s_extension[Extension::EXT_shader_viewport_index_layer].m_supported ? BGFX_CAPS_VIEWPORT_LAYER_ARRAY : 0)
  1498. | (s_extension[Extension::KHR_draw_indirect_count ].m_supported && indirectDrawSupport ? BGFX_CAPS_DRAW_INDIRECT_COUNT : 0)
  1499. | (s_extension[Extension::KHR_fragment_shading_rate ].m_supported ? BGFX_CAPS_VARIABLE_RATE_SHADING : 0)
  1500. ;
  1501. m_variableRateShadingSupported = s_extension[Extension::KHR_fragment_shading_rate].m_supported;
  1502. const uint32_t maxAttachments = bx::min<uint32_t>(
  1503. m_deviceProperties.properties.limits.maxFragmentOutputAttachments
  1504. , m_deviceProperties.properties.limits.maxColorAttachments
  1505. );
  1506. g_caps.limits.maxTextureSize = m_deviceProperties.properties.limits.maxImageDimension2D;
  1507. g_caps.limits.maxTextureLayers = m_deviceProperties.properties.limits.maxImageArrayLayers;
  1508. g_caps.limits.maxFBAttachments = bx::min<uint32_t>(maxAttachments, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS);
  1509. g_caps.limits.maxTextureSamplers = bx::min<uint32_t>(m_deviceProperties.properties.limits.maxPerStageResources, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS);
  1510. g_caps.limits.maxComputeBindings = bx::min<uint32_t>(m_deviceProperties.properties.limits.maxPerStageResources, BGFX_MAX_COMPUTE_BINDINGS);
  1511. g_caps.limits.maxVertexStreams = bx::min<uint32_t>(m_deviceProperties.properties.limits.maxVertexInputBindings, BGFX_CONFIG_MAX_VERTEX_STREAMS);
  1512. {
  1513. const VkSampleCountFlags sampleMask = ~0
  1514. & m_deviceProperties.properties.limits.framebufferColorSampleCounts
  1515. & m_deviceProperties.properties.limits.framebufferDepthSampleCounts
  1516. ;
  1517. for (uint16_t ii = 0, last = 0; ii < BX_COUNTOF(s_msaa); ++ii)
  1518. {
  1519. const VkSampleCountFlags sampleBit = s_msaa[ii].Sample;
  1520. if (sampleBit & sampleMask)
  1521. {
  1522. last = ii;
  1523. }
  1524. else
  1525. {
  1526. s_msaa[ii] = s_msaa[last];
  1527. }
  1528. }
  1529. }
  1530. {
  1531. const VkExtent2D maxFragmentSize = m_deviceShadingRateImageProperties.maxFragmentSize;
  1532. for (uint32_t ii = 0; ii < BX_COUNTOF(s_shadingRate); ++ii)
  1533. {
  1534. ShadingRateVk& shadingRate = s_shadingRate[ii];
  1535. shadingRate.fragmentSize.width = bx::min(shadingRate.initFragmentSize.width, maxFragmentSize.width);
  1536. shadingRate.fragmentSize.height = bx::min(shadingRate.initFragmentSize.height, maxFragmentSize.height);
  1537. }
  1538. }
  1539. for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
  1540. {
  1541. uint16_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE;
  1542. const bool depth = bimg::isDepth(bimg::TextureFormat::Enum(ii) );
  1543. VkFormat fmt = depth
  1544. ? s_textureFormat[ii].m_fmtDsv
  1545. : s_textureFormat[ii].m_fmt
  1546. ;
  1547. for (uint32_t jj = 0, num = depth ? 1 : 2; jj < num; ++jj)
  1548. {
  1549. if (VK_FORMAT_UNDEFINED != fmt)
  1550. {
  1551. for (uint32_t test = 0; test < BX_COUNTOF(s_imageTest); ++test)
  1552. {
  1553. const ImageTest& it = s_imageTest[test];
  1554. VkImageFormatProperties ifp;
  1555. result = vkGetPhysicalDeviceImageFormatProperties(
  1556. m_physicalDevice
  1557. , fmt
  1558. , it.type
  1559. , VK_IMAGE_TILING_OPTIMAL
  1560. , it.usage
  1561. , it.flags
  1562. , &ifp
  1563. );
  1564. if (VK_SUCCESS == result)
  1565. {
  1566. support |= it.formatCaps[jj];
  1567. const bool multisample = VK_SAMPLE_COUNT_1_BIT < ifp.sampleCounts;
  1568. if (it.usage & VK_IMAGE_USAGE_SAMPLED_BIT)
  1569. {
  1570. support |= 0
  1571. | BGFX_CAPS_FORMAT_TEXTURE_VERTEX
  1572. | (multisample ? BGFX_CAPS_FORMAT_TEXTURE_MSAA : 0)
  1573. ;
  1574. }
  1575. if (it.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) )
  1576. {
  1577. support |= 0
  1578. | BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN
  1579. | (multisample ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA : 0)
  1580. ;
  1581. }
  1582. }
  1583. }
  1584. }
  1585. fmt = s_textureFormat[ii].m_fmtSrgb;
  1586. }
  1587. g_caps.formats[ii] = support;
  1588. }
  1589. vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &m_memoryProperties);
  1590. }
  1591. {
  1592. BX_TRACE("---");
  1593. uint32_t queueFamilyPropertyCount = 0;
  1594. vkGetPhysicalDeviceQueueFamilyProperties(
  1595. m_physicalDevice
  1596. , &queueFamilyPropertyCount
  1597. , NULL
  1598. );
  1599. VkQueueFamilyProperties* queueFamilyPropertices = (VkQueueFamilyProperties*)bx::alloc(g_allocator, queueFamilyPropertyCount * sizeof(VkQueueFamilyProperties) );
  1600. vkGetPhysicalDeviceQueueFamilyProperties(
  1601. m_physicalDevice
  1602. , &queueFamilyPropertyCount
  1603. , queueFamilyPropertices
  1604. );
  1605. for (uint32_t ii = 0; ii < queueFamilyPropertyCount; ++ii)
  1606. {
  1607. const VkQueueFamilyProperties& qfp = queueFamilyPropertices[ii];
  1608. BX_TRACE("Queue family property %d:", ii);
  1609. BX_TRACE("\t Queue flags: 0x%08x", qfp.queueFlags);
  1610. BX_TRACE("\t Queue count: %d", qfp.queueCount);
  1611. BX_TRACE("\tTS valid bits: 0x%08x", qfp.timestampValidBits);
  1612. BX_TRACE("\t Min image: %d x %d x %d"
  1613. , qfp.minImageTransferGranularity.width
  1614. , qfp.minImageTransferGranularity.height
  1615. , qfp.minImageTransferGranularity.depth
  1616. );
  1617. constexpr VkQueueFlags requiredFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
  1618. if (UINT32_MAX == m_globalQueueFamily
  1619. && requiredFlags == (requiredFlags & qfp.queueFlags) )
  1620. {
  1621. m_globalQueueFamily = ii;
  1622. }
  1623. }
  1624. bx::free(g_allocator, queueFamilyPropertices);
  1625. if (UINT32_MAX == m_globalQueueFamily)
  1626. {
  1627. BX_TRACE("Init error: Unable to find combined graphics and compute queue.");
  1628. goto error;
  1629. }
  1630. }
  1631. {
  1632. uint32_t numEnabledLayers = 0;
  1633. const char* enabledLayer[Layer::Count];
  1634. BX_TRACE("Enabled device layers:");
  1635. for (uint32_t ii = 0; ii < Layer::Count; ++ii)
  1636. {
  1637. const Layer& layer = s_layer[ii];
  1638. if (layer.m_device.m_supported
  1639. && layer.m_device.m_initialize)
  1640. {
  1641. enabledLayer[numEnabledLayers++] = layer.m_name;
  1642. BX_TRACE("\t%s", layer.m_name);
  1643. }
  1644. }
  1645. uint32_t numEnabledExtensions = 0;
  1646. const char* enabledExtension[Extension::Count + 3];
  1647. enabledExtension[numEnabledExtensions++] = VK_KHR_MAINTENANCE1_EXTENSION_NAME;
  1648. if (!headless)
  1649. {
  1650. enabledExtension[numEnabledExtensions++] = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
  1651. }
  1652. if (BX_ENABLED(BX_PLATFORM_OSX) )
  1653. {
  1654. enabledExtension[numEnabledExtensions++] = VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME;
  1655. }
  1656. for (uint32_t ii = 0; ii < Extension::Count; ++ii)
  1657. {
  1658. const Extension& extension = s_extension[ii];
  1659. bool layerEnabled = extension.m_layer == Layer::Count
  1660. || (s_layer[extension.m_layer].m_device.m_supported && s_layer[extension.m_layer].m_device.m_initialize)
  1661. ;
  1662. if (extension.m_supported
  1663. && extension.m_initialize
  1664. && !extension.m_instanceExt
  1665. && layerEnabled)
  1666. {
  1667. enabledExtension[numEnabledExtensions++] = extension.m_name;
  1668. }
  1669. }
  1670. BX_TRACE("Enabled device extensions:");
  1671. for (uint32_t ii = 0; ii < numEnabledExtensions; ++ii)
  1672. {
  1673. BX_TRACE("\t%s", enabledExtension[ii]);
  1674. }
  1675. float queuePriorities[1] = { 0.0f };
  1676. VkDeviceQueueCreateInfo dcqi;
  1677. dcqi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  1678. dcqi.pNext = NULL;
  1679. dcqi.flags = 0;
  1680. dcqi.queueFamilyIndex = m_globalQueueFamily;
  1681. dcqi.queueCount = 1;
  1682. dcqi.pQueuePriorities = queuePriorities;
  1683. VkDeviceCreateInfo dci;
  1684. dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  1685. dci.pNext = nextFeatures;
  1686. dci.flags = 0;
  1687. dci.queueCreateInfoCount = 1;
  1688. dci.pQueueCreateInfos = &dcqi;
  1689. dci.enabledLayerCount = numEnabledLayers;
  1690. dci.ppEnabledLayerNames = enabledLayer;
  1691. dci.enabledExtensionCount = numEnabledExtensions;
  1692. dci.ppEnabledExtensionNames = enabledExtension;
  1693. dci.pEnabledFeatures = &m_deviceFeatures;
  1694. result = vkCreateDevice(
  1695. m_physicalDevice
  1696. , &dci
  1697. , m_allocatorCb
  1698. , &m_device
  1699. );
  1700. if (VK_SUCCESS != result)
  1701. {
  1702. BX_TRACE("Init error: vkCreateDevice failed %d: %s.", result, getName(result) );
  1703. goto error;
  1704. }
  1705. }
  1706. errorState = ErrorState::DeviceCreated;
  1707. BX_TRACE("Device functions:");
  1708. #define VK_IMPORT_DEVICE_FUNC(_optional, _func) \
  1709. _func = (PFN_##_func)vkGetDeviceProcAddr(m_device, #_func); \
  1710. BX_TRACE("\t%p " #_func, _func); \
  1711. imported &= _optional || NULL != _func
  1712. VK_IMPORT_DEVICE
  1713. #undef VK_IMPORT_DEVICE_FUNC
  1714. if (!imported)
  1715. {
  1716. BX_TRACE("Init error: Failed to load device functions.");
  1717. goto error;
  1718. }
  1719. vkGetDeviceQueue(m_device, m_globalQueueFamily, 0, &m_globalQueue);
  1720. {
  1721. m_maxFrameLatency = _init.resolution.maxFrameLatency == 0
  1722. ? BGFX_CONFIG_MAX_FRAME_LATENCY
  1723. : _init.resolution.maxFrameLatency
  1724. ;
  1725. result = m_cmd.init(m_globalQueueFamily, m_globalQueue);
  1726. if (VK_SUCCESS != result)
  1727. {
  1728. BX_TRACE("Init error: creating command queue failed %d: %s.", result, getName(result) );
  1729. goto error;
  1730. }
  1731. result = m_cmd.alloc(&m_commandBuffer);
  1732. if (VK_SUCCESS != result)
  1733. {
  1734. BX_TRACE("Init error: allocating command buffer failed %d: %s.", result, getName(result) );
  1735. goto error;
  1736. }
  1737. }
  1738. errorState = ErrorState::CommandQueueCreated;
  1739. m_presentElapsed = 0;
  1740. {
  1741. m_resolution = _init.resolution;
  1742. m_resolution.reset &= ~BGFX_RESET_INTERNAL_FORCE;
  1743. m_numWindows = 0;
  1744. if (!headless)
  1745. {
  1746. m_textVideoMem.resize(false, _init.resolution.width, _init.resolution.height);
  1747. m_textVideoMem.clear();
  1748. for (uint8_t ii = 0; ii < BX_COUNTOF(m_swapChainFormats); ++ii)
  1749. {
  1750. m_swapChainFormats[ii] = TextureFormat::Enum(ii);
  1751. }
  1752. result = m_backBuffer.create(
  1753. UINT16_MAX
  1754. , g_platformData.nwh
  1755. , m_resolution.width
  1756. , m_resolution.height
  1757. , m_resolution.formatColor
  1758. );
  1759. if (VK_SUCCESS != result)
  1760. {
  1761. BX_TRACE("Init error: creating swap chain failed %d: %s.", result, getName(result) );
  1762. goto error;
  1763. }
  1764. m_windows[0] = BGFX_INVALID_HANDLE;
  1765. m_numWindows++;
  1766. postReset();
  1767. }
  1768. }
  1769. errorState = ErrorState::SwapChainCreated;
  1770. {
  1771. VkDescriptorPoolSize dps[] =
  1772. {
  1773. { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, MAX_DESCRIPTOR_SETS * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS },
  1774. { VK_DESCRIPTOR_TYPE_SAMPLER, MAX_DESCRIPTOR_SETS * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS },
  1775. { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, MAX_DESCRIPTOR_SETS * 2 },
  1776. { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, MAX_DESCRIPTOR_SETS * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS },
  1777. { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, MAX_DESCRIPTOR_SETS * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS },
  1778. };
  1779. VkDescriptorPoolCreateInfo dpci;
  1780. dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
  1781. dpci.pNext = NULL;
  1782. dpci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
  1783. dpci.maxSets = MAX_DESCRIPTOR_SETS;
  1784. dpci.poolSizeCount = BX_COUNTOF(dps);
  1785. dpci.pPoolSizes = dps;
  1786. for (uint32_t ii = 0; ii < m_maxFrameLatency; ++ii)
  1787. {
  1788. result = vkCreateDescriptorPool(m_device, &dpci, m_allocatorCb, &m_descriptorPool[ii]);
  1789. if (VK_SUCCESS != result)
  1790. {
  1791. BX_TRACE("Init error: vkCreateDescriptorPool failed %d: %s.", result, getName(result) );
  1792. goto error;
  1793. }
  1794. }
  1795. VkPipelineCacheCreateInfo pcci;
  1796. pcci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
  1797. pcci.pNext = NULL;
  1798. pcci.flags = 0;
  1799. pcci.initialDataSize = 0;
  1800. pcci.pInitialData = NULL;
  1801. result = vkCreatePipelineCache(m_device, &pcci, m_allocatorCb, &m_pipelineCache);
  1802. if (VK_SUCCESS != result)
  1803. {
  1804. BX_TRACE("Init error: vkCreatePipelineCache failed %d: %s.", result, getName(result) );
  1805. goto error;
  1806. }
  1807. }
  1808. {
  1809. m_uniformScratchBuffer.createUniform(2<<20, m_maxFrameLatency*2);
  1810. for (uint32_t ii = 0; ii < m_maxFrameLatency; ++ii)
  1811. {
  1812. BX_TRACE("Create scratch staging buffer %d", ii);
  1813. m_scratchStagingBuffer[ii].createStaging(BGFX_CONFIG_MAX_SCRATCH_STAGING_BUFFER_PER_FRAME_SIZE);
  1814. }
  1815. }
  1816. errorState = ErrorState::DescriptorCreated;
  1817. if (NULL == vkSetDebugUtilsObjectNameEXT)
  1818. {
  1819. vkSetDebugUtilsObjectNameEXT = stubSetDebugUtilsObjectNameEXT;
  1820. }
  1821. if (NULL == vkCmdBeginDebugUtilsLabelEXT
  1822. || NULL == vkCmdEndDebugUtilsLabelEXT)
  1823. {
  1824. vkCmdBeginDebugUtilsLabelEXT = stubCmdBeginDebugUtilsLabelEXT;
  1825. vkCmdEndDebugUtilsLabelEXT = stubCmdEndDebugUtilsLabelEXT;
  1826. }
  1827. if (NULL == vkCmdInsertDebugUtilsLabelEXT)
  1828. {
  1829. vkCmdInsertDebugUtilsLabelEXT = stubCmdInsertDebugUtilsLabelEXT;
  1830. }
  1831. // Init reserved part of view name.
  1832. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
  1833. {
  1834. bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d ", ii);
  1835. }
  1836. if (m_timerQuerySupport)
  1837. {
  1838. result = m_gpuTimer.init();
  1839. if (VK_SUCCESS != result)
  1840. {
  1841. BX_TRACE("Init error: creating GPU timer failed %d: %s.", result, getName(result) );
  1842. goto error;
  1843. }
  1844. }
  1845. errorState = ErrorState::TimerQueryCreated;
  1846. result = m_occlusionQuery.init();
  1847. if (VK_SUCCESS != result)
  1848. {
  1849. BX_TRACE("Init error: creating occlusion query failed %d: %s.", result, getName(result) );
  1850. goto error;
  1851. }
  1852. g_internalData.context = m_device;
  1853. return true;
  1854. error:
  1855. BX_TRACE("errorState %d", errorState);
  1856. switch (errorState)
  1857. {
  1858. case ErrorState::TimerQueryCreated:
  1859. if (m_timerQuerySupport)
  1860. {
  1861. m_gpuTimer.shutdown();
  1862. }
  1863. [[fallthrough]];
  1864. case ErrorState::DescriptorCreated:
  1865. m_uniformScratchBuffer.destroy();
  1866. for (uint32_t ii = 0; ii < m_maxFrameLatency; ++ii)
  1867. {
  1868. m_scratchStagingBuffer[ii].destroy();
  1869. vkDestroy(m_descriptorPool[ii]);
  1870. }
  1871. vkDestroy(m_pipelineCache);
  1872. [[fallthrough]];
  1873. case ErrorState::SwapChainCreated:
  1874. m_backBuffer.destroy();
  1875. [[fallthrough]];
  1876. case ErrorState::CommandQueueCreated:
  1877. m_cmd.shutdown();
  1878. [[fallthrough]];
  1879. case ErrorState::DeviceCreated:
  1880. vkDestroyDevice(m_device, m_allocatorCb);
  1881. [[fallthrough]];
  1882. case ErrorState::InstanceCreated:
  1883. if (VK_NULL_HANDLE != m_debugReportCallback)
  1884. {
  1885. vkDestroyDebugReportCallbackEXT(m_instance, m_debugReportCallback, m_allocatorCb);
  1886. }
  1887. vkDestroyInstance(m_instance, m_allocatorCb);
  1888. [[fallthrough]];
  1889. case ErrorState::LoadedVulkan1:
  1890. bx::dlclose(m_vulkan1Dll);
  1891. m_vulkan1Dll = NULL;
  1892. m_allocatorCb = NULL;
  1893. unloadRenderDoc(m_renderDocDll);
  1894. [[fallthrough]];
  1895. case ErrorState::Default:
  1896. break;
  1897. };
  1898. return false;
  1899. }
  1900. void shutdown()
  1901. {
  1902. VK_CHECK(vkDeviceWaitIdle(m_device) );
  1903. if (m_timerQuerySupport)
  1904. {
  1905. m_gpuTimer.shutdown();
  1906. }
  1907. m_occlusionQuery.shutdown();
  1908. preReset();
  1909. m_pipelineStateCache.invalidate();
  1910. m_descriptorSetLayoutCache.invalidate();
  1911. m_renderPassCache.invalidate();
  1912. m_samplerCache.invalidate();
  1913. m_samplerBorderColorCache.invalidate();
  1914. m_imageViewCache.invalidate();
  1915. m_uniformScratchBuffer.destroy();
  1916. for (uint32_t ii = 0; ii < m_maxFrameLatency; ++ii)
  1917. {
  1918. m_scratchStagingBuffer[ii].destroy();
  1919. }
  1920. for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
  1921. {
  1922. m_frameBuffers[ii].destroy();
  1923. }
  1924. for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii)
  1925. {
  1926. m_indexBuffers[ii].destroy();
  1927. }
  1928. for (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexBuffers); ++ii)
  1929. {
  1930. m_vertexBuffers[ii].destroy();
  1931. }
  1932. for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii)
  1933. {
  1934. m_shaders[ii].destroy();
  1935. }
  1936. for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii)
  1937. {
  1938. m_textures[ii].destroy();
  1939. }
  1940. m_backBuffer.destroy();
  1941. m_memoryLru.evictAll();
  1942. m_cmd.shutdown();
  1943. vkDestroy(m_pipelineCache);
  1944. for (uint32_t ii = 0; ii < m_maxFrameLatency; ++ii)
  1945. {
  1946. vkDestroy(m_descriptorPool[ii]);
  1947. }
  1948. vkDestroyDevice(m_device, m_allocatorCb);
  1949. if (VK_NULL_HANDLE != m_debugReportCallback)
  1950. {
  1951. vkDestroyDebugReportCallbackEXT(m_instance, m_debugReportCallback, m_allocatorCb);
  1952. }
  1953. vkDestroyInstance(m_instance, m_allocatorCb);
  1954. bx::dlclose(m_vulkan1Dll);
  1955. m_vulkan1Dll = NULL;
  1956. m_allocatorCb = NULL;
  1957. unloadRenderDoc(m_renderDocDll);
  1958. }
  1959. RendererType::Enum getRendererType() const override
  1960. {
  1961. return RendererType::Vulkan;
  1962. }
  1963. const char* getRendererName() const override
  1964. {
  1965. return BGFX_RENDERER_VULKAN_NAME;
  1966. }
  1967. bool isDeviceRemoved() override
  1968. {
  1969. return false;
  1970. }
  1971. void flip() override
  1972. {
  1973. int64_t start = bx::getHPCounter();
  1974. for (uint16_t ii = 0; ii < m_numWindows; ++ii)
  1975. {
  1976. FrameBufferVK& fb = isValid(m_windows[ii])
  1977. ? m_frameBuffers[m_windows[ii].idx]
  1978. : m_backBuffer
  1979. ;
  1980. fb.present();
  1981. }
  1982. const int64_t now = bx::getHPCounter();
  1983. m_presentElapsed += now - start;
  1984. }
  1985. void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override
  1986. {
  1987. m_indexBuffers[_handle.idx].create(m_commandBuffer, _mem->size, _mem->data, _flags, false);
  1988. }
  1989. void destroyIndexBuffer(IndexBufferHandle _handle) override
  1990. {
  1991. m_indexBuffers[_handle.idx].destroy();
  1992. }
  1993. void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override
  1994. {
  1995. VertexLayout& layout = m_vertexLayouts[_handle.idx];
  1996. bx::memCopy(&layout, &_layout, sizeof(VertexLayout) );
  1997. dump(layout);
  1998. }
  1999. void destroyVertexLayout(VertexLayoutHandle /*_handle*/) override
  2000. {
  2001. }
  2002. void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override
  2003. {
  2004. m_vertexBuffers[_handle.idx].create(m_commandBuffer, _mem->size, _mem->data, _layoutHandle, _flags);
  2005. }
  2006. void destroyVertexBuffer(VertexBufferHandle _handle) override
  2007. {
  2008. m_vertexBuffers[_handle.idx].destroy();
  2009. }
  2010. void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override
  2011. {
  2012. m_indexBuffers[_handle.idx].create(m_commandBuffer, _size, NULL, _flags, false);
  2013. }
  2014. void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override
  2015. {
  2016. m_indexBuffers[_handle.idx].update(m_commandBuffer, _offset, bx::min<uint32_t>(_size, _mem->size), _mem->data);
  2017. }
  2018. void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override
  2019. {
  2020. m_indexBuffers[_handle.idx].destroy();
  2021. }
  2022. void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override
  2023. {
  2024. VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE;
  2025. m_vertexBuffers[_handle.idx].create(m_commandBuffer, _size, NULL, layoutHandle, _flags);
  2026. }
  2027. void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override
  2028. {
  2029. m_vertexBuffers[_handle.idx].update(m_commandBuffer, _offset, bx::min<uint32_t>(_size, _mem->size), _mem->data);
  2030. }
  2031. void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override
  2032. {
  2033. m_vertexBuffers[_handle.idx].destroy();
  2034. }
  2035. void createShader(ShaderHandle _handle, const Memory* _mem) override
  2036. {
  2037. m_shaders[_handle.idx].create(_mem);
  2038. }
  2039. void destroyShader(ShaderHandle _handle) override
  2040. {
  2041. m_shaders[_handle.idx].destroy();
  2042. }
  2043. void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override
  2044. {
  2045. m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL);
  2046. }
  2047. void destroyProgram(ProgramHandle _handle) override
  2048. {
  2049. m_program[_handle.idx].destroy();
  2050. }
  2051. void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override
  2052. {
  2053. return m_textures[_handle.idx].create(m_commandBuffer, _mem, _flags, _skip);
  2054. }
  2055. void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override
  2056. {
  2057. m_textures[_handle.idx].update(m_commandBuffer, _side, _mip, _rect, _z, _depth, _pitch, _mem);
  2058. }
  2059. void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) override
  2060. {
  2061. TextureVK& texture = m_textures[_handle.idx];
  2062. uint32_t height = bx::uint32_max(1, texture.m_height >> _mip);
  2063. uint32_t pitch = texture.m_readback.pitch(_mip);
  2064. uint32_t size = height * pitch;
  2065. DeviceMemoryAllocationVK stagingMemory;
  2066. VkBuffer stagingBuffer;
  2067. VK_CHECK(createReadbackBuffer(size, &stagingBuffer, &stagingMemory) );
  2068. texture.m_readback.copyImageToBuffer(
  2069. m_commandBuffer
  2070. , stagingBuffer
  2071. , texture.m_currentImageLayout
  2072. , texture.m_aspectFlags
  2073. , _mip
  2074. );
  2075. kick(true);
  2076. texture.m_readback.readback(stagingMemory.mem, stagingMemory.offset, _data, _mip);
  2077. vkDestroy(stagingBuffer);
  2078. recycleMemory(stagingMemory);
  2079. }
  2080. void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips, uint16_t _numLayers) override
  2081. {
  2082. const TextureVK& texture = m_textures[_handle.idx];
  2083. const TextureFormat::Enum format = TextureFormat::Enum(texture.m_requestedFormat);
  2084. const uint64_t flags = texture.m_flags;
  2085. const uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
  2086. const Memory* mem = alloc(size);
  2087. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  2088. bx::write(&writer, kChunkMagicTex, bx::ErrorAssert{});
  2089. TextureCreate tc;
  2090. tc.m_width = _width;
  2091. tc.m_height = _height;
  2092. tc.m_depth = 0;
  2093. tc.m_numLayers = _numLayers;
  2094. tc.m_numMips = _numMips;
  2095. tc.m_format = format;
  2096. tc.m_cubeMap = false;
  2097. tc.m_mem = NULL;
  2098. bx::write(&writer, tc, bx::ErrorAssert{});
  2099. destroyTexture(_handle);
  2100. createTexture(_handle, mem, flags, 0);
  2101. bgfx::release(mem);
  2102. }
  2103. void overrideInternal(TextureHandle /*_handle*/, uintptr_t /*_ptr*/, uint16_t /*_layerIndex*/) override
  2104. {
  2105. }
  2106. uintptr_t getInternal(TextureHandle /*_handle*/) override
  2107. {
  2108. return 0;
  2109. }
  2110. void destroyTexture(TextureHandle _handle) override
  2111. {
  2112. m_imageViewCache.invalidateWithParent(_handle.idx);
  2113. m_textures[_handle.idx].destroy();
  2114. }
  2115. void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override
  2116. {
  2117. m_frameBuffers[_handle.idx].create(_num, _attachment);
  2118. }
  2119. void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat) override
  2120. {
  2121. for (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii)
  2122. {
  2123. FrameBufferHandle handle = m_windows[ii];
  2124. if (isValid(handle)
  2125. && m_frameBuffers[handle.idx].m_nwh == _nwh)
  2126. {
  2127. destroyFrameBuffer(handle);
  2128. }
  2129. }
  2130. uint16_t denseIdx = m_numWindows++;
  2131. m_windows[denseIdx] = _handle;
  2132. VK_CHECK(m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _format, _depthFormat) );
  2133. }
  2134. void destroyFrameBuffer(FrameBufferHandle _handle) override
  2135. {
  2136. FrameBufferVK& frameBuffer = m_frameBuffers[_handle.idx];
  2137. uint16_t denseIdx = frameBuffer.destroy();
  2138. if (UINT16_MAX != denseIdx)
  2139. {
  2140. --m_numWindows;
  2141. if (m_numWindows > 1)
  2142. {
  2143. FrameBufferHandle handle = m_windows[m_numWindows];
  2144. m_windows[m_numWindows] = {kInvalidHandle};
  2145. if (m_numWindows != denseIdx)
  2146. {
  2147. m_windows[denseIdx] = handle;
  2148. m_frameBuffers[handle.idx].m_denseIdx = denseIdx;
  2149. }
  2150. }
  2151. }
  2152. }
  2153. void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) override
  2154. {
  2155. if (NULL != m_uniforms[_handle.idx])
  2156. {
  2157. bx::free(g_allocator, m_uniforms[_handle.idx]);
  2158. }
  2159. const uint32_t size = bx::alignUp(g_uniformTypeSize[_type] * _num, 16);
  2160. void* data = bx::alloc(g_allocator, size);
  2161. bx::memSet(data, 0, size);
  2162. m_uniforms[_handle.idx] = data;
  2163. m_uniformReg.add(_handle, _name);
  2164. }
  2165. void destroyUniform(UniformHandle _handle) override
  2166. {
  2167. bx::free(g_allocator, m_uniforms[_handle.idx]);
  2168. m_uniforms[_handle.idx] = NULL;
  2169. }
  2170. void requestScreenShot(FrameBufferHandle _fbh, const char* _filePath) override
  2171. {
  2172. const FrameBufferVK& frameBuffer = isValid(_fbh)
  2173. ? m_frameBuffers[_fbh.idx]
  2174. : m_backBuffer
  2175. ;
  2176. const SwapChainVK& swapChain = frameBuffer.m_swapChain;
  2177. if (!isSwapChainReadable(swapChain) )
  2178. {
  2179. BX_TRACE("Unable to capture screenshot %s.", _filePath);
  2180. return;
  2181. }
  2182. auto callback = [](void* _src, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _userData)
  2183. {
  2184. const char* filePath = (const char*)_userData;
  2185. g_callback->screenShot(
  2186. filePath
  2187. , _width
  2188. , _height
  2189. , _pitch
  2190. , _src
  2191. , _height * _pitch
  2192. , false
  2193. );
  2194. };
  2195. const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(swapChain.m_colorFormat) );
  2196. const uint32_t size = frameBuffer.m_width * frameBuffer.m_height * bpp / 8;
  2197. DeviceMemoryAllocationVK stagingMemory;
  2198. VkBuffer stagingBuffer;
  2199. VK_CHECK(createReadbackBuffer(size, &stagingBuffer, &stagingMemory) );
  2200. readSwapChain(swapChain, stagingBuffer, stagingMemory, callback, _filePath);
  2201. vkDestroy(stagingBuffer);
  2202. recycleMemory(stagingMemory);
  2203. }
  2204. void updateViewName(ViewId _id, const char* _name) override
  2205. {
  2206. bx::strCopy(&s_viewName[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED]
  2207. , BX_COUNTOF(s_viewName[0]) - BGFX_CONFIG_MAX_VIEW_NAME_RESERVED
  2208. , _name
  2209. );
  2210. }
  2211. void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) override
  2212. {
  2213. bx::memCopy(m_uniforms[_loc], _data, _size);
  2214. }
  2215. void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override
  2216. {
  2217. m_occlusionQuery.invalidate(_handle);
  2218. }
  2219. void setMarker(const char* _marker, uint16_t _len) override
  2220. {
  2221. if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) )
  2222. {
  2223. BX_UNUSED(_len);
  2224. const uint32_t abgr = kColorMarker;
  2225. VkDebugUtilsLabelEXT dul;
  2226. dul.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
  2227. dul.pNext = NULL;
  2228. dul.pLabelName = _marker;
  2229. dul.color[0] = ( (abgr >> 24) & 0xff) / 255.0f;
  2230. dul.color[1] = ( (abgr >> 16) & 0xff) / 255.0f;
  2231. dul.color[2] = ( (abgr >> 8) & 0xff) / 255.0f;
  2232. dul.color[3] = ( (abgr >> 0) & 0xff) / 255.0f;
  2233. vkCmdInsertDebugUtilsLabelEXT(m_commandBuffer, &dul);
  2234. }
  2235. }
  2236. virtual void setName(Handle _handle, const char* _name, uint16_t _len) override
  2237. {
  2238. switch (_handle.type)
  2239. {
  2240. case Handle::IndexBuffer:
  2241. setDebugObjectName(m_device, m_indexBuffers[_handle.idx].m_buffer, "%.*s", _len, _name);
  2242. break;
  2243. case Handle::Shader:
  2244. setDebugObjectName(m_device, m_shaders[_handle.idx].m_module, "%.*s", _len, _name);
  2245. break;
  2246. case Handle::Texture:
  2247. setDebugObjectName(m_device, m_textures[_handle.idx].m_textureImage, "%.*s", _len, _name);
  2248. if (VK_NULL_HANDLE != m_textures[_handle.idx].m_singleMsaaImage)
  2249. {
  2250. setDebugObjectName(m_device, m_textures[_handle.idx].m_singleMsaaImage, "%.*s", _len, _name);
  2251. }
  2252. break;
  2253. case Handle::VertexBuffer:
  2254. setDebugObjectName(m_device, m_vertexBuffers[_handle.idx].m_buffer, "%.*s", _len, _name);
  2255. break;
  2256. default:
  2257. BX_ASSERT(false, "Invalid handle type?! %d", _handle.type);
  2258. break;
  2259. }
  2260. }
  2261. template<typename Ty>
  2262. void release(Ty& _object)
  2263. {
  2264. if (VK_NULL_HANDLE != _object)
  2265. {
  2266. m_cmd.release(uint64_t(_object.vk), getType<Ty>() );
  2267. _object = VK_NULL_HANDLE;
  2268. }
  2269. }
  2270. void recycleMemory(DeviceMemoryAllocationVK _alloc)
  2271. {
  2272. m_cmd.recycleMemory(_alloc);
  2273. }
  2274. void submitBlit(BlitState& _bs, uint16_t _view);
  2275. void submitUniformCache(UniformCacheState& _ucs, uint16_t _view);
  2276. void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override;
  2277. void dbgTextRenderBegin(TextVideoMemBlitter& _blitter) override
  2278. {
  2279. const uint32_t width = m_backBuffer.m_width;
  2280. const uint32_t height = m_backBuffer.m_height;
  2281. setFrameBuffer(BGFX_INVALID_HANDLE);
  2282. VkViewport vp;
  2283. vp.x = 0.0f;
  2284. vp.y = float(height);
  2285. vp.width = float(width);
  2286. vp.height = -float(height);
  2287. vp.minDepth = 0.0f;
  2288. vp.maxDepth = 1.0f;
  2289. vkCmdSetViewport(m_commandBuffer, 0, 1, &vp);
  2290. VkRect2D rc;
  2291. rc.offset.x = 0;
  2292. rc.offset.y = 0;
  2293. rc.extent.width = width;
  2294. rc.extent.height = height;
  2295. vkCmdSetScissor(m_commandBuffer, 0, 1, &rc);
  2296. const uint64_t state = 0
  2297. | BGFX_STATE_WRITE_RGB
  2298. | BGFX_STATE_WRITE_A
  2299. | BGFX_STATE_DEPTH_TEST_ALWAYS
  2300. | BGFX_STATE_MSAA
  2301. ;
  2302. const VertexLayout* layout = &m_vertexLayouts[_blitter.m_vb->layoutHandle.idx];
  2303. VkPipeline pso = getPipeline(state
  2304. , packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT)
  2305. , 1
  2306. , &layout
  2307. , _blitter.m_program
  2308. , 0
  2309. );
  2310. vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pso);
  2311. ProgramVK& program = m_program[_blitter.m_program.idx];
  2312. float proj[16];
  2313. bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, false);
  2314. PredefinedUniform& predefined = m_program[_blitter.m_program.idx].m_predefined[0];
  2315. uint8_t flags = predefined.m_type;
  2316. setShaderUniform(flags, predefined.m_loc, proj, 4);
  2317. UniformBuffer* vcb = program.m_vsh->m_constantBuffer;
  2318. if (NULL != vcb)
  2319. {
  2320. commit(*vcb);
  2321. }
  2322. ChunkedScratchBufferVK& uniformScratchBuffer = m_uniformScratchBuffer;
  2323. ChunkedScratchBufferOffset sbo;
  2324. uniformScratchBuffer.write(sbo, m_vsScratch, program.m_vsh->m_size);
  2325. const TextureVK& texture = m_textures[_blitter.m_texture.idx];
  2326. RenderBind bind;
  2327. bind.clear();
  2328. bind.m_bind[0].m_type = Binding::Texture;
  2329. bind.m_bind[0].m_idx = _blitter.m_texture.idx;
  2330. bind.m_bind[0].m_samplerFlags = (uint32_t)(texture.m_flags & BGFX_SAMPLER_BITS_MASK);
  2331. const VkDescriptorSet descriptorSet = getDescriptorSet(program, bind, sbo.buffer, NULL);
  2332. vkCmdBindDescriptorSets(
  2333. m_commandBuffer
  2334. , VK_PIPELINE_BIND_POINT_GRAPHICS
  2335. , program.m_pipelineLayout
  2336. , 0
  2337. , 1
  2338. , &descriptorSet
  2339. , 1
  2340. , sbo.offsets
  2341. );
  2342. const VertexBufferVK& vb = m_vertexBuffers[_blitter.m_vb->handle.idx];
  2343. const VkDeviceSize offset = 0;
  2344. vkCmdBindVertexBuffers(m_commandBuffer, 0, 1, &vb.m_buffer, &offset);
  2345. const BufferVK& ib = m_indexBuffers[_blitter.m_ib->handle.idx];
  2346. vkCmdBindIndexBuffer(
  2347. m_commandBuffer
  2348. , ib.m_buffer
  2349. , 0
  2350. , VK_INDEX_TYPE_UINT16
  2351. );
  2352. }
  2353. void dbgTextRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override
  2354. {
  2355. const uint32_t numVertices = _numIndices*4/6;
  2356. if (0 < numVertices
  2357. && m_backBuffer.isRenderable() )
  2358. {
  2359. m_indexBuffers[_blitter.m_ib->handle.idx].update(m_commandBuffer, 0, _numIndices*2, _blitter.m_ib->data, true);
  2360. m_vertexBuffers[_blitter.m_vb->handle.idx].update(m_commandBuffer, 0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data, true);
  2361. VkRenderPassBeginInfo rpbi;
  2362. rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
  2363. rpbi.pNext = NULL;
  2364. rpbi.renderPass = m_backBuffer.m_renderPass;
  2365. rpbi.framebuffer = m_backBuffer.m_currentFramebuffer;
  2366. rpbi.renderArea.offset.x = 0;
  2367. rpbi.renderArea.offset.y = 0;
  2368. rpbi.renderArea.extent.width = m_backBuffer.m_width;
  2369. rpbi.renderArea.extent.height = m_backBuffer.m_height;
  2370. rpbi.clearValueCount = 0;
  2371. rpbi.pClearValues = NULL;
  2372. vkCmdBeginRenderPass(m_commandBuffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
  2373. vkCmdDrawIndexed(m_commandBuffer, _numIndices, 1, 0, 0, 0);
  2374. vkCmdEndRenderPass(m_commandBuffer);
  2375. }
  2376. }
  2377. void dbgTextRenderEnd(TextVideoMemBlitter& /*_blitter*/) override
  2378. {
  2379. }
  2380. void preReset()
  2381. {
  2382. for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
  2383. {
  2384. m_frameBuffers[ii].preReset();
  2385. }
  2386. if (m_captureSize > 0)
  2387. {
  2388. g_callback->captureEnd();
  2389. release(m_captureBuffer);
  2390. recycleMemory(m_captureMemory);
  2391. m_captureSize = 0;
  2392. }
  2393. }
  2394. void postReset()
  2395. {
  2396. for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
  2397. {
  2398. m_frameBuffers[ii].postReset();
  2399. }
  2400. if (m_resolution.reset & BGFX_RESET_CAPTURE)
  2401. {
  2402. const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_backBuffer.m_swapChain.m_colorFormat) );
  2403. const uint32_t captureSize = m_backBuffer.m_width * m_backBuffer.m_height * bpp / 8;
  2404. const uint8_t dstBpp = bimg::getBitsPerPixel(bimg::TextureFormat::BGRA8);
  2405. const uint32_t dstPitch = m_backBuffer.m_width * dstBpp / 8;
  2406. if (captureSize > m_captureSize)
  2407. {
  2408. release(m_captureBuffer);
  2409. recycleMemory(m_captureMemory);
  2410. m_captureSize = captureSize;
  2411. VK_CHECK(createReadbackBuffer(m_captureSize, &m_captureBuffer, &m_captureMemory) );
  2412. }
  2413. g_callback->captureBegin(m_resolution.width, m_resolution.height, dstPitch, TextureFormat::BGRA8, false);
  2414. }
  2415. }
  2416. bool updateResolution(const Resolution& _resolution)
  2417. {
  2418. const bool suspended = !!(_resolution.reset & BGFX_RESET_SUSPEND);
  2419. float maxAnisotropy = 1.0f;
  2420. if (!!(_resolution.reset & BGFX_RESET_MAXANISOTROPY) )
  2421. {
  2422. maxAnisotropy = m_deviceProperties.properties.limits.maxSamplerAnisotropy;
  2423. }
  2424. if (m_maxAnisotropy != maxAnisotropy)
  2425. {
  2426. m_maxAnisotropy = maxAnisotropy;
  2427. m_samplerCache.invalidate();
  2428. m_samplerBorderColorCache.invalidate();
  2429. }
  2430. bool depthClamp = m_deviceFeatures.depthClamp && !!(_resolution.reset & BGFX_RESET_DEPTH_CLAMP);
  2431. if (m_depthClamp != depthClamp)
  2432. {
  2433. m_depthClamp = depthClamp;
  2434. m_pipelineStateCache.invalidate();
  2435. }
  2436. if (NULL == m_backBuffer.m_nwh)
  2437. {
  2438. return suspended;
  2439. }
  2440. uint32_t flags = _resolution.reset & ~(0
  2441. | BGFX_RESET_SUSPEND
  2442. | BGFX_RESET_MAXANISOTROPY
  2443. | BGFX_RESET_DEPTH_CLAMP
  2444. );
  2445. if (false
  2446. || m_resolution.formatColor != _resolution.formatColor
  2447. || m_resolution.formatDepthStencil != _resolution.formatDepthStencil
  2448. || m_resolution.width != _resolution.width
  2449. || m_resolution.height != _resolution.height
  2450. || m_resolution.reset != flags
  2451. || m_backBuffer.m_swapChain.m_needToRecreateSurface
  2452. || m_backBuffer.m_swapChain.m_needToRecreateSwapchain)
  2453. {
  2454. flags &= ~BGFX_RESET_INTERNAL_FORCE;
  2455. if (m_backBuffer.m_nwh != g_platformData.nwh)
  2456. {
  2457. m_backBuffer.m_nwh = g_platformData.nwh;
  2458. }
  2459. m_resolution = _resolution;
  2460. m_resolution.reset = flags;
  2461. m_textVideoMem.resize(false, _resolution.width, _resolution.height);
  2462. m_textVideoMem.clear();
  2463. preReset();
  2464. m_backBuffer.update(m_commandBuffer, m_resolution);
  2465. // Update the resolution again here, as the actual width and height
  2466. // is now final (as it was potentially clamped by the Vulkan driver).
  2467. m_resolution.width = m_backBuffer.m_width;
  2468. m_resolution.height = m_backBuffer.m_height;
  2469. postReset();
  2470. }
  2471. return suspended;
  2472. }
  2473. void setShaderUniform(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs)
  2474. {
  2475. if (_flags & kUniformFragmentBit)
  2476. {
  2477. bx::memCopy(&m_fsScratch[_regIndex], _val, _numRegs*16);
  2478. }
  2479. else
  2480. {
  2481. bx::memCopy(&m_vsScratch[_regIndex], _val, _numRegs*16);
  2482. }
  2483. }
  2484. void setShaderUniform4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs)
  2485. {
  2486. setShaderUniform(_flags, _regIndex, _val, _numRegs);
  2487. }
  2488. void setShaderUniform4x4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs)
  2489. {
  2490. setShaderUniform(_flags, _regIndex, _val, _numRegs);
  2491. }
  2492. void setFrameBuffer(FrameBufferHandle _fbh, bool _acquire = true)
  2493. {
  2494. BGFX_PROFILER_SCOPE("RendererContextVK::setFrameBuffer()", kColorFrame);
  2495. BX_ASSERT(false
  2496. || isValid(_fbh)
  2497. || NULL != m_backBuffer.m_nwh
  2498. , "Rendering to backbuffer in headless mode."
  2499. );
  2500. FrameBufferVK& newFrameBuffer = isValid(_fbh)
  2501. ? m_frameBuffers[_fbh.idx]
  2502. : m_backBuffer
  2503. ;
  2504. FrameBufferVK& oldFrameBuffer = isValid(m_fbh)
  2505. ? m_frameBuffers[m_fbh.idx]
  2506. : m_backBuffer
  2507. ;
  2508. if (NULL == oldFrameBuffer.m_nwh
  2509. && m_fbh.idx != _fbh.idx)
  2510. {
  2511. oldFrameBuffer.resolve();
  2512. for (uint8_t ii = 0, num = oldFrameBuffer.m_num; ii < num; ++ii)
  2513. {
  2514. TextureVK& texture = m_textures[oldFrameBuffer.m_texture[ii].idx];
  2515. texture.setImageMemoryBarrier(m_commandBuffer, texture.m_sampledLayout);
  2516. if (VK_NULL_HANDLE != texture.m_singleMsaaImage)
  2517. {
  2518. texture.setImageMemoryBarrier(m_commandBuffer, texture.m_sampledLayout, true);
  2519. }
  2520. }
  2521. if (isValid(oldFrameBuffer.m_depth) )
  2522. {
  2523. TextureVK& texture = m_textures[oldFrameBuffer.m_depth.idx];
  2524. const bool writeOnly = 0 != (texture.m_flags&BGFX_TEXTURE_RT_WRITE_ONLY);
  2525. if (!writeOnly)
  2526. {
  2527. texture.setImageMemoryBarrier(m_commandBuffer, texture.m_sampledLayout);
  2528. }
  2529. }
  2530. }
  2531. if (NULL == newFrameBuffer.m_nwh)
  2532. {
  2533. for (uint8_t ii = 0, num = newFrameBuffer.m_num; ii < num; ++ii)
  2534. {
  2535. TextureVK& texture = m_textures[newFrameBuffer.m_texture[ii].idx];
  2536. texture.setImageMemoryBarrier(
  2537. m_commandBuffer
  2538. , VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
  2539. );
  2540. }
  2541. if (isValid(newFrameBuffer.m_depth) )
  2542. {
  2543. TextureVK& texture = m_textures[newFrameBuffer.m_depth.idx];
  2544. texture.setImageMemoryBarrier(
  2545. m_commandBuffer
  2546. , VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
  2547. );
  2548. }
  2549. newFrameBuffer.acquire(m_commandBuffer);
  2550. }
  2551. if (_acquire)
  2552. {
  2553. int64_t start = bx::getHPCounter();
  2554. newFrameBuffer.acquire(m_commandBuffer);
  2555. const int64_t now = bx::getHPCounter();
  2556. if (NULL != newFrameBuffer.m_nwh)
  2557. {
  2558. m_presentElapsed += now - start;
  2559. }
  2560. }
  2561. m_fbh = _fbh;
  2562. }
  2563. void setDebugWireframe(bool _wireframe)
  2564. {
  2565. const bool wireframe = m_deviceFeatures.fillModeNonSolid && _wireframe;
  2566. if (m_wireframe != wireframe)
  2567. {
  2568. m_wireframe = wireframe;
  2569. m_pipelineStateCache.invalidate();
  2570. }
  2571. }
  2572. void setBlendState(VkPipelineColorBlendStateCreateInfo& _desc, uint64_t _state, uint32_t _rgba = 0)
  2573. {
  2574. VkPipelineColorBlendAttachmentState* bas = const_cast<VkPipelineColorBlendAttachmentState*>(_desc.pAttachments);
  2575. uint8_t writeMask = 0;
  2576. writeMask |= (_state & BGFX_STATE_WRITE_R) ? VK_COLOR_COMPONENT_R_BIT : 0;
  2577. writeMask |= (_state & BGFX_STATE_WRITE_G) ? VK_COLOR_COMPONENT_G_BIT : 0;
  2578. writeMask |= (_state & BGFX_STATE_WRITE_B) ? VK_COLOR_COMPONENT_B_BIT : 0;
  2579. writeMask |= (_state & BGFX_STATE_WRITE_A) ? VK_COLOR_COMPONENT_A_BIT : 0;
  2580. bas->blendEnable = !!(BGFX_STATE_BLEND_MASK & _state);
  2581. {
  2582. const uint32_t blend = uint32_t( (_state & BGFX_STATE_BLEND_MASK ) >> BGFX_STATE_BLEND_SHIFT);
  2583. const uint32_t equation = uint32_t( (_state & BGFX_STATE_BLEND_EQUATION_MASK) >> BGFX_STATE_BLEND_EQUATION_SHIFT);
  2584. const uint32_t srcRGB = (blend ) & 0xf;
  2585. const uint32_t dstRGB = (blend >> 4) & 0xf;
  2586. const uint32_t srcA = (blend >> 8) & 0xf;
  2587. const uint32_t dstA = (blend >> 12) & 0xf;
  2588. const uint32_t equRGB = (equation ) & 0x7;
  2589. const uint32_t equA = (equation >> 3) & 0x7;
  2590. bas->srcColorBlendFactor = s_blendFactor[srcRGB][0];
  2591. bas->dstColorBlendFactor = s_blendFactor[dstRGB][0];
  2592. bas->colorBlendOp = s_blendEquation[equRGB];
  2593. bas->srcAlphaBlendFactor = s_blendFactor[srcA][1];
  2594. bas->dstAlphaBlendFactor = s_blendFactor[dstA][1];
  2595. bas->alphaBlendOp = s_blendEquation[equA];
  2596. bas->colorWriteMask = writeMask;
  2597. }
  2598. const FrameBufferVK& frameBuffer = isValid(m_fbh)
  2599. ? m_frameBuffers[m_fbh.idx]
  2600. : m_backBuffer
  2601. ;
  2602. const uint32_t numAttachments = NULL == frameBuffer.m_nwh
  2603. ? frameBuffer.m_num
  2604. : 1
  2605. ;
  2606. if (!!(BGFX_STATE_BLEND_INDEPENDENT & _state)
  2607. && m_deviceFeatures.independentBlend )
  2608. {
  2609. for (uint32_t ii = 1, rgba = _rgba; ii < numAttachments; ++ii, rgba >>= 11)
  2610. {
  2611. ++bas;
  2612. bas->blendEnable = 0 != (rgba & 0x7ff);
  2613. const uint32_t src = (rgba ) & 0xf;
  2614. const uint32_t dst = (rgba >> 4) & 0xf;
  2615. const uint32_t equation = (rgba >> 8) & 0x7;
  2616. bas->srcColorBlendFactor = s_blendFactor[src][0];
  2617. bas->dstColorBlendFactor = s_blendFactor[dst][0];
  2618. bas->colorBlendOp = s_blendEquation[equation];
  2619. bas->srcAlphaBlendFactor = s_blendFactor[src][1];
  2620. bas->dstAlphaBlendFactor = s_blendFactor[dst][1];
  2621. bas->alphaBlendOp = s_blendEquation[equation];
  2622. bas->colorWriteMask = writeMask;
  2623. }
  2624. }
  2625. else
  2626. {
  2627. for (uint32_t ii = 1; ii < numAttachments; ++ii)
  2628. {
  2629. bx::memCopy(&bas[ii], bas, sizeof(VkPipelineColorBlendAttachmentState) );
  2630. }
  2631. }
  2632. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
  2633. _desc.pNext = NULL;
  2634. _desc.flags = 0;
  2635. _desc.logicOpEnable = VK_FALSE;
  2636. _desc.logicOp = VK_LOGIC_OP_CLEAR;
  2637. _desc.attachmentCount = numAttachments;
  2638. _desc.blendConstants[0] = 0.0f;
  2639. _desc.blendConstants[1] = 0.0f;
  2640. _desc.blendConstants[2] = 0.0f;
  2641. _desc.blendConstants[3] = 0.0f;
  2642. }
  2643. void setRasterizerState(VkPipelineRasterizationStateCreateInfo& _desc, uint64_t _state, bool _wireframe = false)
  2644. {
  2645. const uint32_t cull = (_state&BGFX_STATE_CULL_MASK) >> BGFX_STATE_CULL_SHIFT;
  2646. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
  2647. _desc.pNext = NULL;
  2648. _desc.flags = 0;
  2649. _desc.depthClampEnable = m_deviceFeatures.depthClamp && m_depthClamp;
  2650. _desc.rasterizerDiscardEnable = VK_FALSE;
  2651. _desc.polygonMode = m_deviceFeatures.fillModeNonSolid && _wireframe
  2652. ? VK_POLYGON_MODE_LINE
  2653. : VK_POLYGON_MODE_FILL
  2654. ;
  2655. _desc.cullMode = s_cullMode[cull];
  2656. _desc.frontFace = (_state&BGFX_STATE_FRONT_CCW) ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE;
  2657. _desc.depthBiasEnable = VK_FALSE;
  2658. _desc.depthBiasConstantFactor = 0.0f;
  2659. _desc.depthBiasClamp = 0.0f;
  2660. _desc.depthBiasSlopeFactor = 0.0f;
  2661. _desc.lineWidth = 1.0f;
  2662. }
  2663. void setConservativeRasterizerState(VkPipelineRasterizationConservativeStateCreateInfoEXT& _desc, uint64_t _state)
  2664. {
  2665. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT;
  2666. _desc.pNext = NULL;
  2667. _desc.flags = 0;
  2668. _desc.conservativeRasterizationMode = (_state&BGFX_STATE_CONSERVATIVE_RASTER)
  2669. ? VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT
  2670. : VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT
  2671. ;
  2672. _desc.extraPrimitiveOverestimationSize = 0.0f;
  2673. }
  2674. void setLineRasterizerState(VkPipelineRasterizationLineStateCreateInfoEXT& _desc, uint64_t _state)
  2675. {
  2676. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
  2677. _desc.pNext = NULL;
  2678. _desc.lineRasterizationMode = (_state & BGFX_STATE_LINEAA)
  2679. ? VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT
  2680. : VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT
  2681. ;
  2682. _desc.stippledLineEnable = VK_FALSE;
  2683. _desc.lineStippleFactor = 0;
  2684. _desc.lineStipplePattern = 0;
  2685. }
  2686. void setDepthStencilState(VkPipelineDepthStencilStateCreateInfo& _desc, uint64_t _state, uint64_t _stencil = 0)
  2687. {
  2688. const uint32_t fstencil = unpackStencil(0, _stencil);
  2689. uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
  2690. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
  2691. _desc.pNext = NULL;
  2692. _desc.flags = 0;
  2693. _desc.depthTestEnable = 0 != func;
  2694. _desc.depthWriteEnable = !!(BGFX_STATE_WRITE_Z & _state);
  2695. _desc.depthCompareOp = s_cmpFunc[func];
  2696. _desc.depthBoundsTestEnable = VK_FALSE;
  2697. _desc.stencilTestEnable = 0 != _stencil;
  2698. uint32_t bstencil = unpackStencil(1, _stencil);
  2699. uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
  2700. bstencil = frontAndBack ? bstencil : fstencil;
  2701. _desc.front.failOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_FAIL_S_MASK) >> BGFX_STENCIL_OP_FAIL_S_SHIFT];
  2702. _desc.front.passOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_PASS_Z_MASK) >> BGFX_STENCIL_OP_PASS_Z_SHIFT];
  2703. _desc.front.depthFailOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_FAIL_Z_MASK) >> BGFX_STENCIL_OP_FAIL_Z_SHIFT];
  2704. _desc.front.compareOp = s_cmpFunc[(fstencil & BGFX_STENCIL_TEST_MASK) >> BGFX_STENCIL_TEST_SHIFT];
  2705. _desc.front.compareMask = UINT32_MAX;
  2706. _desc.front.writeMask = UINT32_MAX;
  2707. _desc.front.reference = 0;
  2708. _desc.back.failOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_FAIL_S_MASK) >> BGFX_STENCIL_OP_FAIL_S_SHIFT];
  2709. _desc.back.passOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_PASS_Z_MASK) >> BGFX_STENCIL_OP_PASS_Z_SHIFT];
  2710. _desc.back.depthFailOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_FAIL_Z_MASK) >> BGFX_STENCIL_OP_FAIL_Z_SHIFT];
  2711. _desc.back.compareOp = s_cmpFunc[(bstencil&BGFX_STENCIL_TEST_MASK) >> BGFX_STENCIL_TEST_SHIFT];
  2712. _desc.back.compareMask = UINT32_MAX;
  2713. _desc.back.writeMask = UINT32_MAX;
  2714. _desc.back.reference = 0;
  2715. _desc.minDepthBounds = 0.0f;
  2716. _desc.maxDepthBounds = 1.0f;
  2717. }
  2718. void setInputLayout(VkPipelineVertexInputStateCreateInfo& _vertexInputState, uint8_t _numStream, const VertexLayout** _layout, const ProgramVK& _program, uint8_t _numInstanceData)
  2719. {
  2720. _vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
  2721. _vertexInputState.pNext = NULL;
  2722. _vertexInputState.flags = 0;
  2723. _vertexInputState.vertexBindingDescriptionCount = 0;
  2724. _vertexInputState.vertexAttributeDescriptionCount = 0;
  2725. uint16_t unsettedAttr[Attrib::Count];
  2726. bx::memCopy(unsettedAttr, _program.m_vsh->m_attrMask, sizeof(uint16_t) * Attrib::Count);
  2727. for (uint8_t stream = 0; stream < _numStream; ++stream)
  2728. {
  2729. VertexLayout layout;
  2730. bx::memCopy(&layout, _layout[stream], sizeof(VertexLayout) );
  2731. const uint16_t* attrMask = _program.m_vsh->m_attrMask;
  2732. for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
  2733. {
  2734. uint16_t mask = attrMask[ii];
  2735. uint16_t attr = (layout.m_attributes[ii] & mask);
  2736. layout.m_attributes[ii] = attr == 0 || attr == UINT16_MAX ? UINT16_MAX : attr;
  2737. if (unsettedAttr[ii] && attr != UINT16_MAX)
  2738. {
  2739. unsettedAttr[ii] = 0;
  2740. }
  2741. }
  2742. fillVertexLayout(_program.m_vsh, _vertexInputState, layout);
  2743. }
  2744. for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
  2745. {
  2746. if (0 < unsettedAttr[ii])
  2747. {
  2748. uint32_t numAttribs = _vertexInputState.vertexAttributeDescriptionCount;
  2749. VkVertexInputAttributeDescription* inputAttrib = const_cast<VkVertexInputAttributeDescription*>(_vertexInputState.pVertexAttributeDescriptions + numAttribs);
  2750. inputAttrib->location = _program.m_vsh->m_attrRemap[ii];
  2751. inputAttrib->binding = 0;
  2752. inputAttrib->format = VK_FORMAT_R32G32B32_SFLOAT;
  2753. inputAttrib->offset = 0;
  2754. _vertexInputState.vertexAttributeDescriptionCount++;
  2755. }
  2756. }
  2757. if (0 < _numInstanceData)
  2758. {
  2759. fillInstanceBinding(_program.m_vsh, _vertexInputState, _numInstanceData);
  2760. }
  2761. }
  2762. VkResult getRenderPass(uint8_t _num, const VkFormat* _formats, const VkImageAspectFlags* _aspects, const bool* _resolve, VkSampleCountFlagBits _samples, ::VkRenderPass* _renderPass, uint16_t _clearFlags)
  2763. {
  2764. VkResult result = VK_SUCCESS;
  2765. if (VK_SAMPLE_COUNT_1_BIT == _samples)
  2766. {
  2767. _resolve = NULL;
  2768. }
  2769. bx::HashMurmur2A hash;
  2770. hash.begin();
  2771. hash.add(_samples);
  2772. hash.add(_formats, sizeof(VkFormat) * _num);
  2773. hash.add(_clearFlags);
  2774. if (NULL != _resolve)
  2775. {
  2776. hash.add(_resolve, sizeof(bool) * _num);
  2777. }
  2778. uint32_t hashKey = hash.end();
  2779. VkRenderPass renderPass = m_renderPassCache.find(hashKey);
  2780. if (VK_NULL_HANDLE != renderPass)
  2781. {
  2782. *_renderPass = renderPass;
  2783. return result;
  2784. }
  2785. VkAttachmentDescription ad[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS * 2];
  2786. for (uint8_t ii = 0; ii < (_num * 2); ++ii)
  2787. {
  2788. ad[ii].flags = 0;
  2789. ad[ii].format = VK_FORMAT_UNDEFINED;
  2790. ad[ii].samples = _samples;
  2791. ad[ii].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
  2792. ad[ii].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  2793. ad[ii].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  2794. ad[ii].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  2795. ad[ii].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2796. ad[ii].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2797. }
  2798. VkAttachmentReference colorAr[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  2799. VkAttachmentReference resolveAr[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  2800. VkAttachmentReference depthAr;
  2801. uint32_t numColorAr = 0;
  2802. uint32_t numResolveAr = 0;
  2803. colorAr[0].attachment = VK_ATTACHMENT_UNUSED;
  2804. colorAr[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2805. resolveAr[0].attachment = VK_ATTACHMENT_UNUSED;
  2806. resolveAr[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2807. depthAr.attachment = VK_ATTACHMENT_UNUSED;
  2808. depthAr.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  2809. for (uint8_t ii = 0; ii < _num; ++ii)
  2810. {
  2811. ad[ii].format = _formats[ii];
  2812. if (_aspects[ii] & VK_IMAGE_ASPECT_COLOR_BIT)
  2813. {
  2814. colorAr[numColorAr].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2815. colorAr[numColorAr].attachment = ii;
  2816. ad[numColorAr].loadOp = 0 != (_clearFlags & BGFX_CLEAR_COLOR) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
  2817. if (BGFX_CLEAR_NONE != (_clearFlags & (BGFX_CLEAR_DISCARD_COLOR_0 << ii) ) )
  2818. {
  2819. ad[numColorAr].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  2820. }
  2821. resolveAr[numColorAr].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2822. resolveAr[numColorAr].attachment = VK_ATTACHMENT_UNUSED;
  2823. if (NULL != _resolve
  2824. && _resolve[ii])
  2825. {
  2826. const uint32_t resolve = _num + numResolveAr;
  2827. ad[resolve].format = _formats[ii];
  2828. ad[resolve].samples = VK_SAMPLE_COUNT_1_BIT;
  2829. ad[resolve].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  2830. resolveAr[numColorAr].attachment = resolve;
  2831. numResolveAr++;
  2832. }
  2833. numColorAr++;
  2834. }
  2835. else if (_aspects[ii] & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) )
  2836. {
  2837. ad[ii].loadOp = 0 != (_clearFlags & BGFX_CLEAR_DEPTH) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
  2838. ad[ii].storeOp = 0 != (_clearFlags & BGFX_CLEAR_DISCARD_DEPTH) ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
  2839. ad[ii].stencilLoadOp = 0 != (_clearFlags & BGFX_CLEAR_STENCIL) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
  2840. ad[ii].stencilStoreOp = 0 != (_clearFlags & BGFX_CLEAR_DISCARD_STENCIL) ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
  2841. ad[ii].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
  2842. ad[ii].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  2843. ad[ii].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  2844. depthAr.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  2845. depthAr.attachment = ii;
  2846. }
  2847. }
  2848. VkSubpassDescription sd[1];
  2849. sd[0].flags = 0;
  2850. sd[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  2851. sd[0].inputAttachmentCount = 0;
  2852. sd[0].pInputAttachments = NULL;
  2853. sd[0].colorAttachmentCount = bx::max<uint32_t>(numColorAr, 1);
  2854. sd[0].pColorAttachments = colorAr;
  2855. sd[0].pResolveAttachments = resolveAr;
  2856. sd[0].pDepthStencilAttachment = &depthAr;
  2857. sd[0].preserveAttachmentCount = 0;
  2858. sd[0].pPreserveAttachments = NULL;
  2859. const VkPipelineStageFlags graphicsStages = 0
  2860. | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
  2861. | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
  2862. | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
  2863. | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
  2864. | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
  2865. | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
  2866. | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
  2867. ;
  2868. const VkPipelineStageFlags outsideStages = 0
  2869. | graphicsStages
  2870. | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
  2871. | VK_PIPELINE_STAGE_TRANSFER_BIT
  2872. ;
  2873. VkSubpassDependency dep[2];
  2874. dep[0].srcSubpass = VK_SUBPASS_EXTERNAL;
  2875. dep[0].dstSubpass = 0;
  2876. dep[0].srcStageMask = outsideStages;
  2877. dep[0].dstStageMask = graphicsStages;
  2878. dep[0].srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
  2879. dep[0].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
  2880. dep[0].dependencyFlags = 0;
  2881. dep[1].srcSubpass = BX_COUNTOF(sd)-1;
  2882. dep[1].dstSubpass = VK_SUBPASS_EXTERNAL;
  2883. dep[1].srcStageMask = graphicsStages;
  2884. dep[1].dstStageMask = outsideStages;
  2885. dep[1].srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
  2886. dep[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
  2887. dep[1].dependencyFlags = 0;
  2888. VkRenderPassCreateInfo rpi;
  2889. rpi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  2890. rpi.pNext = NULL;
  2891. rpi.flags = 0;
  2892. rpi.attachmentCount = _num + numResolveAr;
  2893. rpi.pAttachments = ad;
  2894. rpi.subpassCount = BX_COUNTOF(sd);
  2895. rpi.pSubpasses = sd;
  2896. rpi.dependencyCount = BX_COUNTOF(dep);
  2897. rpi.pDependencies = dep;
  2898. result = vkCreateRenderPass(m_device, &rpi, m_allocatorCb, &renderPass);
  2899. if (VK_SUCCESS != result)
  2900. {
  2901. BX_TRACE("Create render pass error: vkCreateRenderPass failed %d: %s.", result, getName(result) );
  2902. return result;
  2903. }
  2904. m_renderPassCache.add(hashKey, renderPass);
  2905. *_renderPass = renderPass;
  2906. return result;
  2907. }
  2908. VkResult getRenderPass(uint8_t _num, const Attachment* _attachments, ::VkRenderPass* _renderPass, uint16_t _clearFlags)
  2909. {
  2910. VkFormat formats[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  2911. VkImageAspectFlags aspects[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  2912. VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
  2913. for (uint8_t ii = 0; ii < _num; ++ii)
  2914. {
  2915. const TextureVK& texture = m_textures[_attachments[ii].handle.idx];
  2916. formats[ii] = texture.m_format;
  2917. aspects[ii] = texture.m_aspectFlags;
  2918. samples = texture.m_sampler.Sample;
  2919. }
  2920. return getRenderPass(_num, formats, aspects, NULL, samples, _renderPass, _clearFlags);
  2921. }
  2922. VkResult getRenderPass(const SwapChainVK& swapChain, ::VkRenderPass* _renderPass, uint16_t _clearFlags)
  2923. {
  2924. const VkFormat formats[2] =
  2925. {
  2926. swapChain.m_sci.imageFormat,
  2927. swapChain.m_backBufferDepthStencil.m_format
  2928. };
  2929. const VkImageAspectFlags aspects[2] =
  2930. {
  2931. VK_IMAGE_ASPECT_COLOR_BIT,
  2932. swapChain.m_backBufferDepthStencil.m_aspectFlags
  2933. };
  2934. const bool resolve[2] =
  2935. {
  2936. swapChain.m_supportsManualResolve ? false : true,
  2937. false
  2938. };
  2939. const VkSampleCountFlagBits samples = swapChain.m_sampler.Sample;
  2940. const uint8_t num = swapChain.hasDepthStencil()
  2941. ? BX_COUNTOF(formats)
  2942. : 1
  2943. ;
  2944. return getRenderPass(num, formats, aspects, resolve, samples, _renderPass, _clearFlags);
  2945. }
  2946. VkSampler getSampler(uint32_t _flags, VkFormat _format, const float _palette[][4])
  2947. {
  2948. uint32_t index = ( (_flags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT);
  2949. index = bx::min<uint32_t>(BGFX_CONFIG_MAX_COLOR_PALETTE - 1, index);
  2950. _flags &= BGFX_SAMPLER_BITS_MASK;
  2951. _flags &= ~(m_deviceFeatures.samplerAnisotropy ? 0 : (BGFX_SAMPLER_MIN_ANISOTROPIC | BGFX_SAMPLER_MAG_ANISOTROPIC) );
  2952. // Force both min+max anisotropic, can't be set individually.
  2953. _flags |= 0 != (_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC) )
  2954. ? BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC
  2955. : 0
  2956. ;
  2957. const float* rgba = NULL == _palette
  2958. ? NULL
  2959. : _palette[index]
  2960. ;
  2961. const bool needColor = true
  2962. && needBorderColor(_flags)
  2963. && NULL != rgba
  2964. && m_borderColorSupport
  2965. ;
  2966. uint32_t hashKey;
  2967. VkSampler sampler = VK_NULL_HANDLE;
  2968. if (!needColor)
  2969. {
  2970. bx::HashMurmur2A hash;
  2971. hash.begin();
  2972. hash.add(_flags);
  2973. hash.add(-1);
  2974. hash.add(VK_FORMAT_UNDEFINED);
  2975. hashKey = hash.end();
  2976. sampler = m_samplerCache.find(hashKey);
  2977. }
  2978. else
  2979. {
  2980. bx::HashMurmur2A hash;
  2981. hash.begin();
  2982. hash.add(_flags);
  2983. hash.add(index);
  2984. hash.add(_format);
  2985. hashKey = hash.end();
  2986. const uint32_t colorHashKey = m_samplerBorderColorCache.find(hashKey);
  2987. const uint32_t newColorHashKey = bx::hash<bx::HashMurmur2A>(rgba, sizeof(float) * 4);
  2988. if (newColorHashKey == colorHashKey)
  2989. {
  2990. sampler = m_samplerCache.find(hashKey);
  2991. }
  2992. else
  2993. {
  2994. m_samplerBorderColorCache.add(hashKey, newColorHashKey);
  2995. }
  2996. }
  2997. if (VK_NULL_HANDLE != sampler)
  2998. {
  2999. return sampler;
  3000. }
  3001. const uint32_t cmpFunc = (_flags&BGFX_SAMPLER_COMPARE_MASK)>>BGFX_SAMPLER_COMPARE_SHIFT;
  3002. const float maxLodBias = m_deviceProperties.properties.limits.maxSamplerLodBias;
  3003. const float lodBias = bx::clamp(float(BGFX_CONFIG_MIP_LOD_BIAS), -maxLodBias, maxLodBias);
  3004. VkSamplerCreateInfo sci;
  3005. sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
  3006. sci.pNext = NULL;
  3007. sci.flags = 0;
  3008. sci.magFilter = _flags & BGFX_SAMPLER_MAG_POINT ? VK_FILTER_NEAREST : VK_FILTER_LINEAR;
  3009. sci.minFilter = _flags & BGFX_SAMPLER_MIN_POINT ? VK_FILTER_NEAREST : VK_FILTER_LINEAR;
  3010. sci.mipmapMode = _flags & BGFX_SAMPLER_MIP_POINT ? VK_SAMPLER_MIPMAP_MODE_NEAREST : VK_SAMPLER_MIPMAP_MODE_LINEAR;
  3011. sci.addressModeU = s_textureAddress[(_flags&BGFX_SAMPLER_U_MASK)>>BGFX_SAMPLER_U_SHIFT];
  3012. sci.addressModeV = s_textureAddress[(_flags&BGFX_SAMPLER_V_MASK)>>BGFX_SAMPLER_V_SHIFT];
  3013. sci.addressModeW = s_textureAddress[(_flags&BGFX_SAMPLER_W_MASK)>>BGFX_SAMPLER_W_SHIFT];
  3014. sci.mipLodBias = lodBias;
  3015. sci.anisotropyEnable = !!(_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC | BGFX_SAMPLER_MAG_ANISOTROPIC) );
  3016. sci.maxAnisotropy = m_maxAnisotropy;
  3017. sci.compareEnable = 0 != cmpFunc;
  3018. sci.compareOp = s_cmpFunc[cmpFunc];
  3019. sci.minLod = 0.0f;
  3020. sci.maxLod = VK_LOD_CLAMP_NONE;
  3021. sci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
  3022. sci.unnormalizedCoordinates = VK_FALSE;
  3023. VkSamplerCustomBorderColorCreateInfoEXT cbcci;
  3024. if (needColor)
  3025. {
  3026. cbcci.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
  3027. cbcci.pNext = NULL;
  3028. cbcci.format = _format;
  3029. bx::memCopy(cbcci.customBorderColor.float32, rgba, sizeof(cbcci.customBorderColor.float32) );
  3030. sci.pNext = &cbcci;
  3031. sci.borderColor = VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
  3032. }
  3033. VK_CHECK(vkCreateSampler(m_device, &sci, m_allocatorCb, &sampler) );
  3034. m_samplerCache.add(hashKey, sampler);
  3035. return sampler;
  3036. }
  3037. VkImageView getCachedImageView(TextureHandle _handle, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, bool _stencil = false)
  3038. {
  3039. const TextureVK& texture = m_textures[_handle.idx];
  3040. _stencil = _stencil && !!(texture.m_aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT);
  3041. bx::HashMurmur2A hash;
  3042. hash.begin();
  3043. hash.add(_handle.idx);
  3044. hash.add(_mip);
  3045. hash.add(_numMips);
  3046. hash.add(_type);
  3047. hash.add(_stencil);
  3048. uint32_t hashKey = hash.end();
  3049. VkImageView* viewCached = m_imageViewCache.find(hashKey);
  3050. if (NULL != viewCached)
  3051. {
  3052. return *viewCached;
  3053. }
  3054. const VkImageAspectFlags aspectMask = 0
  3055. | VK_IMAGE_ASPECT_COLOR_BIT
  3056. | ( _stencil ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT)
  3057. ;
  3058. VkImageView view;
  3059. VK_CHECK(texture.createView(0, texture.m_numSides, _mip, _numMips, _type, aspectMask, false, &view) );
  3060. m_imageViewCache.add(hashKey, view, _handle.idx);
  3061. return view;
  3062. }
  3063. VkPipeline getPipeline(ProgramHandle _program)
  3064. {
  3065. ProgramVK& program = m_program[_program.idx];
  3066. bx::HashMurmur2A murmur;
  3067. murmur.begin();
  3068. murmur.add(program.m_vsh->m_hash);
  3069. const uint32_t hash = murmur.end();
  3070. VkPipeline pipeline = m_pipelineStateCache.find(hash);
  3071. if (VK_NULL_HANDLE != pipeline)
  3072. {
  3073. return pipeline;
  3074. }
  3075. VkComputePipelineCreateInfo cpci;
  3076. cpci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
  3077. cpci.pNext = NULL;
  3078. cpci.flags = 0;
  3079. cpci.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
  3080. cpci.stage.pNext = NULL;
  3081. cpci.stage.flags = 0;
  3082. cpci.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
  3083. cpci.stage.module = program.m_vsh->m_module;
  3084. cpci.stage.pName = "main";
  3085. cpci.stage.pSpecializationInfo = NULL;
  3086. cpci.layout = program.m_pipelineLayout;
  3087. cpci.basePipelineHandle = VK_NULL_HANDLE;
  3088. cpci.basePipelineIndex = 0;
  3089. VK_CHECK(vkCreateComputePipelines(m_device, m_pipelineCache, 1, &cpci, m_allocatorCb, &pipeline) );
  3090. m_pipelineStateCache.add(hash, pipeline);
  3091. return pipeline;
  3092. }
  3093. VkPipeline getPipeline(uint64_t _state, uint64_t _stencil, uint8_t _numStreams, const VertexLayout** _layouts, ProgramHandle _program, uint8_t _numInstanceData)
  3094. {
  3095. ProgramVK& program = m_program[_program.idx];
  3096. _state &= 0
  3097. | BGFX_STATE_WRITE_MASK
  3098. | BGFX_STATE_DEPTH_TEST_MASK
  3099. | BGFX_STATE_BLEND_MASK
  3100. | BGFX_STATE_BLEND_EQUATION_MASK
  3101. | (g_caps.supported & BGFX_CAPS_BLEND_INDEPENDENT ? BGFX_STATE_BLEND_INDEPENDENT : 0)
  3102. | BGFX_STATE_BLEND_ALPHA_TO_COVERAGE
  3103. | BGFX_STATE_CULL_MASK
  3104. | BGFX_STATE_FRONT_CCW
  3105. | BGFX_STATE_MSAA
  3106. | (m_lineAASupport ? BGFX_STATE_LINEAA : 0)
  3107. | (g_caps.supported & BGFX_CAPS_CONSERVATIVE_RASTER ? BGFX_STATE_CONSERVATIVE_RASTER : 0)
  3108. | BGFX_STATE_PT_MASK
  3109. ;
  3110. _stencil &= kStencilNoRefMask;
  3111. VertexLayout layout;
  3112. if (0 < _numStreams)
  3113. {
  3114. bx::memCopy(&layout, _layouts[0], sizeof(VertexLayout) );
  3115. const uint16_t* attrMask = program.m_vsh->m_attrMask;
  3116. for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
  3117. {
  3118. uint16_t mask = attrMask[ii];
  3119. uint16_t attr = (layout.m_attributes[ii] & mask);
  3120. layout.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr;
  3121. }
  3122. }
  3123. const FrameBufferVK& frameBuffer = isValid(m_fbh)
  3124. ? m_frameBuffers[m_fbh.idx]
  3125. : m_backBuffer
  3126. ;
  3127. bx::HashMurmur2A murmur;
  3128. murmur.begin();
  3129. murmur.add(_state);
  3130. murmur.add(_stencil);
  3131. murmur.add(program.m_vsh->m_hash);
  3132. murmur.add(program.m_vsh->m_attrMask, sizeof(program.m_vsh->m_attrMask) );
  3133. if (NULL != program.m_fsh)
  3134. {
  3135. murmur.add(program.m_fsh->m_hash);
  3136. }
  3137. for (uint8_t ii = 0; ii < _numStreams; ++ii)
  3138. {
  3139. murmur.add(_layouts[ii]->m_hash);
  3140. }
  3141. murmur.add(layout.m_attributes, sizeof(layout.m_attributes) );
  3142. murmur.add(_numInstanceData);
  3143. murmur.add(frameBuffer.m_renderPass);
  3144. const uint32_t hash = murmur.end();
  3145. VkPipeline pipeline = m_pipelineStateCache.find(hash);
  3146. if (VK_NULL_HANDLE != pipeline)
  3147. {
  3148. return pipeline;
  3149. }
  3150. VkPipelineColorBlendAttachmentState blendAttachmentState[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  3151. VkPipelineColorBlendStateCreateInfo colorBlendState;
  3152. colorBlendState.pAttachments = blendAttachmentState;
  3153. setBlendState(colorBlendState, _state);
  3154. VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
  3155. inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
  3156. inputAssemblyState.pNext = NULL;
  3157. inputAssemblyState.flags = 0;
  3158. inputAssemblyState.topology = s_primInfo[(_state&BGFX_STATE_PT_MASK) >> BGFX_STATE_PT_SHIFT].m_topology;
  3159. inputAssemblyState.primitiveRestartEnable = VK_FALSE;
  3160. VkPipelineRasterizationStateCreateInfo rasterizationState;
  3161. setRasterizerState(rasterizationState, _state, m_wireframe);
  3162. VkBaseInStructure* nextRasterizationState = (VkBaseInStructure*)&rasterizationState;
  3163. VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeRasterizationState;
  3164. if (s_extension[Extension::EXT_conservative_rasterization].m_supported)
  3165. {
  3166. nextRasterizationState->pNext = (VkBaseInStructure*)&conservativeRasterizationState;
  3167. nextRasterizationState = (VkBaseInStructure*)&conservativeRasterizationState;
  3168. setConservativeRasterizerState(conservativeRasterizationState, _state);
  3169. }
  3170. VkPipelineRasterizationLineStateCreateInfoEXT lineRasterizationState;
  3171. if (m_lineAASupport)
  3172. {
  3173. nextRasterizationState->pNext = (VkBaseInStructure*)&lineRasterizationState;
  3174. nextRasterizationState = (VkBaseInStructure*)&lineRasterizationState;
  3175. setLineRasterizerState(lineRasterizationState, _state);
  3176. }
  3177. VkPipelineDepthStencilStateCreateInfo depthStencilState;
  3178. setDepthStencilState(depthStencilState, _state, _stencil);
  3179. VkVertexInputBindingDescription inputBinding[BGFX_CONFIG_MAX_VERTEX_STREAMS + 1];
  3180. VkVertexInputAttributeDescription inputAttrib[Attrib::Count + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
  3181. VkPipelineVertexInputStateCreateInfo vertexInputState;
  3182. vertexInputState.pVertexBindingDescriptions = inputBinding;
  3183. vertexInputState.pVertexAttributeDescriptions = inputAttrib;
  3184. setInputLayout(vertexInputState, _numStreams, _layouts, program, _numInstanceData);
  3185. const VkDynamicState dynamicStates[] =
  3186. {
  3187. VK_DYNAMIC_STATE_VIEWPORT,
  3188. VK_DYNAMIC_STATE_SCISSOR,
  3189. VK_DYNAMIC_STATE_BLEND_CONSTANTS,
  3190. VK_DYNAMIC_STATE_STENCIL_REFERENCE,
  3191. VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR, // optional
  3192. };
  3193. VkPipelineDynamicStateCreateInfo dynamicState;
  3194. dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
  3195. dynamicState.pNext = NULL;
  3196. dynamicState.flags = 0;
  3197. dynamicState.dynamicStateCount = BX_COUNTOF(dynamicStates) -
  3198. (m_variableRateShadingSupported ? 0 : 1)
  3199. ;
  3200. dynamicState.pDynamicStates = dynamicStates;
  3201. VkPipelineShaderStageCreateInfo shaderStages[2];
  3202. shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
  3203. shaderStages[0].pNext = NULL;
  3204. shaderStages[0].flags = 0;
  3205. shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
  3206. shaderStages[0].module = program.m_vsh->m_module;
  3207. shaderStages[0].pName = "main";
  3208. shaderStages[0].pSpecializationInfo = NULL;
  3209. if (NULL != program.m_fsh)
  3210. {
  3211. shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
  3212. shaderStages[1].pNext = NULL;
  3213. shaderStages[1].flags = 0;
  3214. shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
  3215. shaderStages[1].module = program.m_fsh->m_module;
  3216. shaderStages[1].pName = "main";
  3217. shaderStages[1].pSpecializationInfo = NULL;
  3218. }
  3219. VkPipelineViewportStateCreateInfo viewportState;
  3220. viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
  3221. viewportState.pNext = NULL;
  3222. viewportState.flags = 0;
  3223. viewportState.viewportCount = 1;
  3224. viewportState.pViewports = NULL;
  3225. viewportState.scissorCount = 1;
  3226. viewportState.pScissors = NULL;
  3227. VkPipelineMultisampleStateCreateInfo multisampleState;
  3228. multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
  3229. multisampleState.pNext = NULL;
  3230. multisampleState.flags = 0;
  3231. multisampleState.rasterizationSamples = frameBuffer.m_sampler.Sample;
  3232. multisampleState.sampleShadingEnable = VK_FALSE;
  3233. multisampleState.minSampleShading = 0.0f;
  3234. multisampleState.pSampleMask = NULL;
  3235. multisampleState.alphaToCoverageEnable = !!(BGFX_STATE_BLEND_ALPHA_TO_COVERAGE & _state);
  3236. multisampleState.alphaToOneEnable = VK_FALSE;
  3237. VkGraphicsPipelineCreateInfo graphicsPipeline;
  3238. graphicsPipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
  3239. graphicsPipeline.pNext = NULL;
  3240. graphicsPipeline.flags = 0;
  3241. graphicsPipeline.stageCount = NULL == program.m_fsh ? 1 : 2;
  3242. graphicsPipeline.pStages = shaderStages;
  3243. graphicsPipeline.pVertexInputState = &vertexInputState;
  3244. graphicsPipeline.pInputAssemblyState = &inputAssemblyState;
  3245. graphicsPipeline.pTessellationState = NULL;
  3246. graphicsPipeline.pViewportState = &viewportState;
  3247. graphicsPipeline.pRasterizationState = &rasterizationState;
  3248. graphicsPipeline.pMultisampleState = &multisampleState;
  3249. graphicsPipeline.pDepthStencilState = &depthStencilState;
  3250. graphicsPipeline.pColorBlendState = &colorBlendState;
  3251. graphicsPipeline.pDynamicState = &dynamicState;
  3252. graphicsPipeline.layout = program.m_pipelineLayout;
  3253. graphicsPipeline.renderPass = frameBuffer.m_renderPass;
  3254. graphicsPipeline.subpass = 0;
  3255. graphicsPipeline.basePipelineHandle = VK_NULL_HANDLE;
  3256. graphicsPipeline.basePipelineIndex = 0;
  3257. uint32_t length = g_callback->cacheReadSize(hash);
  3258. bool cached = length > 0;
  3259. void* cachedData = NULL;
  3260. VkPipelineCacheCreateInfo pcci;
  3261. pcci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
  3262. pcci.pNext = NULL;
  3263. pcci.flags = 0;
  3264. pcci.initialDataSize = 0;
  3265. pcci.pInitialData = NULL;
  3266. if (cached)
  3267. {
  3268. cachedData = bx::alloc(g_allocator, length);
  3269. if (g_callback->cacheRead(hash, cachedData, length) )
  3270. {
  3271. BX_TRACE("Loading cached pipeline state (size %d).", length);
  3272. bx::MemoryReader reader(cachedData, length);
  3273. pcci.initialDataSize = (size_t)reader.remaining();
  3274. pcci.pInitialData = reader.getDataPtr();
  3275. }
  3276. }
  3277. VkPipelineCache cache;
  3278. VK_CHECK(vkCreatePipelineCache(m_device, &pcci, m_allocatorCb, &cache) );
  3279. VK_CHECK(vkCreateGraphicsPipelines(
  3280. m_device
  3281. , cache
  3282. , 1
  3283. , &graphicsPipeline
  3284. , m_allocatorCb
  3285. , &pipeline
  3286. ) );
  3287. m_pipelineStateCache.add(hash, pipeline);
  3288. size_t dataSize;
  3289. VK_CHECK(vkGetPipelineCacheData(m_device, cache, &dataSize, NULL) );
  3290. if (0 < dataSize)
  3291. {
  3292. if (length < dataSize)
  3293. {
  3294. cachedData = bx::realloc(g_allocator, cachedData, dataSize);
  3295. }
  3296. VK_CHECK(vkGetPipelineCacheData(m_device, cache, &dataSize, cachedData) );
  3297. g_callback->cacheWrite(hash, cachedData, (uint32_t)dataSize);
  3298. }
  3299. VK_CHECK(vkMergePipelineCaches(m_device, m_pipelineCache, 1, &cache) );
  3300. vkDestroy(cache);
  3301. if (NULL != cachedData)
  3302. {
  3303. bx::free(g_allocator, cachedData);
  3304. }
  3305. return pipeline;
  3306. }
  3307. VkDescriptorSet getDescriptorSet(const ProgramVK& _program, const RenderBind& _renderBind, VkBuffer _uniformBuffer, const float _palette[][4])
  3308. {
  3309. VkDescriptorSet descriptorSet;
  3310. VkDescriptorSetAllocateInfo dsai;
  3311. dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
  3312. dsai.pNext = NULL;
  3313. dsai.descriptorPool = m_descriptorPool[m_cmd.m_currentFrameInFlight];
  3314. dsai.descriptorSetCount = 1;
  3315. dsai.pSetLayouts = &_program.m_descriptorSetLayout;
  3316. VK_CHECK(vkAllocateDescriptorSets(m_device, &dsai, &descriptorSet) );
  3317. VkDescriptorImageInfo imageInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  3318. VkDescriptorBufferInfo bufferInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  3319. constexpr uint32_t kMaxDescriptorSets = 2 * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS + 2;
  3320. VkWriteDescriptorSet wds[kMaxDescriptorSets] = {};
  3321. uint32_t wdsCount = 0;
  3322. uint32_t bufferCount = 0;
  3323. uint32_t imageCount = 0;
  3324. for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage)
  3325. {
  3326. const Binding& bind = _renderBind.m_bind[stage];
  3327. const BindInfo& bindInfo = _program.m_bindInfo[stage];
  3328. if (kInvalidHandle != bind.m_idx
  3329. && isValid(bindInfo.uniformHandle) )
  3330. {
  3331. switch (bind.m_type)
  3332. {
  3333. case Binding::Image:
  3334. {
  3335. const bool isImageDescriptor = BindType::Image == bindInfo.type;
  3336. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3337. wds[wdsCount].pNext = NULL;
  3338. wds[wdsCount].dstSet = descriptorSet;
  3339. wds[wdsCount].dstBinding = bindInfo.binding;
  3340. wds[wdsCount].dstArrayElement = 0;
  3341. wds[wdsCount].descriptorCount = 1;
  3342. wds[wdsCount].descriptorType = isImageDescriptor
  3343. ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
  3344. : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
  3345. ;
  3346. wds[wdsCount].pImageInfo = NULL;
  3347. wds[wdsCount].pBufferInfo = NULL;
  3348. wds[wdsCount].pTexelBufferView = NULL;
  3349. const TextureVK& texture = m_textures[bind.m_idx];
  3350. VkImageViewType type = texture.m_type;
  3351. if (UINT32_MAX != bindInfo.index)
  3352. {
  3353. type = _program.m_textures[bindInfo.index].type;
  3354. }
  3355. else if (type == VK_IMAGE_VIEW_TYPE_CUBE
  3356. || type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
  3357. {
  3358. type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
  3359. }
  3360. BX_ASSERT(
  3361. texture.m_currentImageLayout == texture.m_sampledLayout
  3362. , "Mismatching image layout. Texture currently used as a framebuffer attachment?"
  3363. );
  3364. imageInfo[imageCount].imageLayout = texture.m_sampledLayout;
  3365. imageInfo[imageCount].sampler = VK_NULL_HANDLE;
  3366. imageInfo[imageCount].imageView = getCachedImageView(
  3367. { bind.m_idx }
  3368. , bind.m_mip
  3369. , 1
  3370. , type
  3371. );
  3372. wds[wdsCount].pImageInfo = &imageInfo[imageCount];
  3373. ++imageCount;
  3374. ++wdsCount;
  3375. }
  3376. break;
  3377. case Binding::VertexBuffer:
  3378. case Binding::IndexBuffer:
  3379. {
  3380. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3381. wds[wdsCount].pNext = NULL;
  3382. wds[wdsCount].dstSet = descriptorSet;
  3383. wds[wdsCount].dstBinding = bindInfo.binding;
  3384. wds[wdsCount].dstArrayElement = 0;
  3385. wds[wdsCount].descriptorCount = 1;
  3386. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
  3387. wds[wdsCount].pImageInfo = NULL;
  3388. wds[wdsCount].pBufferInfo = NULL;
  3389. wds[wdsCount].pTexelBufferView = NULL;
  3390. const BufferVK& sb = bind.m_type == Binding::VertexBuffer
  3391. ? m_vertexBuffers[bind.m_idx]
  3392. : m_indexBuffers[bind.m_idx]
  3393. ;
  3394. bufferInfo[bufferCount].buffer = sb.m_buffer;
  3395. bufferInfo[bufferCount].offset = 0;
  3396. bufferInfo[bufferCount].range = sb.m_size;
  3397. wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount];
  3398. ++bufferCount;
  3399. ++wdsCount;
  3400. }
  3401. break;
  3402. case Binding::Texture:
  3403. {
  3404. TextureVK& texture = m_textures[bind.m_idx];
  3405. const uint32_t samplerFlags = 0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags)
  3406. ? bind.m_samplerFlags
  3407. : (uint32_t)texture.m_flags
  3408. ;
  3409. const bool sampleStencil = !!(samplerFlags & BGFX_SAMPLER_SAMPLE_STENCIL);
  3410. VkSampler sampler = getSampler(samplerFlags, texture.m_format, _palette);
  3411. const VkImageViewType type = UINT32_MAX == bindInfo.index
  3412. ? texture.m_type
  3413. : _program.m_textures[bindInfo.index].type
  3414. ;
  3415. BX_ASSERT(
  3416. texture.m_currentImageLayout == texture.m_sampledLayout
  3417. , "Mismatching image layout. Texture currently used as a framebuffer attachment?"
  3418. );
  3419. imageInfo[imageCount].imageLayout = texture.m_sampledLayout;
  3420. imageInfo[imageCount].sampler = sampler;
  3421. imageInfo[imageCount].imageView = getCachedImageView(
  3422. { bind.m_idx }
  3423. , 0
  3424. , texture.m_numMips
  3425. , type
  3426. , sampleStencil
  3427. );
  3428. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3429. wds[wdsCount].pNext = NULL;
  3430. wds[wdsCount].dstSet = descriptorSet;
  3431. wds[wdsCount].dstBinding = bindInfo.binding;
  3432. wds[wdsCount].dstArrayElement = 0;
  3433. wds[wdsCount].descriptorCount = 1;
  3434. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
  3435. wds[wdsCount].pImageInfo = &imageInfo[imageCount];
  3436. wds[wdsCount].pBufferInfo = NULL;
  3437. wds[wdsCount].pTexelBufferView = NULL;
  3438. ++wdsCount;
  3439. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3440. wds[wdsCount].pNext = NULL;
  3441. wds[wdsCount].dstSet = descriptorSet;
  3442. wds[wdsCount].dstBinding = bindInfo.samplerBinding;
  3443. wds[wdsCount].dstArrayElement = 0;
  3444. wds[wdsCount].descriptorCount = 1;
  3445. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
  3446. wds[wdsCount].pImageInfo = &imageInfo[imageCount];
  3447. wds[wdsCount].pBufferInfo = NULL;
  3448. wds[wdsCount].pTexelBufferView = NULL;
  3449. ++wdsCount;
  3450. ++imageCount;
  3451. }
  3452. break;
  3453. }
  3454. }
  3455. }
  3456. const uint32_t vsSize = _program.m_vsh->m_size;
  3457. const uint32_t fsSize = NULL != _program.m_fsh ? _program.m_fsh->m_size : 0;
  3458. if (0 < vsSize)
  3459. {
  3460. bufferInfo[bufferCount].buffer = _uniformBuffer;
  3461. bufferInfo[bufferCount].offset = 0;
  3462. bufferInfo[bufferCount].range = vsSize;
  3463. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3464. wds[wdsCount].pNext = NULL;
  3465. wds[wdsCount].dstSet = descriptorSet;
  3466. wds[wdsCount].dstBinding = _program.m_vsh->m_uniformBinding;
  3467. wds[wdsCount].dstArrayElement = 0;
  3468. wds[wdsCount].descriptorCount = 1;
  3469. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  3470. wds[wdsCount].pImageInfo = NULL;
  3471. wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount];
  3472. wds[wdsCount].pTexelBufferView = NULL;
  3473. ++wdsCount;
  3474. ++bufferCount;
  3475. }
  3476. if (0 < fsSize)
  3477. {
  3478. bufferInfo[bufferCount].buffer = _uniformBuffer;
  3479. bufferInfo[bufferCount].offset = 0;
  3480. bufferInfo[bufferCount].range = fsSize;
  3481. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3482. wds[wdsCount].pNext = NULL;
  3483. wds[wdsCount].dstSet = descriptorSet;
  3484. wds[wdsCount].dstBinding = _program.m_fsh->m_uniformBinding;
  3485. wds[wdsCount].dstArrayElement = 0;
  3486. wds[wdsCount].descriptorCount = 1;
  3487. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  3488. wds[wdsCount].pImageInfo = NULL;
  3489. wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount];
  3490. wds[wdsCount].pTexelBufferView = NULL;
  3491. ++wdsCount;
  3492. ++bufferCount;
  3493. }
  3494. vkUpdateDescriptorSets(m_device, wdsCount, wds, 0, NULL);
  3495. VkDescriptorSet temp = descriptorSet;
  3496. release(temp);
  3497. return descriptorSet;
  3498. }
  3499. bool isSwapChainReadable(const SwapChainVK& _swapChain)
  3500. {
  3501. return true
  3502. && NULL != _swapChain.m_nwh
  3503. && _swapChain.m_needPresent
  3504. && _swapChain.m_supportsReadback
  3505. && bimg::imageConvert(bimg::TextureFormat::BGRA8, bimg::TextureFormat::Enum(_swapChain.m_colorFormat) )
  3506. ;
  3507. }
  3508. typedef void (*SwapChainReadFunc)(void* /*src*/, uint32_t /*width*/, uint32_t /*height*/, uint32_t /*pitch*/, const void* /*userData*/);
  3509. bool readSwapChain(const SwapChainVK& _swapChain, VkBuffer _buffer, DeviceMemoryAllocationVK _memory, SwapChainReadFunc _func, const void* _userData = NULL)
  3510. {
  3511. if (isSwapChainReadable(_swapChain) )
  3512. {
  3513. // source for the copy is the last rendered swapchain image
  3514. const VkImage image = _swapChain.m_backBufferColorImage[_swapChain.m_backBufferColorIdx];
  3515. const VkImageLayout layout = _swapChain.m_backBufferColorImageLayout[_swapChain.m_backBufferColorIdx];
  3516. const uint32_t width = _swapChain.m_sci.imageExtent.width;
  3517. const uint32_t height = _swapChain.m_sci.imageExtent.height;
  3518. ReadbackVK readback;
  3519. readback.create(image, width, height, _swapChain.m_colorFormat);
  3520. const uint32_t pitch = readback.pitch();
  3521. readback.copyImageToBuffer(m_commandBuffer, _buffer, layout, VK_IMAGE_ASPECT_COLOR_BIT);
  3522. // stall for commandbuffer to finish
  3523. kick(true);
  3524. uint8_t* src;
  3525. VK_CHECK(vkMapMemory(m_device, _memory.mem, _memory.offset, _memory.size, 0, (void**)&src) );
  3526. if (_swapChain.m_colorFormat == TextureFormat::RGBA8)
  3527. {
  3528. bimg::imageSwizzleBgra8(src, pitch, width, height, src, pitch);
  3529. _func(src, width, height, pitch, _userData);
  3530. }
  3531. else if (_swapChain.m_colorFormat == TextureFormat::BGRA8)
  3532. {
  3533. _func(src, width, height, pitch, _userData);
  3534. }
  3535. else
  3536. {
  3537. const uint8_t dstBpp = bimg::getBitsPerPixel(bimg::TextureFormat::BGRA8);
  3538. const uint32_t dstPitch = width * dstBpp / 8;
  3539. const uint32_t dstSize = height * dstPitch;
  3540. void* dst = bx::alloc(g_allocator, dstSize);
  3541. bimg::imageConvert(g_allocator, dst, bimg::TextureFormat::BGRA8, src, bimg::TextureFormat::Enum(_swapChain.m_colorFormat), width, height, 1);
  3542. _func(dst, width, height, dstPitch, _userData);
  3543. bx::free(g_allocator, dst);
  3544. }
  3545. vkUnmapMemory(m_device, _memory.mem);
  3546. readback.destroy();
  3547. return true;
  3548. }
  3549. return false;
  3550. }
  3551. void capture()
  3552. {
  3553. if (m_captureSize > 0)
  3554. {
  3555. m_backBuffer.resolve();
  3556. auto callback = [](void* _src, uint32_t /*_width*/, uint32_t _height, uint32_t _pitch, const void* /*_userData*/)
  3557. {
  3558. const uint32_t size = _height * _pitch;
  3559. g_callback->captureFrame(_src, size);
  3560. };
  3561. readSwapChain(m_backBuffer.m_swapChain, m_captureBuffer, m_captureMemory, callback);
  3562. }
  3563. }
  3564. bool isVisible(Frame* _render, OcclusionQueryHandle _handle, bool _visible)
  3565. {
  3566. return _visible == (0 != _render->m_occlusion[_handle.idx]);
  3567. }
  3568. void commit(UniformBuffer& _uniformBuffer)
  3569. {
  3570. _uniformBuffer.reset();
  3571. for (;;)
  3572. {
  3573. uint32_t opcode = _uniformBuffer.read();
  3574. if (UniformType::End == opcode)
  3575. {
  3576. break;
  3577. }
  3578. uint8_t type;
  3579. uint16_t loc;
  3580. uint16_t num;
  3581. uint16_t copy;
  3582. UniformBuffer::decodeOpcode(opcode, type, loc, num, copy);
  3583. const char* data;
  3584. if (copy)
  3585. {
  3586. data = _uniformBuffer.read(g_uniformTypeSize[type]*num);
  3587. }
  3588. else
  3589. {
  3590. UniformHandle handle;
  3591. bx::memCopy(&handle, _uniformBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) );
  3592. data = (const char*)m_uniforms[handle.idx];
  3593. }
  3594. switch (type)
  3595. {
  3596. case UniformType::Mat3:
  3597. case UniformType::Mat3|kUniformFragmentBit:
  3598. {
  3599. float* value = (float*)data;
  3600. for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9)
  3601. {
  3602. Matrix4 mtx;
  3603. mtx.un.val[ 0] = value[0];
  3604. mtx.un.val[ 1] = value[1];
  3605. mtx.un.val[ 2] = value[2];
  3606. mtx.un.val[ 3] = 0.0f;
  3607. mtx.un.val[ 4] = value[3];
  3608. mtx.un.val[ 5] = value[4];
  3609. mtx.un.val[ 6] = value[5];
  3610. mtx.un.val[ 7] = 0.0f;
  3611. mtx.un.val[ 8] = value[6];
  3612. mtx.un.val[ 9] = value[7];
  3613. mtx.un.val[10] = value[8];
  3614. mtx.un.val[11] = 0.0f;
  3615. setShaderUniform(uint8_t(type), loc, &mtx.un.val[0], 3);
  3616. }
  3617. }
  3618. break;
  3619. case UniformType::Sampler:
  3620. case UniformType::Sampler|kUniformFragmentBit:
  3621. // do nothing, but VkDescriptorSetImageInfo would be set before drawing
  3622. break;
  3623. case UniformType::Vec4:
  3624. case UniformType::Vec4 | kUniformFragmentBit:
  3625. case UniformType::Mat4:
  3626. case UniformType::Mat4 | kUniformFragmentBit:
  3627. {
  3628. setShaderUniform(uint8_t(type), loc, data, num);
  3629. }
  3630. break;
  3631. case UniformType::End:
  3632. break;
  3633. default:
  3634. BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy);
  3635. break;
  3636. }
  3637. }
  3638. }
  3639. void clearQuad(const Rect& _rect, const Clear& _clear, const float _palette[][4])
  3640. {
  3641. VkClearRect rect[1];
  3642. rect[0].rect.offset.x = _rect.m_x;
  3643. rect[0].rect.offset.y = _rect.m_y;
  3644. rect[0].rect.extent.width = _rect.m_width;
  3645. rect[0].rect.extent.height = _rect.m_height;
  3646. rect[0].baseArrayLayer = 0;
  3647. rect[0].layerCount = 1;
  3648. uint32_t numMrt;
  3649. bgfx::TextureFormat::Enum mrtFormat[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  3650. VkImageAspectFlags depthAspectMask;
  3651. const FrameBufferVK& fb = isValid(m_fbh)
  3652. ? m_frameBuffers[m_fbh.idx]
  3653. : m_backBuffer
  3654. ;
  3655. if (NULL == fb.m_nwh)
  3656. {
  3657. numMrt = fb.m_num;
  3658. for (uint8_t ii = 0; ii < fb.m_num; ++ii)
  3659. {
  3660. mrtFormat[ii] = bgfx::TextureFormat::Enum(m_textures[fb.m_texture[ii].idx].m_requestedFormat);
  3661. }
  3662. depthAspectMask = isValid(fb.m_depth) ? m_textures[fb.m_depth.idx].m_aspectFlags : 0;
  3663. rect[0].layerCount = fb.m_attachment[0].numLayers;
  3664. }
  3665. else
  3666. {
  3667. numMrt = 1;
  3668. mrtFormat[0] = fb.m_swapChain.m_colorFormat;
  3669. depthAspectMask = fb.m_swapChain.m_backBufferDepthStencil.m_aspectFlags;
  3670. }
  3671. VkClearAttachment attachments[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS + 1];
  3672. uint32_t mrt = 0;
  3673. if (BGFX_CLEAR_COLOR & _clear.m_flags)
  3674. {
  3675. for (uint32_t ii = 0; ii < numMrt; ++ii)
  3676. {
  3677. attachments[mrt].colorAttachment = mrt;
  3678. attachments[mrt].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  3679. VkClearColorValue& clearValue = attachments[mrt].clearValue.color;
  3680. const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(mrtFormat[ii]) );
  3681. const bx::EncodingType::Enum type = bx::EncodingType::Enum(blockInfo.encoding);
  3682. if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)
  3683. {
  3684. const uint8_t index = bx::min<uint8_t>(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[ii]);
  3685. switch (type)
  3686. {
  3687. case bx::EncodingType::Int:
  3688. case bx::EncodingType::Uint:
  3689. clearValue.int32[0] = int32_t(_palette[index][0]);
  3690. clearValue.int32[1] = int32_t(_palette[index][1]);
  3691. clearValue.int32[2] = int32_t(_palette[index][2]);
  3692. clearValue.int32[3] = int32_t(_palette[index][3]);
  3693. break;
  3694. default:
  3695. bx::memCopy(&clearValue.float32, _palette[index], sizeof(clearValue.float32) );
  3696. break;
  3697. }
  3698. }
  3699. else
  3700. {
  3701. switch (type)
  3702. {
  3703. case bx::EncodingType::Int:
  3704. case bx::EncodingType::Uint:
  3705. clearValue.uint32[0] = _clear.m_index[0];
  3706. clearValue.uint32[1] = _clear.m_index[1];
  3707. clearValue.uint32[2] = _clear.m_index[2];
  3708. clearValue.uint32[3] = _clear.m_index[3];
  3709. break;
  3710. default:
  3711. bx::unpackRgba8(clearValue.float32, _clear.m_index);
  3712. break;
  3713. }
  3714. }
  3715. ++mrt;
  3716. }
  3717. }
  3718. depthAspectMask &= 0
  3719. | (_clear.m_flags & BGFX_CLEAR_DEPTH ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
  3720. | (_clear.m_flags & BGFX_CLEAR_STENCIL ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)
  3721. ;
  3722. if (0 != depthAspectMask)
  3723. {
  3724. attachments[mrt].colorAttachment = VK_ATTACHMENT_UNUSED;
  3725. // The above is meaningless and not required by the spec, but Khronos
  3726. // Validation Layer has a conditional jump depending on this, even
  3727. // without VK_IMAGE_ASPECT_COLOR_BIT set. Valgrind found this.
  3728. attachments[mrt].aspectMask = depthAspectMask;
  3729. attachments[mrt].clearValue.depthStencil.stencil = _clear.m_stencil;
  3730. attachments[mrt].clearValue.depthStencil.depth = _clear.m_depth;
  3731. ++mrt;
  3732. }
  3733. if (mrt > 0)
  3734. {
  3735. vkCmdClearAttachments(m_commandBuffer, mrt, attachments, BX_COUNTOF(rect), rect);
  3736. }
  3737. }
  3738. void kick(bool _finishAll = false)
  3739. {
  3740. m_cmd.kick(_finishAll);
  3741. VK_CHECK(m_cmd.alloc(&m_commandBuffer) );
  3742. m_cmd.finish(_finishAll);
  3743. }
  3744. int32_t selectMemoryType(uint32_t _memoryTypeBits, uint32_t _propertyFlags, int32_t _startIndex = 0) const
  3745. {
  3746. for (int32_t ii = _startIndex, num = m_memoryProperties.memoryTypeCount; ii < num; ++ii)
  3747. {
  3748. const VkMemoryType& memType = m_memoryProperties.memoryTypes[ii];
  3749. if ( (0 != ( (1<<ii) & _memoryTypeBits) )
  3750. && ( (memType.propertyFlags & _propertyFlags) == _propertyFlags) )
  3751. {
  3752. return ii;
  3753. }
  3754. }
  3755. BX_TRACE("Failed to find memory that supports flags 0x%08x.", _propertyFlags);
  3756. return -1;
  3757. }
  3758. VkResult allocateMemory(const VkMemoryRequirements* requirements, VkMemoryPropertyFlags propertyFlags, DeviceMemoryAllocationVK* memory, bool _forcePrivateDeviceAllocation)
  3759. {
  3760. BGFX_PROFILER_SCOPE("RendererContextVK::allocateMemory", kColorResource);
  3761. // Forcing the use of a private device allocation for a certain memory allocation
  3762. // can be desirable when memory mapping the allocation. A memory allocation
  3763. // can only be mapped once. So handing out multiple subregions of one bigger
  3764. // allocation can lead to problems, when they get mapped multiple times.
  3765. // Right now, with the LRU system, we are still only handing out the full
  3766. // memory allocation, and never subregions of it, so it's impossible right
  3767. // now to map a single allocation multiple times.
  3768. // The argument is there to indicate this, but it's ignored right now, for the above
  3769. // reason: any cached memory is fine, as long as we don't partition it.
  3770. BX_UNUSED(_forcePrivateDeviceAllocation);
  3771. {
  3772. // Check LRU cache.
  3773. int memoryType = selectMemoryType(requirements->memoryTypeBits, propertyFlags, 0);
  3774. bool found = m_memoryLru.find(bx::narrowCast<uint32_t>(requirements->size), memoryType, memory);
  3775. if (found)
  3776. {
  3777. return VK_SUCCESS;
  3778. }
  3779. }
  3780. VkMemoryAllocateInfo ma;
  3781. ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
  3782. ma.pNext = NULL;
  3783. ma.allocationSize = requirements->size;
  3784. VkResult result = VK_ERROR_UNKNOWN;
  3785. int32_t searchIndex = -1;
  3786. do
  3787. {
  3788. searchIndex++;
  3789. searchIndex = selectMemoryType(requirements->memoryTypeBits, propertyFlags, searchIndex);
  3790. if (searchIndex >= 0)
  3791. {
  3792. BGFX_PROFILER_SCOPE("vkAllocateMemory", kColorResource);
  3793. ma.memoryTypeIndex = searchIndex;
  3794. memory->memoryTypeIndex = searchIndex;
  3795. memory->size = bx::narrowCast<uint32_t>(ma.allocationSize);
  3796. memory->offset = 0;
  3797. result = vkAllocateMemory(m_device, &ma, m_allocatorCb, &memory->mem);
  3798. }
  3799. }
  3800. while (result != VK_SUCCESS
  3801. && searchIndex >= 0);
  3802. return result;
  3803. }
  3804. VkResult createHostBuffer(uint32_t _size, VkMemoryPropertyFlags _flags, ::VkBuffer* _buffer, DeviceMemoryAllocationVK* _memory, bool _forcePrivateDeviceAllocation, const void* _data = NULL)
  3805. {
  3806. BGFX_PROFILER_SCOPE("RendererContextVK::createHostBuffer", kColorResource);
  3807. VkResult result = VK_SUCCESS;
  3808. VkBufferCreateInfo bci;
  3809. bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  3810. bci.pNext = NULL;
  3811. bci.flags = 0;
  3812. bci.size = _size;
  3813. bci.queueFamilyIndexCount = 0;
  3814. bci.pQueueFamilyIndices = NULL;
  3815. bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  3816. bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
  3817. result = vkCreateBuffer(m_device, &bci, m_allocatorCb, _buffer);
  3818. if (VK_SUCCESS != result)
  3819. {
  3820. BX_TRACE("Create host buffer error: vkCreateBuffer failed %d: %s.", result, getName(result) );
  3821. return result;
  3822. }
  3823. VkMemoryRequirements mr;
  3824. vkGetBufferMemoryRequirements(m_device, *_buffer, &mr);
  3825. result = allocateMemory(&mr, _flags, _memory, _forcePrivateDeviceAllocation);
  3826. if (VK_SUCCESS != result
  3827. && (_flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) )
  3828. {
  3829. result = allocateMemory(&mr, _flags & ~VK_MEMORY_PROPERTY_HOST_CACHED_BIT, _memory, _forcePrivateDeviceAllocation);
  3830. }
  3831. if (VK_SUCCESS != result)
  3832. {
  3833. BX_TRACE("Create host buffer error: vkAllocateMemory failed %d: %s.", result, getName(result) );
  3834. return result;
  3835. }
  3836. result = vkBindBufferMemory(m_device, *_buffer, _memory->mem, _memory->offset);
  3837. if (VK_SUCCESS != result)
  3838. {
  3839. BX_TRACE("Create host buffer error: vkBindBufferMemory failed %d: %s.", result, getName(result) );
  3840. return result;
  3841. }
  3842. if (_data != NULL)
  3843. {
  3844. BGFX_PROFILER_SCOPE("map and copy data", kColorResource);
  3845. void* dst;
  3846. result = vkMapMemory(m_device, _memory->mem, _memory->offset, _size, 0, &dst);
  3847. if (VK_SUCCESS != result)
  3848. {
  3849. BX_TRACE("Create host buffer error: vkMapMemory failed %d: %s.", result, getName(result) );
  3850. return result;
  3851. }
  3852. bx::memCopy(dst, _data, _size);
  3853. vkUnmapMemory(m_device, _memory->mem);
  3854. }
  3855. return result;
  3856. }
  3857. VkResult createStagingBuffer(uint32_t _size, ::VkBuffer* _buffer, DeviceMemoryAllocationVK* _memory, const void* _data = NULL)
  3858. {
  3859. const VkMemoryPropertyFlags flags = 0
  3860. | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
  3861. | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
  3862. ;
  3863. return createHostBuffer(_size, flags, _buffer, _memory, false, _data);
  3864. }
  3865. StagingBufferVK allocFromScratchStagingBuffer(uint32_t _size, uint32_t _align, const void* _data = NULL)
  3866. {
  3867. BGFX_PROFILER_SCOPE("RendererContextVK::allocFromScratchStagingBuffer", kColorResource);
  3868. StagingBufferVK result;
  3869. StagingScratchBufferVK& scratch = m_scratchStagingBuffer[m_cmd.m_currentFrameInFlight];
  3870. if (_size <= BGFX_CONFIG_MAX_STAGING_SCRATCH_BUFFER_SIZE)
  3871. {
  3872. const uint32_t scratchOffset = scratch.alloc(_size, _align);
  3873. if (UINT32_MAX != scratchOffset)
  3874. {
  3875. result.m_isFromScratch = true;
  3876. result.m_deviceMem = scratch.m_deviceMem;
  3877. result.m_size = _size;
  3878. result.m_offset = scratchOffset;
  3879. result.m_buffer = scratch.m_buffer;
  3880. result.m_data = scratch.m_data + result.m_offset;
  3881. if (_data != NULL)
  3882. {
  3883. BGFX_PROFILER_SCOPE("copy to scratch", kColorResource);
  3884. bx::memCopy(result.m_data, _data, _size);
  3885. }
  3886. return result;
  3887. }
  3888. }
  3889. // Not enough space or too big, we will create a new staging buffer on the spot.
  3890. VK_CHECK(createStagingBuffer(_size, &result.m_buffer, &result.m_deviceMem, _data) );
  3891. result.m_isFromScratch = false;
  3892. result.m_offset = 0;
  3893. result.m_size = _size;
  3894. result.m_data = NULL;
  3895. return result;
  3896. }
  3897. VkResult createReadbackBuffer(uint32_t _size, ::VkBuffer* _buffer, DeviceMemoryAllocationVK* _memory)
  3898. {
  3899. const VkMemoryPropertyFlags flags = 0
  3900. | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
  3901. | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
  3902. | VK_MEMORY_PROPERTY_HOST_CACHED_BIT
  3903. ;
  3904. return createHostBuffer(_size, flags, _buffer, _memory, true, NULL);
  3905. }
  3906. VkAllocationCallbacks* m_allocatorCb;
  3907. VkDebugReportCallbackEXT m_debugReportCallback;
  3908. VkInstance m_instance;
  3909. VkPhysicalDevice m_physicalDevice;
  3910. uint32_t m_instanceApiVersion;
  3911. VkPhysicalDeviceFragmentShadingRatePropertiesKHR m_deviceShadingRateImageProperties;
  3912. VkPhysicalDeviceProperties2 m_deviceProperties;
  3913. VkPhysicalDeviceMemoryProperties m_memoryProperties;
  3914. VkPhysicalDeviceFeatures m_deviceFeatures;
  3915. bool m_lineAASupport;
  3916. bool m_borderColorSupport;
  3917. bool m_timerQuerySupport;
  3918. FrameBufferVK m_backBuffer;
  3919. TextureFormat::Enum m_swapChainFormats[TextureFormat::Count];
  3920. uint16_t m_numWindows;
  3921. FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
  3922. int64_t m_presentElapsed;
  3923. MemoryLruVK m_memoryLru;
  3924. ChunkedScratchBufferVK m_uniformScratchBuffer;
  3925. StagingScratchBufferVK m_scratchStagingBuffer[BGFX_CONFIG_MAX_FRAME_LATENCY];
  3926. uint32_t m_maxFrameLatency;
  3927. CommandQueueVK m_cmd;
  3928. VkCommandBuffer m_commandBuffer;
  3929. VkDevice m_device;
  3930. uint32_t m_globalQueueFamily;
  3931. VkQueue m_globalQueue;
  3932. VkDescriptorPool m_descriptorPool[BGFX_CONFIG_MAX_FRAME_LATENCY];
  3933. VkPipelineCache m_pipelineCache;
  3934. TimerQueryVK m_gpuTimer;
  3935. OcclusionQueryVK m_occlusionQuery;
  3936. void* m_renderDocDll;
  3937. void* m_vulkan1Dll;
  3938. IndexBufferVK m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
  3939. VertexBufferVK m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
  3940. ShaderVK m_shaders[BGFX_CONFIG_MAX_SHADERS];
  3941. ProgramVK m_program[BGFX_CONFIG_MAX_PROGRAMS];
  3942. TextureVK m_textures[BGFX_CONFIG_MAX_TEXTURES];
  3943. VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS];
  3944. FrameBufferVK m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS];
  3945. void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
  3946. Matrix4 m_predefinedUniforms[PredefinedUniform::Count];
  3947. UniformRegistry m_uniformReg;
  3948. StateCacheT<VkPipeline> m_pipelineStateCache;
  3949. StateCacheT<VkDescriptorSetLayout> m_descriptorSetLayoutCache;
  3950. StateCacheT<VkRenderPass> m_renderPassCache;
  3951. StateCacheT<VkSampler> m_samplerCache;
  3952. StateCacheT<uint32_t> m_samplerBorderColorCache;
  3953. StateCacheLru<VkImageView, 1024> m_imageViewCache;
  3954. Resolution m_resolution;
  3955. float m_maxAnisotropy;
  3956. bool m_depthClamp;
  3957. bool m_wireframe;
  3958. VkBuffer m_captureBuffer;
  3959. DeviceMemoryAllocationVK m_captureMemory;
  3960. uint32_t m_captureSize;
  3961. bool m_variableRateShadingSupported;
  3962. TextVideoMem m_textVideoMem;
  3963. uint8_t m_fsScratch[64<<10];
  3964. uint8_t m_vsScratch[64<<10];
  3965. FrameBufferHandle m_fbh;
  3966. };
  3967. static RendererContextVK* s_renderVK;
  3968. RendererContextI* rendererCreate(const Init& _init)
  3969. {
  3970. s_renderVK = BX_NEW(g_allocator, RendererContextVK);
  3971. if (!s_renderVK->init(_init) )
  3972. {
  3973. bx::deleteObject(g_allocator, s_renderVK);
  3974. s_renderVK = NULL;
  3975. }
  3976. return s_renderVK;
  3977. }
  3978. void rendererDestroy()
  3979. {
  3980. s_renderVK->shutdown();
  3981. bx::deleteObject(g_allocator, s_renderVK);
  3982. s_renderVK = NULL;
  3983. }
  3984. #define VK_DESTROY_FUNC(_name) \
  3985. void vkDestroy(Vk##_name& _obj) \
  3986. { \
  3987. if (VK_NULL_HANDLE != _obj) \
  3988. { \
  3989. BGFX_PROFILER_SCOPE("vkDestroy" #_name, kColorResource); \
  3990. vkDestroy##_name(s_renderVK->m_device, _obj.vk, s_renderVK->m_allocatorCb); \
  3991. _obj = VK_NULL_HANDLE; \
  3992. } \
  3993. } \
  3994. void release(Vk##_name& _obj) \
  3995. { \
  3996. s_renderVK->release(_obj); \
  3997. }
  3998. VK_DESTROY
  3999. #undef VK_DESTROY_FUNC
  4000. void vkDestroy(VkDeviceMemory& _obj)
  4001. {
  4002. if (VK_NULL_HANDLE != _obj)
  4003. {
  4004. BGFX_PROFILER_SCOPE("vkFreeMemory", kColorResource);
  4005. vkFreeMemory(s_renderVK->m_device, _obj.vk, s_renderVK->m_allocatorCb);
  4006. _obj = VK_NULL_HANDLE;
  4007. }
  4008. }
  4009. void vkDestroy(VkSurfaceKHR& _obj)
  4010. {
  4011. if (VK_NULL_HANDLE != _obj)
  4012. {
  4013. BGFX_PROFILER_SCOPE("vkDestroySurfaceKHR", kColorResource);
  4014. vkDestroySurfaceKHR(s_renderVK->m_instance, _obj.vk, s_renderVK->m_allocatorCb);
  4015. _obj = VK_NULL_HANDLE;
  4016. }
  4017. }
  4018. void vkDestroy(VkDescriptorSet& _obj)
  4019. {
  4020. if (VK_NULL_HANDLE != _obj)
  4021. {
  4022. _obj = VK_NULL_HANDLE;
  4023. }
  4024. }
  4025. void release(VkDeviceMemory& _obj)
  4026. {
  4027. s_renderVK->release(_obj);
  4028. }
  4029. void release(VkSurfaceKHR& _obj)
  4030. {
  4031. s_renderVK->release(_obj);
  4032. }
  4033. void release(VkDescriptorSet& _obj)
  4034. {
  4035. s_renderVK->release(_obj);
  4036. }
  4037. void MemoryLruVK::recycle(DeviceMemoryAllocationVK& _alloc)
  4038. {
  4039. if (MAX_ENTRIES == lru.getNumHandles() )
  4040. {
  4041. // Evict LRU
  4042. uint16_t handle = lru.getBack();
  4043. DeviceMemoryAllocationVK& alloc = entries[handle];
  4044. totalSizeCached -= alloc.size;
  4045. release(alloc.mem);
  4046. // Touch slot and overwrite
  4047. lru.touch(handle);
  4048. alloc = _alloc;
  4049. }
  4050. else
  4051. {
  4052. uint16_t handle = lru.alloc();
  4053. entries[handle] = _alloc;
  4054. }
  4055. totalSizeCached += _alloc.size;
  4056. while (totalSizeCached > BGFX_CONFIG_CACHED_DEVICE_MEMORY_ALLOCATIONS_SIZE)
  4057. {
  4058. BX_ASSERT(lru.getNumHandles() > 0, "Memory badly counted.");
  4059. uint16_t handle = lru.getBack();
  4060. DeviceMemoryAllocationVK& alloc = entries[handle];
  4061. totalSizeCached -= alloc.size;
  4062. release(alloc.mem);
  4063. lru.free(handle);
  4064. }
  4065. }
  4066. bool MemoryLruVK::find(uint32_t _size, int32_t _memoryTypeIndex, DeviceMemoryAllocationVK *_alloc)
  4067. {
  4068. BGFX_PROFILER_SCOPE("MemoryLruVK::find", kColorResource);
  4069. // Find best fit.
  4070. uint16_t slot;
  4071. {
  4072. int16_t bestIdx = MAX_ENTRIES;
  4073. uint32_t bestWaste = 0xffff'ffff;
  4074. slot = lru.getFront();
  4075. while (UINT16_MAX != slot)
  4076. {
  4077. DeviceMemoryAllocationVK& alloc = entries[slot];
  4078. if (alloc.memoryTypeIndex == _memoryTypeIndex)
  4079. {
  4080. // 50% waste allowed, otherwise we'll just allocate a new one.
  4081. // This is to prevent we trash this cache of useful allocations
  4082. // with a handful of tiny allocations.
  4083. if (alloc.size >= _size
  4084. && alloc.size <= _size * 2)
  4085. {
  4086. const uint32_t waste = bx::narrowCast<uint32_t>(alloc.size - _size);
  4087. if (waste < bestWaste)
  4088. {
  4089. bestIdx = slot;
  4090. bestWaste = waste;
  4091. if (waste == 0)
  4092. {
  4093. break;
  4094. }
  4095. }
  4096. }
  4097. }
  4098. slot = lru.getNext(slot);
  4099. }
  4100. slot = bestIdx;
  4101. }
  4102. if (MAX_ENTRIES != slot)
  4103. {
  4104. *_alloc = entries[slot];
  4105. lru.free(slot);
  4106. totalSizeCached -= _alloc->size;
  4107. return true;
  4108. }
  4109. return false;
  4110. }
  4111. void MemoryLruVK::evictAll()
  4112. {
  4113. uint16_t slot = lru.getFront();
  4114. while (slot != UINT16_MAX)
  4115. {
  4116. release(entries[slot].mem);
  4117. slot = lru.getNext(slot);
  4118. }
  4119. lru.reset();
  4120. totalSizeCached = 0;
  4121. }
  4122. void StagingScratchBufferVK::create(uint32_t _size, uint32_t _count, VkBufferUsageFlags usage, uint32_t _align)
  4123. {
  4124. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  4125. const VkDevice device = s_renderVK->m_device;
  4126. const uint32_t entrySize = bx::strideAlign(_size, _align);
  4127. const uint32_t chunkSize = entrySize * _count;
  4128. VkBufferCreateInfo bci;
  4129. bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  4130. bci.pNext = NULL;
  4131. bci.flags = 0;
  4132. bci.size = chunkSize;
  4133. bci.usage = usage;
  4134. bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  4135. bci.queueFamilyIndexCount = 0;
  4136. bci.pQueueFamilyIndices = NULL;
  4137. VK_CHECK(vkCreateBuffer(
  4138. device
  4139. , &bci
  4140. , allocatorCb
  4141. , &m_buffer
  4142. ) );
  4143. VkMemoryRequirements mr;
  4144. vkGetBufferMemoryRequirements(
  4145. device
  4146. , m_buffer
  4147. , &mr
  4148. );
  4149. VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  4150. VkResult result = s_renderVK->allocateMemory(&mr, flags, &m_deviceMem, true);
  4151. if (VK_SUCCESS != result)
  4152. {
  4153. flags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  4154. VK_CHECK(s_renderVK->allocateMemory(&mr, flags, &m_deviceMem, true) );
  4155. }
  4156. m_size = (uint32_t)mr.size;
  4157. m_chunkPos = 0;
  4158. m_align = _align;
  4159. VK_CHECK(vkBindBufferMemory(device, m_buffer, m_deviceMem.mem, m_deviceMem.offset) );
  4160. VK_CHECK(vkMapMemory(device, m_deviceMem.mem, m_deviceMem.offset, m_size, 0, (void**)&m_data) );
  4161. }
  4162. void StagingScratchBufferVK::createUniform(uint32_t _size, uint32_t _count)
  4163. {
  4164. const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.properties.limits;
  4165. const uint32_t align = uint32_t(deviceLimits.minUniformBufferOffsetAlignment);
  4166. create(_size, _count, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, align);
  4167. }
  4168. void StagingScratchBufferVK::createStaging(uint32_t _size)
  4169. {
  4170. const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.properties.limits;
  4171. const uint32_t align = uint32_t(deviceLimits.optimalBufferCopyOffsetAlignment);
  4172. create(_size, 1, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, align);
  4173. }
  4174. void StagingScratchBufferVK::destroy()
  4175. {
  4176. vkUnmapMemory(s_renderVK->m_device, m_deviceMem.mem);
  4177. s_renderVK->release(m_buffer);
  4178. s_renderVK->recycleMemory(m_deviceMem);
  4179. }
  4180. uint32_t StagingScratchBufferVK::alloc(uint32_t _size, uint32_t _minAlign)
  4181. {
  4182. const uint32_t align = bx::uint32_lcm(m_align, _minAlign);
  4183. const uint32_t offset = bx::strideAlign(m_chunkPos, align);
  4184. if (offset + _size <= m_size)
  4185. {
  4186. m_chunkPos = offset + _size;
  4187. return offset;
  4188. }
  4189. return UINT32_MAX;
  4190. }
  4191. uint32_t StagingScratchBufferVK::write(const void* _data, uint32_t _size, uint32_t _minAlign)
  4192. {
  4193. uint32_t offset = alloc(_size, _minAlign);
  4194. BX_ASSERT(offset != UINT32_MAX, "Not enough space on ScratchBuffer left to allocate %u bytes with alignment %u.", _size, _minAlign);
  4195. if (_size > 0)
  4196. {
  4197. bx::memCopy(&m_data[offset], _data, _size);
  4198. }
  4199. return offset;
  4200. }
  4201. void StagingScratchBufferVK::flush(bool _reset)
  4202. {
  4203. const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.properties.limits;
  4204. VkDevice device = s_renderVK->m_device;
  4205. const uint32_t align = uint32_t(deviceLimits.nonCoherentAtomSize);
  4206. const uint32_t size = bx::min(bx::strideAlign(m_chunkPos, align), m_size);
  4207. VkMappedMemoryRange range;
  4208. range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
  4209. range.pNext = NULL;
  4210. range.memory = m_deviceMem.mem;
  4211. range.offset = m_deviceMem.offset;
  4212. range.size = size;
  4213. VK_CHECK(vkFlushMappedMemoryRanges(device, 1, &range) );
  4214. if (_reset)
  4215. {
  4216. m_chunkPos = 0;
  4217. }
  4218. }
  4219. void ChunkedScratchBufferVK::create(uint32_t _chunkSize, uint32_t _numChunks, VkBufferUsageFlags usage, uint32_t _align)
  4220. {
  4221. const uint32_t chunkSize = bx::alignUp(_chunkSize, 1<<20);
  4222. m_chunkPos = 0;
  4223. m_chunkSize = chunkSize;
  4224. m_align = _align;
  4225. m_usage = usage;
  4226. m_chunkControl.m_size = 0;
  4227. m_chunkControl.reset();
  4228. bx::memSet(m_consume, 0, sizeof(m_consume) );
  4229. m_totalUsed = 0;
  4230. for (uint32_t ii = 0; ii < _numChunks; ++ii)
  4231. {
  4232. addChunk();
  4233. }
  4234. }
  4235. void ChunkedScratchBufferVK::createUniform(uint32_t _chunkSize, uint32_t _numChunks)
  4236. {
  4237. const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.properties.limits;
  4238. const uint32_t align = uint32_t(deviceLimits.minUniformBufferOffsetAlignment);
  4239. create(_chunkSize, _numChunks, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, align);
  4240. }
  4241. void ChunkedScratchBufferVK::destroy()
  4242. {
  4243. for (Chunk& sbc : m_chunks)
  4244. {
  4245. vkUnmapMemory(s_renderVK->m_device, sbc.deviceMem.mem);
  4246. s_renderVK->release(sbc.buffer);
  4247. s_renderVK->recycleMemory(sbc.deviceMem);
  4248. }
  4249. }
  4250. void ChunkedScratchBufferVK::addChunk(uint32_t _at)
  4251. {
  4252. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  4253. const VkDevice device = s_renderVK->m_device;
  4254. Chunk sbc;
  4255. VkBufferCreateInfo bci =
  4256. {
  4257. .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
  4258. .pNext = NULL,
  4259. .flags = 0,
  4260. .size = m_chunkSize,
  4261. .usage = m_usage,
  4262. .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
  4263. .queueFamilyIndexCount = 0,
  4264. .pQueueFamilyIndices = NULL,
  4265. };
  4266. VK_CHECK(vkCreateBuffer(
  4267. device
  4268. , &bci
  4269. , allocatorCb
  4270. , &sbc.buffer
  4271. ) );
  4272. VkMemoryRequirements mr;
  4273. vkGetBufferMemoryRequirements(
  4274. device
  4275. , sbc.buffer
  4276. , &mr
  4277. );
  4278. VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  4279. VkResult result = s_renderVK->allocateMemory(&mr, flags, &sbc.deviceMem, true);
  4280. if (VK_SUCCESS != result)
  4281. {
  4282. flags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  4283. VK_CHECK(s_renderVK->allocateMemory(&mr, flags, &sbc.deviceMem, true) );
  4284. }
  4285. m_chunkSize = bx::narrowCast<uint32_t>(mr.size);
  4286. VK_CHECK(vkBindBufferMemory(device, sbc.buffer, sbc.deviceMem.mem, sbc.deviceMem.offset) );
  4287. VK_CHECK(vkMapMemory(device, sbc.deviceMem.mem, sbc.deviceMem.offset, m_chunkSize, 0, (void**)&sbc.data) );
  4288. const uint32_t lastChunk = bx::max(uint32_t(m_chunks.size()-1), 1);
  4289. const uint32_t at = UINT32_MAX == _at ? lastChunk : _at;
  4290. const uint32_t chunkIndex = at % bx::max(m_chunks.size(), 1);
  4291. m_chunkControl.resize(m_chunkSize);
  4292. m_chunks.insert(&m_chunks[chunkIndex], sbc);
  4293. }
  4294. ChunkedScratchBufferAlloc ChunkedScratchBufferVK::alloc(uint32_t _size)
  4295. {
  4296. BX_ASSERT(_size < m_chunkSize, "Size can't be larger than chunk size (size: %d, chunk size: %d)!", _size, m_chunkSize);
  4297. uint32_t offset = m_chunkPos;
  4298. uint32_t nextOffset = offset + _size;
  4299. uint32_t chunkIdx = m_chunkControl.m_write/m_chunkSize;
  4300. if (nextOffset >= m_chunkSize)
  4301. {
  4302. const uint32_t total = m_chunkSize - m_chunkPos + _size;
  4303. uint32_t reserved = m_chunkControl.reserve(total, true);
  4304. if (total != reserved)
  4305. {
  4306. addChunk(chunkIdx + 1);
  4307. reserved = m_chunkControl.reserve(total, true);
  4308. BX_ASSERT(total == reserved, "Failed to reserve chunk memory after adding chunk.");
  4309. }
  4310. m_chunkPos = 0;
  4311. offset = 0;
  4312. nextOffset = _size;
  4313. chunkIdx = m_chunkControl.m_write/m_chunkSize;
  4314. }
  4315. else
  4316. {
  4317. const uint32_t size = m_chunkControl.reserve(_size, true);
  4318. BX_ASSERT(size == _size, "Failed to reserve chunk memory.");
  4319. BX_UNUSED(size);
  4320. }
  4321. m_chunkPos = nextOffset;
  4322. return { .offset = offset, .chunkIdx = chunkIdx };
  4323. }
  4324. void ChunkedScratchBufferVK::write(ChunkedScratchBufferOffset& _outSbo, const void* _vsData, uint32_t _vsSize, const void* _fsData, uint32_t _fsSize)
  4325. {
  4326. const uint32_t vsSize = bx::strideAlign(_vsSize, m_align);
  4327. const uint32_t fsSize = bx::strideAlign(_fsSize, m_align);
  4328. const uint32_t size = vsSize + fsSize;
  4329. const ChunkedScratchBufferAlloc sba = alloc(size);
  4330. const uint32_t offset0 = sba.offset;
  4331. const uint32_t offset1 = offset0 + vsSize;
  4332. const Chunk& sbc = m_chunks[sba.chunkIdx];
  4333. _outSbo.buffer = sbc.buffer;
  4334. _outSbo.offsets[0] = offset0;
  4335. _outSbo.offsets[1] = offset1;
  4336. bx::memCopy(&sbc.data[offset0], _vsData, _vsSize);
  4337. bx::memCopy(&sbc.data[offset1], _fsData, _fsSize);
  4338. }
  4339. void ChunkedScratchBufferVK::begin()
  4340. {
  4341. BX_ASSERT(0 == m_chunkPos, "");
  4342. const uint32_t numConsumed = m_consume[s_renderVK->m_cmd.m_currentFrameInFlight];
  4343. m_chunkControl.consume(numConsumed);
  4344. }
  4345. void ChunkedScratchBufferVK::end()
  4346. {
  4347. uint32_t numFlush = m_chunkControl.getNumReserved();
  4348. if (0 != m_chunkPos)
  4349. {
  4350. retry:
  4351. const uint32_t remainder = m_chunkSize - m_chunkPos;
  4352. const uint32_t rem = m_chunkControl.reserve(remainder, true);
  4353. if (rem != remainder)
  4354. {
  4355. const uint32_t chunkIdx = m_chunkControl.m_write/m_chunkSize;
  4356. addChunk(chunkIdx + 1);
  4357. goto retry;
  4358. }
  4359. m_chunkPos = 0;
  4360. }
  4361. const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.properties.limits;
  4362. const uint32_t align = uint32_t(deviceLimits.nonCoherentAtomSize);
  4363. VkDevice device = s_renderVK->m_device;
  4364. const uint32_t numReserved = m_chunkControl.getNumReserved();
  4365. BX_ASSERT(0 == numReserved % m_chunkSize, "Number of reserved must always be aligned to chunk size!");
  4366. const uint32_t first = m_chunkControl.m_current / m_chunkSize;
  4367. for (uint32_t ii = first, end = numReserved / m_chunkSize + first; ii < end; ++ii)
  4368. {
  4369. const Chunk& chunk = m_chunks[ii % m_chunks.size()];
  4370. VkMappedMemoryRange range;
  4371. range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
  4372. range.pNext = NULL;
  4373. range.memory = chunk.deviceMem.mem;
  4374. range.offset = chunk.deviceMem.offset;
  4375. range.size = bx::alignUp(bx::min(numFlush, m_chunkSize), align);
  4376. VK_CHECK(vkFlushMappedMemoryRanges(device, 1, &range) );
  4377. m_chunkControl.commit(m_chunkSize);
  4378. numFlush -= m_chunkSize;
  4379. }
  4380. m_consume[s_renderVK->m_cmd.m_currentFrameInFlight] = numReserved;
  4381. m_totalUsed = m_chunkControl.getNumUsed();
  4382. }
  4383. void BufferVK::create(VkCommandBuffer _commandBuffer, uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride)
  4384. {
  4385. BX_UNUSED(_stride);
  4386. m_size = _size;
  4387. m_flags = _flags;
  4388. m_dynamic = NULL == _data;
  4389. const bool storage = m_flags & BGFX_BUFFER_COMPUTE_READ_WRITE;
  4390. const bool indirect = m_flags & BGFX_BUFFER_DRAW_INDIRECT;
  4391. VkBufferCreateInfo bci;
  4392. bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  4393. bci.pNext = NULL;
  4394. bci.flags = 0;
  4395. bci.size = _size;
  4396. bci.usage = 0
  4397. | (_vertex ? VK_BUFFER_USAGE_VERTEX_BUFFER_BIT : VK_BUFFER_USAGE_INDEX_BUFFER_BIT)
  4398. | (storage || indirect ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : 0)
  4399. | (indirect ? VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT : 0)
  4400. | VK_BUFFER_USAGE_TRANSFER_DST_BIT
  4401. ;
  4402. bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  4403. bci.queueFamilyIndexCount = 0;
  4404. bci.pQueueFamilyIndices = NULL;
  4405. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  4406. const VkDevice device = s_renderVK->m_device;
  4407. VK_CHECK(vkCreateBuffer(device, &bci, allocatorCb, &m_buffer) );
  4408. VkMemoryRequirements mr;
  4409. vkGetBufferMemoryRequirements(device, m_buffer, &mr);
  4410. VK_CHECK(s_renderVK->allocateMemory(&mr, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &m_deviceMem, false) );
  4411. VK_CHECK(vkBindBufferMemory(device, m_buffer, m_deviceMem.mem, m_deviceMem.offset) );
  4412. if (!m_dynamic)
  4413. {
  4414. update(_commandBuffer, 0, _size, _data);
  4415. }
  4416. }
  4417. void BufferVK::update(VkCommandBuffer _commandBuffer, uint32_t _offset, uint32_t _size, void* _data, bool _discard)
  4418. {
  4419. BGFX_PROFILER_SCOPE("BufferVK::update", kColorFrame);
  4420. BX_UNUSED(_discard);
  4421. StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(_size, 16, _data);
  4422. VkBufferCopy region;
  4423. region.srcOffset = stagingBuffer.m_offset;
  4424. region.dstOffset = _offset;
  4425. region.size = _size;
  4426. vkCmdCopyBuffer(_commandBuffer, stagingBuffer.m_buffer, m_buffer, 1, &region);
  4427. setMemoryBarrier(
  4428. _commandBuffer
  4429. , VK_PIPELINE_STAGE_TRANSFER_BIT
  4430. , VK_PIPELINE_STAGE_TRANSFER_BIT
  4431. );
  4432. if (!stagingBuffer.m_isFromScratch)
  4433. {
  4434. s_renderVK->release(stagingBuffer.m_buffer);
  4435. s_renderVK->recycleMemory(stagingBuffer.m_deviceMem);
  4436. }
  4437. }
  4438. void BufferVK::destroy()
  4439. {
  4440. if (VK_NULL_HANDLE != m_buffer)
  4441. {
  4442. s_renderVK->release(m_buffer);
  4443. s_renderVK->recycleMemory(m_deviceMem);
  4444. m_dynamic = false;
  4445. }
  4446. }
  4447. void VertexBufferVK::create(VkCommandBuffer _commandBuffer, uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle, uint16_t _flags)
  4448. {
  4449. BufferVK::create(_commandBuffer, _size, _data, _flags, true);
  4450. m_layoutHandle = _layoutHandle;
  4451. }
  4452. void ShaderVK::create(const Memory* _mem)
  4453. {
  4454. bx::MemoryReader reader(_mem->data, _mem->size);
  4455. bx::ErrorAssert err;
  4456. uint32_t magic;
  4457. bx::read(&reader, magic, &err);
  4458. VkShaderStageFlagBits shaderStage = VK_SHADER_STAGE_ALL;
  4459. if (isShaderType(magic, 'C') )
  4460. {
  4461. shaderStage = VK_SHADER_STAGE_COMPUTE_BIT;
  4462. }
  4463. else if (isShaderType(magic, 'F') )
  4464. {
  4465. shaderStage = VK_SHADER_STAGE_FRAGMENT_BIT;
  4466. }
  4467. else if (isShaderType(magic, 'V') )
  4468. {
  4469. shaderStage = VK_SHADER_STAGE_VERTEX_BIT;
  4470. }
  4471. const bool fragment = isShaderType(magic, 'F');
  4472. uint32_t hashIn;
  4473. bx::read(&reader, hashIn, &err);
  4474. uint32_t hashOut;
  4475. if (isShaderVerLess(magic, 6) )
  4476. {
  4477. hashOut = hashIn;
  4478. }
  4479. else
  4480. {
  4481. bx::read(&reader, hashOut, &err);
  4482. }
  4483. uint16_t count;
  4484. bx::read(&reader, count, &err);
  4485. m_numPredefined = 0;
  4486. m_numUniforms = count;
  4487. m_numTextures = 0;
  4488. m_oldBindingModel = isShaderVerLess(magic, 11);
  4489. BX_TRACE("%s Shader consts %d"
  4490. , getShaderTypeName(magic)
  4491. , count
  4492. );
  4493. uint8_t fragmentBit = fragment ? kUniformFragmentBit : 0;
  4494. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++ii)
  4495. {
  4496. m_bindInfo[ii].uniformHandle = BGFX_INVALID_HANDLE;
  4497. m_bindInfo[ii].type = BindType::Count;
  4498. m_bindInfo[ii].binding = 0;
  4499. m_bindInfo[ii].samplerBinding = 0;
  4500. m_bindInfo[ii].index = UINT32_MAX;
  4501. }
  4502. if (0 < count)
  4503. {
  4504. for (uint32_t ii = 0; ii < count; ++ii)
  4505. {
  4506. uint8_t nameSize = 0;
  4507. bx::read(&reader, nameSize, &err);
  4508. char name[256];
  4509. bx::read(&reader, &name, nameSize, &err);
  4510. name[nameSize] = '\0';
  4511. uint8_t type = 0;
  4512. bx::read(&reader, type, &err);
  4513. uint8_t num;
  4514. bx::read(&reader, num, &err);
  4515. uint16_t regIndex;
  4516. bx::read(&reader, regIndex, &err);
  4517. uint16_t regCount;
  4518. bx::read(&reader, regCount, &err);
  4519. const bool hasTexData = !isShaderVerLess(magic, 8);
  4520. const bool hasTexFormat = !isShaderVerLess(magic, 10);
  4521. uint8_t texComponent = 0;
  4522. uint8_t texDimension = 0;
  4523. uint16_t texFormat = 0;
  4524. if (hasTexData)
  4525. {
  4526. bx::read(&reader, texComponent, &err);
  4527. bx::read(&reader, texDimension, &err);
  4528. }
  4529. if (hasTexFormat)
  4530. {
  4531. bx::read(&reader, texFormat, &err);
  4532. }
  4533. const char* kind = "invalid";
  4534. BX_UNUSED(num, texComponent, texFormat);
  4535. auto textureDimensionToViewType = [](TextureDimension::Enum dimension)
  4536. {
  4537. switch (dimension)
  4538. {
  4539. case TextureDimension::Dimension1D: return VK_IMAGE_VIEW_TYPE_1D;
  4540. case TextureDimension::Dimension2D: return VK_IMAGE_VIEW_TYPE_2D;
  4541. case TextureDimension::Dimension2DArray: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
  4542. case TextureDimension::DimensionCube: return VK_IMAGE_VIEW_TYPE_CUBE;
  4543. case TextureDimension::DimensionCubeArray: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
  4544. case TextureDimension::Dimension3D: return VK_IMAGE_VIEW_TYPE_3D;
  4545. default: return VK_IMAGE_VIEW_TYPE_MAX_ENUM;
  4546. }
  4547. };
  4548. if (UINT16_MAX != regIndex)
  4549. {
  4550. PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
  4551. if (PredefinedUniform::Count != predefined)
  4552. {
  4553. kind = "predefined";
  4554. m_predefined[m_numPredefined].m_loc = regIndex;
  4555. m_predefined[m_numPredefined].m_count = regCount;
  4556. m_predefined[m_numPredefined].m_type = uint8_t(predefined|fragmentBit);
  4557. m_numPredefined++;
  4558. }
  4559. else if (UniformType::End == (~kUniformMask & type) )
  4560. {
  4561. // regCount is used for descriptor type
  4562. const bool isBuffer = idToDescriptorType(regCount) == DescriptorType::StorageBuffer;
  4563. if (0 == regIndex)
  4564. {
  4565. continue;
  4566. }
  4567. const uint8_t reverseShift = m_oldBindingModel
  4568. ? (fragment ? kSpirvOldFragmentShift : 0) + (isBuffer ? kSpirvOldBufferShift : kSpirvOldImageShift)
  4569. : kSpirvBindShift;
  4570. const uint16_t stage = regIndex - reverseShift; // regIndex is used for buffer binding index
  4571. m_bindInfo[stage].type = isBuffer ? BindType::Buffer : BindType::Image;
  4572. m_bindInfo[stage].uniformHandle = { 0 };
  4573. m_bindInfo[stage].binding = regIndex;
  4574. if (!isBuffer)
  4575. {
  4576. const VkImageViewType viewType = hasTexData
  4577. ? textureDimensionToViewType(idToTextureDimension(texDimension) )
  4578. : VK_IMAGE_VIEW_TYPE_MAX_ENUM
  4579. ;
  4580. if (VK_IMAGE_VIEW_TYPE_MAX_ENUM != viewType)
  4581. {
  4582. m_bindInfo[stage].index = m_numTextures;
  4583. m_textures[m_numTextures].type = viewType;
  4584. m_numTextures++;
  4585. }
  4586. }
  4587. kind = "storage";
  4588. }
  4589. else if (UniformType::Sampler == (~kUniformMask & type) )
  4590. {
  4591. const uint8_t reverseShift = m_oldBindingModel
  4592. ? (fragment ? kSpirvOldFragmentShift : 0) + kSpirvOldTextureShift
  4593. : kSpirvBindShift;
  4594. const uint16_t stage = regIndex - reverseShift; // regIndex is used for image/sampler binding index
  4595. const UniformRegInfo* info = s_renderVK->m_uniformReg.find(name);
  4596. BX_ASSERT(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
  4597. m_bindInfo[stage].uniformHandle = info->m_handle;
  4598. m_bindInfo[stage].type = BindType::Sampler;
  4599. m_bindInfo[stage].binding = regIndex;
  4600. m_bindInfo[stage].samplerBinding = regIndex + kSpirvSamplerShift;
  4601. const VkImageViewType viewType = hasTexData
  4602. ? textureDimensionToViewType(idToTextureDimension(texDimension) )
  4603. : VK_IMAGE_VIEW_TYPE_MAX_ENUM
  4604. ;
  4605. if (VK_IMAGE_VIEW_TYPE_MAX_ENUM != viewType)
  4606. {
  4607. m_bindInfo[stage].index = m_numTextures;
  4608. m_textures[m_numTextures].type = viewType;
  4609. m_numTextures++;
  4610. }
  4611. kind = "sampler";
  4612. }
  4613. else
  4614. {
  4615. const UniformRegInfo* info = s_renderVK->m_uniformReg.find(name);
  4616. BX_ASSERT(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
  4617. if (NULL != info)
  4618. {
  4619. if (NULL == m_constantBuffer)
  4620. {
  4621. m_constantBuffer = UniformBuffer::create(1024);
  4622. }
  4623. kind = "user";
  4624. m_constantBuffer->writeUniformHandle(type|fragmentBit, regIndex, info->m_handle, regCount);
  4625. }
  4626. }
  4627. }
  4628. BX_TRACE("\t%s: %s (%s), r.index %3d, r.count %2d, r.texComponent %1d, r.texDimension %1d"
  4629. , kind
  4630. , name
  4631. , getUniformTypeName(UniformType::Enum(type&~kUniformMask) )
  4632. , regIndex
  4633. , regCount
  4634. , texComponent
  4635. , texDimension
  4636. );
  4637. BX_UNUSED(kind);
  4638. }
  4639. if (NULL != m_constantBuffer)
  4640. {
  4641. m_constantBuffer->finish();
  4642. }
  4643. }
  4644. uint32_t shaderSize;
  4645. bx::read(&reader, shaderSize, &err);
  4646. const void* code = reader.getDataPtr();
  4647. bx::skip(&reader, shaderSize+1);
  4648. m_code = alloc(shaderSize);
  4649. bx::memCopy(m_code->data, code, shaderSize);
  4650. VkShaderModuleCreateInfo smci;
  4651. smci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
  4652. smci.pNext = NULL;
  4653. smci.flags = 0;
  4654. smci.codeSize = m_code->size;
  4655. smci.pCode = (const uint32_t*)m_code->data;
  4656. BX_TRACE("%x", bx::hash<bx::HashMurmur3>(code, shaderSize) );
  4657. VK_CHECK(vkCreateShaderModule(
  4658. s_renderVK->m_device
  4659. , &smci
  4660. , s_renderVK->m_allocatorCb
  4661. , &m_module
  4662. ) );
  4663. bx::memSet(m_attrMask, 0, sizeof(m_attrMask) );
  4664. bx::memSet(m_attrRemap, 0, sizeof(m_attrRemap) );
  4665. bx::read(&reader, m_numAttrs, &err);
  4666. for (uint8_t ii = 0; ii < m_numAttrs; ++ii)
  4667. {
  4668. uint16_t id;
  4669. bx::read(&reader, id, &err);
  4670. Attrib::Enum attr = idToAttrib(id);
  4671. if (Attrib::Count != attr)
  4672. {
  4673. m_attrMask[attr] = UINT16_MAX;
  4674. m_attrRemap[attr] = ii;
  4675. }
  4676. }
  4677. bx::HashMurmur2A murmur;
  4678. murmur.begin();
  4679. murmur.add(hashIn);
  4680. murmur.add(hashOut);
  4681. murmur.add(m_code->data, m_code->size);
  4682. murmur.add(m_numAttrs);
  4683. murmur.add(m_attrMask, m_numAttrs);
  4684. murmur.add(m_attrRemap, m_numAttrs);
  4685. m_hash = murmur.end();
  4686. bx::read(&reader, m_size, &err);
  4687. // fill binding description with uniform information
  4688. uint16_t bidx = 0;
  4689. if (m_size > 0)
  4690. {
  4691. m_uniformBinding = fragment ? (m_oldBindingModel ? kSpirvOldFragmentBinding : kSpirvFragmentBinding) : 0;
  4692. VkDescriptorSetLayoutBinding& binding = m_bindings[bidx];
  4693. binding.stageFlags = shaderStage;
  4694. binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  4695. binding.binding = m_uniformBinding;
  4696. binding.pImmutableSamplers = NULL;
  4697. binding.descriptorCount = 1;
  4698. bidx++;
  4699. }
  4700. for (uint32_t ii = 0; ii < BX_COUNTOF(m_bindInfo); ++ii)
  4701. {
  4702. switch (m_bindInfo[ii].type)
  4703. {
  4704. case BindType::Buffer:
  4705. case BindType::Image:
  4706. {
  4707. VkDescriptorSetLayoutBinding& binding = m_bindings[bidx];
  4708. binding.stageFlags = shaderStage;
  4709. binding.descriptorType = BindType::Buffer == m_bindInfo[ii].type
  4710. ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
  4711. : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
  4712. ;
  4713. binding.binding = m_bindInfo[ii].binding;
  4714. binding.pImmutableSamplers = NULL;
  4715. binding.descriptorCount = 1;
  4716. bidx++;
  4717. }
  4718. break;
  4719. case BindType::Sampler:
  4720. {
  4721. VkDescriptorSetLayoutBinding& textureBinding = m_bindings[bidx];
  4722. textureBinding.stageFlags = shaderStage;
  4723. textureBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
  4724. textureBinding.binding = m_bindInfo[ii].binding;
  4725. textureBinding.pImmutableSamplers = NULL;
  4726. textureBinding.descriptorCount = 1;
  4727. bidx++;
  4728. VkDescriptorSetLayoutBinding& samplerBinding = m_bindings[bidx];
  4729. samplerBinding.stageFlags = shaderStage;
  4730. samplerBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
  4731. samplerBinding.binding = m_bindInfo[ii].samplerBinding;
  4732. samplerBinding.pImmutableSamplers = NULL;
  4733. samplerBinding.descriptorCount = 1;
  4734. bidx++;
  4735. }
  4736. break;
  4737. default:
  4738. break;
  4739. }
  4740. }
  4741. m_numBindings = bidx;
  4742. }
  4743. void ShaderVK::destroy()
  4744. {
  4745. if (NULL != m_constantBuffer)
  4746. {
  4747. UniformBuffer::destroy(m_constantBuffer);
  4748. m_constantBuffer = NULL;
  4749. }
  4750. m_numPredefined = 0;
  4751. if (NULL != m_code)
  4752. {
  4753. release(m_code);
  4754. m_code = NULL;
  4755. m_hash = 0;
  4756. }
  4757. if (VK_NULL_HANDLE != m_module)
  4758. {
  4759. vkDestroy(m_module);
  4760. }
  4761. }
  4762. void ProgramVK::create(const ShaderVK* _vsh, const ShaderVK* _fsh)
  4763. {
  4764. BX_ASSERT(NULL != _vsh->m_code, "Vertex shader doesn't exist.");
  4765. m_vsh = _vsh;
  4766. bx::memCopy(
  4767. &m_predefined[0]
  4768. , _vsh->m_predefined
  4769. , _vsh->m_numPredefined * sizeof(PredefinedUniform)
  4770. );
  4771. m_numPredefined = _vsh->m_numPredefined;
  4772. if (NULL != _fsh)
  4773. {
  4774. BX_ASSERT(NULL != _fsh->m_code, "Fragment shader doesn't exist.");
  4775. m_fsh = _fsh;
  4776. bx::memCopy(
  4777. &m_predefined[m_numPredefined]
  4778. , _fsh->m_predefined
  4779. , _fsh->m_numPredefined * sizeof(PredefinedUniform)
  4780. );
  4781. m_numPredefined += _fsh->m_numPredefined;
  4782. }
  4783. m_numTextures = 0;
  4784. for (uint8_t stage = 0; stage < BX_COUNTOF(m_bindInfo); ++stage)
  4785. {
  4786. const ShaderVK* shader = NULL;
  4787. if (isValid(m_vsh->m_bindInfo[stage].uniformHandle) )
  4788. {
  4789. shader = _vsh;
  4790. BX_ASSERT(false
  4791. || NULL == m_fsh
  4792. || !isValid(m_fsh->m_bindInfo[stage].uniformHandle)
  4793. || !(m_vsh->m_oldBindingModel || m_fsh->m_oldBindingModel)
  4794. , "Shared vertex/fragment bindings require shader binary version >= 11."
  4795. );
  4796. }
  4797. else if (NULL != m_fsh
  4798. && isValid(m_fsh->m_bindInfo[stage].uniformHandle) )
  4799. {
  4800. shader = _fsh;
  4801. }
  4802. if (NULL != shader)
  4803. {
  4804. m_bindInfo[stage] = shader->m_bindInfo[stage];
  4805. uint32_t& index = m_bindInfo[stage].index;
  4806. if (UINT32_MAX != index)
  4807. {
  4808. m_textures[m_numTextures] = shader->m_textures[index];
  4809. index = m_numTextures;
  4810. m_numTextures++;
  4811. }
  4812. }
  4813. }
  4814. // create exact pipeline layout
  4815. m_descriptorSetLayout = VK_NULL_HANDLE;
  4816. uint32_t numBindings = m_vsh->m_numBindings + (m_fsh ? m_fsh->m_numBindings : 0);
  4817. if (0 < numBindings)
  4818. {
  4819. // generate descriptor set layout hash
  4820. bx::HashMurmur2A murmur;
  4821. murmur.begin();
  4822. murmur.add(m_vsh->m_bindings, sizeof(VkDescriptorSetLayoutBinding) * m_vsh->m_numBindings);
  4823. if (NULL != m_fsh)
  4824. {
  4825. murmur.add(m_fsh->m_bindings, sizeof(VkDescriptorSetLayoutBinding) * m_fsh->m_numBindings);
  4826. }
  4827. uint32_t descriptorSetLayoutHash = murmur.end();
  4828. m_descriptorSetLayout = s_renderVK->m_descriptorSetLayoutCache.find(descriptorSetLayoutHash);
  4829. if (VK_NULL_HANDLE == m_descriptorSetLayout)
  4830. {
  4831. VkDescriptorSetLayoutBinding bindings[2 * BX_COUNTOF(ShaderVK::m_bindings)];
  4832. bx::memCopy(
  4833. bindings
  4834. , m_vsh->m_bindings
  4835. , sizeof(VkDescriptorSetLayoutBinding) * m_vsh->m_numBindings
  4836. );
  4837. numBindings = m_vsh->m_numBindings;
  4838. if (NULL != m_fsh)
  4839. {
  4840. for (uint16_t ii = 0; ii < m_fsh->m_numBindings; ++ii)
  4841. {
  4842. const VkDescriptorSetLayoutBinding& fsBinding = m_fsh->m_bindings[ii];
  4843. uint16_t vsBindingIdx = UINT16_MAX;
  4844. for (uint16_t jj = 0; jj < m_vsh->m_numBindings; jj++)
  4845. {
  4846. if (fsBinding.binding == bindings[jj].binding)
  4847. {
  4848. vsBindingIdx = jj;
  4849. break;
  4850. }
  4851. }
  4852. if (UINT16_MAX != vsBindingIdx)
  4853. {
  4854. BX_ASSERT(
  4855. bindings[vsBindingIdx].descriptorType == fsBinding.descriptorType
  4856. , "Mismatching descriptor types. Shaders compiled with different versions of shaderc?"
  4857. );
  4858. bindings[vsBindingIdx].stageFlags |= fsBinding.stageFlags;
  4859. }
  4860. else
  4861. {
  4862. bindings[numBindings] = fsBinding;
  4863. numBindings++;
  4864. }
  4865. }
  4866. }
  4867. VkDescriptorSetLayoutCreateInfo dslci;
  4868. dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
  4869. dslci.pNext = NULL;
  4870. dslci.flags = 0;
  4871. dslci.bindingCount = numBindings;
  4872. dslci.pBindings = bindings;
  4873. VK_CHECK(vkCreateDescriptorSetLayout(
  4874. s_renderVK->m_device
  4875. , &dslci
  4876. , s_renderVK->m_allocatorCb
  4877. , &m_descriptorSetLayout
  4878. ) );
  4879. s_renderVK->m_descriptorSetLayoutCache.add(descriptorSetLayoutHash, m_descriptorSetLayout);
  4880. }
  4881. }
  4882. VkPipelineLayoutCreateInfo plci;
  4883. plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
  4884. plci.pNext = NULL;
  4885. plci.flags = 0;
  4886. plci.pushConstantRangeCount = 0;
  4887. plci.pPushConstantRanges = NULL;
  4888. plci.setLayoutCount = (m_descriptorSetLayout == VK_NULL_HANDLE ? 0 : 1);
  4889. plci.pSetLayouts = &m_descriptorSetLayout;
  4890. VK_CHECK(vkCreatePipelineLayout(
  4891. s_renderVK->m_device
  4892. , &plci
  4893. , s_renderVK->m_allocatorCb
  4894. , &m_pipelineLayout
  4895. ) );
  4896. }
  4897. void ProgramVK::destroy()
  4898. {
  4899. s_renderVK->release(m_pipelineLayout);
  4900. m_numPredefined = 0;
  4901. m_vsh = NULL;
  4902. m_fsh = NULL;
  4903. }
  4904. VkResult TimerQueryVK::init()
  4905. {
  4906. BGFX_PROFILER_SCOPE("TimerQueryVK::init", kColorFrame);
  4907. VkResult result = VK_SUCCESS;
  4908. const VkDevice device = s_renderVK->m_device;
  4909. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4910. const uint32_t count = m_control.m_size * 2;
  4911. VkQueryPoolCreateInfo qpci;
  4912. qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
  4913. qpci.pNext = NULL;
  4914. qpci.flags = 0;
  4915. qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
  4916. qpci.queryCount = count;
  4917. qpci.pipelineStatistics = 0;
  4918. result = vkCreateQueryPool(device, &qpci, s_renderVK->m_allocatorCb, &m_queryPool);
  4919. if (VK_SUCCESS != result)
  4920. {
  4921. BX_TRACE("Create timer query error: vkCreateQueryPool failed %d: %s.", result, getName(result) );
  4922. return result;
  4923. }
  4924. vkCmdResetQueryPool(commandBuffer, m_queryPool, 0, count);
  4925. const uint32_t size = count * sizeof(uint64_t);
  4926. result = s_renderVK->createReadbackBuffer(size, &m_readback, &m_readbackMemory);
  4927. if (VK_SUCCESS != result)
  4928. {
  4929. return result;
  4930. }
  4931. result = vkMapMemory(device, m_readbackMemory.mem, m_readbackMemory.offset, VK_WHOLE_SIZE, 0, (void**)&m_queryResult);
  4932. if (VK_SUCCESS != result)
  4933. {
  4934. BX_TRACE("Create timer query error: vkMapMemory failed %d: %s.", result, getName(result) );
  4935. return result;
  4936. }
  4937. m_frequency = uint64_t(1000000000.0 / double(s_renderVK->m_deviceProperties.properties.limits.timestampPeriod) );
  4938. for (uint32_t ii = 0; ii < BX_COUNTOF(m_result); ++ii)
  4939. {
  4940. m_result[ii].reset();
  4941. }
  4942. m_control.reset();
  4943. return result;
  4944. }
  4945. void TimerQueryVK::shutdown()
  4946. {
  4947. vkDestroy(m_queryPool);
  4948. vkDestroy(m_readback);
  4949. vkUnmapMemory(s_renderVK->m_device, m_readbackMemory.mem);
  4950. s_renderVK->recycleMemory(m_readbackMemory);
  4951. }
  4952. uint32_t TimerQueryVK::begin(uint32_t _resultIdx, uint32_t _frameNum)
  4953. {
  4954. BGFX_PROFILER_SCOPE("TimerQueryVK::begin", kColorFrame);
  4955. while (0 == m_control.reserve(1) )
  4956. {
  4957. m_control.consume(1);
  4958. }
  4959. Result& result = m_result[_resultIdx];
  4960. ++result.m_pending;
  4961. const uint32_t idx = m_control.m_current;
  4962. Query& query = m_query[idx];
  4963. query.m_resultIdx = _resultIdx;
  4964. query.m_ready = false;
  4965. query.m_frameNum = _frameNum;
  4966. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4967. const uint32_t offset = idx * 2 + 0;
  4968. vkCmdResetQueryPool(commandBuffer, m_queryPool, offset, 2);
  4969. vkCmdWriteTimestamp(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, m_queryPool, offset + 0);
  4970. m_control.commit(1);
  4971. return idx;
  4972. }
  4973. void TimerQueryVK::end(uint32_t _idx)
  4974. {
  4975. BGFX_PROFILER_SCOPE("TimerQueryVK::end", kColorFrame);
  4976. Query& query = m_query[_idx];
  4977. query.m_ready = true;
  4978. query.m_completed = s_renderVK->m_cmd.m_submitted + s_renderVK->m_maxFrameLatency;
  4979. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4980. const uint32_t offset = _idx * 2 + 0;
  4981. vkCmdWriteTimestamp(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, m_queryPool, offset + 1);
  4982. vkCmdCopyQueryPoolResults(
  4983. commandBuffer
  4984. , m_queryPool
  4985. , offset
  4986. , 2
  4987. , m_readback
  4988. , offset * sizeof(uint64_t)
  4989. , sizeof(uint64_t)
  4990. , VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT
  4991. );
  4992. setMemoryBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT);
  4993. while (update() )
  4994. {
  4995. }
  4996. }
  4997. bool TimerQueryVK::update()
  4998. {
  4999. if (0 != m_control.getNumUsed() )
  5000. {
  5001. uint32_t idx = m_control.m_read;
  5002. Query& query = m_query[idx];
  5003. if (!query.m_ready)
  5004. {
  5005. return false;
  5006. }
  5007. if (query.m_completed > s_renderVK->m_cmd.m_submitted)
  5008. {
  5009. return false;
  5010. }
  5011. m_control.consume(1);
  5012. Result& result = m_result[query.m_resultIdx];
  5013. --result.m_pending;
  5014. result.m_frameNum = query.m_frameNum;
  5015. uint32_t offset = idx * 2;
  5016. result.m_begin = m_queryResult[offset+0];
  5017. result.m_end = m_queryResult[offset+1];
  5018. return true;
  5019. }
  5020. return false;
  5021. }
  5022. VkResult OcclusionQueryVK::init()
  5023. {
  5024. BGFX_PROFILER_SCOPE("OcclusionQueryVK::init", kColorFrame);
  5025. VkResult result = VK_SUCCESS;
  5026. const VkDevice device = s_renderVK->m_device;
  5027. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  5028. const uint32_t count = BX_COUNTOF(m_handle);
  5029. VkQueryPoolCreateInfo qpci;
  5030. qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
  5031. qpci.pNext = NULL;
  5032. qpci.flags = 0;
  5033. qpci.queryType = VK_QUERY_TYPE_OCCLUSION;
  5034. qpci.queryCount = count;
  5035. qpci.pipelineStatistics = 0;
  5036. result = vkCreateQueryPool(device, &qpci, s_renderVK->m_allocatorCb, &m_queryPool);
  5037. if (VK_SUCCESS != result)
  5038. {
  5039. BX_TRACE("Create occlusion query error: vkCreateQueryPool failed %d: %s.", result, getName(result) );
  5040. return result;
  5041. }
  5042. vkCmdResetQueryPool(commandBuffer, m_queryPool, 0, count);
  5043. const uint32_t size = count * sizeof(uint32_t);
  5044. result = s_renderVK->createReadbackBuffer(size, &m_readback, &m_readbackMemory);
  5045. if (VK_SUCCESS != result)
  5046. {
  5047. return result;
  5048. }
  5049. result = vkMapMemory(device, m_readbackMemory.mem, m_readbackMemory.offset, VK_WHOLE_SIZE, 0, (void**)&m_queryResult);
  5050. if (VK_SUCCESS != result)
  5051. {
  5052. BX_TRACE("Create occlusion query error: vkMapMemory failed %d: %s.", result, getName(result) );
  5053. return result;
  5054. }
  5055. m_control.reset();
  5056. return result;
  5057. }
  5058. void OcclusionQueryVK::shutdown()
  5059. {
  5060. vkDestroy(m_queryPool);
  5061. vkDestroy(m_readback);
  5062. vkUnmapMemory(s_renderVK->m_device, m_readbackMemory.mem);
  5063. s_renderVK->recycleMemory(m_readbackMemory);
  5064. }
  5065. void OcclusionQueryVK::begin(OcclusionQueryHandle _handle)
  5066. {
  5067. BGFX_PROFILER_SCOPE("OcclusionQueryVK::shutdown", kColorFrame);
  5068. m_control.reserve(1);
  5069. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  5070. m_handle[m_control.m_current] = _handle;
  5071. vkCmdBeginQuery(commandBuffer, m_queryPool, _handle.idx, 0);
  5072. }
  5073. void OcclusionQueryVK::end()
  5074. {
  5075. BGFX_PROFILER_SCOPE("OcclusionQueryVK::end", kColorFrame);
  5076. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  5077. const OcclusionQueryHandle handle = m_handle[m_control.m_current];
  5078. vkCmdEndQuery(commandBuffer, m_queryPool, handle.idx);
  5079. m_control.commit(1);
  5080. }
  5081. void OcclusionQueryVK::flush(Frame* _render)
  5082. {
  5083. BGFX_PROFILER_SCOPE("OcclusionQueryVK::flush", kColorFrame);
  5084. if (0 < m_control.getNumUsed() )
  5085. {
  5086. VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  5087. const uint32_t size = m_control.m_size;
  5088. // need to copy each result individually because VK_QUERY_RESULT_WAIT_BIT causes
  5089. // vkWaitForFences to hang indefinitely if we copy all results (including unavailable ones)
  5090. for (uint32_t ii = 0, num = m_control.getNumUsed(); ii < num; ++ii)
  5091. {
  5092. const OcclusionQueryHandle& handle = m_handle[(m_control.m_read + ii) % size];
  5093. if (isValid(handle) )
  5094. {
  5095. vkCmdCopyQueryPoolResults(
  5096. commandBuffer
  5097. , m_queryPool
  5098. , handle.idx
  5099. , 1
  5100. , m_readback
  5101. , handle.idx * sizeof(uint32_t)
  5102. , sizeof(uint32_t)
  5103. , VK_QUERY_RESULT_WAIT_BIT
  5104. );
  5105. }
  5106. }
  5107. setMemoryBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT);
  5108. s_renderVK->kick(true);
  5109. commandBuffer = s_renderVK->m_commandBuffer;
  5110. // resetting in the new command buffer prevents a false positive validation layer error
  5111. const uint32_t count = BX_COUNTOF(m_handle);
  5112. vkCmdResetQueryPool(commandBuffer, m_queryPool, 0, count);
  5113. resolve(_render);
  5114. }
  5115. }
  5116. void OcclusionQueryVK::resolve(Frame* _render)
  5117. {
  5118. while (0 != m_control.getNumUsed() )
  5119. {
  5120. OcclusionQueryHandle handle = m_handle[m_control.m_read];
  5121. if (isValid(handle) )
  5122. {
  5123. _render->m_occlusion[handle.idx] = m_queryResult[handle.idx];
  5124. }
  5125. m_control.consume(1);
  5126. }
  5127. }
  5128. void OcclusionQueryVK::invalidate(OcclusionQueryHandle _handle)
  5129. {
  5130. const uint32_t size = m_control.m_size;
  5131. for (uint32_t ii = 0, num = m_control.getNumUsed(); ii < num; ++ii)
  5132. {
  5133. OcclusionQueryHandle& handle = m_handle[(m_control.m_read + ii) % size];
  5134. if (handle.idx == _handle.idx)
  5135. {
  5136. handle.idx = bgfx::kInvalidHandle;
  5137. }
  5138. }
  5139. }
  5140. void ReadbackVK::create(VkImage _image, uint32_t _width, uint32_t _height, TextureFormat::Enum _format)
  5141. {
  5142. m_image = _image;
  5143. m_width = _width;
  5144. m_height = _height;
  5145. m_format = _format;
  5146. }
  5147. void ReadbackVK::destroy()
  5148. {
  5149. m_image = VK_NULL_HANDLE;
  5150. }
  5151. uint32_t ReadbackVK::pitch(uint8_t _mip) const
  5152. {
  5153. uint32_t mipWidth = bx::uint32_max(1, m_width >> _mip);
  5154. uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_format) );
  5155. return mipWidth * bpp / 8;
  5156. }
  5157. void ReadbackVK::copyImageToBuffer(VkCommandBuffer _commandBuffer, VkBuffer _buffer, VkImageLayout _layout, VkImageAspectFlags _aspect, uint8_t _mip) const
  5158. {
  5159. BGFX_PROFILER_SCOPE("ReadbackVK::copyImageToBuffer", kColorFrame);
  5160. uint32_t mipWidth = bx::uint32_max(1, m_width >> _mip);
  5161. uint32_t mipHeight = bx::uint32_max(1, m_height >> _mip);
  5162. setImageMemoryBarrier(
  5163. _commandBuffer
  5164. , m_image
  5165. , _aspect
  5166. , _layout
  5167. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5168. , _mip
  5169. , 1
  5170. , 0
  5171. , 1
  5172. );
  5173. VkBufferImageCopy bic;
  5174. bic.bufferOffset = 0;
  5175. bic.bufferRowLength = mipWidth;
  5176. bic.bufferImageHeight = mipHeight;
  5177. bic.imageSubresource.aspectMask = _aspect;
  5178. bic.imageSubresource.mipLevel = _mip;
  5179. bic.imageSubresource.baseArrayLayer = 0;
  5180. bic.imageSubresource.layerCount = 1;
  5181. bic.imageOffset = { 0, 0, 0 };
  5182. bic.imageExtent = { mipWidth, mipHeight, 1 };
  5183. vkCmdCopyImageToBuffer(
  5184. _commandBuffer
  5185. , m_image
  5186. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5187. , _buffer
  5188. , 1
  5189. , &bic
  5190. );
  5191. // Make changes to the buffer visible to the host
  5192. setMemoryBarrier(
  5193. _commandBuffer
  5194. , VK_PIPELINE_STAGE_TRANSFER_BIT
  5195. , VK_PIPELINE_STAGE_HOST_BIT
  5196. );
  5197. setImageMemoryBarrier(
  5198. _commandBuffer
  5199. , m_image
  5200. , _aspect
  5201. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5202. , _layout
  5203. , _mip
  5204. , 1
  5205. , 0
  5206. , 1
  5207. );
  5208. }
  5209. void ReadbackVK::readback(VkDeviceMemory _memory, VkDeviceSize _offset, void* _data, uint8_t _mip) const
  5210. {
  5211. BGFX_PROFILER_SCOPE("ReadbackVK::readback", kColorResource);
  5212. if (m_image == VK_NULL_HANDLE)
  5213. {
  5214. return;
  5215. }
  5216. const uint32_t mipHeight = bx::uint32_max(1, m_height >> _mip);
  5217. const uint32_t rowPitch = pitch(_mip);
  5218. const uint8_t* src;
  5219. VK_CHECK(vkMapMemory(s_renderVK->m_device, _memory, 0, VK_WHOLE_SIZE, 0, (void**)&src) );
  5220. src += _offset;
  5221. bx::gather(_data, src, rowPitch, rowPitch, mipHeight);
  5222. vkUnmapMemory(s_renderVK->m_device, _memory);
  5223. }
  5224. VkResult TextureVK::create(VkCommandBuffer _commandBuffer, uint32_t _width, uint32_t _height, uint64_t _flags, VkFormat _format)
  5225. {
  5226. BGFX_PROFILER_SCOPE("TextureVK::create", kColorResource);
  5227. BX_ASSERT(0 != (_flags & BGFX_TEXTURE_RT_MASK), "");
  5228. _flags |= BGFX_TEXTURE_RT_WRITE_ONLY;
  5229. m_flags = _flags;
  5230. m_width = _width;
  5231. m_height = _height;
  5232. m_depth = 1;
  5233. m_numLayers = 1;
  5234. m_requestedFormat = uint8_t(bimg::TextureFormat::Count);
  5235. m_textureFormat = uint8_t(bimg::TextureFormat::Count);
  5236. m_format = _format;
  5237. m_components = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
  5238. m_aspectFlags = getAspectMask(m_format);
  5239. m_sampler = s_msaa[bx::uint32_satsub( (m_flags & BGFX_TEXTURE_RT_MSAA_MASK) >> BGFX_TEXTURE_RT_MSAA_SHIFT, 1)];
  5240. m_type = VK_IMAGE_VIEW_TYPE_2D;
  5241. m_numMips = 1;
  5242. m_numSides = 1;
  5243. VkResult result = createImages(_commandBuffer);
  5244. if (VK_SUCCESS == result)
  5245. {
  5246. const VkImageLayout layout = 0 != (m_aspectFlags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) )
  5247. ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
  5248. : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
  5249. ;
  5250. setImageMemoryBarrier(_commandBuffer, layout);
  5251. }
  5252. return result;
  5253. }
  5254. VkResult TextureVK::createImages(VkCommandBuffer _commandBuffer)
  5255. {
  5256. BGFX_PROFILER_SCOPE("TextureVK::createImages", kColorResource);
  5257. VkResult result = VK_SUCCESS;
  5258. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  5259. const VkDevice device = s_renderVK->m_device;
  5260. if (m_sampler.Count > 1)
  5261. {
  5262. BX_ASSERT(VK_IMAGE_VIEW_TYPE_3D != m_type, "Can't create multisample 3D image.");
  5263. BX_ASSERT(m_numMips <= 1, "Can't create multisample image with mip chain.");
  5264. }
  5265. // create texture and allocate its device memory
  5266. VkImageCreateInfo ici;
  5267. ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
  5268. ici.pNext = NULL;
  5269. ici.flags = 0
  5270. | (VK_IMAGE_VIEW_TYPE_CUBE == m_type
  5271. ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
  5272. : 0
  5273. )
  5274. | (VK_IMAGE_VIEW_TYPE_3D == m_type
  5275. ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR
  5276. : 0
  5277. )
  5278. ;
  5279. ici.pQueueFamilyIndices = NULL;
  5280. ici.queueFamilyIndexCount = 0;
  5281. ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  5282. ici.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  5283. ici.usage = 0
  5284. | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
  5285. | VK_IMAGE_USAGE_TRANSFER_DST_BIT
  5286. | VK_IMAGE_USAGE_SAMPLED_BIT
  5287. | (m_flags & BGFX_TEXTURE_RT_MASK
  5288. ? (m_aspectFlags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
  5289. ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
  5290. : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
  5291. )
  5292. : 0
  5293. )
  5294. | (m_flags & BGFX_TEXTURE_COMPUTE_WRITE ? VK_IMAGE_USAGE_STORAGE_BIT : 0)
  5295. ;
  5296. ici.format = m_format;
  5297. ici.samples = m_sampler.Sample;
  5298. ici.mipLevels = m_numMips;
  5299. ici.arrayLayers = m_numSides;
  5300. ici.extent.width = m_width;
  5301. ici.extent.height = m_height;
  5302. ici.extent.depth = m_depth;
  5303. ici.imageType = VK_IMAGE_VIEW_TYPE_3D == m_type
  5304. ? VK_IMAGE_TYPE_3D
  5305. : VK_IMAGE_TYPE_2D
  5306. ;
  5307. ici.tiling = VK_IMAGE_TILING_OPTIMAL;
  5308. result = vkCreateImage(device, &ici, allocatorCb, &m_textureImage);
  5309. if (VK_SUCCESS != result)
  5310. {
  5311. BX_TRACE("Create texture image error: vkCreateImage failed %d: %s.", result, getName(result) );
  5312. return result;
  5313. }
  5314. VkMemoryRequirements imageMemReq;
  5315. vkGetImageMemoryRequirements(device, m_textureImage, &imageMemReq);
  5316. result = s_renderVK->allocateMemory(&imageMemReq, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &m_textureDeviceMem, false);
  5317. if (VK_SUCCESS != result)
  5318. {
  5319. BX_TRACE("Create texture image error: allocateMemory failed %d: %s.", result, getName(result) );
  5320. return result;
  5321. }
  5322. result = vkBindImageMemory(device, m_textureImage, m_textureDeviceMem.mem, m_textureDeviceMem.offset);
  5323. if (VK_SUCCESS != result)
  5324. {
  5325. BX_TRACE("Create texture image error: vkBindImageMemory failed %d: %s.", result, getName(result) );
  5326. return result;
  5327. }
  5328. m_sampledLayout = m_flags & BGFX_TEXTURE_COMPUTE_WRITE
  5329. ? VK_IMAGE_LAYOUT_GENERAL
  5330. : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
  5331. ;
  5332. const bool needResolve = true
  5333. && 1 < m_sampler.Count
  5334. && 0 != (ici.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
  5335. && 0 == (m_flags & BGFX_TEXTURE_MSAA_SAMPLE)
  5336. && 0 == (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY)
  5337. ;
  5338. if (needResolve)
  5339. {
  5340. VkImageCreateInfo ici_resolve = ici;
  5341. ici_resolve.samples = s_msaa[0].Sample;
  5342. ici_resolve.usage &= ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
  5343. ici_resolve.flags &= ~VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
  5344. result = vkCreateImage(device, &ici_resolve, allocatorCb, &m_singleMsaaImage);
  5345. if (VK_SUCCESS != result)
  5346. {
  5347. BX_TRACE("Create texture image error: vkCreateImage failed %d: %s.", result, getName(result) );
  5348. return result;
  5349. }
  5350. VkMemoryRequirements imageMemReq_resolve;
  5351. vkGetImageMemoryRequirements(device, m_singleMsaaImage, &imageMemReq_resolve);
  5352. result = s_renderVK->allocateMemory(&imageMemReq_resolve, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &m_singleMsaaDeviceMem, false);
  5353. if (VK_SUCCESS != result)
  5354. {
  5355. BX_TRACE("Create texture image error: allocateMemory failed %d: %s.", result, getName(result) );
  5356. return result;
  5357. }
  5358. result = vkBindImageMemory(device, m_singleMsaaImage, m_singleMsaaDeviceMem.mem, m_singleMsaaDeviceMem.offset);
  5359. if (VK_SUCCESS != result)
  5360. {
  5361. BX_TRACE("Create texture image error: vkBindImageMemory failed %d: %s.", result, getName(result) );
  5362. return result;
  5363. }
  5364. setImageMemoryBarrier(_commandBuffer, m_sampledLayout, true);
  5365. }
  5366. return result;
  5367. }
  5368. void* TextureVK::create(VkCommandBuffer _commandBuffer, const Memory* _mem, uint64_t _flags, uint8_t _skip)
  5369. {
  5370. BGFX_PROFILER_SCOPE("TextureVK::create", kColorResource);
  5371. bimg::ImageContainer imageContainer;
  5372. if (bimg::imageParse(imageContainer, _mem->data, _mem->size) )
  5373. {
  5374. const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(imageContainer.m_format);
  5375. const uint8_t startLod = bx::min<uint8_t>(_skip, imageContainer.m_numMips - 1);
  5376. bimg::TextureInfo ti;
  5377. bimg::imageGetSize(
  5378. &ti
  5379. , uint16_t(imageContainer.m_width >> startLod)
  5380. , uint16_t(imageContainer.m_height >> startLod)
  5381. , uint16_t(imageContainer.m_depth >> startLod)
  5382. , imageContainer.m_cubeMap
  5383. , 1 < imageContainer.m_numMips
  5384. , imageContainer.m_numLayers
  5385. , imageContainer.m_format
  5386. );
  5387. ti.numMips = bx::min<uint8_t>(imageContainer.m_numMips - startLod, ti.numMips);
  5388. m_flags = _flags;
  5389. m_width = ti.width;
  5390. m_height = ti.height;
  5391. m_depth = ti.depth;
  5392. m_numLayers = ti.numLayers;
  5393. m_requestedFormat = uint8_t(imageContainer.m_format);
  5394. m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) );
  5395. m_format = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) )
  5396. ? s_textureFormat[m_textureFormat].m_fmtDsv
  5397. : (m_flags & BGFX_TEXTURE_SRGB) ? s_textureFormat[m_textureFormat].m_fmtSrgb : s_textureFormat[m_textureFormat].m_fmt
  5398. ;
  5399. m_components = s_textureFormat[m_textureFormat].m_mapping;
  5400. const bool convert = m_textureFormat != m_requestedFormat;
  5401. const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) );
  5402. m_aspectFlags = getAspectMask(m_format);
  5403. m_sampler = s_msaa[bx::uint32_satsub( (m_flags & BGFX_TEXTURE_RT_MSAA_MASK) >> BGFX_TEXTURE_RT_MSAA_SHIFT, 1)];
  5404. if (imageContainer.m_cubeMap)
  5405. {
  5406. m_type = imageContainer.m_numLayers > 1
  5407. ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
  5408. : VK_IMAGE_VIEW_TYPE_CUBE
  5409. ;
  5410. }
  5411. else if (imageContainer.m_depth > 1)
  5412. {
  5413. m_type = VK_IMAGE_VIEW_TYPE_3D;
  5414. }
  5415. else if (imageContainer.m_numLayers > 1)
  5416. {
  5417. m_type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
  5418. }
  5419. else
  5420. {
  5421. m_type = VK_IMAGE_VIEW_TYPE_2D;
  5422. }
  5423. m_numMips = ti.numMips;
  5424. m_numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1);
  5425. const uint16_t numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1);
  5426. const uint32_t numSrd = numSides * ti.numMips;
  5427. uint32_t kk = 0;
  5428. const bool compressed = bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) );
  5429. const bool swizzle = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE);
  5430. const bool writeOnly = 0 != (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY);
  5431. const bool computeWrite = 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE);
  5432. const bool renderTarget = 0 != (m_flags & BGFX_TEXTURE_RT_MASK);
  5433. const bool blit = 0 != (m_flags & BGFX_TEXTURE_BLIT_DST);
  5434. BX_UNUSED(swizzle, writeOnly, computeWrite, renderTarget, blit);
  5435. BX_TRACE(
  5436. "Texture %3d: %s (requested: %s), %dx%dx%d%s RT[%c], BO[%c], CW[%c]%s."
  5437. , (int)(this - s_renderVK->m_textures)
  5438. , getName( (TextureFormat::Enum)m_textureFormat)
  5439. , getName( (TextureFormat::Enum)m_requestedFormat)
  5440. , ti.width
  5441. , ti.height
  5442. , ti.depth
  5443. , imageContainer.m_cubeMap ? "x6" : ""
  5444. , renderTarget ? 'x' : ' '
  5445. , writeOnly ? 'x' : ' '
  5446. , computeWrite ? 'x' : ' '
  5447. , swizzle ? " (swizzle BGRA8 -> RGBA8)" : ""
  5448. );
  5449. VK_CHECK(createImages(_commandBuffer) );
  5450. // decode images
  5451. struct ImageInfo
  5452. {
  5453. uint8_t* data;
  5454. uint32_t width;
  5455. uint32_t height;
  5456. uint32_t depth;
  5457. uint32_t pitch;
  5458. uint32_t slice;
  5459. uint32_t size;
  5460. uint32_t mipLevel;
  5461. uint32_t layer;
  5462. };
  5463. ImageInfo* imageInfos = (ImageInfo*)bx::alloc(g_allocator, sizeof(ImageInfo) * numSrd);
  5464. bx::memSet(imageInfos, 0, sizeof(ImageInfo) * numSrd);
  5465. uint32_t alignment = 1; // tightly aligned buffer
  5466. for (uint16_t side = 0; side < numSides; ++side)
  5467. {
  5468. for (uint8_t lod = 0; lod < ti.numMips; ++lod)
  5469. {
  5470. bimg::ImageMip mip;
  5471. if (bimg::imageGetRawData(imageContainer, side, lod + startLod, _mem->data, _mem->size, mip) )
  5472. {
  5473. if (convert)
  5474. {
  5475. const uint32_t pitch = bx::strideAlign(bx::max<uint32_t>(mip.m_width, 4) * bpp / 8, alignment);
  5476. const uint32_t slice = bx::strideAlign(bx::max<uint32_t>(mip.m_height, 4) * pitch, alignment);
  5477. const uint32_t size = slice * mip.m_depth;
  5478. uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, size);
  5479. bimg::imageDecodeToBgra8(
  5480. g_allocator
  5481. , temp
  5482. , mip.m_data
  5483. , mip.m_width
  5484. , mip.m_height
  5485. , pitch
  5486. , mip.m_format
  5487. );
  5488. imageInfos[kk].data = temp;
  5489. imageInfos[kk].width = mip.m_width;
  5490. imageInfos[kk].height = mip.m_height;
  5491. imageInfos[kk].depth = mip.m_depth;
  5492. imageInfos[kk].pitch = pitch;
  5493. imageInfos[kk].slice = slice;
  5494. imageInfos[kk].size = size;
  5495. imageInfos[kk].mipLevel = lod;
  5496. imageInfos[kk].layer = side;
  5497. }
  5498. else if (compressed)
  5499. {
  5500. const uint32_t pitch = bx::strideAlign( (mip.m_width / blockInfo.blockWidth) * mip.m_blockSize, alignment);
  5501. const uint32_t slice = bx::strideAlign( (mip.m_height / blockInfo.blockHeight) * pitch, alignment);
  5502. const uint32_t size = slice * mip.m_depth;
  5503. uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, size);
  5504. bimg::imageCopy(
  5505. temp
  5506. , mip.m_height / blockInfo.blockHeight
  5507. , (mip.m_width / blockInfo.blockWidth) * mip.m_blockSize
  5508. , mip.m_depth
  5509. , mip.m_data
  5510. , pitch
  5511. );
  5512. imageInfos[kk].data = temp;
  5513. imageInfos[kk].width = mip.m_width;
  5514. imageInfos[kk].height = mip.m_height;
  5515. imageInfos[kk].depth = mip.m_depth;
  5516. imageInfos[kk].pitch = pitch;
  5517. imageInfos[kk].slice = slice;
  5518. imageInfos[kk].size = size;
  5519. imageInfos[kk].mipLevel = lod;
  5520. imageInfos[kk].layer = side;
  5521. }
  5522. else
  5523. {
  5524. const uint32_t pitch = bx::strideAlign(mip.m_width * mip.m_bpp / 8, alignment);
  5525. const uint32_t slice = bx::strideAlign(mip.m_height * pitch, alignment);
  5526. const uint32_t size = slice * mip.m_depth;
  5527. uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, size);
  5528. bimg::imageCopy(
  5529. temp
  5530. , mip.m_height
  5531. , mip.m_width * mip.m_bpp / 8
  5532. , mip.m_depth
  5533. , mip.m_data
  5534. , pitch
  5535. );
  5536. imageInfos[kk].data = temp;
  5537. imageInfos[kk].width = mip.m_width;
  5538. imageInfos[kk].height = mip.m_height;
  5539. imageInfos[kk].depth = mip.m_depth;
  5540. imageInfos[kk].pitch = pitch;
  5541. imageInfos[kk].slice = slice;
  5542. imageInfos[kk].size = size;
  5543. imageInfos[kk].mipLevel = lod;
  5544. imageInfos[kk].layer = side;
  5545. }
  5546. }
  5547. ++kk;
  5548. }
  5549. }
  5550. uint32_t totalMemSize = 0;
  5551. VkBufferImageCopy* bufferCopyInfo = (VkBufferImageCopy*)bx::alloc(g_allocator, sizeof(VkBufferImageCopy) * numSrd);
  5552. for (uint32_t ii = 0; ii < numSrd; ++ii)
  5553. {
  5554. const uint32_t idealWidth = bx::max<uint32_t>(1, m_width >> imageInfos[ii].mipLevel);
  5555. const uint32_t idealHeight = bx::max<uint32_t>(1, m_height >> imageInfos[ii].mipLevel);
  5556. bufferCopyInfo[ii].bufferOffset = totalMemSize;
  5557. bufferCopyInfo[ii].bufferRowLength = 0; // assume that image data are tightly aligned
  5558. bufferCopyInfo[ii].bufferImageHeight = 0; // assume that image data are tightly aligned
  5559. bufferCopyInfo[ii].imageSubresource.aspectMask = m_aspectFlags;
  5560. bufferCopyInfo[ii].imageSubresource.mipLevel = imageInfos[ii].mipLevel;
  5561. bufferCopyInfo[ii].imageSubresource.baseArrayLayer = imageInfos[ii].layer;
  5562. bufferCopyInfo[ii].imageSubresource.layerCount = 1;
  5563. bufferCopyInfo[ii].imageOffset = { 0, 0, 0 };
  5564. bufferCopyInfo[ii].imageExtent = { idealWidth, idealHeight, imageInfos[ii].depth };
  5565. totalMemSize += imageInfos[ii].size;
  5566. }
  5567. if (totalMemSize > 0)
  5568. {
  5569. const VkDevice device = s_renderVK->m_device;
  5570. const bimg::ImageBlockInfo &dstBlockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) );
  5571. StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(totalMemSize, dstBlockInfo.blockSize);
  5572. uint8_t* mappedMemory;
  5573. if (!stagingBuffer.m_isFromScratch)
  5574. {
  5575. VK_CHECK(vkMapMemory(
  5576. device
  5577. , stagingBuffer.m_deviceMem.mem
  5578. , stagingBuffer.m_deviceMem.offset
  5579. , totalMemSize
  5580. , 0
  5581. , (void**)&mappedMemory
  5582. ) );
  5583. }
  5584. else
  5585. {
  5586. mappedMemory = stagingBuffer.m_data;
  5587. }
  5588. // copy image to staging buffer
  5589. for (uint32_t ii = 0; ii < numSrd; ++ii)
  5590. {
  5591. bx::memCopy(mappedMemory, imageInfos[ii].data, imageInfos[ii].size);
  5592. mappedMemory += imageInfos[ii].size;
  5593. bufferCopyInfo[ii].bufferOffset += stagingBuffer.m_offset;
  5594. BX_ASSERT(
  5595. bx::uint32_mod(bx::narrowCast<uint32_t>(bufferCopyInfo[ii].bufferOffset), dstBlockInfo.blockSize) == 0
  5596. , "Alignment for subimage %u is not aligned correctly (%u)."
  5597. , ii, bufferCopyInfo[ii].bufferOffset, dstBlockInfo.blockSize
  5598. );
  5599. }
  5600. if (!stagingBuffer.m_isFromScratch)
  5601. {
  5602. vkUnmapMemory(device, stagingBuffer.m_deviceMem.mem);
  5603. }
  5604. copyBufferToTexture(_commandBuffer, stagingBuffer.m_buffer, numSrd, bufferCopyInfo);
  5605. if (!stagingBuffer.m_isFromScratch)
  5606. {
  5607. s_renderVK->release(stagingBuffer.m_buffer);
  5608. s_renderVK->recycleMemory(stagingBuffer.m_deviceMem);
  5609. }
  5610. }
  5611. else
  5612. {
  5613. setImageMemoryBarrier(_commandBuffer, m_sampledLayout);
  5614. }
  5615. bx::free(g_allocator, bufferCopyInfo);
  5616. for (uint32_t ii = 0; ii < numSrd; ++ii)
  5617. {
  5618. bx::free(g_allocator, imageInfos[ii].data);
  5619. }
  5620. bx::free(g_allocator, imageInfos);
  5621. m_readback.create(m_textureImage, m_width, m_height, TextureFormat::Enum(m_textureFormat) );
  5622. }
  5623. return m_directAccessPtr;
  5624. }
  5625. void TextureVK::destroy()
  5626. {
  5627. BGFX_PROFILER_SCOPE("TextureVK::destroy", kColorResource);
  5628. m_readback.destroy();
  5629. if (VK_NULL_HANDLE != m_textureImage)
  5630. {
  5631. s_renderVK->release(m_textureImage);
  5632. s_renderVK->recycleMemory(m_textureDeviceMem);
  5633. }
  5634. if (VK_NULL_HANDLE != m_singleMsaaImage)
  5635. {
  5636. s_renderVK->release(m_singleMsaaImage);
  5637. s_renderVK->recycleMemory(m_singleMsaaDeviceMem);
  5638. }
  5639. m_aspectFlags = VK_IMAGE_ASPECT_NONE;
  5640. m_currentImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  5641. m_currentSingleMsaaImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  5642. }
  5643. void TextureVK::update(VkCommandBuffer _commandBuffer, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem)
  5644. {
  5645. BGFX_PROFILER_SCOPE("TextureVK::update", kColorResource);
  5646. const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) );
  5647. const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) );
  5648. uint32_t rectpitch = _rect.m_width * bpp / 8;
  5649. uint32_t slicepitch = rectpitch * _rect.m_height;
  5650. uint32_t align = blockInfo.blockSize;
  5651. if (bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ) )
  5652. {
  5653. rectpitch = (_rect.m_width / blockInfo.blockWidth ) * blockInfo.blockSize;
  5654. slicepitch = (_rect.m_height / blockInfo.blockHeight) * rectpitch;
  5655. }
  5656. const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch;
  5657. const uint32_t size = UINT16_MAX == _pitch ? slicepitch * _depth: _rect.m_height * _pitch * _depth;
  5658. const bool convert = m_textureFormat != m_requestedFormat;
  5659. VkBufferImageCopy region;
  5660. region.bufferOffset = 0;
  5661. region.bufferRowLength = (_pitch == UINT16_MAX ? 0 : _pitch * 8 / bpp);
  5662. region.bufferImageHeight = 0;
  5663. region.imageSubresource.aspectMask = m_aspectFlags;
  5664. region.imageSubresource.mipLevel = _mip;
  5665. region.imageSubresource.baseArrayLayer = 0;
  5666. region.imageSubresource.layerCount = 1;
  5667. region.imageOffset = { _rect.m_x, _rect.m_y, 0 };
  5668. region.imageExtent = { _rect.m_width, _rect.m_height, _depth };
  5669. uint8_t* data = _mem->data;
  5670. uint8_t* temp = NULL;
  5671. if (convert)
  5672. {
  5673. temp = (uint8_t*)bx::alloc(g_allocator, slicepitch);
  5674. bimg::imageDecodeToBgra8(g_allocator, temp, data, _rect.m_width, _rect.m_height, srcpitch, bimg::TextureFormat::Enum(m_requestedFormat) );
  5675. data = temp;
  5676. region.imageExtent =
  5677. {
  5678. bx::max(1u, m_width >> _mip),
  5679. bx::max(1u, m_height >> _mip),
  5680. _depth,
  5681. };
  5682. }
  5683. StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(size, align, data);
  5684. region.bufferOffset += stagingBuffer.m_offset;
  5685. BX_ASSERT(region.bufferOffset % align == 0,
  5686. "Alignment for image (mip %u, z %u) is not aligned correctly (%u).",
  5687. _mip, _z, region.bufferOffset, align);
  5688. if (VK_IMAGE_VIEW_TYPE_3D == m_type)
  5689. {
  5690. region.imageOffset.z = _z;
  5691. }
  5692. else if (VK_IMAGE_VIEW_TYPE_CUBE == m_type
  5693. || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == m_type)
  5694. {
  5695. region.imageSubresource.baseArrayLayer = _z * 6 + _side;
  5696. }
  5697. else
  5698. {
  5699. region.imageSubresource.baseArrayLayer = _z;
  5700. }
  5701. copyBufferToTexture(_commandBuffer, stagingBuffer.m_buffer, 1, &region);
  5702. if (!stagingBuffer.m_isFromScratch)
  5703. {
  5704. s_renderVK->release(stagingBuffer.m_buffer);
  5705. s_renderVK->recycleMemory(stagingBuffer.m_deviceMem);
  5706. }
  5707. if (NULL != temp)
  5708. {
  5709. bx::free(g_allocator, temp);
  5710. }
  5711. }
  5712. void TextureVK::resolve(VkCommandBuffer _commandBuffer, uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip)
  5713. {
  5714. BGFX_PROFILER_SCOPE("TextureVK::resolve", kColorResource);
  5715. const bool needResolve = VK_NULL_HANDLE != m_singleMsaaImage;
  5716. const bool needMipGen = true
  5717. && !needResolve
  5718. && 0 != (m_flags & BGFX_TEXTURE_RT_MASK)
  5719. && 0 == (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY)
  5720. && (_mip + 1) < m_numMips
  5721. && 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS)
  5722. ;
  5723. const VkImageLayout oldLayout = m_currentImageLayout;
  5724. const VkImageLayout oldSingleMsaaLayout = m_currentSingleMsaaImageLayout;
  5725. const uint32_t numLayers = false
  5726. || m_type == VK_IMAGE_VIEW_TYPE_CUBE
  5727. || m_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
  5728. ? m_numSides
  5729. : _numLayers
  5730. ;
  5731. if (needResolve)
  5732. {
  5733. setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
  5734. setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
  5735. VkImageResolve resolve;
  5736. resolve.srcOffset.x = 0;
  5737. resolve.srcOffset.y = 0;
  5738. resolve.srcOffset.z = 0;
  5739. resolve.dstOffset.x = 0;
  5740. resolve.dstOffset.y = 0;
  5741. resolve.dstOffset.z = 0;
  5742. resolve.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  5743. resolve.srcSubresource.mipLevel = _mip;
  5744. resolve.srcSubresource.baseArrayLayer = _layer;
  5745. resolve.srcSubresource.layerCount = numLayers;
  5746. resolve.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  5747. resolve.dstSubresource.mipLevel = _mip;
  5748. resolve.dstSubresource.baseArrayLayer = _layer;
  5749. resolve.dstSubresource.layerCount = numLayers;
  5750. resolve.extent.width = m_width;
  5751. resolve.extent.height = m_height;
  5752. resolve.extent.depth = 1;
  5753. vkCmdResolveImage(
  5754. _commandBuffer
  5755. , m_textureImage
  5756. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5757. , m_singleMsaaImage
  5758. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5759. , 1
  5760. , &resolve
  5761. );
  5762. }
  5763. if (needMipGen)
  5764. {
  5765. BGFX_PROFILER_SCOPE("Resolve - Generate Mipmaps", kColorResource);
  5766. setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
  5767. int32_t mipWidth = bx::max<int32_t>(int32_t(m_width) >> _mip, 1);
  5768. int32_t mipHeight = bx::max<int32_t>(int32_t(m_height) >> _mip, 1);
  5769. const VkFilter filter = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) )
  5770. ? VK_FILTER_NEAREST
  5771. : VK_FILTER_LINEAR
  5772. ;
  5773. VkImageBlit blit;
  5774. blit.srcOffsets[0] = { 0, 0, 0 };
  5775. blit.srcOffsets[1] = { mipWidth, mipHeight, 1 };
  5776. blit.srcSubresource.aspectMask = m_aspectFlags;
  5777. blit.srcSubresource.mipLevel = 0;
  5778. blit.srcSubresource.baseArrayLayer = _layer;
  5779. blit.srcSubresource.layerCount = numLayers;
  5780. blit.dstOffsets[0] = { 0, 0, 0 };
  5781. blit.dstOffsets[1] = { mipWidth, mipHeight, 1 };
  5782. blit.dstSubresource.aspectMask = m_aspectFlags;
  5783. blit.dstSubresource.mipLevel = 0;
  5784. blit.dstSubresource.baseArrayLayer = _layer;
  5785. blit.dstSubresource.layerCount = numLayers;
  5786. for (uint32_t i = _mip + 1; i < m_numMips; i++)
  5787. {
  5788. BGFX_PROFILER_SCOPE("Mipmap", kColorResource);
  5789. blit.srcOffsets[1] = { mipWidth, mipHeight, 1 };
  5790. blit.srcSubresource.mipLevel = i - 1;
  5791. mipWidth = bx::uint32_max(mipWidth >> 1, 1);
  5792. mipHeight = bx::uint32_max(mipHeight >> 1, 1);
  5793. blit.dstOffsets[1] = { mipWidth, mipHeight, 1 };
  5794. blit.dstSubresource.mipLevel = i;
  5795. vk::setImageMemoryBarrier(
  5796. _commandBuffer
  5797. , m_textureImage
  5798. , m_aspectFlags
  5799. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5800. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5801. , blit.srcSubresource.mipLevel
  5802. , 1
  5803. , _layer
  5804. , numLayers
  5805. );
  5806. vkCmdBlitImage(
  5807. _commandBuffer
  5808. , m_textureImage
  5809. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5810. , m_textureImage
  5811. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5812. , 1
  5813. , &blit
  5814. , filter
  5815. );
  5816. }
  5817. vk::setImageMemoryBarrier(
  5818. _commandBuffer
  5819. , m_textureImage
  5820. , m_aspectFlags
  5821. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5822. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5823. , _mip
  5824. , m_numMips - _mip - 1
  5825. , _layer
  5826. , numLayers
  5827. );
  5828. }
  5829. setImageMemoryBarrier(_commandBuffer, oldLayout);
  5830. setImageMemoryBarrier(_commandBuffer, oldSingleMsaaLayout, true);
  5831. }
  5832. void TextureVK::copyBufferToTexture(VkCommandBuffer _commandBuffer, VkBuffer _stagingBuffer, uint32_t _bufferImageCopyCount, VkBufferImageCopy* _bufferImageCopy)
  5833. {
  5834. BGFX_PROFILER_SCOPE("TextureVK::copyBufferToTexture", kColorResource);
  5835. const VkImageLayout oldLayout = m_currentImageLayout == VK_IMAGE_LAYOUT_UNDEFINED
  5836. ? m_sampledLayout
  5837. : m_currentImageLayout
  5838. ;
  5839. setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
  5840. bimg::TextureFormat::Enum format = bimg::TextureFormat::Enum(m_textureFormat);
  5841. const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(format);
  5842. for (uint32_t ii = 0; ii < _bufferImageCopyCount; ++ii)
  5843. {
  5844. BX_ASSERT(
  5845. bx::uint32_mod(bx::narrowCast<uint32_t>(_bufferImageCopy[ii].bufferOffset), blockInfo.blockSize) == 0
  5846. , "Misaligned texture of type %s to offset %u, which is not a multiple of %u."
  5847. , bimg::getName(format), _bufferImageCopy[ii].bufferOffset, blockInfo.blockSize
  5848. );
  5849. }
  5850. BX_UNUSED(blockInfo);
  5851. vkCmdCopyBufferToImage(
  5852. _commandBuffer
  5853. , _stagingBuffer
  5854. , m_textureImage
  5855. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5856. , _bufferImageCopyCount
  5857. , _bufferImageCopy
  5858. );
  5859. setImageMemoryBarrier(_commandBuffer, oldLayout);
  5860. }
  5861. VkImageLayout TextureVK::setImageMemoryBarrier(VkCommandBuffer _commandBuffer, VkImageLayout _newImageLayout, bool _singleMsaaImage)
  5862. {
  5863. if (_singleMsaaImage && VK_NULL_HANDLE == m_singleMsaaImage)
  5864. {
  5865. return VK_IMAGE_LAYOUT_UNDEFINED;
  5866. }
  5867. VkImageLayout& currentLayout = _singleMsaaImage
  5868. ? m_currentSingleMsaaImageLayout
  5869. : m_currentImageLayout
  5870. ;
  5871. const VkImageLayout oldLayout = currentLayout;
  5872. if (currentLayout == _newImageLayout)
  5873. {
  5874. return oldLayout;
  5875. }
  5876. const VkImage image = _singleMsaaImage
  5877. ? m_singleMsaaImage
  5878. : m_textureImage
  5879. ;
  5880. vk::setImageMemoryBarrier(
  5881. _commandBuffer
  5882. , image
  5883. , m_aspectFlags
  5884. , currentLayout
  5885. , _newImageLayout
  5886. );
  5887. currentLayout = _newImageLayout;
  5888. return oldLayout;
  5889. }
  5890. VkResult TextureVK::createView(uint32_t _layer, uint32_t _numLayers, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, VkImageAspectFlags _aspectMask, bool _renderTarget, ::VkImageView* _view) const
  5891. {
  5892. VkResult result = VK_SUCCESS;
  5893. if (VK_IMAGE_VIEW_TYPE_3D == m_type)
  5894. {
  5895. BX_ASSERT(false
  5896. || !_renderTarget
  5897. || !(m_aspectFlags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) )
  5898. , "3D image can't be a depth attachment"
  5899. );
  5900. }
  5901. if (VK_IMAGE_VIEW_TYPE_CUBE == _type
  5902. || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == _type)
  5903. {
  5904. BX_ASSERT(_numLayers % 6 == 0, "");
  5905. BX_ASSERT(
  5906. VK_IMAGE_VIEW_TYPE_3D != m_type
  5907. , "3D image can't be aliased as a cube texture"
  5908. );
  5909. }
  5910. VkImageViewCreateInfo viewInfo;
  5911. viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
  5912. viewInfo.pNext = NULL;
  5913. viewInfo.flags = 0;
  5914. viewInfo.image = ( (VK_NULL_HANDLE != m_singleMsaaImage) && !_renderTarget)
  5915. ? m_singleMsaaImage
  5916. : m_textureImage
  5917. ;
  5918. viewInfo.viewType = _type;
  5919. viewInfo.format = m_format;
  5920. viewInfo.components = m_components;
  5921. viewInfo.subresourceRange.aspectMask = m_aspectFlags & _aspectMask;
  5922. viewInfo.subresourceRange.baseMipLevel = _mip;
  5923. viewInfo.subresourceRange.levelCount = _numMips;
  5924. viewInfo.subresourceRange.baseArrayLayer = _layer;
  5925. viewInfo.subresourceRange.layerCount = 1;
  5926. if (VK_IMAGE_VIEW_TYPE_2D != _type
  5927. && VK_IMAGE_VIEW_TYPE_3D != _type)
  5928. {
  5929. viewInfo.subresourceRange.layerCount = VK_IMAGE_VIEW_TYPE_CUBE == _type
  5930. ? 6
  5931. : _numLayers
  5932. ;
  5933. }
  5934. VkImageView view = VK_NULL_HANDLE;
  5935. result = vkCreateImageView(
  5936. s_renderVK->m_device
  5937. , &viewInfo
  5938. , s_renderVK->m_allocatorCb
  5939. , &view
  5940. );
  5941. if (VK_SUCCESS != result)
  5942. {
  5943. BX_TRACE("Create texture view error: vkCreateImageView failed %d: %s.", result, getName(result) );
  5944. return result;
  5945. }
  5946. *_view = view;
  5947. return result;
  5948. }
  5949. VkImageAspectFlags TextureVK::getAspectMask(VkFormat _format)
  5950. {
  5951. switch (_format)
  5952. {
  5953. case VK_FORMAT_S8_UINT:
  5954. return VK_IMAGE_ASPECT_STENCIL_BIT;
  5955. case VK_FORMAT_D16_UNORM:
  5956. case VK_FORMAT_X8_D24_UNORM_PACK32:
  5957. case VK_FORMAT_D32_SFLOAT:
  5958. return VK_IMAGE_ASPECT_DEPTH_BIT;
  5959. case VK_FORMAT_D16_UNORM_S8_UINT:
  5960. case VK_FORMAT_D24_UNORM_S8_UINT:
  5961. case VK_FORMAT_D32_SFLOAT_S8_UINT:
  5962. return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
  5963. default:
  5964. return VK_IMAGE_ASPECT_COLOR_BIT;
  5965. }
  5966. }
  5967. VkResult SwapChainVK::create(VkCommandBuffer _commandBuffer, void* _nwh, const Resolution& _resolution)
  5968. {
  5969. struct ErrorState
  5970. {
  5971. enum Enum
  5972. {
  5973. Default,
  5974. SurfaceCreated,
  5975. SwapChainCreated,
  5976. AttachmentsCreated
  5977. };
  5978. };
  5979. ErrorState::Enum errorState = ErrorState::Default;
  5980. VkResult result = VK_SUCCESS;
  5981. if (NULL == _nwh)
  5982. {
  5983. return result;
  5984. }
  5985. m_nwh = _nwh;
  5986. m_resolution = _resolution;
  5987. m_queue = s_renderVK->m_globalQueue;
  5988. result = createSurface();
  5989. if (VK_SUCCESS != result)
  5990. {
  5991. BX_TRACE("Create swap chain error: creating surface failed %d: %s.", result, getName(result) );
  5992. goto error;
  5993. }
  5994. errorState = ErrorState::SurfaceCreated;
  5995. {
  5996. m_sci.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
  5997. m_sci.pNext = NULL;
  5998. m_sci.flags = 0;
  5999. m_sci.imageArrayLayers = 1;
  6000. m_sci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
  6001. m_sci.queueFamilyIndexCount = 0;
  6002. m_sci.preTransform = BX_ENABLED(BX_PLATFORM_NX)
  6003. ? VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR
  6004. : VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
  6005. ;
  6006. m_sci.oldSwapchain = VK_NULL_HANDLE;
  6007. for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii)
  6008. {
  6009. m_backBufferColorImage[ii] = VK_NULL_HANDLE;
  6010. m_backBufferColorImageView[ii] = VK_NULL_HANDLE;
  6011. m_backBufferFrameBuffer[ii] = VK_NULL_HANDLE;
  6012. m_backBufferFence[ii] = VK_NULL_HANDLE;
  6013. m_presentDoneSemaphore[ii] = VK_NULL_HANDLE;
  6014. m_renderDoneSemaphore[ii] = VK_NULL_HANDLE;
  6015. }
  6016. m_lastImageRenderedSemaphore = VK_NULL_HANDLE;
  6017. m_lastImageAcquiredSemaphore = VK_NULL_HANDLE;
  6018. result = createSwapChain();
  6019. if (VK_SUCCESS != result)
  6020. {
  6021. BX_TRACE("Create swap chain error: creating swapchain and image views failed %d: %s", result, getName(result) );
  6022. goto error;
  6023. }
  6024. }
  6025. errorState = ErrorState::SwapChainCreated;
  6026. {
  6027. result = createAttachments(_commandBuffer);
  6028. if (VK_SUCCESS != result)
  6029. {
  6030. BX_TRACE("Create swap chain error: creating MSAA/depth attachments failed %d: %s.", result, getName(result) );
  6031. goto error;
  6032. }
  6033. }
  6034. errorState = ErrorState::AttachmentsCreated;
  6035. {
  6036. result = createFrameBuffer();
  6037. if (VK_SUCCESS != result)
  6038. {
  6039. BX_TRACE("Create swap chain error: creating frame buffers failed %d: %s.", result, getName(result) );
  6040. goto error;
  6041. }
  6042. }
  6043. return VK_SUCCESS;
  6044. error:
  6045. BX_TRACE("errorState %d", errorState);
  6046. switch (errorState)
  6047. {
  6048. case ErrorState::AttachmentsCreated:
  6049. releaseAttachments();
  6050. [[fallthrough]];
  6051. case ErrorState::SwapChainCreated:
  6052. releaseSwapChain();
  6053. [[fallthrough]];
  6054. case ErrorState::SurfaceCreated:
  6055. releaseSurface();
  6056. [[fallthrough]];
  6057. case ErrorState::Default:
  6058. break;
  6059. };
  6060. return VK_SUCCESS != result
  6061. ? result
  6062. : VK_ERROR_INITIALIZATION_FAILED
  6063. ;
  6064. }
  6065. void SwapChainVK::destroy()
  6066. {
  6067. if (VK_NULL_HANDLE != m_swapChain)
  6068. {
  6069. releaseFrameBuffer();
  6070. releaseAttachments();
  6071. releaseSwapChain();
  6072. releaseSurface();
  6073. // can't delay-delete the surface, since there can only be one swapchain per surface
  6074. // new framebuffer with the same window would get an error at swapchain creation
  6075. s_renderVK->kick(true);
  6076. }
  6077. m_nwh = NULL;
  6078. }
  6079. void SwapChainVK::update(VkCommandBuffer _commandBuffer, void* _nwh, const Resolution& _resolution)
  6080. {
  6081. BGFX_PROFILER_SCOPE("SwapChainVK::update", kColorFrame);
  6082. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  6083. m_lastImageRenderedSemaphore = VK_NULL_HANDLE;
  6084. m_lastImageAcquiredSemaphore = VK_NULL_HANDLE;
  6085. const uint64_t recreateSurfaceMask = BGFX_RESET_HIDPI;
  6086. const uint64_t recreateSwapchainMask = BGFX_RESET_VSYNC | BGFX_RESET_SRGB_BACKBUFFER;
  6087. const uint64_t recreateAttachmentsMask = BGFX_RESET_MSAA_MASK;
  6088. const bool recreateSurface = false
  6089. || m_needToRecreateSurface
  6090. || m_nwh != _nwh
  6091. || (m_resolution.reset & recreateSurfaceMask) != (_resolution.reset & recreateSurfaceMask)
  6092. ;
  6093. const bool recreateSwapchain = false
  6094. || m_needToRecreateSwapchain
  6095. || m_resolution.formatColor != _resolution.formatColor
  6096. || m_resolution.formatDepthStencil != _resolution.formatDepthStencil
  6097. || m_resolution.width != _resolution.width
  6098. || m_resolution.height != _resolution.height
  6099. || (m_resolution.reset & recreateSwapchainMask) != (_resolution.reset & recreateSwapchainMask)
  6100. || recreateSurface
  6101. ;
  6102. const bool recreateAttachments = false
  6103. || (m_resolution.reset & recreateAttachmentsMask) != (_resolution.reset & recreateAttachmentsMask)
  6104. || recreateSwapchain
  6105. ;
  6106. m_nwh = _nwh;
  6107. m_resolution = _resolution;
  6108. if (recreateAttachments)
  6109. {
  6110. releaseFrameBuffer();
  6111. releaseAttachments();
  6112. if (recreateSwapchain)
  6113. {
  6114. releaseSwapChain();
  6115. if (recreateSurface)
  6116. {
  6117. m_sci.oldSwapchain = VK_NULL_HANDLE;
  6118. releaseSurface();
  6119. s_renderVK->kick(true);
  6120. _commandBuffer = s_renderVK->m_commandBuffer;
  6121. VkResult result = createSurface();
  6122. if (VK_SUCCESS != result)
  6123. {
  6124. BX_TRACE("Surface lost.");
  6125. return;
  6126. }
  6127. }
  6128. VkSurfaceCapabilitiesKHR surfaceCapabilities = {};
  6129. VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, m_surface, &surfaceCapabilities);
  6130. const uint32_t width = bx::clamp<uint32_t>(
  6131. m_resolution.width
  6132. , surfaceCapabilities.minImageExtent.width
  6133. , surfaceCapabilities.maxImageExtent.width
  6134. );
  6135. const uint32_t height = bx::clamp<uint32_t>(
  6136. m_resolution.height
  6137. , surfaceCapabilities.minImageExtent.height
  6138. , surfaceCapabilities.maxImageExtent.height
  6139. );
  6140. // swapchain can't have size 0
  6141. // on some platforms this happens when minimized
  6142. if (width == 0
  6143. || height == 0
  6144. || VK_SUCCESS != result)
  6145. {
  6146. m_sci.oldSwapchain = VK_NULL_HANDLE;
  6147. s_renderVK->kick(true);
  6148. return;
  6149. }
  6150. VK_CHECK(createSwapChain() );
  6151. }
  6152. VK_CHECK(createAttachments(_commandBuffer) );
  6153. VK_CHECK(createFrameBuffer() );
  6154. }
  6155. }
  6156. VkResult SwapChainVK::createSurface()
  6157. {
  6158. BGFX_PROFILER_SCOPE("SwapChainVK::createSurface", kColorFrame);
  6159. VkResult result = VK_ERROR_EXTENSION_NOT_PRESENT;
  6160. const VkInstance instance = s_renderVK->m_instance;
  6161. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  6162. #if BX_PLATFORM_WINDOWS
  6163. {
  6164. if (NULL != vkCreateWin32SurfaceKHR)
  6165. {
  6166. VkWin32SurfaceCreateInfoKHR sci;
  6167. sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
  6168. sci.pNext = NULL;
  6169. sci.flags = 0;
  6170. sci.hinstance = (HINSTANCE)GetModuleHandle(NULL);
  6171. sci.hwnd = (HWND)m_nwh;
  6172. result = vkCreateWin32SurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  6173. BX_WARN(VK_SUCCESS == result, "vkCreateWin32SurfaceKHR failed %d: %s.", result, getName(result) );
  6174. }
  6175. }
  6176. #elif BX_PLATFORM_ANDROID
  6177. {
  6178. if (NULL != vkCreateAndroidSurfaceKHR)
  6179. {
  6180. VkAndroidSurfaceCreateInfoKHR sci;
  6181. sci.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
  6182. sci.pNext = NULL;
  6183. sci.flags = 0;
  6184. sci.window = (ANativeWindow*)m_nwh;
  6185. result = vkCreateAndroidSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  6186. BX_WARN(VK_SUCCESS == result, "vkCreateAndroidSurfaceKHR failed %d: %s.", result, getName(result) );
  6187. }
  6188. }
  6189. #elif BX_PLATFORM_LINUX
  6190. {
  6191. if (g_platformData.type == bgfx::NativeWindowHandleType::Wayland)
  6192. {
  6193. if (s_extension[Extension::KHR_wayland_surface].m_supported
  6194. && NULL != vkCreateWaylandSurfaceKHR
  6195. )
  6196. {
  6197. BX_TRACE("Attempting Wayland surface creation.");
  6198. VkWaylandSurfaceCreateInfoKHR sci;
  6199. sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
  6200. sci.pNext = NULL;
  6201. sci.flags = 0;
  6202. sci.display = (wl_display*)g_platformData.ndt;
  6203. sci.surface = (wl_surface*)m_nwh;
  6204. result = vkCreateWaylandSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  6205. BX_WARN(VK_SUCCESS == result, "vkCreateWaylandSurfaceKHR failed %d: %s.", result, getName(result) );
  6206. }
  6207. }
  6208. else
  6209. {
  6210. if (s_extension[Extension::KHR_xlib_surface].m_supported
  6211. && NULL != vkCreateXlibSurfaceKHR
  6212. )
  6213. {
  6214. BX_TRACE("Attempting Xlib surface creation.");
  6215. VkXlibSurfaceCreateInfoKHR sci;
  6216. sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
  6217. sci.pNext = NULL;
  6218. sci.flags = 0;
  6219. sci.dpy = (Display*)g_platformData.ndt;
  6220. sci.window = (Window)m_nwh;
  6221. result = vkCreateXlibSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  6222. BX_WARN(VK_SUCCESS == result, "vkCreateXlibSurfaceKHR failed %d: %s.", result, getName(result) );
  6223. }
  6224. if (VK_SUCCESS != result
  6225. && s_extension[Extension::KHR_xcb_surface].m_supported
  6226. && NULL != vkCreateXcbSurfaceKHR
  6227. )
  6228. {
  6229. void* xcbdll = bx::dlopen("libX11-xcb.so.1");
  6230. if (NULL != xcbdll)
  6231. {
  6232. BX_TRACE("Attempting XCB surface creation.");
  6233. typedef xcb_connection_t* (*PFN_XGETXCBCONNECTION)(Display*);
  6234. PFN_XGETXCBCONNECTION XGetXCBConnection = (PFN_XGETXCBCONNECTION)bx::dlsym(xcbdll, "XGetXCBConnection");
  6235. VkXcbSurfaceCreateInfoKHR sci;
  6236. sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
  6237. sci.pNext = NULL;
  6238. sci.flags = 0;
  6239. sci.connection = XGetXCBConnection( (Display*)g_platformData.ndt);
  6240. sci.window = bx::narrowCast<xcb_window_t>(uintptr_t(m_nwh) );
  6241. result = vkCreateXcbSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  6242. BX_WARN(VK_SUCCESS == result, "vkCreateXcbSurfaceKHR failed %d: %s.", result, getName(result) );
  6243. bx::dlclose(xcbdll);
  6244. }
  6245. }
  6246. }
  6247. }
  6248. #elif BX_PLATFORM_OSX
  6249. {
  6250. if (NULL != vkCreateMacOSSurfaceMVK)
  6251. {
  6252. NSWindow* window = (NSWindow*)(m_nwh);
  6253. CAMetalLayer* layer = (CAMetalLayer*)(m_nwh);
  6254. if ([window isKindOfClass:[NSWindow class]])
  6255. {
  6256. NSView *contentView = (NSView *)window.contentView;
  6257. layer = [CAMetalLayer layer];
  6258. [contentView setWantsLayer : YES];
  6259. [contentView setLayer : layer];
  6260. }
  6261. else if ([layer isKindOfClass:[CAMetalLayer class]])
  6262. {
  6263. NSView *contentView = (NSView *)layer.delegate;
  6264. window = contentView.window;
  6265. }
  6266. else
  6267. {
  6268. BX_WARN(0, "Unable to create MoltenVk surface. Please set platform data window to an NSWindow or CAMetalLayer");
  6269. return result;
  6270. }
  6271. if (m_resolution.reset & BGFX_RESET_HIDPI)
  6272. {
  6273. layer.contentsScale = [window backingScaleFactor];
  6274. }
  6275. VkMacOSSurfaceCreateInfoMVK sci;
  6276. sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
  6277. sci.pNext = NULL;
  6278. sci.flags = 0;
  6279. sci.pView = (__bridge void*)layer;
  6280. result = vkCreateMacOSSurfaceMVK(instance, &sci, allocatorCb, &m_surface);
  6281. BX_WARN(VK_SUCCESS == result, "vkCreateMacOSSurfaceMVK failed %d: %s.", result, getName(result) );
  6282. }
  6283. }
  6284. #elif BX_PLATFORM_NX
  6285. if (NULL != vkCreateViSurfaceNN)
  6286. {
  6287. VkViSurfaceCreateInfoNN sci;
  6288. sci.sType = VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN;
  6289. sci.pNext = NULL;
  6290. sci.flags = 0;
  6291. sci.window = m_nwh;
  6292. result = vkCreateViSurfaceNN(instance, &sci, allocatorCb, &m_surface);
  6293. BX_WARN(VK_SUCCESS == result, "vkCreateViSurfaceNN failed %d: %s.", result, getName(result) );
  6294. }
  6295. #else
  6296. # error "Figure out KHR surface..."
  6297. #endif // BX_PLATFORM_
  6298. m_needToRecreateSurface = false;
  6299. if (VK_SUCCESS != result)
  6300. {
  6301. BX_TRACE("Create surface error: vkCreate[Platform]SurfaceKHR failed %d: %s.", result, getName(result) );
  6302. return result;
  6303. }
  6304. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  6305. const uint32_t queueFamily = s_renderVK->m_globalQueueFamily;
  6306. VkBool32 surfaceSupported;
  6307. result = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamily, m_surface, &surfaceSupported);
  6308. if (VK_SUCCESS != result
  6309. || !surfaceSupported)
  6310. {
  6311. BX_TRACE("Create surface error: Presentation to the given surface not supported.");
  6312. return VK_ERROR_INITIALIZATION_FAILED;
  6313. }
  6314. return result;
  6315. }
  6316. void SwapChainVK::releaseSurface()
  6317. {
  6318. release(m_surface);
  6319. }
  6320. VkResult SwapChainVK::createSwapChain()
  6321. {
  6322. BGFX_PROFILER_SCOPE("SwapChainVK::createSwapchain", kColorFrame);
  6323. VkResult result = VK_SUCCESS;
  6324. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  6325. const VkDevice device = s_renderVK->m_device;
  6326. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  6327. // Waiting for the device to be idle seems to get rid of VK_DEVICE_LOST
  6328. // upon resizing the window quickly. See:
  6329. // - https://github.com/mpv-player/mpv/issues/8360
  6330. // - https://github.com/bkaradzic/bgfx/issues/3227
  6331. result = vkDeviceWaitIdle(device);
  6332. BX_WARN(VK_SUCCESS == result, "Create swapchain error: vkDeviceWaitIdle() failed: %d: %s", result, getName(result) );
  6333. VkSurfaceCapabilitiesKHR surfaceCapabilities;
  6334. result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, m_surface, &surfaceCapabilities);
  6335. if (VK_SUCCESS != result)
  6336. {
  6337. BX_TRACE("Create swapchain error: vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed %d: %s.", result, getName(result) );
  6338. return result;
  6339. }
  6340. const uint32_t minSwapBufferCount = bx::max<uint32_t>(surfaceCapabilities.minImageCount, 2);
  6341. const uint32_t maxSwapBufferCount = surfaceCapabilities.maxImageCount == 0
  6342. ? kMaxBackBuffers
  6343. : bx::min<uint32_t>(surfaceCapabilities.maxImageCount, kMaxBackBuffers)
  6344. ;
  6345. if (minSwapBufferCount > maxSwapBufferCount)
  6346. {
  6347. BX_TRACE("Create swapchain error: Incompatible swapchain image count (min: %d, max: %d, MaxBackBuffers: %d)."
  6348. , minSwapBufferCount
  6349. , maxSwapBufferCount
  6350. , kMaxBackBuffers
  6351. );
  6352. return VK_ERROR_INITIALIZATION_FAILED;
  6353. }
  6354. const uint32_t swapBufferCount = bx::clamp<uint32_t>(m_resolution.numBackBuffers, minSwapBufferCount, maxSwapBufferCount);
  6355. const VkColorSpaceKHR surfaceColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
  6356. const bool srgb = !!(m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER);
  6357. m_colorFormat = findSurfaceFormat(m_resolution.formatColor, surfaceColorSpace, srgb);
  6358. m_depthFormat = bgfx::TextureFormat::UnknownDepth;
  6359. if (TextureFormat::Count == m_colorFormat)
  6360. {
  6361. BX_TRACE("Create swapchain error: Unable to find surface format (srgb: %d).", srgb);
  6362. return VK_ERROR_INITIALIZATION_FAILED;
  6363. }
  6364. const VkFormat surfaceFormat = srgb
  6365. ? s_textureFormat[m_colorFormat].m_fmtSrgb
  6366. : s_textureFormat[m_colorFormat].m_fmt
  6367. ;
  6368. const uint32_t width = bx::clamp<uint32_t>(
  6369. m_resolution.width
  6370. , surfaceCapabilities.minImageExtent.width
  6371. , surfaceCapabilities.maxImageExtent.width
  6372. );
  6373. const uint32_t height = bx::clamp<uint32_t>(
  6374. m_resolution.height
  6375. , surfaceCapabilities.minImageExtent.height
  6376. , surfaceCapabilities.maxImageExtent.height
  6377. );
  6378. if (width != m_resolution.width || height != m_resolution.height)
  6379. {
  6380. BX_TRACE("Clamped swapchain resolution from %dx%d to %dx%d"
  6381. , m_resolution.width
  6382. , m_resolution.height
  6383. , width
  6384. , height
  6385. );
  6386. }
  6387. VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
  6388. if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)
  6389. {
  6390. compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
  6391. }
  6392. else if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR)
  6393. {
  6394. compositeAlpha = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
  6395. }
  6396. else if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR)
  6397. {
  6398. compositeAlpha = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR;
  6399. }
  6400. const VkImageUsageFlags imageUsageMask = 0
  6401. | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
  6402. | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
  6403. | VK_IMAGE_USAGE_TRANSFER_DST_BIT
  6404. ;
  6405. const VkImageUsageFlags imageUsage = surfaceCapabilities.supportedUsageFlags & imageUsageMask;
  6406. m_supportsReadback = 0 != (imageUsage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
  6407. m_supportsManualResolve = 0 != (imageUsage & VK_IMAGE_USAGE_TRANSFER_DST_BIT);
  6408. const bool vsync = !!(m_resolution.reset & BGFX_RESET_VSYNC);
  6409. uint32_t presentModeIdx = findPresentMode(vsync);
  6410. if (UINT32_MAX == presentModeIdx)
  6411. {
  6412. BX_TRACE("Create swapchain error: Unable to find present mode (vsync: %d).", vsync);
  6413. return VK_ERROR_INITIALIZATION_FAILED;
  6414. }
  6415. m_sci.surface = m_surface;
  6416. m_sci.minImageCount = swapBufferCount;
  6417. m_sci.imageFormat = surfaceFormat;
  6418. m_sci.imageColorSpace = surfaceColorSpace;
  6419. m_sci.imageExtent.width = width;
  6420. m_sci.imageExtent.height = height;
  6421. m_sci.imageUsage = imageUsage;
  6422. m_sci.compositeAlpha = compositeAlpha;
  6423. m_sci.presentMode = s_presentMode[presentModeIdx].mode;
  6424. m_sci.clipped = VK_FALSE;
  6425. result = vkCreateSwapchainKHR(device, &m_sci, allocatorCb, &m_swapChain);
  6426. if (VK_SUCCESS != result)
  6427. {
  6428. BX_TRACE("Create swapchain error: vkCreateSwapchainKHR failed %d: %s.", result, getName(result) );
  6429. return result;
  6430. }
  6431. m_sci.oldSwapchain = m_swapChain;
  6432. result = vkGetSwapchainImagesKHR(device, m_swapChain, &m_numSwapChainImages, NULL);
  6433. if (VK_SUCCESS != result)
  6434. {
  6435. BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR failed %d: %s.", result, getName(result) );
  6436. return result;
  6437. }
  6438. BX_TRACE("Create swapchain numSwapChainImages %d, minImageCount %d, BX_COUNTOF(m_backBufferColorImage) %d"
  6439. , m_numSwapChainImages
  6440. , m_sci.minImageCount
  6441. , BX_COUNTOF(m_backBufferColorImage)
  6442. );
  6443. setDebugObjectName(device, m_swapChain, "m_swapChain");
  6444. if (m_numSwapChainImages < m_sci.minImageCount)
  6445. {
  6446. BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR: numSwapchainImages %d < minImageCount %d."
  6447. , m_numSwapChainImages
  6448. , m_sci.minImageCount
  6449. );
  6450. return VK_ERROR_INITIALIZATION_FAILED;
  6451. }
  6452. if (m_numSwapChainImages > BX_COUNTOF(m_backBufferColorImage) )
  6453. {
  6454. BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR: numSwapchainImages %d > countof(m_backBufferColorImage) %d."
  6455. , m_numSwapChainImages
  6456. , BX_COUNTOF(m_backBufferColorImage)
  6457. );
  6458. return VK_ERROR_INITIALIZATION_FAILED;
  6459. }
  6460. result = vkGetSwapchainImagesKHR(device, m_swapChain, &m_numSwapChainImages, &m_backBufferColorImage[0]);
  6461. if (VK_SUCCESS != result && VK_INCOMPLETE != result)
  6462. {
  6463. BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR failed %d: %s."
  6464. , result
  6465. , getName(result)
  6466. );
  6467. return result;
  6468. }
  6469. VkImageViewCreateInfo ivci;
  6470. ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
  6471. ivci.pNext = NULL;
  6472. ivci.flags = 0;
  6473. ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
  6474. ivci.format = m_sci.imageFormat;
  6475. ivci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
  6476. ivci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
  6477. ivci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
  6478. ivci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
  6479. ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  6480. ivci.subresourceRange.baseMipLevel = 0;
  6481. ivci.subresourceRange.levelCount = 1;
  6482. ivci.subresourceRange.baseArrayLayer = 0;
  6483. ivci.subresourceRange.layerCount = 1;
  6484. for (uint32_t ii = 0; ii < m_numSwapChainImages; ++ii)
  6485. {
  6486. ivci.image = m_backBufferColorImage[ii];
  6487. result = vkCreateImageView(device, &ivci, allocatorCb, &m_backBufferColorImageView[ii]);
  6488. if (VK_SUCCESS != result)
  6489. {
  6490. BX_TRACE("Create swapchain error: vkCreateImageView failed %d: %s.", result, getName(result) );
  6491. return result;
  6492. }
  6493. setDebugObjectName(device, m_backBufferColorImageView[ii], "m_backBufferColorImageView[%d]", ii);
  6494. m_backBufferColorImageLayout[ii] = VK_IMAGE_LAYOUT_UNDEFINED;
  6495. }
  6496. BX_TRACE("Successfully created swapchain (%dx%d) with %d images.", width, height, m_numSwapChainImages);
  6497. VkSemaphoreCreateInfo sci;
  6498. sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
  6499. sci.pNext = NULL;
  6500. sci.flags = 0;
  6501. // We will make a fully filled pool of semaphores and cycle through those.
  6502. // This is to make sure we have enough, even in the case where there are
  6503. // more frames in flight than images on the swapchain.
  6504. for (uint32_t ii = 0; ii < kMaxBackBuffers; ++ii)
  6505. {
  6506. if (VK_SUCCESS != vkCreateSemaphore(device, &sci, allocatorCb, &m_presentDoneSemaphore[ii])
  6507. || VK_SUCCESS != vkCreateSemaphore(device, &sci, allocatorCb, &m_renderDoneSemaphore[ii]) )
  6508. {
  6509. BX_TRACE("Create swapchain error: vkCreateSemaphore failed %d: %s.", result, getName(result) );
  6510. return result;
  6511. }
  6512. setDebugObjectName(device, m_presentDoneSemaphore[ii], "m_presentDoneSemaphore[%d]", ii);
  6513. setDebugObjectName(device, m_renderDoneSemaphore[ii], "m_renderDoneSemaphore[%d]", ii);
  6514. }
  6515. m_backBufferColorIdx = 0;
  6516. m_currentSemaphore = 0;
  6517. m_needPresent = false;
  6518. m_needToRecreateSwapchain = false;
  6519. return result;
  6520. }
  6521. void SwapChainVK::releaseSwapChain()
  6522. {
  6523. BGFX_PROFILER_SCOPE("SwapChainVK::releaseSwapChain", kColorFrame);
  6524. for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii)
  6525. {
  6526. release(m_backBufferColorImageView[ii]);
  6527. m_backBufferFence[ii] = VK_NULL_HANDLE;
  6528. }
  6529. for (uint32_t ii = 0; ii < kMaxBackBuffers; ++ii)
  6530. {
  6531. release(m_presentDoneSemaphore[ii]);
  6532. release(m_renderDoneSemaphore[ii]);
  6533. }
  6534. release(m_swapChain);
  6535. }
  6536. VkResult SwapChainVK::createAttachments(VkCommandBuffer _commandBuffer)
  6537. {
  6538. BGFX_PROFILER_SCOPE("SwapChainVK::createAttachments", kColorFrame);
  6539. VkResult result = VK_SUCCESS;
  6540. const uint32_t samplerIndex = (m_resolution.reset & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT;
  6541. const uint64_t textureFlags = (uint64_t(samplerIndex + 1) << BGFX_TEXTURE_RT_MSAA_SHIFT) | BGFX_TEXTURE_RT | BGFX_TEXTURE_RT_WRITE_ONLY;
  6542. m_sampler = s_msaa[samplerIndex];
  6543. const uint16_t requiredCaps = m_sampler.Count > 1
  6544. ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA
  6545. : BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
  6546. ;
  6547. if (bimg::isDepth(bimg::TextureFormat::Enum(m_resolution.formatDepthStencil) ) )
  6548. {
  6549. // the spec guarantees that at least one of D24S8 and D32FS8 is supported
  6550. VkFormat depthFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
  6551. if (g_caps.formats[m_resolution.formatDepthStencil] & requiredCaps)
  6552. {
  6553. depthFormat = s_textureFormat[m_resolution.formatDepthStencil].m_fmtDsv;
  6554. }
  6555. else if (g_caps.formats[TextureFormat::D24S8] & requiredCaps)
  6556. {
  6557. depthFormat = s_textureFormat[TextureFormat::D24S8].m_fmtDsv;
  6558. }
  6559. result = m_backBufferDepthStencil.create(
  6560. _commandBuffer
  6561. , m_sci.imageExtent.width
  6562. , m_sci.imageExtent.height
  6563. , textureFlags
  6564. , depthFormat
  6565. );
  6566. if (VK_SUCCESS != result)
  6567. {
  6568. BX_TRACE("Create swapchain error: creating depth stencil image failed %d: %s.", result, getName(result) );
  6569. return result;
  6570. }
  6571. result = m_backBufferDepthStencil.createView(0, 1, 0, 1
  6572. , VK_IMAGE_VIEW_TYPE_2D
  6573. , m_backBufferDepthStencil.m_aspectFlags
  6574. , true
  6575. , &m_backBufferDepthStencilImageView
  6576. );
  6577. if (VK_SUCCESS != result)
  6578. {
  6579. BX_TRACE("Create swapchain error: creating depth stencil image view failed %d: %s.", result, getName(result) );
  6580. return result;
  6581. }
  6582. if (m_sampler.Count > 1)
  6583. {
  6584. result = m_backBufferColorMsaa.create(
  6585. _commandBuffer
  6586. , m_sci.imageExtent.width
  6587. , m_sci.imageExtent.height
  6588. , textureFlags
  6589. , m_sci.imageFormat
  6590. );
  6591. if (VK_SUCCESS != result)
  6592. {
  6593. BX_TRACE("Create swapchain error: creating MSAA color image failed %d: %s.", result, getName(result) );
  6594. return result;
  6595. }
  6596. result = m_backBufferColorMsaa.createView(0, 1, 0, 1
  6597. , VK_IMAGE_VIEW_TYPE_2D
  6598. , m_backBufferColorMsaa.m_aspectFlags
  6599. , true
  6600. , &m_backBufferColorMsaaImageView
  6601. );
  6602. if (VK_SUCCESS != result)
  6603. {
  6604. BX_TRACE("Create swapchain error: creating MSAA color image view failed %d: %s.", result, getName(result) );
  6605. return result;
  6606. }
  6607. }
  6608. }
  6609. return result;
  6610. }
  6611. void SwapChainVK::releaseAttachments()
  6612. {
  6613. BGFX_PROFILER_SCOPE("SwapChainVK::releaseAttachments", kColorFrame);
  6614. release(m_backBufferDepthStencilImageView);
  6615. release(m_backBufferColorMsaaImageView);
  6616. m_backBufferDepthStencil.destroy();
  6617. m_backBufferColorMsaa.destroy();
  6618. }
  6619. VkResult SwapChainVK::createFrameBuffer()
  6620. {
  6621. BGFX_PROFILER_SCOPE("SwapChainVK::createFrameBuffer", kColorFrame);
  6622. VkResult result = VK_SUCCESS;
  6623. const VkDevice device = s_renderVK->m_device;
  6624. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  6625. VkRenderPass renderPass;
  6626. result = s_renderVK->getRenderPass(*this, &renderPass, 0);
  6627. if (VK_SUCCESS != result)
  6628. {
  6629. return result;
  6630. }
  6631. for (uint32_t ii = 0; ii < m_numSwapChainImages; ++ii)
  6632. {
  6633. uint32_t numAttachments = 0;
  6634. ::VkImageView attachments[3];
  6635. attachments[numAttachments++] = m_sampler.Count > 1
  6636. ? m_backBufferColorMsaaImageView
  6637. : m_backBufferColorImageView[ii]
  6638. ;
  6639. if (NULL != m_backBufferDepthStencilImageView)
  6640. {
  6641. attachments[numAttachments++] = m_backBufferDepthStencilImageView;
  6642. }
  6643. if (m_sampler.Count > 1 && !m_supportsManualResolve)
  6644. {
  6645. attachments[numAttachments++] = m_backBufferColorImageView[ii];
  6646. }
  6647. VkFramebufferCreateInfo fci;
  6648. fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
  6649. fci.pNext = NULL;
  6650. fci.flags = 0;
  6651. fci.renderPass = renderPass;
  6652. fci.attachmentCount = numAttachments;
  6653. fci.pAttachments = attachments;
  6654. fci.width = m_sci.imageExtent.width;
  6655. fci.height = m_sci.imageExtent.height;
  6656. fci.layers = 1;
  6657. result = vkCreateFramebuffer(device, &fci, allocatorCb, &m_backBufferFrameBuffer[ii]);
  6658. if (VK_SUCCESS != result)
  6659. {
  6660. return result;
  6661. }
  6662. }
  6663. return result;
  6664. }
  6665. void SwapChainVK::releaseFrameBuffer()
  6666. {
  6667. for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii)
  6668. {
  6669. release(m_backBufferFrameBuffer[ii]);
  6670. }
  6671. }
  6672. uint32_t SwapChainVK::findPresentMode(bool _vsync)
  6673. {
  6674. BGFX_PROFILER_SCOPE("SwapChainVK::findPresentMode", kColorFrame);
  6675. VkResult result = VK_SUCCESS;
  6676. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  6677. uint32_t numPresentModes;
  6678. result = vkGetPhysicalDeviceSurfacePresentModesKHR(
  6679. physicalDevice
  6680. , m_surface
  6681. , &numPresentModes
  6682. , NULL
  6683. );
  6684. if (VK_SUCCESS != result)
  6685. {
  6686. BX_TRACE("findPresentMode error: vkGetPhysicalDeviceSurfacePresentModesKHR failed %d: %s.", result, getName(result) );
  6687. return UINT32_MAX;
  6688. }
  6689. VkPresentModeKHR presentModes[16];
  6690. numPresentModes = bx::min<uint32_t>(numPresentModes, BX_COUNTOF(presentModes) );
  6691. result = vkGetPhysicalDeviceSurfacePresentModesKHR(
  6692. physicalDevice
  6693. , m_surface
  6694. , &numPresentModes
  6695. , presentModes
  6696. );
  6697. if (VK_SUCCESS != result)
  6698. {
  6699. BX_TRACE("findPresentMode error: vkGetPhysicalDeviceSurfacePresentModesKHR failed %d: %s.", result, getName(result) );
  6700. return UINT32_MAX;
  6701. }
  6702. uint32_t idx = UINT32_MAX;
  6703. for (uint32_t ii = 0; ii < BX_COUNTOF(s_presentMode) && UINT32_MAX == idx; ++ii)
  6704. {
  6705. for (uint32_t jj = 0; jj < numPresentModes; ++jj)
  6706. {
  6707. const PresentMode& pm = s_presentMode[ii];
  6708. if (pm.mode == presentModes[jj]
  6709. && pm.vsync == _vsync)
  6710. {
  6711. idx = ii;
  6712. break;
  6713. }
  6714. }
  6715. }
  6716. if (UINT32_MAX == idx)
  6717. {
  6718. idx = 0;
  6719. BX_TRACE("Present mode not found! Defaulting to %s.", s_presentMode[idx].name);
  6720. }
  6721. return idx;
  6722. }
  6723. TextureFormat::Enum SwapChainVK::findSurfaceFormat(TextureFormat::Enum _format, VkColorSpaceKHR _colorSpace, bool _srgb)
  6724. {
  6725. BGFX_PROFILER_SCOPE("SwapChainVK::findSurfaceFormat", kColorFrame);
  6726. VkResult result = VK_SUCCESS;
  6727. TextureFormat::Enum selectedFormat = TextureFormat::Count;
  6728. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  6729. uint32_t numSurfaceFormats;
  6730. result = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &numSurfaceFormats, NULL);
  6731. if (VK_SUCCESS != result)
  6732. {
  6733. BX_TRACE("findSurfaceFormat error: vkGetPhysicalDeviceSurfaceFormatsKHR failed %d: %s.", result, getName(result) );
  6734. return selectedFormat;
  6735. }
  6736. VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)bx::alloc(g_allocator, numSurfaceFormats * sizeof(VkSurfaceFormatKHR) );
  6737. result = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats);
  6738. if (VK_SUCCESS != result)
  6739. {
  6740. BX_TRACE("findSurfaceFormat error: vkGetPhysicalDeviceSurfaceFormatsKHR failed %d: %s.", result, getName(result) );
  6741. bx::free(g_allocator, surfaceFormats);
  6742. return selectedFormat;
  6743. }
  6744. const TextureFormat::Enum requestedFormats[] =
  6745. {
  6746. _format,
  6747. TextureFormat::BGRA8,
  6748. TextureFormat::RGBA8,
  6749. };
  6750. for (uint32_t ii = 0; ii < BX_COUNTOF(requestedFormats) && TextureFormat::Count == selectedFormat; ++ii)
  6751. {
  6752. const TextureFormat::Enum requested = requestedFormats[ii];
  6753. const VkFormat requestedVkFormat = _srgb
  6754. ? s_textureFormat[requested].m_fmtSrgb
  6755. : s_textureFormat[requested].m_fmt
  6756. ;
  6757. for (uint32_t jj = 0; jj < numSurfaceFormats; jj++)
  6758. {
  6759. if (_colorSpace == surfaceFormats[jj].colorSpace
  6760. && requestedVkFormat == surfaceFormats[jj].format)
  6761. {
  6762. selectedFormat = requested;
  6763. if (0 != ii
  6764. && s_renderVK->m_swapChainFormats[_format] != selectedFormat)
  6765. {
  6766. s_renderVK->m_swapChainFormats[_format] = selectedFormat;
  6767. BX_TRACE(
  6768. "findSurfaceFormat: Surface format %s not found! Defaulting to %s."
  6769. , bimg::getName(bimg::TextureFormat::Enum(_format) )
  6770. , bimg::getName(bimg::TextureFormat::Enum(selectedFormat) )
  6771. );
  6772. }
  6773. break;
  6774. }
  6775. }
  6776. }
  6777. bx::free(g_allocator, surfaceFormats);
  6778. if (TextureFormat::Count == selectedFormat)
  6779. {
  6780. BX_TRACE("findSurfaceFormat error: No supported surface format found.");
  6781. }
  6782. return selectedFormat;
  6783. }
  6784. bool SwapChainVK::acquire(VkCommandBuffer _commandBuffer)
  6785. {
  6786. BGFX_PROFILER_SCOPE("SwapChainVK::acquire", kColorFrame);
  6787. if (VK_NULL_HANDLE == m_swapChain
  6788. || m_needToRecreateSwapchain)
  6789. {
  6790. return false;
  6791. }
  6792. if (!m_needPresent)
  6793. {
  6794. const VkDevice device = s_renderVK->m_device;
  6795. m_lastImageAcquiredSemaphore = m_presentDoneSemaphore[m_currentSemaphore];
  6796. m_lastImageRenderedSemaphore = m_renderDoneSemaphore[m_currentSemaphore];
  6797. m_currentSemaphore = (m_currentSemaphore + 1) % kMaxBackBuffers;
  6798. VkResult result;
  6799. {
  6800. BGFX_PROFILER_SCOPE("vkAcquireNextImageKHR", kColorFrame);
  6801. result = vkAcquireNextImageKHR(
  6802. device
  6803. , m_swapChain
  6804. , UINT64_MAX
  6805. , m_lastImageAcquiredSemaphore
  6806. , VK_NULL_HANDLE
  6807. , &m_backBufferColorIdx
  6808. );
  6809. }
  6810. if (result != VK_SUCCESS)
  6811. {
  6812. BX_TRACE("vkAcquireNextImageKHR(...): result = %s", getName(result) );
  6813. }
  6814. switch (result)
  6815. {
  6816. case VK_SUCCESS:
  6817. break;
  6818. case VK_ERROR_SURFACE_LOST_KHR:
  6819. m_needToRecreateSurface = true;
  6820. m_needToRecreateSwapchain = true;
  6821. return false;
  6822. case VK_ERROR_OUT_OF_DATE_KHR:
  6823. case VK_SUBOPTIMAL_KHR:
  6824. m_needToRecreateSwapchain = true;
  6825. return false;
  6826. default:
  6827. BX_ASSERT(VK_SUCCESS == result, "vkAcquireNextImageKHR(...); VK error 0x%x: %s", result, getName(result) );
  6828. return false;
  6829. }
  6830. if (VK_NULL_HANDLE != m_backBufferFence[m_backBufferColorIdx])
  6831. {
  6832. BGFX_PROFILER_SCOPE("vkWaitForFences", kColorWait);
  6833. VK_CHECK(vkWaitForFences(
  6834. device
  6835. , 1
  6836. , &m_backBufferFence[m_backBufferColorIdx]
  6837. , VK_TRUE
  6838. , UINT64_MAX
  6839. ) );
  6840. }
  6841. transitionImage(_commandBuffer);
  6842. m_needPresent = true;
  6843. }
  6844. return true;
  6845. }
  6846. void SwapChainVK::present()
  6847. {
  6848. BGFX_PROFILER_SCOPE("SwapChainVk::present", kColorFrame);
  6849. if (VK_NULL_HANDLE != m_swapChain
  6850. && m_needPresent)
  6851. {
  6852. VkPresentInfoKHR pi;
  6853. pi.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
  6854. pi.pNext = NULL;
  6855. pi.waitSemaphoreCount = 1;
  6856. pi.pWaitSemaphores = &m_lastImageRenderedSemaphore;
  6857. pi.swapchainCount = 1;
  6858. pi.pSwapchains = &m_swapChain;
  6859. pi.pImageIndices = &m_backBufferColorIdx;
  6860. pi.pResults = NULL;
  6861. VkResult result;
  6862. {
  6863. BGFX_PROFILER_SCOPE("vkQueuePresentHKR", kColorFrame);
  6864. result = vkQueuePresentKHR(m_queue, &pi);
  6865. }
  6866. if (result != VK_SUCCESS)
  6867. {
  6868. BX_TRACE("vkQueuePresentKHR(...): result = %s", getName(result) );
  6869. }
  6870. switch (result)
  6871. {
  6872. case VK_ERROR_SURFACE_LOST_KHR:
  6873. m_needToRecreateSurface = true;
  6874. m_needToRecreateSwapchain = true;
  6875. break;
  6876. case VK_ERROR_OUT_OF_DATE_KHR:
  6877. case VK_SUBOPTIMAL_KHR:
  6878. m_needToRecreateSwapchain = true;
  6879. break;
  6880. default:
  6881. BX_ASSERT(VK_SUCCESS == result, "vkQueuePresentKHR(...); VK error 0x%x: %s", result, getName(result) );
  6882. break;
  6883. }
  6884. m_needPresent = false;
  6885. m_lastImageRenderedSemaphore = VK_NULL_HANDLE;
  6886. }
  6887. }
  6888. void SwapChainVK::transitionImage(VkCommandBuffer _commandBuffer)
  6889. {
  6890. VkImageLayout& layout = m_backBufferColorImageLayout[m_backBufferColorIdx];
  6891. const bool toPresent = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout;
  6892. const VkImageLayout newLayout = toPresent
  6893. ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
  6894. : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
  6895. ;
  6896. layout = toPresent ? layout : VK_IMAGE_LAYOUT_UNDEFINED;
  6897. setImageMemoryBarrier(
  6898. _commandBuffer
  6899. , m_backBufferColorImage[m_backBufferColorIdx]
  6900. , VK_IMAGE_ASPECT_COLOR_BIT
  6901. , layout
  6902. , newLayout
  6903. );
  6904. layout = newLayout;
  6905. }
  6906. void FrameBufferVK::create(uint8_t _num, const Attachment* _attachment)
  6907. {
  6908. BGFX_PROFILER_SCOPE("FrameBufferVK::create", kColorFrame);
  6909. m_numTh = _num;
  6910. bx::memCopy(m_attachment, _attachment, sizeof(Attachment) * _num);
  6911. postReset();
  6912. }
  6913. VkResult FrameBufferVK::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _colorFormat, TextureFormat::Enum _depthFormat)
  6914. {
  6915. BGFX_PROFILER_SCOPE("FrameBufferVK::create", kColorFrame);
  6916. VkResult result = VK_SUCCESS;
  6917. Resolution resolution = s_renderVK->m_resolution;
  6918. resolution.formatColor = TextureFormat::Count == _colorFormat ? resolution.formatColor : _colorFormat;
  6919. resolution.formatDepthStencil = TextureFormat::Count == _depthFormat ? resolution.formatDepthStencil : _depthFormat;
  6920. resolution.width = _width;
  6921. resolution.height = _height;
  6922. if (_denseIdx != UINT16_MAX)
  6923. {
  6924. resolution.reset &= ~BGFX_RESET_MSAA_MASK;
  6925. }
  6926. result = m_swapChain.create(s_renderVK->m_commandBuffer, _nwh, resolution);
  6927. if (VK_SUCCESS != result)
  6928. {
  6929. return result;
  6930. }
  6931. result = s_renderVK->getRenderPass(m_swapChain, &m_renderPass, 0);
  6932. if (VK_SUCCESS != result)
  6933. {
  6934. return result;
  6935. }
  6936. m_denseIdx = _denseIdx;
  6937. m_nwh = _nwh;
  6938. m_width = m_swapChain.m_sci.imageExtent.width;
  6939. m_height = m_swapChain.m_sci.imageExtent.height;
  6940. m_sampler = m_swapChain.m_sampler;
  6941. return result;
  6942. }
  6943. VkRenderPass FrameBufferVK::getRenderPass(uint16_t _clearFlags) const
  6944. {
  6945. VkRenderPass renderPass;
  6946. if (m_numTh > 0)
  6947. {
  6948. VK_CHECK(s_renderVK->getRenderPass(m_numTh, m_attachment, &renderPass, _clearFlags) );
  6949. }
  6950. else
  6951. {
  6952. VK_CHECK(s_renderVK->getRenderPass(m_swapChain, &renderPass, _clearFlags) );
  6953. }
  6954. return renderPass;
  6955. }
  6956. void FrameBufferVK::preReset()
  6957. {
  6958. BGFX_PROFILER_SCOPE("FrameBufferVK::preReset", kColorFrame);
  6959. if (VK_NULL_HANDLE != m_framebuffer)
  6960. {
  6961. s_renderVK->release(m_framebuffer);
  6962. for (uint8_t ii = 0; ii < m_numTh; ++ii)
  6963. {
  6964. s_renderVK->release(m_textureImageViews[ii]);
  6965. }
  6966. }
  6967. }
  6968. void FrameBufferVK::postReset()
  6969. {
  6970. BGFX_PROFILER_SCOPE("FrameBufferVK::postReset", kColorFrame);
  6971. if (m_numTh > 0)
  6972. {
  6973. const VkDevice device = s_renderVK->m_device;
  6974. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  6975. VK_CHECK(s_renderVK->getRenderPass(m_numTh, m_attachment, &m_renderPass, 0) );
  6976. m_depth = BGFX_INVALID_HANDLE;
  6977. m_num = 0;
  6978. for (uint8_t ii = 0; ii < m_numTh; ++ii)
  6979. {
  6980. const Attachment& at = m_attachment[ii];
  6981. const TextureVK& texture = s_renderVK->m_textures[at.handle.idx];
  6982. VK_CHECK(texture.createView(
  6983. at.layer
  6984. , at.numLayers
  6985. , at.mip
  6986. , 1
  6987. , at.numLayers > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D
  6988. , texture.m_aspectFlags
  6989. , true
  6990. , &m_textureImageViews[ii]
  6991. ) );
  6992. if (texture.m_aspectFlags & VK_IMAGE_ASPECT_COLOR_BIT)
  6993. {
  6994. m_texture[m_num] = at.handle;
  6995. m_num++;
  6996. }
  6997. else if (texture.m_aspectFlags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) )
  6998. {
  6999. m_depth = at.handle;
  7000. }
  7001. }
  7002. const TextureVK& firstTexture = s_renderVK->m_textures[m_attachment[0].handle.idx];
  7003. m_width = bx::uint32_max(firstTexture.m_width >> m_attachment[0].mip, 1);
  7004. m_height = bx::uint32_max(firstTexture.m_height >> m_attachment[0].mip, 1);
  7005. m_sampler = firstTexture.m_sampler;
  7006. VkFramebufferCreateInfo fci;
  7007. fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
  7008. fci.pNext = NULL;
  7009. fci.flags = 0;
  7010. fci.renderPass = m_renderPass;
  7011. fci.attachmentCount = m_numTh;
  7012. fci.pAttachments = &m_textureImageViews[0];
  7013. fci.width = m_width;
  7014. fci.height = m_height;
  7015. fci.layers = m_attachment[0].numLayers;
  7016. VK_CHECK(vkCreateFramebuffer(device, &fci, allocatorCb, &m_framebuffer) );
  7017. m_currentFramebuffer = m_framebuffer;
  7018. }
  7019. }
  7020. void FrameBufferVK::update(VkCommandBuffer _commandBuffer, const Resolution& _resolution)
  7021. {
  7022. BGFX_PROFILER_SCOPE("FrameBufferVK::update", kColorResource);
  7023. m_swapChain.update(_commandBuffer, m_nwh, _resolution);
  7024. VK_CHECK(s_renderVK->getRenderPass(m_swapChain, &m_renderPass, 0) );
  7025. // Don't believe the passed Resolution, as the Vulkan driver might have
  7026. // specified another resolution, which we had to obey.
  7027. m_width = m_swapChain.m_sci.imageExtent.width;
  7028. m_height = m_swapChain.m_sci.imageExtent.height;
  7029. m_sampler = m_swapChain.m_sampler;
  7030. }
  7031. void FrameBufferVK::resolve()
  7032. {
  7033. if (!m_needResolve)
  7034. {
  7035. return;
  7036. }
  7037. BGFX_PROFILER_SCOPE("FrameBufferVK::resolve", kColorFrame);
  7038. if (NULL == m_nwh)
  7039. {
  7040. for (uint32_t ii = 0; ii < m_numTh; ++ii)
  7041. {
  7042. const Attachment& at = m_attachment[ii];
  7043. if (isValid(at.handle) )
  7044. {
  7045. TextureVK& texture = s_renderVK->m_textures[at.handle.idx];
  7046. texture.resolve(s_renderVK->m_commandBuffer, at.resolve, at.layer, at.numLayers, at.mip);
  7047. }
  7048. }
  7049. }
  7050. else if (isRenderable()
  7051. && m_sampler.Count > 1
  7052. && m_swapChain.m_supportsManualResolve)
  7053. {
  7054. m_swapChain.m_backBufferColorMsaa.m_singleMsaaImage = m_swapChain.m_backBufferColorImage[m_swapChain.m_backBufferColorIdx];
  7055. m_swapChain.m_backBufferColorMsaa.m_currentSingleMsaaImageLayout = m_swapChain.m_backBufferColorImageLayout[m_swapChain.m_backBufferColorIdx];
  7056. m_swapChain.m_backBufferColorMsaa.resolve(s_renderVK->m_commandBuffer, 0, 0, 1, 0);
  7057. m_swapChain.m_backBufferColorMsaa.m_singleMsaaImage = VK_NULL_HANDLE;
  7058. m_swapChain.m_backBufferColorMsaa.m_currentSingleMsaaImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  7059. }
  7060. m_needResolve = false;
  7061. }
  7062. uint16_t FrameBufferVK::destroy()
  7063. {
  7064. BGFX_PROFILER_SCOPE("FrameBufferVK::destroy", kColorFrame);
  7065. preReset();
  7066. if (NULL != m_nwh)
  7067. {
  7068. m_swapChain.destroy();
  7069. m_nwh = NULL;
  7070. m_needPresent = false;
  7071. }
  7072. m_numTh = 0;
  7073. m_num = 0;
  7074. m_depth = BGFX_INVALID_HANDLE;
  7075. m_needResolve = false;
  7076. uint16_t denseIdx = m_denseIdx;
  7077. m_denseIdx = UINT16_MAX;
  7078. return denseIdx;
  7079. }
  7080. bool FrameBufferVK::acquire(VkCommandBuffer _commandBuffer)
  7081. {
  7082. BGFX_PROFILER_SCOPE("FrameBufferVK::acquire", kColorFrame);
  7083. bool acquired = true;
  7084. if (NULL != m_nwh)
  7085. {
  7086. acquired = m_swapChain.acquire(_commandBuffer);
  7087. m_needPresent = m_swapChain.m_needPresent;
  7088. m_currentFramebuffer = m_swapChain.m_backBufferFrameBuffer[m_swapChain.m_backBufferColorIdx];
  7089. }
  7090. m_needResolve = true;
  7091. return acquired;
  7092. }
  7093. void FrameBufferVK::present()
  7094. {
  7095. BGFX_PROFILER_SCOPE("FrameBufferVK::present", kColorFrame);
  7096. m_swapChain.present();
  7097. m_needPresent = false;
  7098. }
  7099. bool FrameBufferVK::isRenderable() const
  7100. {
  7101. return false
  7102. || (NULL == m_nwh)
  7103. || m_swapChain.m_needPresent
  7104. ;
  7105. }
  7106. VkResult CommandQueueVK::init(uint32_t _queueFamily, VkQueue _queue)
  7107. {
  7108. m_queueFamily = _queueFamily;
  7109. m_queue = _queue;
  7110. m_activeCommandBuffer = VK_NULL_HANDLE;
  7111. m_consumeIndex = 0;
  7112. return reset();
  7113. }
  7114. VkResult CommandQueueVK::reset()
  7115. {
  7116. shutdown();
  7117. m_currentFrameInFlight = 0;
  7118. m_consumeIndex = 0;
  7119. m_numSignalSemaphores = 0;
  7120. m_numWaitSemaphores = 0;
  7121. m_activeCommandBuffer = VK_NULL_HANDLE;
  7122. m_currentFence = VK_NULL_HANDLE;
  7123. m_completedFence = VK_NULL_HANDLE;
  7124. m_submitted = 0;
  7125. VkCommandPoolCreateInfo cpci;
  7126. cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
  7127. cpci.pNext = NULL;
  7128. cpci.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
  7129. cpci.queueFamilyIndex = m_queueFamily;
  7130. VkCommandBufferAllocateInfo cbai;
  7131. cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
  7132. cbai.pNext = NULL;
  7133. cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
  7134. cbai.commandBufferCount = 1;
  7135. VkFenceCreateInfo fci;
  7136. fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
  7137. fci.pNext = NULL;
  7138. fci.flags = VK_FENCE_CREATE_SIGNALED_BIT;
  7139. VkResult result = VK_SUCCESS;
  7140. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  7141. const VkDevice device = s_renderVK->m_device;
  7142. for (uint32_t ii = 0, maxFrameLatency = s_renderVK->m_maxFrameLatency; ii < maxFrameLatency; ++ii)
  7143. {
  7144. result = vkCreateCommandPool(
  7145. device
  7146. , &cpci
  7147. , allocatorCb
  7148. , &m_commandList[ii].m_commandPool
  7149. );
  7150. if (VK_SUCCESS != result)
  7151. {
  7152. BX_TRACE("Create command queue error: vkCreateCommandPool failed %d: %s.", result, getName(result) );
  7153. return result;
  7154. }
  7155. cbai.commandPool = m_commandList[ii].m_commandPool;
  7156. result = vkAllocateCommandBuffers(
  7157. device
  7158. , &cbai
  7159. , &m_commandList[ii].m_commandBuffer
  7160. );
  7161. if (VK_SUCCESS != result)
  7162. {
  7163. BX_TRACE("Create command queue error: vkAllocateCommandBuffers failed %d: %s.", result, getName(result) );
  7164. return result;
  7165. }
  7166. result = vkCreateFence(
  7167. device
  7168. , &fci
  7169. , allocatorCb
  7170. , &m_commandList[ii].m_fence
  7171. );
  7172. if (VK_SUCCESS != result)
  7173. {
  7174. BX_TRACE("Create command queue error: vkCreateFence failed %d: %s.", result, getName(result) );
  7175. return result;
  7176. }
  7177. }
  7178. return result;
  7179. }
  7180. void CommandQueueVK::shutdown()
  7181. {
  7182. kick(true);
  7183. finish(true);
  7184. for (uint32_t ii = 0, maxFrameLatency = s_renderVK->m_maxFrameLatency; ii < maxFrameLatency; ++ii)
  7185. {
  7186. vkDestroy(m_commandList[ii].m_fence);
  7187. m_commandList[ii].m_commandBuffer = VK_NULL_HANDLE;
  7188. vkDestroy(m_commandList[ii].m_commandPool);
  7189. }
  7190. }
  7191. VkResult CommandQueueVK::alloc(VkCommandBuffer* _outCommandBuffer)
  7192. {
  7193. BGFX_PROFILER_SCOPE("CommandQueueVK::alloc", kColorResource);
  7194. VkResult result = VK_SUCCESS;
  7195. if (m_activeCommandBuffer == VK_NULL_HANDLE)
  7196. {
  7197. const VkDevice device = s_renderVK->m_device;
  7198. CommandList& commandList = m_commandList[m_currentFrameInFlight];
  7199. {
  7200. BGFX_PROFILER_SCOPE("vkWaitForFences", kColorWait);
  7201. result = vkWaitForFences(device, 1, &commandList.m_fence, VK_TRUE, UINT64_MAX);
  7202. }
  7203. if (VK_SUCCESS != result)
  7204. {
  7205. BX_TRACE("Allocate command buffer error: vkWaitForFences failed %d: %s.", result, getName(result) );
  7206. return result;
  7207. }
  7208. result = vkResetCommandPool(device, commandList.m_commandPool, 0);
  7209. if (VK_SUCCESS != result)
  7210. {
  7211. BX_TRACE("Allocate command buffer error: vkResetCommandPool failed %d: %s.", result, getName(result) );
  7212. return result;
  7213. }
  7214. VkCommandBufferBeginInfo cbi;
  7215. cbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
  7216. cbi.pNext = NULL;
  7217. cbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
  7218. cbi.pInheritanceInfo = NULL;
  7219. result = vkBeginCommandBuffer(commandList.m_commandBuffer, &cbi);
  7220. if (VK_SUCCESS != result)
  7221. {
  7222. BX_TRACE("Allocate command buffer error: vkBeginCommandBuffer failed %d: %s.", result, getName(result) );
  7223. return result;
  7224. }
  7225. m_activeCommandBuffer = commandList.m_commandBuffer;
  7226. m_currentFence = commandList.m_fence;
  7227. }
  7228. if (NULL != _outCommandBuffer)
  7229. {
  7230. *_outCommandBuffer = m_activeCommandBuffer;
  7231. }
  7232. return result;
  7233. }
  7234. void CommandQueueVK::addWaitSemaphore(VkSemaphore _semaphore, VkPipelineStageFlags _waitFlags)
  7235. {
  7236. BX_ASSERT(m_numWaitSemaphores < BX_COUNTOF(m_waitSemaphores), "Too many wait semaphores.");
  7237. m_waitSemaphores[m_numWaitSemaphores] = _semaphore;
  7238. m_waitSemaphoreStages[m_numWaitSemaphores] = _waitFlags;
  7239. m_numWaitSemaphores++;
  7240. }
  7241. void CommandQueueVK::addSignalSemaphore(VkSemaphore _semaphore)
  7242. {
  7243. BX_ASSERT(m_numSignalSemaphores < BX_COUNTOF(m_signalSemaphores), "Too many signal semaphores.");
  7244. m_signalSemaphores[m_numSignalSemaphores] = _semaphore;
  7245. m_numSignalSemaphores++;
  7246. }
  7247. void CommandQueueVK::kick(bool _wait)
  7248. {
  7249. BGFX_PROFILER_SCOPE("CommandQueueVK::kick", kColorDraw);
  7250. if (VK_NULL_HANDLE != m_activeCommandBuffer)
  7251. {
  7252. const VkDevice device = s_renderVK->m_device;
  7253. setMemoryBarrier(
  7254. m_activeCommandBuffer
  7255. , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
  7256. , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
  7257. );
  7258. VK_CHECK(vkEndCommandBuffer(m_activeCommandBuffer) );
  7259. m_completedFence = m_currentFence;
  7260. m_currentFence = VK_NULL_HANDLE;
  7261. VK_CHECK(vkResetFences(device, 1, &m_completedFence) );
  7262. VkSubmitInfo si;
  7263. si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  7264. si.pNext = NULL;
  7265. si.waitSemaphoreCount = m_numWaitSemaphores;
  7266. si.pWaitSemaphores = &m_waitSemaphores[0];
  7267. si.pWaitDstStageMask = m_waitSemaphoreStages;
  7268. si.commandBufferCount = 1;
  7269. si.pCommandBuffers = &m_activeCommandBuffer;
  7270. si.signalSemaphoreCount = m_numSignalSemaphores;
  7271. si.pSignalSemaphores = &m_signalSemaphores[0];
  7272. m_numWaitSemaphores = 0;
  7273. m_numSignalSemaphores = 0;
  7274. {
  7275. BGFX_PROFILER_SCOPE("vkQueueSubmit", kColorDraw);
  7276. VK_CHECK(vkQueueSubmit(m_queue, 1, &si, m_completedFence) );
  7277. }
  7278. if (_wait)
  7279. {
  7280. BGFX_PROFILER_SCOPE("vkWaitForFences", kColorWait);
  7281. VK_CHECK(vkWaitForFences(device, 1, &m_completedFence, VK_TRUE, UINT64_MAX) );
  7282. }
  7283. m_activeCommandBuffer = VK_NULL_HANDLE;
  7284. m_currentFrameInFlight = (m_currentFrameInFlight + 1) % s_renderVK->m_maxFrameLatency;
  7285. m_submitted++;
  7286. }
  7287. }
  7288. void CommandQueueVK::finish(bool _finishAll)
  7289. {
  7290. BGFX_PROFILER_SCOPE("CommandQueueVK::finish", kColorDraw);
  7291. if (_finishAll)
  7292. {
  7293. for (uint32_t ii = 0, maxFrameLatency = s_renderVK->m_maxFrameLatency; ii < maxFrameLatency; ++ii)
  7294. {
  7295. consume();
  7296. }
  7297. m_consumeIndex = m_currentFrameInFlight;
  7298. }
  7299. else
  7300. {
  7301. consume();
  7302. }
  7303. }
  7304. void CommandQueueVK::release(uint64_t _handle, VkObjectType _type)
  7305. {
  7306. Resource resource;
  7307. resource.m_type = _type;
  7308. resource.m_handle = _handle;
  7309. m_release[m_currentFrameInFlight].push_back(resource);
  7310. }
  7311. void CommandQueueVK::recycleMemory(DeviceMemoryAllocationVK _mem)
  7312. {
  7313. m_recycleAllocs[m_currentFrameInFlight].push_back(_mem);
  7314. }
  7315. void CommandQueueVK::consume()
  7316. {
  7317. BGFX_PROFILER_SCOPE("CommandQueueVK::consume", kColorResource);
  7318. m_consumeIndex = (m_consumeIndex + 1) % s_renderVK->m_maxFrameLatency;
  7319. for (DeviceMemoryAllocationVK& alloc : m_recycleAllocs[m_consumeIndex])
  7320. {
  7321. s_renderVK->m_memoryLru.recycle(alloc);
  7322. }
  7323. m_recycleAllocs[m_consumeIndex].clear();
  7324. for (const Resource& resource : m_release[m_consumeIndex])
  7325. {
  7326. switch (resource.m_type)
  7327. {
  7328. case VK_OBJECT_TYPE_BUFFER: destroy<VkBuffer >(resource.m_handle); break;
  7329. case VK_OBJECT_TYPE_IMAGE_VIEW: destroy<VkImageView >(resource.m_handle); break;
  7330. case VK_OBJECT_TYPE_IMAGE: destroy<VkImage >(resource.m_handle); break;
  7331. case VK_OBJECT_TYPE_FRAMEBUFFER: destroy<VkFramebuffer >(resource.m_handle); break;
  7332. case VK_OBJECT_TYPE_PIPELINE_LAYOUT: destroy<VkPipelineLayout >(resource.m_handle); break;
  7333. case VK_OBJECT_TYPE_PIPELINE: destroy<VkPipeline >(resource.m_handle); break;
  7334. case VK_OBJECT_TYPE_DESCRIPTOR_SET: destroy<VkDescriptorSet >(resource.m_handle); break;
  7335. case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT: destroy<VkDescriptorSetLayout>(resource.m_handle); break;
  7336. case VK_OBJECT_TYPE_RENDER_PASS: destroy<VkRenderPass >(resource.m_handle); break;
  7337. case VK_OBJECT_TYPE_SAMPLER: destroy<VkSampler >(resource.m_handle); break;
  7338. case VK_OBJECT_TYPE_SEMAPHORE: destroy<VkSemaphore >(resource.m_handle); break;
  7339. case VK_OBJECT_TYPE_SURFACE_KHR: destroy<VkSurfaceKHR >(resource.m_handle); break;
  7340. case VK_OBJECT_TYPE_SWAPCHAIN_KHR: destroy<VkSwapchainKHR >(resource.m_handle); break;
  7341. case VK_OBJECT_TYPE_DEVICE_MEMORY: destroy<VkDeviceMemory >(resource.m_handle); break;
  7342. default:
  7343. BX_ASSERT(false, "Invalid resource type: %d", resource.m_type);
  7344. break;
  7345. }
  7346. }
  7347. m_release[m_consumeIndex].clear();
  7348. }
  7349. void RendererContextVK::submitBlit(BlitState& _bs, uint16_t _view)
  7350. {
  7351. BGFX_PROFILER_SCOPE("RendererContextVK::submitBlit", kColorFrame);
  7352. VkImageLayout srcLayouts[BGFX_CONFIG_MAX_BLIT_ITEMS];
  7353. VkImageLayout dstLayouts[BGFX_CONFIG_MAX_BLIT_ITEMS];
  7354. BlitState bs0 = _bs;
  7355. while (bs0.hasItem(_view) )
  7356. {
  7357. uint16_t item = bs0.m_item;
  7358. const BlitItem& blit = bs0.advance();
  7359. TextureVK& src = m_textures[blit.m_src.idx];
  7360. TextureVK& dst = m_textures[blit.m_dst.idx];
  7361. srcLayouts[item] = VK_NULL_HANDLE != src.m_singleMsaaImage ? src.m_currentSingleMsaaImageLayout : src.m_currentImageLayout;
  7362. dstLayouts[item] = dst.m_currentImageLayout;
  7363. }
  7364. bs0 = _bs;
  7365. while (bs0.hasItem(_view) )
  7366. {
  7367. const BlitItem& blit = bs0.advance();
  7368. TextureVK& src = m_textures[blit.m_src.idx];
  7369. TextureVK& dst = m_textures[blit.m_dst.idx];
  7370. src.setImageMemoryBarrier(
  7371. m_commandBuffer
  7372. , blit.m_src.idx == blit.m_dst.idx ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  7373. , VK_NULL_HANDLE != src.m_singleMsaaImage
  7374. );
  7375. if (blit.m_src.idx != blit.m_dst.idx)
  7376. {
  7377. dst.setImageMemoryBarrier(m_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
  7378. }
  7379. const uint16_t srcSamples = VK_NULL_HANDLE != src.m_singleMsaaImage ? 1 : src.m_sampler.Count;
  7380. const uint16_t dstSamples = dst.m_sampler.Count;
  7381. BX_UNUSED(srcSamples, dstSamples);
  7382. BX_ASSERT(
  7383. srcSamples == dstSamples
  7384. , "Mismatching texture sample count (%d != %d)."
  7385. , srcSamples
  7386. , dstSamples
  7387. );
  7388. VkImageCopy copyInfo;
  7389. copyInfo.srcSubresource.aspectMask = src.m_aspectFlags;
  7390. copyInfo.srcSubresource.mipLevel = blit.m_srcMip;
  7391. copyInfo.srcSubresource.baseArrayLayer = 0;
  7392. copyInfo.srcSubresource.layerCount = 1;
  7393. copyInfo.srcOffset.x = blit.m_srcX;
  7394. copyInfo.srcOffset.y = blit.m_srcY;
  7395. copyInfo.srcOffset.z = 0;
  7396. copyInfo.dstSubresource.aspectMask = dst.m_aspectFlags;
  7397. copyInfo.dstSubresource.mipLevel = blit.m_dstMip;
  7398. copyInfo.dstSubresource.baseArrayLayer = 0;
  7399. copyInfo.dstSubresource.layerCount = 1;
  7400. copyInfo.dstOffset.x = blit.m_dstX;
  7401. copyInfo.dstOffset.y = blit.m_dstY;
  7402. copyInfo.dstOffset.z = 0;
  7403. copyInfo.extent.width = blit.m_width;
  7404. copyInfo.extent.height = blit.m_height;
  7405. copyInfo.extent.depth = 1;
  7406. const uint32_t depth = bx::max<uint32_t>(1, blit.m_depth);
  7407. if (VK_IMAGE_VIEW_TYPE_3D == src.m_type)
  7408. {
  7409. BX_ASSERT(VK_IMAGE_VIEW_TYPE_3D == dst.m_type, "Can't blit between 2D and 3D image.");
  7410. copyInfo.srcOffset.z = blit.m_srcZ;
  7411. copyInfo.dstOffset.z = blit.m_dstZ;
  7412. copyInfo.extent.depth = depth;
  7413. }
  7414. else
  7415. {
  7416. copyInfo.srcSubresource.baseArrayLayer = blit.m_srcZ;
  7417. copyInfo.dstSubresource.baseArrayLayer = blit.m_dstZ;
  7418. copyInfo.srcSubresource.layerCount = depth;
  7419. copyInfo.dstSubresource.layerCount = depth;
  7420. }
  7421. vkCmdCopyImage(
  7422. m_commandBuffer
  7423. , VK_NULL_HANDLE != src.m_singleMsaaImage ? src.m_singleMsaaImage : src.m_textureImage
  7424. , VK_NULL_HANDLE != src.m_singleMsaaImage ? src.m_currentSingleMsaaImageLayout : src.m_currentImageLayout
  7425. , dst.m_textureImage
  7426. , dst.m_currentImageLayout
  7427. , 1
  7428. , &copyInfo
  7429. );
  7430. setMemoryBarrier(
  7431. m_commandBuffer
  7432. , VK_PIPELINE_STAGE_TRANSFER_BIT
  7433. , VK_PIPELINE_STAGE_TRANSFER_BIT
  7434. );
  7435. }
  7436. while (_bs.hasItem(_view) )
  7437. {
  7438. uint16_t item = _bs.m_item;
  7439. const BlitItem& blit = _bs.advance();
  7440. TextureVK& src = m_textures[blit.m_src.idx];
  7441. TextureVK& dst = m_textures[blit.m_dst.idx];
  7442. src.setImageMemoryBarrier(m_commandBuffer, srcLayouts[item], VK_NULL_HANDLE != src.m_singleMsaaImage);
  7443. dst.setImageMemoryBarrier(m_commandBuffer, dstLayouts[item]);
  7444. }
  7445. }
  7446. void RendererContextVK::submitUniformCache(UniformCacheState& _ucs, uint16_t _view)
  7447. {
  7448. while (_ucs.hasItem(_view) )
  7449. {
  7450. const UniformCacheItem& uci = _ucs.advance();
  7451. bx::memCopy(m_uniforms[uci.m_handle], &_ucs.m_frame->m_uniformCacheFrame.m_data[uci.m_offset], uci.m_size);
  7452. }
  7453. }
  7454. void RendererContextVK::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
  7455. {
  7456. BX_UNUSED(_clearQuad);
  7457. if (updateResolution(_render->m_resolution) )
  7458. {
  7459. return;
  7460. }
  7461. if (_render->m_capture)
  7462. {
  7463. renderDocTriggerCapture();
  7464. }
  7465. BGFX_VK_PROFILER_BEGIN_LITERAL("rendererSubmit", kColorFrame);
  7466. int64_t timeBegin = bx::getHPCounter();
  7467. int64_t captureElapsed = 0;
  7468. uint32_t frameQueryIdx = UINT32_MAX;
  7469. if (m_timerQuerySupport)
  7470. {
  7471. frameQueryIdx = m_gpuTimer.begin(BGFX_CONFIG_MAX_VIEWS, _render->m_frameNum);
  7472. }
  7473. if (0 < _render->m_iboffset)
  7474. {
  7475. BGFX_PROFILER_SCOPE("bgfx/Update transient index buffer", kColorResource);
  7476. TransientIndexBuffer* ib = _render->m_transientIb;
  7477. m_indexBuffers[ib->handle.idx].update(m_commandBuffer, 0, _render->m_iboffset, ib->data);
  7478. }
  7479. if (0 < _render->m_vboffset)
  7480. {
  7481. BGFX_PROFILER_SCOPE("bgfx/Update transient vertex buffer", kColorResource);
  7482. TransientVertexBuffer* vb = _render->m_transientVb;
  7483. m_vertexBuffers[vb->handle.idx].update(m_commandBuffer, 0, _render->m_vboffset, vb->data);
  7484. }
  7485. _render->sort();
  7486. RenderDraw currentState;
  7487. currentState.clear();
  7488. currentState.m_stateFlags = BGFX_STATE_NONE;
  7489. currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
  7490. static ViewState viewState;
  7491. viewState.reset(_render);
  7492. bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);
  7493. setDebugWireframe(wireframe);
  7494. ProgramHandle currentProgram = BGFX_INVALID_HANDLE;
  7495. bool hasPredefined = false;
  7496. VkPipeline currentPipeline = VK_NULL_HANDLE;
  7497. VkDescriptorSet currentDescriptorSet = VK_NULL_HANDLE;
  7498. uint32_t currentBindHash = 0;
  7499. uint32_t descriptorSetCount = 0;
  7500. VkIndexType currentIndexFormat = VK_INDEX_TYPE_MAX_ENUM;
  7501. SortKey key;
  7502. uint16_t view = UINT16_MAX;
  7503. FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };
  7504. UniformCacheState ucs(_render);
  7505. BlitState bs(_render);
  7506. uint64_t blendFactor = UINT64_MAX;
  7507. bool wasCompute = false;
  7508. bool viewHasScissor = false;
  7509. bool restoreScissor = false;
  7510. Rect viewScissorRect;
  7511. viewScissorRect.clear();
  7512. bool isFrameBufferValid = false;
  7513. uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {};
  7514. uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {};
  7515. uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {};
  7516. uint32_t statsNumIndices = 0;
  7517. uint32_t statsKeyType[2] = {};
  7518. const uint64_t f0 = BGFX_STATE_BLEND_FACTOR;
  7519. const uint64_t f1 = BGFX_STATE_BLEND_INV_FACTOR;
  7520. const uint64_t f2 = BGFX_STATE_BLEND_FACTOR<<4;
  7521. const uint64_t f3 = BGFX_STATE_BLEND_INV_FACTOR<<4;
  7522. VkDescriptorPool& descriptorPool = m_descriptorPool[m_cmd.m_currentFrameInFlight];
  7523. vkResetDescriptorPool(m_device, descriptorPool, 0);
  7524. ChunkedScratchBufferVK& uniformScratchBuffer = m_uniformScratchBuffer;
  7525. uniformScratchBuffer.begin();
  7526. StagingScratchBufferVK& stagingScratchBuffer = m_scratchStagingBuffer[m_cmd.m_currentFrameInFlight];
  7527. setMemoryBarrier(
  7528. m_commandBuffer
  7529. , VK_PIPELINE_STAGE_TRANSFER_BIT
  7530. , VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
  7531. );
  7532. VkRenderPassBeginInfo rpbi;
  7533. rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
  7534. rpbi.pNext = NULL;
  7535. rpbi.clearValueCount = 0;
  7536. rpbi.pClearValues = NULL;
  7537. bool beginRenderPass = false;
  7538. Profiler<TimerQueryVK> profiler(
  7539. _render
  7540. , m_gpuTimer
  7541. , s_viewName
  7542. , m_timerQuerySupport
  7543. );
  7544. m_occlusionQuery.flush(_render);
  7545. if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
  7546. {
  7547. viewState.m_rect = _render->m_view[0].m_rect;
  7548. int32_t numItems = _render->m_numRenderItems;
  7549. for (int32_t item = 0; item < numItems;)
  7550. {
  7551. const uint64_t encodedKey = _render->m_sortKeys[item];
  7552. const bool isCompute = key.decode(encodedKey, _render->m_viewRemap);
  7553. statsKeyType[isCompute]++;
  7554. const bool viewChanged = 0
  7555. || key.m_view != view
  7556. || item == numItems
  7557. ;
  7558. const uint32_t itemIdx = _render->m_sortValues[item];
  7559. const RenderItem& renderItem = _render->m_renderItem[itemIdx];
  7560. const RenderBind& renderBind = _render->m_renderItemBind[itemIdx];
  7561. ++item;
  7562. if (viewChanged)
  7563. {
  7564. view = key.m_view;
  7565. currentProgram = BGFX_INVALID_HANDLE;
  7566. hasPredefined = false;
  7567. if (_render->m_view[view].m_fbh.idx != fbh.idx)
  7568. {
  7569. if ( beginRenderPass )
  7570. {
  7571. vkCmdEndRenderPass(m_commandBuffer);
  7572. beginRenderPass = false;
  7573. }
  7574. fbh = _render->m_view[view].m_fbh;
  7575. setFrameBuffer(fbh);
  7576. }
  7577. }
  7578. if (!isCompute
  7579. && (viewChanged || wasCompute) )
  7580. {
  7581. if (wasCompute)
  7582. {
  7583. wasCompute = false;
  7584. currentBindHash = 0;
  7585. }
  7586. if (beginRenderPass && (false
  7587. || _render->m_view[view].m_fbh.idx != fbh.idx
  7588. || !_render->m_view[view].m_rect.isEqual(viewState.m_rect)
  7589. ) )
  7590. {
  7591. vkCmdEndRenderPass(m_commandBuffer);
  7592. beginRenderPass = false;
  7593. }
  7594. if (item > 1)
  7595. {
  7596. profiler.end();
  7597. }
  7598. if (beginRenderPass && bs.hasItem(view) )
  7599. {
  7600. vkCmdEndRenderPass(m_commandBuffer);
  7601. beginRenderPass = false;
  7602. }
  7603. submitUniformCache(ucs, view);
  7604. submitBlit(bs, view);
  7605. BGFX_VK_PROFILER_END();
  7606. setViewType(view, " ");
  7607. BGFX_VK_PROFILER_BEGIN(view, kColorView);
  7608. profiler.begin(view);
  7609. const FrameBufferVK& fb = isValid(m_fbh)
  7610. ? m_frameBuffers[m_fbh.idx]
  7611. : m_backBuffer
  7612. ;
  7613. isFrameBufferValid = fb.isRenderable();
  7614. if (isFrameBufferValid)
  7615. {
  7616. VkRenderPass renderPass = fb.getRenderPass(_render->m_view[view].m_clear.m_flags);
  7617. viewState.m_rect = _render->m_view[view].m_rect;
  7618. Rect rect = _render->m_view[view].m_rect;
  7619. Rect scissorRect = _render->m_view[view].m_scissor;
  7620. viewHasScissor = !scissorRect.isZero();
  7621. viewScissorRect = viewHasScissor ? scissorRect : rect;
  7622. restoreScissor = false;
  7623. // Clamp the rect to what's valid according to Vulkan.
  7624. rect.m_width = bx::min(rect.m_width, bx::narrowCast<uint16_t>(fb.m_width) - rect.m_x);
  7625. rect.m_height = bx::min(rect.m_height, bx::narrowCast<uint16_t>(fb.m_height) - rect.m_y);
  7626. if (_render->m_view[view].m_rect.m_width != rect.m_width
  7627. || _render->m_view[view].m_rect.m_height != rect.m_height)
  7628. {
  7629. BX_TRACE("Clamp render pass from %dx%d to %dx%d"
  7630. , _render->m_view[view].m_rect.m_width
  7631. , _render->m_view[view].m_rect.m_height
  7632. , rect.m_width
  7633. , rect.m_height
  7634. );
  7635. }
  7636. rpbi.framebuffer = fb.m_currentFramebuffer;
  7637. rpbi.renderPass = renderPass;
  7638. rpbi.renderArea.offset.x = rect.m_x;
  7639. rpbi.renderArea.offset.y = rect.m_y;
  7640. rpbi.renderArea.extent.width = rect.m_width;
  7641. rpbi.renderArea.extent.height = rect.m_height;
  7642. VkViewport vp;
  7643. vp.x = float(rect.m_x);
  7644. vp.y = float(rect.m_y + rect.m_height);
  7645. vp.width = float(rect.m_width);
  7646. vp.height = -float(rect.m_height);
  7647. vp.minDepth = 0.0f;
  7648. vp.maxDepth = 1.0f;
  7649. vkCmdSetViewport(m_commandBuffer, 0, 1, &vp);
  7650. VkRect2D rc;
  7651. rc.offset.x = viewScissorRect.m_x;
  7652. rc.offset.y = viewScissorRect.m_y;
  7653. rc.extent.width = viewScissorRect.m_width;
  7654. rc.extent.height = viewScissorRect.m_height;
  7655. vkCmdSetScissor(m_commandBuffer, 0, 1, &rc);
  7656. if (!beginRenderPass)
  7657. {
  7658. uint32_t numMrt;
  7659. bgfx::TextureFormat::Enum mrtFormat[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  7660. VkImageAspectFlags depthAspectMask;
  7661. if (NULL == fb.m_nwh)
  7662. {
  7663. numMrt = fb.m_num;
  7664. for (uint8_t ii = 0; ii < fb.m_num; ++ii)
  7665. {
  7666. mrtFormat[ii] = bgfx::TextureFormat::Enum(m_textures[fb.m_texture[ii].idx].m_requestedFormat);
  7667. }
  7668. depthAspectMask = isValid(fb.m_depth) ? m_textures[fb.m_depth.idx].m_aspectFlags : 0;
  7669. }
  7670. else
  7671. {
  7672. numMrt = 1;
  7673. mrtFormat[0] = fb.m_swapChain.m_colorFormat;
  7674. depthAspectMask = fb.m_swapChain.m_backBufferDepthStencil.m_aspectFlags;
  7675. }
  7676. VkClearValue clearValues[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS + 1];
  7677. uint32_t mrt = 0;
  7678. const Clear& clr = _render->m_view[view].m_clear;
  7679. for (uint32_t ii = 0; ii < numMrt; ++ii)
  7680. {
  7681. if (BGFX_CLEAR_COLOR & clr.m_flags)
  7682. {
  7683. VkClearColorValue& clearValue = clearValues[mrt].color;
  7684. const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(mrtFormat[ii]) );
  7685. const bx::EncodingType::Enum type = bx::EncodingType::Enum(blockInfo.encoding);
  7686. if (BGFX_CLEAR_COLOR_USE_PALETTE & clr.m_flags)
  7687. {
  7688. const uint8_t index = bx::min<uint8_t>(BGFX_CONFIG_MAX_COLOR_PALETTE - 1, clr.m_index[ii]);
  7689. const float* rgba = _render->m_colorPalette[index];
  7690. switch (type)
  7691. {
  7692. case bx::EncodingType::Int:
  7693. case bx::EncodingType::Uint:
  7694. clearValue.int32[0] = int32_t(rgba[0]);
  7695. clearValue.int32[1] = int32_t(rgba[1]);
  7696. clearValue.int32[2] = int32_t(rgba[2]);
  7697. clearValue.int32[3] = int32_t(rgba[3]);
  7698. break;
  7699. default:
  7700. bx::memCopy(&clearValue.float32, rgba, sizeof(clearValue.float32) );
  7701. break;
  7702. }
  7703. }
  7704. else
  7705. {
  7706. switch (type)
  7707. {
  7708. case bx::EncodingType::Int:
  7709. case bx::EncodingType::Uint:
  7710. clearValue.uint32[0] = clr.m_index[0];
  7711. clearValue.uint32[1] = clr.m_index[1];
  7712. clearValue.uint32[2] = clr.m_index[2];
  7713. clearValue.uint32[3] = clr.m_index[3];
  7714. break;
  7715. default:
  7716. bx::unpackRgba8(clearValue.float32, clr.m_index);
  7717. break;
  7718. }
  7719. }
  7720. }
  7721. ++mrt;
  7722. }
  7723. depthAspectMask &= 0
  7724. | (clr.m_flags & BGFX_CLEAR_DEPTH ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
  7725. | (clr.m_flags & BGFX_CLEAR_STENCIL ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)
  7726. ;
  7727. if (0 != depthAspectMask)
  7728. {
  7729. clearValues[mrt].depthStencil.stencil = clr.m_stencil;
  7730. clearValues[mrt].depthStencil.depth = clr.m_depth;
  7731. ++mrt;
  7732. }
  7733. rpbi.clearValueCount = mrt;
  7734. rpbi.pClearValues = clearValues;
  7735. vkCmdBeginRenderPass(m_commandBuffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
  7736. beginRenderPass = true;
  7737. }
  7738. else
  7739. {
  7740. const Clear& clr = _render->m_view[view].m_clear;
  7741. if (BGFX_CLEAR_NONE != clr.m_flags)
  7742. {
  7743. Rect clearRect = rect;
  7744. clearRect.setIntersect(rect, viewScissorRect);
  7745. clearQuad(clearRect, clr, _render->m_colorPalette);
  7746. }
  7747. }
  7748. if (m_variableRateShadingSupported)
  7749. {
  7750. VkFragmentShadingRateCombinerOpKHR combinerOp[] =
  7751. {
  7752. VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
  7753. VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
  7754. };
  7755. vkCmdSetFragmentShadingRateKHR(
  7756. m_commandBuffer
  7757. , &s_shadingRate[_render->m_view[view].m_shadingRate].fragmentSize
  7758. , combinerOp
  7759. );
  7760. }
  7761. }
  7762. }
  7763. if (isCompute)
  7764. {
  7765. if (!wasCompute)
  7766. {
  7767. wasCompute = true;
  7768. currentBindHash = 0;
  7769. BGFX_VK_PROFILER_END();
  7770. setViewType(view, "C");
  7771. BGFX_VK_PROFILER_BEGIN(view, kColorCompute);
  7772. if (beginRenderPass)
  7773. {
  7774. vkCmdEndRenderPass(m_commandBuffer);
  7775. beginRenderPass = false;
  7776. }
  7777. }
  7778. // renderpass external subpass dependencies handle graphics -> compute and compute -> graphics
  7779. // but not compute -> compute (possibly also across views if they contain no draw calls)
  7780. setMemoryBarrier(
  7781. m_commandBuffer
  7782. , VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
  7783. , VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
  7784. );
  7785. const RenderCompute& compute = renderItem.compute;
  7786. const VkPipeline pipeline = getPipeline(key.m_program);
  7787. if (currentPipeline != pipeline)
  7788. {
  7789. currentPipeline = pipeline;
  7790. vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
  7791. }
  7792. bool constantsChanged = false;
  7793. if (compute.m_uniformBegin < compute.m_uniformEnd
  7794. || currentProgram.idx != key.m_program.idx)
  7795. {
  7796. rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd);
  7797. currentProgram = key.m_program;
  7798. ProgramVK& program = m_program[currentProgram.idx];
  7799. UniformBuffer* vcb = program.m_vsh->m_constantBuffer;
  7800. if (NULL != vcb)
  7801. {
  7802. commit(*vcb);
  7803. }
  7804. hasPredefined = 0 < program.m_numPredefined;
  7805. constantsChanged = true;
  7806. }
  7807. const ProgramVK& program = m_program[currentProgram.idx];
  7808. if (constantsChanged
  7809. || hasPredefined)
  7810. {
  7811. viewState.setPredefined<4>(this, view, program, _render, compute);
  7812. }
  7813. if (VK_NULL_HANDLE != program.m_descriptorSetLayout)
  7814. {
  7815. ChunkedScratchBufferOffset sbo;
  7816. const uint32_t vsSize = program.m_vsh->m_size;
  7817. uint32_t numOffsets = 0;
  7818. if (constantsChanged
  7819. || hasPredefined)
  7820. {
  7821. if (vsSize > 0)
  7822. {
  7823. uniformScratchBuffer.write(sbo, m_vsScratch, vsSize);
  7824. numOffsets = 1;
  7825. }
  7826. }
  7827. bx::HashMurmur2A hash;
  7828. hash.begin();
  7829. hash.add(program.m_descriptorSetLayout);
  7830. hash.add(renderBind.m_bind, sizeof(renderBind.m_bind) );
  7831. hash.add(sbo.buffer);
  7832. hash.add(vsSize);
  7833. hash.add(0);
  7834. const uint32_t bindHash = hash.end();
  7835. if (currentBindHash != bindHash)
  7836. {
  7837. currentBindHash = bindHash;
  7838. currentDescriptorSet = getDescriptorSet(
  7839. program
  7840. , renderBind
  7841. , sbo.buffer
  7842. , _render->m_colorPalette
  7843. );
  7844. descriptorSetCount++;
  7845. }
  7846. vkCmdBindDescriptorSets(
  7847. m_commandBuffer
  7848. , VK_PIPELINE_BIND_POINT_COMPUTE
  7849. , program.m_pipelineLayout
  7850. , 0
  7851. , 1
  7852. , &currentDescriptorSet
  7853. , numOffsets
  7854. , sbo.offsets
  7855. );
  7856. }
  7857. if (isValid(compute.m_indirectBuffer) )
  7858. {
  7859. const VertexBufferVK& vb = m_vertexBuffers[compute.m_indirectBuffer.idx];
  7860. uint32_t numDrawIndirect = UINT32_MAX == compute.m_numIndirect
  7861. ? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  7862. : compute.m_numIndirect
  7863. ;
  7864. uint32_t args = compute.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
  7865. for (uint32_t ii = 0; ii < numDrawIndirect; ++ii)
  7866. {
  7867. vkCmdDispatchIndirect(m_commandBuffer, vb.m_buffer, args);
  7868. args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
  7869. }
  7870. }
  7871. else
  7872. {
  7873. vkCmdDispatch(m_commandBuffer, compute.m_numX, compute.m_numY, compute.m_numZ);
  7874. }
  7875. continue;
  7876. }
  7877. const RenderDraw& draw = renderItem.draw;
  7878. rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd);
  7879. const bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY);
  7880. {
  7881. const bool occluded = true
  7882. && isValid(draw.m_occlusionQuery)
  7883. && !hasOcclusionQuery
  7884. && !isVisible(_render, draw.m_occlusionQuery, 0 != (draw.m_submitFlags & BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) )
  7885. ;
  7886. if (occluded
  7887. || !isFrameBufferValid
  7888. || 0 == draw.m_streamMask
  7889. || _render->m_frameCache.isZeroArea(viewScissorRect, draw.m_scissor) )
  7890. {
  7891. continue;
  7892. }
  7893. }
  7894. const uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags;
  7895. currentState.m_stateFlags = draw.m_stateFlags;
  7896. if (0 != draw.m_streamMask)
  7897. {
  7898. const bool bindAttribs = hasVertexStreamChanged(currentState, draw);
  7899. currentState.m_streamMask = draw.m_streamMask;
  7900. currentState.m_instanceDataBuffer = draw.m_instanceDataBuffer;
  7901. currentState.m_instanceDataOffset = draw.m_instanceDataOffset;
  7902. currentState.m_instanceDataStride = draw.m_instanceDataStride;
  7903. const VertexLayout* layouts[BGFX_CONFIG_MAX_VERTEX_STREAMS];
  7904. VkBuffer streamBuffers[BGFX_CONFIG_MAX_VERTEX_STREAMS + 1];
  7905. VkDeviceSize streamOffsets[BGFX_CONFIG_MAX_VERTEX_STREAMS + 1];
  7906. uint8_t numStreams = 0;
  7907. uint32_t numVertices = draw.m_numVertices;
  7908. if (UINT8_MAX != draw.m_streamMask)
  7909. {
  7910. for (BitMaskToIndexIteratorT it(draw.m_streamMask)
  7911. ; !it.isDone()
  7912. ; it.next(), numStreams++
  7913. )
  7914. {
  7915. const uint8_t idx = it.idx;
  7916. currentState.m_stream[idx] = draw.m_stream[idx];
  7917. const VertexBufferHandle handle = draw.m_stream[idx].m_handle;
  7918. const VertexBufferVK& vb = m_vertexBuffers[handle.idx];
  7919. const uint16_t decl = isValid(draw.m_stream[idx].m_layoutHandle)
  7920. ? draw.m_stream[idx].m_layoutHandle.idx
  7921. : vb.m_layoutHandle.idx
  7922. ;
  7923. const VertexLayout& layout = m_vertexLayouts[decl];
  7924. const uint32_t stride = layout.m_stride;
  7925. streamBuffers[numStreams] = m_vertexBuffers[handle.idx].m_buffer;
  7926. streamOffsets[numStreams] = draw.m_stream[idx].m_startVertex * stride;
  7927. layouts[numStreams] = &layout;
  7928. numVertices = bx::uint32_min(UINT32_MAX == draw.m_numVertices
  7929. ? vb.m_size/stride
  7930. : draw.m_numVertices
  7931. , numVertices
  7932. );
  7933. }
  7934. }
  7935. if (bindAttribs)
  7936. {
  7937. uint32_t numVertexBuffers = numStreams;
  7938. if (isValid(draw.m_instanceDataBuffer) )
  7939. {
  7940. streamOffsets[numVertexBuffers] = draw.m_instanceDataOffset;
  7941. streamBuffers[numVertexBuffers] = m_vertexBuffers[draw.m_instanceDataBuffer.idx].m_buffer;
  7942. numVertexBuffers++;
  7943. }
  7944. if (0 < numVertexBuffers)
  7945. {
  7946. vkCmdBindVertexBuffers(
  7947. m_commandBuffer
  7948. , 0
  7949. , numVertexBuffers
  7950. , &streamBuffers[0]
  7951. , streamOffsets
  7952. );
  7953. }
  7954. }
  7955. const VkPipeline pipeline =
  7956. getPipeline(draw.m_stateFlags
  7957. , draw.m_stencil
  7958. , numStreams
  7959. , layouts
  7960. , key.m_program
  7961. , uint8_t(draw.m_instanceDataStride/16)
  7962. );
  7963. if (currentPipeline != pipeline)
  7964. {
  7965. currentPipeline = pipeline;
  7966. vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
  7967. }
  7968. const bool hasStencil = 0 != draw.m_stencil;
  7969. if (hasStencil
  7970. && currentState.m_stencil != draw.m_stencil)
  7971. {
  7972. currentState.m_stencil = draw.m_stencil;
  7973. const uint32_t fstencil = unpackStencil(0, draw.m_stencil);
  7974. const uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
  7975. vkCmdSetStencilReference(m_commandBuffer, VK_STENCIL_FRONT_AND_BACK, ref);
  7976. }
  7977. const bool hasFactor = 0
  7978. || f0 == (draw.m_stateFlags & f0)
  7979. || f1 == (draw.m_stateFlags & f1)
  7980. || f2 == (draw.m_stateFlags & f2)
  7981. || f3 == (draw.m_stateFlags & f3)
  7982. ;
  7983. if (hasFactor
  7984. && blendFactor != draw.m_rgba)
  7985. {
  7986. blendFactor = draw.m_rgba;
  7987. float bf[4];
  7988. bf[0] = ( (draw.m_rgba>>24) )/255.0f;
  7989. bf[1] = ( (draw.m_rgba>>16)&0xff)/255.0f;
  7990. bf[2] = ( (draw.m_rgba>> 8)&0xff)/255.0f;
  7991. bf[3] = ( (draw.m_rgba )&0xff)/255.0f;
  7992. vkCmdSetBlendConstants(m_commandBuffer, bf);
  7993. }
  7994. const uint16_t scissor = draw.m_scissor;
  7995. if (currentState.m_scissor != scissor)
  7996. {
  7997. currentState.m_scissor = scissor;
  7998. if (UINT16_MAX == scissor)
  7999. {
  8000. if (restoreScissor
  8001. || viewHasScissor)
  8002. {
  8003. restoreScissor = false;
  8004. VkRect2D rc;
  8005. rc.offset.x = viewScissorRect.m_x;
  8006. rc.offset.y = viewScissorRect.m_y;
  8007. rc.extent.width = viewScissorRect.m_width;
  8008. rc.extent.height = viewScissorRect.m_height;
  8009. vkCmdSetScissor(m_commandBuffer, 0, 1, &rc);
  8010. }
  8011. }
  8012. else
  8013. {
  8014. restoreScissor = true;
  8015. Rect scissorRect;
  8016. scissorRect.setIntersect(viewScissorRect, _render->m_frameCache.m_rectCache.m_cache[scissor]);
  8017. VkRect2D rc;
  8018. rc.offset.x = scissorRect.m_x;
  8019. rc.offset.y = scissorRect.m_y;
  8020. rc.extent.width = scissorRect.m_width;
  8021. rc.extent.height = scissorRect.m_height;
  8022. vkCmdSetScissor(m_commandBuffer, 0, 1, &rc);
  8023. }
  8024. }
  8025. bool constantsChanged = false;
  8026. if (draw.m_uniformBegin < draw.m_uniformEnd
  8027. || currentProgram.idx != key.m_program.idx
  8028. || BGFX_STATE_ALPHA_REF_MASK & changedFlags)
  8029. {
  8030. currentProgram = key.m_program;
  8031. ProgramVK& program = m_program[currentProgram.idx];
  8032. UniformBuffer* vcb = program.m_vsh->m_constantBuffer;
  8033. if (NULL != vcb)
  8034. {
  8035. commit(*vcb);
  8036. }
  8037. if (NULL != program.m_fsh)
  8038. {
  8039. UniformBuffer* fcb = program.m_fsh->m_constantBuffer;
  8040. if (NULL != fcb)
  8041. {
  8042. commit(*fcb);
  8043. }
  8044. }
  8045. hasPredefined = 0 < program.m_numPredefined;
  8046. constantsChanged = true;
  8047. }
  8048. const ProgramVK& program = m_program[currentProgram.idx];
  8049. if (hasPredefined)
  8050. {
  8051. uint32_t ref = (draw.m_stateFlags & BGFX_STATE_ALPHA_REF_MASK) >> BGFX_STATE_ALPHA_REF_SHIFT;
  8052. viewState.m_alphaRef = ref / 255.0f;
  8053. viewState.setPredefined<4>(this, view, program, _render, draw);
  8054. }
  8055. if (VK_NULL_HANDLE != program.m_descriptorSetLayout)
  8056. {
  8057. ChunkedScratchBufferOffset sbo;
  8058. const uint32_t vsSize = program.m_vsh->m_size;
  8059. const uint32_t fsSize = NULL != program.m_fsh ? program.m_fsh->m_size : 0;
  8060. uint32_t numOffsets = 0;
  8061. if (true
  8062. && (constantsChanged || hasPredefined)
  8063. && (0 < vsSize || 0 < fsSize)
  8064. )
  8065. {
  8066. uniformScratchBuffer.write(sbo, m_vsScratch, vsSize, m_fsScratch, fsSize);
  8067. numOffsets = (0 < vsSize) + (0 < fsSize);
  8068. }
  8069. bx::HashMurmur2A hash;
  8070. hash.begin();
  8071. hash.add(program.m_descriptorSetLayout);
  8072. hash.add(renderBind.m_bind, sizeof(renderBind.m_bind) );
  8073. hash.add(sbo.buffer);
  8074. hash.add(vsSize);
  8075. hash.add(fsSize);
  8076. const uint32_t bindHash = hash.end();
  8077. if (currentBindHash != bindHash)
  8078. {
  8079. currentBindHash = bindHash;
  8080. currentDescriptorSet = getDescriptorSet(
  8081. program
  8082. , renderBind
  8083. , sbo.buffer
  8084. , _render->m_colorPalette
  8085. );
  8086. descriptorSetCount++;
  8087. }
  8088. vkCmdBindDescriptorSets(
  8089. m_commandBuffer
  8090. , VK_PIPELINE_BIND_POINT_GRAPHICS
  8091. , program.m_pipelineLayout
  8092. , 0
  8093. , 1
  8094. , &currentDescriptorSet
  8095. , numOffsets
  8096. , sbo.offsets
  8097. );
  8098. }
  8099. VkBuffer bufferIndirect = VK_NULL_HANDLE;
  8100. VkBuffer bufferNumIndirect = VK_NULL_HANDLE;
  8101. uint32_t numDrawIndirect = 0;
  8102. uint32_t bufferOffsetIndirect = 0;
  8103. uint32_t bufferNumOffsetIndirect = 0;
  8104. if (isValid(draw.m_indirectBuffer) )
  8105. {
  8106. const VertexBufferVK& vb = m_vertexBuffers[draw.m_indirectBuffer.idx];
  8107. bufferIndirect = vb.m_buffer;
  8108. numDrawIndirect = UINT32_MAX == draw.m_numIndirect
  8109. ? vb.m_size / BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  8110. : draw.m_numIndirect
  8111. ;
  8112. bufferOffsetIndirect = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
  8113. if (isValid(draw.m_numIndirectBuffer) )
  8114. {
  8115. bufferNumIndirect = m_indexBuffers[draw.m_numIndirectBuffer.idx].m_buffer;
  8116. bufferNumOffsetIndirect = draw.m_numIndirectIndex * sizeof(uint32_t);
  8117. }
  8118. }
  8119. if (hasOcclusionQuery)
  8120. {
  8121. m_occlusionQuery.begin(draw.m_occlusionQuery);
  8122. }
  8123. const uint8_t primIndex = uint8_t( (draw.m_stateFlags & BGFX_STATE_PT_MASK) >> BGFX_STATE_PT_SHIFT);
  8124. const PrimInfo& prim = s_primInfo[primIndex];
  8125. uint32_t numPrimsSubmitted = 0;
  8126. uint32_t numIndices = 0;
  8127. if (!isValid(draw.m_indexBuffer) )
  8128. {
  8129. numPrimsSubmitted = numVertices / prim.m_div - prim.m_sub;
  8130. if (isValid(draw.m_indirectBuffer) )
  8131. {
  8132. if (isValid(draw.m_numIndirectBuffer) )
  8133. {
  8134. vkCmdDrawIndirectCountKHR(
  8135. m_commandBuffer
  8136. , bufferIndirect
  8137. , bufferOffsetIndirect
  8138. , bufferNumIndirect
  8139. , bufferNumOffsetIndirect
  8140. , numDrawIndirect
  8141. , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  8142. );
  8143. }
  8144. else
  8145. {
  8146. vkCmdDrawIndirect(
  8147. m_commandBuffer
  8148. , bufferIndirect
  8149. , bufferOffsetIndirect
  8150. , numDrawIndirect
  8151. , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  8152. );
  8153. }
  8154. }
  8155. else
  8156. {
  8157. vkCmdDraw(
  8158. m_commandBuffer
  8159. , numVertices
  8160. , draw.m_numInstances
  8161. , 0
  8162. , 0
  8163. );
  8164. }
  8165. }
  8166. else
  8167. {
  8168. const bool isIndex16 = draw.isIndex16();
  8169. const uint32_t indexSize = isIndex16 ? 2 : 4;
  8170. const VkIndexType indexFormat = isIndex16 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32;
  8171. const BufferVK& ib = m_indexBuffers[draw.m_indexBuffer.idx];
  8172. numIndices = UINT32_MAX == draw.m_numIndices
  8173. ? ib.m_size / indexSize
  8174. : draw.m_numIndices
  8175. ;
  8176. numPrimsSubmitted = numIndices / prim.m_div - prim.m_sub;
  8177. if (currentState.m_indexBuffer.idx != draw.m_indexBuffer.idx
  8178. || currentIndexFormat != indexFormat)
  8179. {
  8180. currentState.m_indexBuffer = draw.m_indexBuffer;
  8181. currentIndexFormat = indexFormat;
  8182. vkCmdBindIndexBuffer(
  8183. m_commandBuffer
  8184. , m_indexBuffers[draw.m_indexBuffer.idx].m_buffer
  8185. , 0
  8186. , indexFormat
  8187. );
  8188. }
  8189. if (isValid(draw.m_indirectBuffer) )
  8190. {
  8191. if (isValid(draw.m_numIndirectBuffer) )
  8192. {
  8193. vkCmdDrawIndexedIndirectCountKHR(
  8194. m_commandBuffer
  8195. , bufferIndirect
  8196. , bufferOffsetIndirect
  8197. , bufferNumIndirect
  8198. , bufferNumOffsetIndirect
  8199. , numDrawIndirect
  8200. , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  8201. );
  8202. }
  8203. else
  8204. {
  8205. vkCmdDrawIndexedIndirect(
  8206. m_commandBuffer
  8207. , bufferIndirect
  8208. , bufferOffsetIndirect
  8209. , numDrawIndirect
  8210. , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  8211. );
  8212. }
  8213. }
  8214. else
  8215. {
  8216. vkCmdDrawIndexed(
  8217. m_commandBuffer
  8218. , numIndices
  8219. , draw.m_numInstances
  8220. , draw.m_startIndex
  8221. , 0
  8222. , 0
  8223. );
  8224. }
  8225. }
  8226. uint32_t numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
  8227. statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
  8228. statsNumPrimsRendered[primIndex] += numPrimsRendered;
  8229. statsNumInstances[primIndex] += draw.m_numInstances;
  8230. statsNumIndices += numIndices;
  8231. if (hasOcclusionQuery)
  8232. {
  8233. m_occlusionQuery.end();
  8234. }
  8235. }
  8236. }
  8237. if (beginRenderPass)
  8238. {
  8239. vkCmdEndRenderPass(m_commandBuffer);
  8240. beginRenderPass = false;
  8241. }
  8242. if (wasCompute)
  8243. {
  8244. setViewType(view, "C");
  8245. BGFX_VK_PROFILER_END();
  8246. BGFX_VK_PROFILER_BEGIN(view, kColorCompute);
  8247. }
  8248. submitBlit(bs, BGFX_CONFIG_MAX_VIEWS);
  8249. if (0 < _render->m_numRenderItems)
  8250. {
  8251. captureElapsed = -bx::getHPCounter();
  8252. capture();
  8253. captureElapsed += bx::getHPCounter();
  8254. profiler.end();
  8255. }
  8256. }
  8257. BGFX_VK_PROFILER_END();
  8258. int64_t timeEnd = bx::getHPCounter();
  8259. int64_t frameTime = timeEnd - timeBegin;
  8260. static int64_t min = frameTime;
  8261. static int64_t max = frameTime;
  8262. min = bx::min<int64_t>(min, frameTime);
  8263. max = bx::max<int64_t>(max, frameTime);
  8264. static uint32_t maxGpuLatency = 0;
  8265. static double maxGpuElapsed = 0.0f;
  8266. double elapsedGpuMs = 0.0;
  8267. static int64_t presentMin = m_presentElapsed;
  8268. static int64_t presentMax = m_presentElapsed;
  8269. presentMin = bx::min<int64_t>(presentMin, m_presentElapsed);
  8270. presentMax = bx::max<int64_t>(presentMax, m_presentElapsed);
  8271. if (UINT32_MAX != frameQueryIdx)
  8272. {
  8273. m_gpuTimer.end(frameQueryIdx);
  8274. const TimerQueryVK::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS];
  8275. double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency);
  8276. elapsedGpuMs = (result.m_end - result.m_begin) * toGpuMs;
  8277. maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed;
  8278. maxGpuLatency = bx::uint32_imax(maxGpuLatency, result.m_pending-1);
  8279. }
  8280. maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.getNumUsed()-1);
  8281. const int64_t timerFreq = bx::getHPFrequency();
  8282. VkPhysicalDeviceMemoryBudgetPropertiesEXT dmbp;
  8283. dmbp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
  8284. dmbp.pNext = NULL;
  8285. int64_t gpuMemoryAvailable = -INT64_MAX;
  8286. int64_t gpuMemoryUsed = -INT64_MAX;
  8287. if (s_extension[Extension::EXT_memory_budget].m_supported)
  8288. {
  8289. VkPhysicalDeviceMemoryProperties2 pdmp2;
  8290. pdmp2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
  8291. pdmp2.pNext = &dmbp;
  8292. vkGetPhysicalDeviceMemoryProperties2KHR(m_physicalDevice, &pdmp2);
  8293. gpuMemoryAvailable = 0;
  8294. gpuMemoryUsed = 0;
  8295. for (uint32_t ii = 0; ii < m_memoryProperties.memoryHeapCount; ++ii)
  8296. {
  8297. if (!!(m_memoryProperties.memoryHeaps[ii].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) )
  8298. {
  8299. gpuMemoryAvailable += dmbp.heapBudget[ii];
  8300. gpuMemoryUsed += dmbp.heapUsage[ii];
  8301. }
  8302. }
  8303. }
  8304. Stats& perfStats = _render->m_perfStats;
  8305. perfStats.cpuTimeBegin = timeBegin;
  8306. perfStats.cpuTimeEnd = timeEnd;
  8307. perfStats.cpuTimerFreq = timerFreq;
  8308. const TimerQueryVK::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS];
  8309. perfStats.gpuTimeBegin = result.m_begin;
  8310. perfStats.gpuTimeEnd = result.m_end;
  8311. perfStats.gpuTimerFreq = m_gpuTimer.m_frequency;
  8312. perfStats.numDraw = statsKeyType[0];
  8313. perfStats.numCompute = statsKeyType[1];
  8314. perfStats.numBlit = _render->m_numBlitItems;
  8315. perfStats.maxGpuLatency = maxGpuLatency;
  8316. perfStats.gpuFrameNum = result.m_frameNum;
  8317. bx::memCopy(perfStats.numPrims, statsNumPrimsRendered, sizeof(perfStats.numPrims) );
  8318. perfStats.gpuMemoryMax = gpuMemoryAvailable;
  8319. perfStats.gpuMemoryUsed = gpuMemoryUsed;
  8320. if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
  8321. {
  8322. BGFX_VK_PROFILER_BEGIN_LITERAL("debugstats", kColorFrame);
  8323. TextVideoMem& tvm = m_textVideoMem;
  8324. static int64_t next = timeEnd;
  8325. if (timeEnd >= next)
  8326. {
  8327. next = timeEnd + timerFreq;
  8328. double freq = double(timerFreq);
  8329. double toMs = 1000.0 / freq;
  8330. tvm.clear();
  8331. uint16_t pos = 0;
  8332. tvm.printf(0, pos++, BGFX_CONFIG_DEBUG ? 0x8c : 0x8f
  8333. , " %s / " BX_COMPILER_NAME
  8334. " / " BX_CPU_NAME
  8335. " / " BX_ARCH_NAME
  8336. " / " BX_PLATFORM_NAME
  8337. " / Version 1.%d.%d (commit: " BGFX_REV_SHA1 ")"
  8338. , getRendererName()
  8339. , BGFX_API_VERSION
  8340. , BGFX_REV_NUMBER
  8341. );
  8342. const VkPhysicalDeviceProperties& pdp = m_deviceProperties.properties;
  8343. tvm.printf(0, pos++, 0x8f, " Device: %s (%s)"
  8344. , pdp.deviceName
  8345. , getName(pdp.deviceType)
  8346. );
  8347. if (0 <= gpuMemoryAvailable && 0 <= gpuMemoryUsed)
  8348. {
  8349. for (uint32_t ii = 0; ii < m_memoryProperties.memoryHeapCount; ++ii)
  8350. {
  8351. char budget[16];
  8352. bx::prettify(budget, BX_COUNTOF(budget), dmbp.heapBudget[ii]);
  8353. char usage[16];
  8354. bx::prettify(usage, BX_COUNTOF(usage), dmbp.heapUsage[ii]);
  8355. const bool local = (!!(m_memoryProperties.memoryHeaps[ii].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) );
  8356. tvm.printf(0, pos++, 0x8f, " Memory %d %s - Budget: %12s, Usage: %12s"
  8357. , ii
  8358. , local ? "(local) " : "(non-local)"
  8359. , budget
  8360. , usage
  8361. );
  8362. }
  8363. }
  8364. pos = 10;
  8365. tvm.printf(10, pos++, 0x8b, " Frame: % 7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS"
  8366. , double(frameTime)*toMs
  8367. , double(min)*toMs
  8368. , double(max)*toMs
  8369. , freq/frameTime
  8370. );
  8371. tvm.printf(10, pos++, 0x8b, " Present: % 7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] "
  8372. , double(m_presentElapsed)*toMs
  8373. , double(presentMin)*toMs
  8374. , double(presentMax)*toMs
  8375. );
  8376. const uint32_t msaa = (m_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT;
  8377. tvm.printf(10, pos++, 0x8b, " Reset flags: [%c] vsync, [%c] MSAAx%d, [%c] MaxAnisotropy "
  8378. , !!(m_resolution.reset&BGFX_RESET_VSYNC) ? '\xfe' : ' '
  8379. , 0 != msaa ? '\xfe' : ' '
  8380. , 1<<msaa
  8381. , !!(m_resolution.reset&BGFX_RESET_MAXANISOTROPY) ? '\xfe' : ' '
  8382. );
  8383. double elapsedCpuMs = double(frameTime)*toMs;
  8384. tvm.printf(10, pos++, 0x8b, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] %c GPU %7.4f [ms] (latency %d) "
  8385. , _render->m_numRenderItems
  8386. , statsKeyType[0]
  8387. , statsKeyType[1]
  8388. , elapsedCpuMs
  8389. , elapsedCpuMs > maxGpuElapsed ? '>' : '<'
  8390. , maxGpuElapsed
  8391. , maxGpuLatency
  8392. );
  8393. for (uint32_t ii = 0; ii < Topology::Count; ++ii)
  8394. {
  8395. tvm.printf(10, pos++, 0x8b, " %9s: %7d (#inst: %5d), submitted: %7d "
  8396. , getName(Topology::Enum(ii) )
  8397. , statsNumPrimsRendered[ii]
  8398. , statsNumInstances[ii]
  8399. , statsNumPrimsSubmitted[ii]
  8400. );
  8401. }
  8402. if (NULL != m_renderDocDll)
  8403. {
  8404. tvm.printf(tvm.m_width-27, 0, 0x4f, " [F11 - RenderDoc capture] ");
  8405. }
  8406. tvm.printf(10, pos++, 0x8b, " Indices: %7d ", statsNumIndices);
  8407. tvm.printf(10, pos++, 0x8b, " DVB size: %7d ", _render->m_vboffset);
  8408. tvm.printf(10, pos++, 0x8b, " DIB size: %7d ", _render->m_iboffset);
  8409. pos++;
  8410. tvm.printf(10, pos++, 0x8b, " Occlusion queries: %3d ", m_occlusionQuery.m_control.getNumUsed() );
  8411. pos++;
  8412. tvm.printf(10, pos++, 0x8b, " State cache: ");
  8413. tvm.printf(10, pos++, 0x8b, " PSO | DSL | DS ");
  8414. tvm.printf(10, pos++, 0x8b, " %6d | %6d | %6d "
  8415. , m_pipelineStateCache.getCount()
  8416. , m_descriptorSetLayoutCache.getCount()
  8417. , descriptorSetCount
  8418. );
  8419. pos++;
  8420. {
  8421. char strUsed[64];
  8422. bx::prettify(strUsed, sizeof(strUsed), m_uniformScratchBuffer.m_totalUsed);
  8423. char strTotal[64];
  8424. bx::prettify(strTotal, sizeof(strTotal), m_uniformScratchBuffer.m_chunkControl.m_size);
  8425. tvm.printf(10, pos++, 0x8b, "Uniform scratch size: %s / %s.", strUsed, strTotal);
  8426. }
  8427. pos++;
  8428. double captureMs = double(captureElapsed)*toMs;
  8429. tvm.printf(10, pos++, 0x8b, " Capture: %7.4f [ms] ", captureMs);
  8430. uint8_t attr[2] = { 0x8c, 0x8a };
  8431. uint8_t attrIndex = _render->m_waitSubmit < _render->m_waitRender;
  8432. tvm.printf(10, pos++, attr[attrIndex&1], " Submit wait: %7.4f [ms] ", _render->m_waitSubmit*toMs);
  8433. tvm.printf(10, pos++, attr[(attrIndex+1)&1], " Render wait: %7.4f [ms] ", _render->m_waitRender*toMs);
  8434. min = frameTime;
  8435. max = frameTime;
  8436. presentMin = m_presentElapsed;
  8437. presentMax = m_presentElapsed;
  8438. }
  8439. dbgTextSubmit(this, _textVideoMemBlitter, tvm);
  8440. BGFX_VK_PROFILER_END();
  8441. }
  8442. else if (_render->m_debug & BGFX_DEBUG_TEXT)
  8443. {
  8444. BGFX_VK_PROFILER_BEGIN_LITERAL("debugtext", kColorFrame);
  8445. dbgTextSubmit(this, _textVideoMemBlitter, _render->m_textVideoMem);
  8446. BGFX_VK_PROFILER_END();
  8447. }
  8448. m_presentElapsed = 0;
  8449. uniformScratchBuffer.end();
  8450. {
  8451. BGFX_PROFILER_SCOPE("stagingScratchBuffer::flush", kColorResource);
  8452. stagingScratchBuffer.flush();
  8453. }
  8454. for (uint16_t ii = 0; ii < m_numWindows; ++ii)
  8455. {
  8456. FrameBufferVK& fb = isValid(m_windows[ii])
  8457. ? m_frameBuffers[m_windows[ii].idx]
  8458. : m_backBuffer
  8459. ;
  8460. if (fb.m_needPresent)
  8461. {
  8462. fb.resolve();
  8463. fb.m_swapChain.transitionImage(m_commandBuffer);
  8464. m_cmd.addWaitSemaphore(fb.m_swapChain.m_lastImageAcquiredSemaphore, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
  8465. m_cmd.addSignalSemaphore(fb.m_swapChain.m_lastImageRenderedSemaphore);
  8466. fb.m_swapChain.m_lastImageAcquiredSemaphore = VK_NULL_HANDLE;
  8467. fb.m_swapChain.m_backBufferFence[fb.m_swapChain.m_backBufferColorIdx] = m_cmd.m_currentFence;
  8468. }
  8469. }
  8470. kick();
  8471. }
  8472. } /* namespace vk */ } // namespace bgfx
  8473. #else
  8474. namespace bgfx { namespace vk
  8475. {
  8476. RendererContextI* rendererCreate(const Init& _init)
  8477. {
  8478. BX_UNUSED(_init);
  8479. return NULL;
  8480. }
  8481. void rendererDestroy()
  8482. {
  8483. }
  8484. } /* namespace vk */ } // namespace bgfx
  8485. #endif // BGFX_CONFIG_RENDERER_VULKAN