renderer_vk.cpp 309 KB

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