renderer_vk.cpp 303 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664
  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.idx = kInvalidHandle;
  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(NULL != m_renderDocDll);
  1056. m_vulkan1Dll = bx::dlopen(
  1057. #if BX_PLATFORM_WINDOWS
  1058. "vulkan-1.dll"
  1059. #elif BX_PLATFORM_ANDROID
  1060. "libvulkan.so"
  1061. #elif BX_PLATFORM_OSX
  1062. "libMoltenVK.dylib"
  1063. #else
  1064. "libvulkan.so.1"
  1065. #endif // BX_PLATFORM_*
  1066. );
  1067. if (NULL == m_vulkan1Dll)
  1068. {
  1069. BX_TRACE("Init error: Failed to load vulkan dynamic library.");
  1070. goto error;
  1071. }
  1072. errorState = ErrorState::LoadedVulkan1;
  1073. BX_TRACE("Shared library functions:");
  1074. #define VK_IMPORT_FUNC(_optional, _func) \
  1075. _func = (PFN_##_func)bx::dlsym(m_vulkan1Dll, #_func); \
  1076. BX_TRACE("\t%p " #_func, _func); \
  1077. imported &= _optional || NULL != _func
  1078. VK_IMPORT
  1079. #undef VK_IMPORT_FUNC
  1080. if (!imported)
  1081. {
  1082. BX_TRACE("Init error: Failed to load shared library functions.");
  1083. goto error;
  1084. }
  1085. {
  1086. s_layer[Layer::VK_LAYER_LUNARG_standard_validation].m_device.m_initialize = _init.debug;
  1087. s_layer[Layer::VK_LAYER_LUNARG_standard_validation].m_instance.m_initialize = _init.debug;
  1088. s_layer[Layer::VK_LAYER_KHRONOS_validation ].m_device.m_initialize = _init.debug;
  1089. s_layer[Layer::VK_LAYER_KHRONOS_validation ].m_instance.m_initialize = _init.debug;
  1090. s_extension[Extension::EXT_debug_report].m_initialize = _init.debug;
  1091. s_extension[Extension::EXT_shader_viewport_index_layer].m_initialize = !!(_init.capabilities & BGFX_CAPS_VIEWPORT_LAYER_ARRAY);
  1092. s_extension[Extension::EXT_conservative_rasterization ].m_initialize = !!(_init.capabilities & BGFX_CAPS_CONSERVATIVE_RASTER );
  1093. s_extension[Extension::KHR_draw_indirect_count ].m_initialize = !!(_init.capabilities & BGFX_CAPS_DRAW_INDIRECT_COUNT );
  1094. dumpExtensions(VK_NULL_HANDLE, s_extension);
  1095. if (s_layer[Layer::VK_LAYER_KHRONOS_validation].m_device.m_supported
  1096. || s_layer[Layer::VK_LAYER_KHRONOS_validation].m_instance.m_supported)
  1097. {
  1098. s_layer[Layer::VK_LAYER_LUNARG_standard_validation].m_device.m_supported = false;
  1099. s_layer[Layer::VK_LAYER_LUNARG_standard_validation].m_instance.m_supported = false;
  1100. }
  1101. uint32_t numEnabledLayers = 0;
  1102. const char* enabledLayer[Layer::Count];
  1103. BX_TRACE("Enabled instance layers:");
  1104. for (uint32_t ii = 0; ii < Layer::Count; ++ii)
  1105. {
  1106. const Layer& layer = s_layer[ii];
  1107. if (layer.m_instance.m_supported
  1108. && layer.m_instance.m_initialize)
  1109. {
  1110. enabledLayer[numEnabledLayers++] = layer.m_name;
  1111. BX_TRACE("\t%s", layer.m_name);
  1112. }
  1113. }
  1114. uint32_t numEnabledExtensions = 0;
  1115. const char* enabledExtension[Extension::Count + 1];
  1116. if (!headless)
  1117. {
  1118. enabledExtension[numEnabledExtensions++] = VK_KHR_SURFACE_EXTENSION_NAME;
  1119. }
  1120. for (uint32_t ii = 0; ii < Extension::Count; ++ii)
  1121. {
  1122. const Extension& extension = s_extension[ii];
  1123. const LayerInfo& layerInfo = s_layer[extension.m_layer].m_instance;
  1124. const bool layerEnabled = false
  1125. || extension.m_layer == Layer::Count || (layerInfo.m_supported && layerInfo.m_initialize)
  1126. ;
  1127. if (extension.m_supported
  1128. && extension.m_initialize
  1129. && extension.m_instanceExt
  1130. && layerEnabled)
  1131. {
  1132. enabledExtension[numEnabledExtensions++] = extension.m_name;
  1133. }
  1134. }
  1135. BX_TRACE("Enabled instance extensions:");
  1136. for (uint32_t ii = 0; ii < numEnabledExtensions; ++ii)
  1137. {
  1138. BX_TRACE("\t%s", enabledExtension[ii]);
  1139. }
  1140. uint32_t vulkanApiVersionSelector;
  1141. if (NULL != vkEnumerateInstanceVersion)
  1142. {
  1143. result = vkEnumerateInstanceVersion(&vulkanApiVersionSelector);
  1144. if (VK_SUCCESS != result)
  1145. {
  1146. BX_TRACE(
  1147. "Init error: vkEnumerateInstanceVersion failed %d: %s."
  1148. , result
  1149. , getName(result)
  1150. );
  1151. goto error;
  1152. }
  1153. }
  1154. else
  1155. {
  1156. vulkanApiVersionSelector = VK_API_VERSION_1_0;
  1157. }
  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_numFramesInFlight = _init.resolution.maxFrameLatency == 0
  1646. ? BGFX_CONFIG_MAX_FRAME_LATENCY
  1647. : _init.resolution.maxFrameLatency
  1648. ;
  1649. result = m_cmd.init(m_globalQueueFamily, m_globalQueue, m_numFramesInFlight);
  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(UINT16_MAX, g_platformData.nwh, m_resolution.width, m_resolution.height, m_resolution.format);
  1677. if (VK_SUCCESS != result)
  1678. {
  1679. BX_TRACE("Init error: creating swap chain failed %d: %s.", result, getName(result) );
  1680. goto error;
  1681. }
  1682. m_windows[0] = BGFX_INVALID_HANDLE;
  1683. m_numWindows++;
  1684. postReset();
  1685. }
  1686. }
  1687. errorState = ErrorState::SwapChainCreated;
  1688. {
  1689. VkDescriptorPoolSize dps[] =
  1690. {
  1691. { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, MAX_DESCRIPTOR_SETS * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS },
  1692. { VK_DESCRIPTOR_TYPE_SAMPLER, MAX_DESCRIPTOR_SETS * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS },
  1693. { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, MAX_DESCRIPTOR_SETS * 2 },
  1694. { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, MAX_DESCRIPTOR_SETS * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS },
  1695. { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, MAX_DESCRIPTOR_SETS * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS },
  1696. };
  1697. VkDescriptorPoolCreateInfo dpci;
  1698. dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
  1699. dpci.pNext = NULL;
  1700. dpci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
  1701. dpci.maxSets = MAX_DESCRIPTOR_SETS;
  1702. dpci.poolSizeCount = BX_COUNTOF(dps);
  1703. dpci.pPoolSizes = dps;
  1704. result = vkCreateDescriptorPool(m_device, &dpci, m_allocatorCb, &m_descriptorPool);
  1705. if (VK_SUCCESS != result)
  1706. {
  1707. BX_TRACE("Init error: vkCreateDescriptorPool failed %d: %s.", result, getName(result) );
  1708. goto error;
  1709. }
  1710. VkPipelineCacheCreateInfo pcci;
  1711. pcci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
  1712. pcci.pNext = NULL;
  1713. pcci.flags = 0;
  1714. pcci.initialDataSize = 0;
  1715. pcci.pInitialData = NULL;
  1716. result = vkCreatePipelineCache(m_device, &pcci, m_allocatorCb, &m_pipelineCache);
  1717. if (VK_SUCCESS != result)
  1718. {
  1719. BX_TRACE("Init error: vkCreatePipelineCache failed %d: %s.", result, getName(result) );
  1720. goto error;
  1721. }
  1722. }
  1723. {
  1724. const uint32_t size = 128;
  1725. const uint32_t count = BGFX_CONFIG_MAX_DRAW_CALLS;
  1726. for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii)
  1727. {
  1728. BX_TRACE("Create scratch buffer %d", ii);
  1729. m_scratchBuffer[ii].createUniform(size, count);
  1730. }
  1731. for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii)
  1732. {
  1733. BX_TRACE("Create scratch staging buffer %d", ii);
  1734. m_scratchStagingBuffer[ii].createStaging(BGFX_CONFIG_PER_FRAME_SCRATCH_STAGING_BUFFER_SIZE);
  1735. }
  1736. }
  1737. errorState = ErrorState::DescriptorCreated;
  1738. if (NULL == vkSetDebugUtilsObjectNameEXT)
  1739. {
  1740. vkSetDebugUtilsObjectNameEXT = stubSetDebugUtilsObjectNameEXT;
  1741. }
  1742. if (NULL == vkCmdBeginDebugUtilsLabelEXT
  1743. || NULL == vkCmdEndDebugUtilsLabelEXT)
  1744. {
  1745. vkCmdBeginDebugUtilsLabelEXT = stubCmdBeginDebugUtilsLabelEXT;
  1746. vkCmdEndDebugUtilsLabelEXT = stubCmdEndDebugUtilsLabelEXT;
  1747. }
  1748. if (NULL == vkCmdInsertDebugUtilsLabelEXT)
  1749. {
  1750. vkCmdInsertDebugUtilsLabelEXT = stubCmdInsertDebugUtilsLabelEXT;
  1751. }
  1752. // Init reserved part of view name.
  1753. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
  1754. {
  1755. bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d ", ii);
  1756. }
  1757. if (m_timerQuerySupport)
  1758. {
  1759. result = m_gpuTimer.init();
  1760. if (VK_SUCCESS != result)
  1761. {
  1762. BX_TRACE("Init error: creating GPU timer failed %d: %s.", result, getName(result) );
  1763. goto error;
  1764. }
  1765. }
  1766. errorState = ErrorState::TimerQueryCreated;
  1767. result = m_occlusionQuery.init();
  1768. if (VK_SUCCESS != result)
  1769. {
  1770. BX_TRACE("Init error: creating occlusion query failed %d: %s.", result, getName(result) );
  1771. goto error;
  1772. }
  1773. g_internalData.context = m_device;
  1774. return true;
  1775. error:
  1776. BX_TRACE("errorState %d", errorState);
  1777. switch (errorState)
  1778. {
  1779. case ErrorState::TimerQueryCreated:
  1780. if (m_timerQuerySupport)
  1781. {
  1782. m_gpuTimer.shutdown();
  1783. }
  1784. [[fallthrough]];
  1785. case ErrorState::DescriptorCreated:
  1786. for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii)
  1787. {
  1788. m_scratchBuffer[ii].destroy();
  1789. m_scratchStagingBuffer[ii].destroy();
  1790. }
  1791. vkDestroy(m_pipelineCache);
  1792. vkDestroy(m_descriptorPool);
  1793. [[fallthrough]];
  1794. case ErrorState::SwapChainCreated:
  1795. m_backBuffer.destroy();
  1796. [[fallthrough]];
  1797. case ErrorState::CommandQueueCreated:
  1798. m_cmd.shutdown();
  1799. [[fallthrough]];
  1800. case ErrorState::DeviceCreated:
  1801. vkDestroyDevice(m_device, m_allocatorCb);
  1802. [[fallthrough]];
  1803. case ErrorState::InstanceCreated:
  1804. if (VK_NULL_HANDLE != m_debugReportCallback)
  1805. {
  1806. vkDestroyDebugReportCallbackEXT(m_instance, m_debugReportCallback, m_allocatorCb);
  1807. }
  1808. vkDestroyInstance(m_instance, m_allocatorCb);
  1809. [[fallthrough]];
  1810. case ErrorState::LoadedVulkan1:
  1811. bx::dlclose(m_vulkan1Dll);
  1812. m_vulkan1Dll = NULL;
  1813. m_allocatorCb = NULL;
  1814. unloadRenderDoc(m_renderDocDll);
  1815. [[fallthrough]];
  1816. case ErrorState::Default:
  1817. break;
  1818. };
  1819. return false;
  1820. }
  1821. void shutdown()
  1822. {
  1823. VK_CHECK(vkDeviceWaitIdle(m_device) );
  1824. if (m_timerQuerySupport)
  1825. {
  1826. m_gpuTimer.shutdown();
  1827. }
  1828. m_occlusionQuery.shutdown();
  1829. preReset();
  1830. m_pipelineStateCache.invalidate();
  1831. m_descriptorSetLayoutCache.invalidate();
  1832. m_renderPassCache.invalidate();
  1833. m_samplerCache.invalidate();
  1834. m_samplerBorderColorCache.invalidate();
  1835. m_imageViewCache.invalidate();
  1836. for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii)
  1837. {
  1838. m_scratchBuffer[ii].destroy();
  1839. }
  1840. for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii)
  1841. {
  1842. m_scratchStagingBuffer[ii].destroy();
  1843. }
  1844. for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
  1845. {
  1846. m_frameBuffers[ii].destroy();
  1847. }
  1848. for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii)
  1849. {
  1850. m_indexBuffers[ii].destroy();
  1851. }
  1852. for (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexBuffers); ++ii)
  1853. {
  1854. m_vertexBuffers[ii].destroy();
  1855. }
  1856. for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii)
  1857. {
  1858. m_shaders[ii].destroy();
  1859. }
  1860. for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii)
  1861. {
  1862. m_textures[ii].destroy();
  1863. }
  1864. m_backBuffer.destroy();
  1865. m_memoryLru.evictAll();
  1866. m_cmd.shutdown();
  1867. vkDestroy(m_pipelineCache);
  1868. vkDestroy(m_descriptorPool);
  1869. vkDestroyDevice(m_device, m_allocatorCb);
  1870. if (VK_NULL_HANDLE != m_debugReportCallback)
  1871. {
  1872. vkDestroyDebugReportCallbackEXT(m_instance, m_debugReportCallback, m_allocatorCb);
  1873. }
  1874. vkDestroyInstance(m_instance, m_allocatorCb);
  1875. bx::dlclose(m_vulkan1Dll);
  1876. m_vulkan1Dll = NULL;
  1877. m_allocatorCb = NULL;
  1878. unloadRenderDoc(m_renderDocDll);
  1879. }
  1880. RendererType::Enum getRendererType() const override
  1881. {
  1882. return RendererType::Vulkan;
  1883. }
  1884. const char* getRendererName() const override
  1885. {
  1886. return BGFX_RENDERER_VULKAN_NAME;
  1887. }
  1888. bool isDeviceRemoved() override
  1889. {
  1890. return false;
  1891. }
  1892. void flip() override
  1893. {
  1894. int64_t start = bx::getHPCounter();
  1895. for (uint16_t ii = 0; ii < m_numWindows; ++ii)
  1896. {
  1897. FrameBufferVK& fb = isValid(m_windows[ii])
  1898. ? m_frameBuffers[m_windows[ii].idx]
  1899. : m_backBuffer
  1900. ;
  1901. fb.present();
  1902. }
  1903. int64_t now = bx::getHPCounter();
  1904. m_presentElapsed += now - start;
  1905. }
  1906. void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override
  1907. {
  1908. m_indexBuffers[_handle.idx].create(m_commandBuffer, _mem->size, _mem->data, _flags, false);
  1909. }
  1910. void destroyIndexBuffer(IndexBufferHandle _handle) override
  1911. {
  1912. m_indexBuffers[_handle.idx].destroy();
  1913. }
  1914. void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override
  1915. {
  1916. VertexLayout& layout = m_vertexLayouts[_handle.idx];
  1917. bx::memCopy(&layout, &_layout, sizeof(VertexLayout) );
  1918. dump(layout);
  1919. }
  1920. void destroyVertexLayout(VertexLayoutHandle /*_handle*/) override
  1921. {
  1922. }
  1923. void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override
  1924. {
  1925. m_vertexBuffers[_handle.idx].create(m_commandBuffer, _mem->size, _mem->data, _layoutHandle, _flags);
  1926. }
  1927. void destroyVertexBuffer(VertexBufferHandle _handle) override
  1928. {
  1929. m_vertexBuffers[_handle.idx].destroy();
  1930. }
  1931. void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override
  1932. {
  1933. m_indexBuffers[_handle.idx].create(m_commandBuffer, _size, NULL, _flags, false);
  1934. }
  1935. void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override
  1936. {
  1937. m_indexBuffers[_handle.idx].update(m_commandBuffer, _offset, bx::min<uint32_t>(_size, _mem->size), _mem->data);
  1938. }
  1939. void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override
  1940. {
  1941. m_indexBuffers[_handle.idx].destroy();
  1942. }
  1943. void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override
  1944. {
  1945. VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE;
  1946. m_vertexBuffers[_handle.idx].create(m_commandBuffer, _size, NULL, layoutHandle, _flags);
  1947. }
  1948. void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override
  1949. {
  1950. m_vertexBuffers[_handle.idx].update(m_commandBuffer, _offset, bx::min<uint32_t>(_size, _mem->size), _mem->data);
  1951. }
  1952. void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override
  1953. {
  1954. m_vertexBuffers[_handle.idx].destroy();
  1955. }
  1956. void createShader(ShaderHandle _handle, const Memory* _mem) override
  1957. {
  1958. m_shaders[_handle.idx].create(_mem);
  1959. }
  1960. void destroyShader(ShaderHandle _handle) override
  1961. {
  1962. m_shaders[_handle.idx].destroy();
  1963. }
  1964. void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override
  1965. {
  1966. m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL);
  1967. }
  1968. void destroyProgram(ProgramHandle _handle) override
  1969. {
  1970. m_program[_handle.idx].destroy();
  1971. }
  1972. void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override
  1973. {
  1974. return m_textures[_handle.idx].create(m_commandBuffer, _mem, _flags, _skip);
  1975. }
  1976. void updateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/) override
  1977. {
  1978. }
  1979. 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
  1980. {
  1981. m_textures[_handle.idx].update(m_commandBuffer, _side, _mip, _rect, _z, _depth, _pitch, _mem);
  1982. }
  1983. void updateTextureEnd() override
  1984. {
  1985. }
  1986. void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) override
  1987. {
  1988. TextureVK& texture = m_textures[_handle.idx];
  1989. uint32_t height = bx::uint32_max(1, texture.m_height >> _mip);
  1990. uint32_t pitch = texture.m_readback.pitch(_mip);
  1991. uint32_t size = height * pitch;
  1992. DeviceMemoryAllocationVK stagingMemory;
  1993. VkBuffer stagingBuffer;
  1994. VK_CHECK(createReadbackBuffer(size, &stagingBuffer, &stagingMemory) );
  1995. texture.m_readback.copyImageToBuffer(
  1996. m_commandBuffer
  1997. , stagingBuffer
  1998. , texture.m_currentImageLayout
  1999. , texture.m_aspectMask
  2000. , _mip
  2001. );
  2002. kick(true);
  2003. texture.m_readback.readback(stagingMemory.mem, stagingMemory.offset, _data, _mip);
  2004. vkDestroy(stagingBuffer);
  2005. recycleMemory(stagingMemory);
  2006. }
  2007. void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips, uint16_t _numLayers) override
  2008. {
  2009. const TextureVK& texture = m_textures[_handle.idx];
  2010. const TextureFormat::Enum format = TextureFormat::Enum(texture.m_requestedFormat);
  2011. const uint64_t flags = texture.m_flags;
  2012. const uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
  2013. const Memory* mem = alloc(size);
  2014. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  2015. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  2016. bx::write(&writer, magic, bx::ErrorAssert{});
  2017. TextureCreate tc;
  2018. tc.m_width = _width;
  2019. tc.m_height = _height;
  2020. tc.m_depth = 0;
  2021. tc.m_numLayers = _numLayers;
  2022. tc.m_numMips = _numMips;
  2023. tc.m_format = format;
  2024. tc.m_cubeMap = false;
  2025. tc.m_mem = NULL;
  2026. bx::write(&writer, tc, bx::ErrorAssert{});
  2027. destroyTexture(_handle);
  2028. createTexture(_handle, mem, flags, 0);
  2029. bgfx::release(mem);
  2030. }
  2031. void overrideInternal(TextureHandle /*_handle*/, uintptr_t /*_ptr*/) override
  2032. {
  2033. }
  2034. uintptr_t getInternal(TextureHandle /*_handle*/) override
  2035. {
  2036. return 0;
  2037. }
  2038. void destroyTexture(TextureHandle _handle) override
  2039. {
  2040. m_imageViewCache.invalidateWithParent(_handle.idx);
  2041. m_textures[_handle.idx].destroy();
  2042. }
  2043. void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override
  2044. {
  2045. m_frameBuffers[_handle.idx].create(_num, _attachment);
  2046. }
  2047. void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat) override
  2048. {
  2049. for (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii)
  2050. {
  2051. FrameBufferHandle handle = m_windows[ii];
  2052. if (isValid(handle)
  2053. && m_frameBuffers[handle.idx].m_nwh == _nwh)
  2054. {
  2055. destroyFrameBuffer(handle);
  2056. }
  2057. }
  2058. uint16_t denseIdx = m_numWindows++;
  2059. m_windows[denseIdx] = _handle;
  2060. VK_CHECK(m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _format, _depthFormat) );
  2061. }
  2062. void destroyFrameBuffer(FrameBufferHandle _handle) override
  2063. {
  2064. FrameBufferVK& frameBuffer = m_frameBuffers[_handle.idx];
  2065. if (_handle.idx == m_fbh.idx)
  2066. {
  2067. setFrameBuffer(BGFX_INVALID_HANDLE, false);
  2068. }
  2069. uint16_t denseIdx = frameBuffer.destroy();
  2070. if (UINT16_MAX != denseIdx)
  2071. {
  2072. --m_numWindows;
  2073. if (m_numWindows > 1)
  2074. {
  2075. FrameBufferHandle handle = m_windows[m_numWindows];
  2076. m_windows[m_numWindows] = {kInvalidHandle};
  2077. if (m_numWindows != denseIdx)
  2078. {
  2079. m_windows[denseIdx] = handle;
  2080. m_frameBuffers[handle.idx].m_denseIdx = denseIdx;
  2081. }
  2082. }
  2083. }
  2084. }
  2085. void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) override
  2086. {
  2087. if (NULL != m_uniforms[_handle.idx])
  2088. {
  2089. bx::free(g_allocator, m_uniforms[_handle.idx]);
  2090. }
  2091. const uint32_t size = bx::alignUp(g_uniformTypeSize[_type] * _num, 16);
  2092. void* data = bx::alloc(g_allocator, size);
  2093. bx::memSet(data, 0, size);
  2094. m_uniforms[_handle.idx] = data;
  2095. m_uniformReg.add(_handle, _name);
  2096. }
  2097. void destroyUniform(UniformHandle _handle) override
  2098. {
  2099. bx::free(g_allocator, m_uniforms[_handle.idx]);
  2100. m_uniforms[_handle.idx] = NULL;
  2101. }
  2102. void requestScreenShot(FrameBufferHandle _fbh, const char* _filePath) override
  2103. {
  2104. const FrameBufferVK& frameBuffer = isValid(_fbh)
  2105. ? m_frameBuffers[_fbh.idx]
  2106. : m_backBuffer
  2107. ;
  2108. const SwapChainVK& swapChain = frameBuffer.m_swapChain;
  2109. if (!isSwapChainReadable(swapChain) )
  2110. {
  2111. BX_TRACE("Unable to capture screenshot %s.", _filePath);
  2112. return;
  2113. }
  2114. auto callback = [](void* _src, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _userData)
  2115. {
  2116. const char* filePath = (const char*)_userData;
  2117. g_callback->screenShot(
  2118. filePath
  2119. , _width
  2120. , _height
  2121. , _pitch
  2122. , _src
  2123. , _height * _pitch
  2124. , false
  2125. );
  2126. };
  2127. const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(swapChain.m_colorFormat) );
  2128. const uint32_t size = frameBuffer.m_width * frameBuffer.m_height * bpp / 8;
  2129. DeviceMemoryAllocationVK stagingMemory;
  2130. VkBuffer stagingBuffer;
  2131. VK_CHECK(createReadbackBuffer(size, &stagingBuffer, &stagingMemory) );
  2132. readSwapChain(swapChain, stagingBuffer, stagingMemory, callback, _filePath);
  2133. vkDestroy(stagingBuffer);
  2134. recycleMemory(stagingMemory);
  2135. }
  2136. void updateViewName(ViewId _id, const char* _name) override
  2137. {
  2138. bx::strCopy(&s_viewName[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED]
  2139. , BX_COUNTOF(s_viewName[0]) - BGFX_CONFIG_MAX_VIEW_NAME_RESERVED
  2140. , _name
  2141. );
  2142. }
  2143. void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) override
  2144. {
  2145. bx::memCopy(m_uniforms[_loc], _data, _size);
  2146. }
  2147. void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override
  2148. {
  2149. m_occlusionQuery.invalidate(_handle);
  2150. }
  2151. void setMarker(const char* _marker, uint16_t _len) override
  2152. {
  2153. if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) )
  2154. {
  2155. BX_UNUSED(_len);
  2156. const uint32_t abgr = kColorMarker;
  2157. VkDebugUtilsLabelEXT dul;
  2158. dul.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
  2159. dul.pNext = NULL;
  2160. dul.pLabelName = _marker;
  2161. dul.color[0] = ((abgr >> 24) & 0xff) / 255.0f;
  2162. dul.color[1] = ((abgr >> 16) & 0xff) / 255.0f;
  2163. dul.color[2] = ((abgr >> 8) & 0xff) / 255.0f;
  2164. dul.color[3] = ((abgr >> 0) & 0xff) / 255.0f;
  2165. vkCmdInsertDebugUtilsLabelEXT(m_commandBuffer, &dul);
  2166. }
  2167. }
  2168. virtual void setName(Handle _handle, const char* _name, uint16_t _len) override
  2169. {
  2170. switch (_handle.type)
  2171. {
  2172. case Handle::IndexBuffer:
  2173. setDebugObjectName(m_device, m_indexBuffers[_handle.idx].m_buffer, "%.*s", _len, _name);
  2174. break;
  2175. case Handle::Shader:
  2176. setDebugObjectName(m_device, m_shaders[_handle.idx].m_module, "%.*s", _len, _name);
  2177. break;
  2178. case Handle::Texture:
  2179. setDebugObjectName(m_device, m_textures[_handle.idx].m_textureImage, "%.*s", _len, _name);
  2180. if (VK_NULL_HANDLE != m_textures[_handle.idx].m_singleMsaaImage)
  2181. {
  2182. setDebugObjectName(m_device, m_textures[_handle.idx].m_singleMsaaImage, "%.*s", _len, _name);
  2183. }
  2184. break;
  2185. case Handle::VertexBuffer:
  2186. setDebugObjectName(m_device, m_vertexBuffers[_handle.idx].m_buffer, "%.*s", _len, _name);
  2187. break;
  2188. default:
  2189. BX_ASSERT(false, "Invalid handle type?! %d", _handle.type);
  2190. break;
  2191. }
  2192. }
  2193. template<typename Ty>
  2194. void release(Ty& _object)
  2195. {
  2196. if (VK_NULL_HANDLE != _object)
  2197. {
  2198. m_cmd.release(uint64_t(_object.vk), getType<Ty>() );
  2199. _object = VK_NULL_HANDLE;
  2200. }
  2201. }
  2202. void recycleMemory(DeviceMemoryAllocationVK _alloc)
  2203. {
  2204. m_cmd.recycleMemory(_alloc);
  2205. }
  2206. void submitBlit(BlitState& _bs, uint16_t _view);
  2207. void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override;
  2208. void blitSetup(TextVideoMemBlitter& _blitter) override
  2209. {
  2210. const uint32_t width = m_backBuffer.m_width;
  2211. const uint32_t height = m_backBuffer.m_height;
  2212. setFrameBuffer(BGFX_INVALID_HANDLE);
  2213. VkViewport vp;
  2214. vp.x = 0.0f;
  2215. vp.y = float(height);
  2216. vp.width = float(width);
  2217. vp.height = -float(height);
  2218. vp.minDepth = 0.0f;
  2219. vp.maxDepth = 1.0f;
  2220. vkCmdSetViewport(m_commandBuffer, 0, 1, &vp);
  2221. VkRect2D rc;
  2222. rc.offset.x = 0;
  2223. rc.offset.y = 0;
  2224. rc.extent.width = width;
  2225. rc.extent.height = height;
  2226. vkCmdSetScissor(m_commandBuffer, 0, 1, &rc);
  2227. const uint64_t state = 0
  2228. | BGFX_STATE_WRITE_RGB
  2229. | BGFX_STATE_WRITE_A
  2230. | BGFX_STATE_DEPTH_TEST_ALWAYS
  2231. | BGFX_STATE_MSAA
  2232. ;
  2233. const VertexLayout* layout = &m_vertexLayouts[_blitter.m_vb->layoutHandle.idx];
  2234. VkPipeline pso = getPipeline(state
  2235. , packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT)
  2236. , 1
  2237. , &layout
  2238. , _blitter.m_program
  2239. , 0
  2240. );
  2241. vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pso);
  2242. ProgramVK& program = m_program[_blitter.m_program.idx];
  2243. float proj[16];
  2244. bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, false);
  2245. PredefinedUniform& predefined = m_program[_blitter.m_program.idx].m_predefined[0];
  2246. uint8_t flags = predefined.m_type;
  2247. setShaderUniform(flags, predefined.m_loc, proj, 4);
  2248. UniformBuffer* vcb = program.m_vsh->m_constantBuffer;
  2249. if (NULL != vcb)
  2250. {
  2251. commit(*vcb);
  2252. }
  2253. ScratchBufferVK& scratchBuffer = m_scratchBuffer[m_cmd.m_currentFrameInFlight];
  2254. const uint32_t bufferOffset = scratchBuffer.write(m_vsScratch, program.m_vsh->m_size);
  2255. const TextureVK& texture = m_textures[_blitter.m_texture.idx];
  2256. RenderBind bind;
  2257. bind.clear();
  2258. bind.m_bind[0].m_type = Binding::Texture;
  2259. bind.m_bind[0].m_idx = _blitter.m_texture.idx;
  2260. bind.m_bind[0].m_samplerFlags = (uint32_t)(texture.m_flags & BGFX_SAMPLER_BITS_MASK);
  2261. const VkDescriptorSet descriptorSet = getDescriptorSet(program, bind, scratchBuffer, NULL);
  2262. vkCmdBindDescriptorSets(
  2263. m_commandBuffer
  2264. , VK_PIPELINE_BIND_POINT_GRAPHICS
  2265. , program.m_pipelineLayout
  2266. , 0
  2267. , 1
  2268. , &descriptorSet
  2269. , 1
  2270. , &bufferOffset
  2271. );
  2272. const VertexBufferVK& vb = m_vertexBuffers[_blitter.m_vb->handle.idx];
  2273. const VkDeviceSize offset = 0;
  2274. vkCmdBindVertexBuffers(m_commandBuffer, 0, 1, &vb.m_buffer, &offset);
  2275. const BufferVK& ib = m_indexBuffers[_blitter.m_ib->handle.idx];
  2276. vkCmdBindIndexBuffer(
  2277. m_commandBuffer
  2278. , ib.m_buffer
  2279. , 0
  2280. , VK_INDEX_TYPE_UINT16
  2281. );
  2282. }
  2283. void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override
  2284. {
  2285. const uint32_t numVertices = _numIndices*4/6;
  2286. if (0 < numVertices
  2287. && m_backBuffer.isRenderable() )
  2288. {
  2289. m_indexBuffers[_blitter.m_ib->handle.idx].update(m_commandBuffer, 0, _numIndices*2, _blitter.m_ib->data, true);
  2290. m_vertexBuffers[_blitter.m_vb->handle.idx].update(m_commandBuffer, 0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data, true);
  2291. VkRenderPassBeginInfo rpbi;
  2292. rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
  2293. rpbi.pNext = NULL;
  2294. rpbi.renderPass = m_backBuffer.m_renderPass;
  2295. rpbi.framebuffer = m_backBuffer.m_currentFramebuffer;
  2296. rpbi.renderArea.offset.x = 0;
  2297. rpbi.renderArea.offset.y = 0;
  2298. rpbi.renderArea.extent.width = m_backBuffer.m_width;
  2299. rpbi.renderArea.extent.height = m_backBuffer.m_height;
  2300. rpbi.clearValueCount = 0;
  2301. rpbi.pClearValues = NULL;
  2302. vkCmdBeginRenderPass(m_commandBuffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
  2303. vkCmdDrawIndexed(m_commandBuffer, _numIndices, 1, 0, 0, 0);
  2304. vkCmdEndRenderPass(m_commandBuffer);
  2305. }
  2306. }
  2307. void preReset()
  2308. {
  2309. for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
  2310. {
  2311. m_frameBuffers[ii].preReset();
  2312. }
  2313. if (m_captureSize > 0)
  2314. {
  2315. g_callback->captureEnd();
  2316. release(m_captureBuffer);
  2317. recycleMemory(m_captureMemory);
  2318. m_captureSize = 0;
  2319. }
  2320. }
  2321. void postReset()
  2322. {
  2323. for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
  2324. {
  2325. m_frameBuffers[ii].postReset();
  2326. }
  2327. if (m_resolution.reset & BGFX_RESET_CAPTURE)
  2328. {
  2329. const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_backBuffer.m_swapChain.m_colorFormat) );
  2330. const uint32_t captureSize = m_backBuffer.m_width * m_backBuffer.m_height * bpp / 8;
  2331. const uint8_t dstBpp = bimg::getBitsPerPixel(bimg::TextureFormat::BGRA8);
  2332. const uint32_t dstPitch = m_backBuffer.m_width * dstBpp / 8;
  2333. if (captureSize > m_captureSize)
  2334. {
  2335. release(m_captureBuffer);
  2336. recycleMemory(m_captureMemory);
  2337. m_captureSize = captureSize;
  2338. VK_CHECK(createReadbackBuffer(m_captureSize, &m_captureBuffer, &m_captureMemory) );
  2339. }
  2340. g_callback->captureBegin(m_resolution.width, m_resolution.height, dstPitch, TextureFormat::BGRA8, false);
  2341. }
  2342. }
  2343. bool updateResolution(const Resolution& _resolution)
  2344. {
  2345. const bool suspended = !!(_resolution.reset & BGFX_RESET_SUSPEND);
  2346. float maxAnisotropy = 1.0f;
  2347. if (!!(_resolution.reset & BGFX_RESET_MAXANISOTROPY) )
  2348. {
  2349. maxAnisotropy = m_deviceProperties.limits.maxSamplerAnisotropy;
  2350. }
  2351. if (m_maxAnisotropy != maxAnisotropy)
  2352. {
  2353. m_maxAnisotropy = maxAnisotropy;
  2354. m_samplerCache.invalidate();
  2355. m_samplerBorderColorCache.invalidate();
  2356. }
  2357. bool depthClamp = m_deviceFeatures.depthClamp && !!(_resolution.reset & BGFX_RESET_DEPTH_CLAMP);
  2358. if (m_depthClamp != depthClamp)
  2359. {
  2360. m_depthClamp = depthClamp;
  2361. m_pipelineStateCache.invalidate();
  2362. }
  2363. if (NULL == m_backBuffer.m_nwh)
  2364. {
  2365. return suspended;
  2366. }
  2367. uint32_t flags = _resolution.reset & ~(0
  2368. | BGFX_RESET_SUSPEND
  2369. | BGFX_RESET_MAXANISOTROPY
  2370. | BGFX_RESET_DEPTH_CLAMP
  2371. );
  2372. if (false
  2373. || m_resolution.format != _resolution.format
  2374. || m_resolution.width != _resolution.width
  2375. || m_resolution.height != _resolution.height
  2376. || m_resolution.reset != flags
  2377. || m_backBuffer.m_swapChain.m_needToRecreateSurface
  2378. || m_backBuffer.m_swapChain.m_needToRecreateSwapchain)
  2379. {
  2380. flags &= ~BGFX_RESET_INTERNAL_FORCE;
  2381. if (m_backBuffer.m_nwh != g_platformData.nwh)
  2382. {
  2383. m_backBuffer.m_nwh = g_platformData.nwh;
  2384. }
  2385. m_resolution = _resolution;
  2386. m_resolution.reset = flags;
  2387. m_textVideoMem.resize(false, _resolution.width, _resolution.height);
  2388. m_textVideoMem.clear();
  2389. preReset();
  2390. m_backBuffer.update(m_commandBuffer, m_resolution);
  2391. // Update the resolution again here, as the actual width and height
  2392. // is now final (as it was potentially clamped by the Vulkan driver).
  2393. m_resolution.width = m_backBuffer.m_width;
  2394. m_resolution.height = m_backBuffer.m_height;
  2395. postReset();
  2396. }
  2397. return suspended;
  2398. }
  2399. void setShaderUniform(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs)
  2400. {
  2401. if (_flags & kUniformFragmentBit)
  2402. {
  2403. bx::memCopy(&m_fsScratch[_regIndex], _val, _numRegs*16);
  2404. }
  2405. else
  2406. {
  2407. bx::memCopy(&m_vsScratch[_regIndex], _val, _numRegs*16);
  2408. }
  2409. }
  2410. void setShaderUniform4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs)
  2411. {
  2412. setShaderUniform(_flags, _regIndex, _val, _numRegs);
  2413. }
  2414. void setShaderUniform4x4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs)
  2415. {
  2416. setShaderUniform(_flags, _regIndex, _val, _numRegs);
  2417. }
  2418. void setFrameBuffer(FrameBufferHandle _fbh, bool _acquire = true)
  2419. {
  2420. BGFX_PROFILER_SCOPE("Vk::setFrameBuffer()", kColorFrame);
  2421. BX_ASSERT(false
  2422. || isValid(_fbh)
  2423. || NULL != m_backBuffer.m_nwh
  2424. , "Rendering to backbuffer in headless mode."
  2425. );
  2426. FrameBufferVK& newFrameBuffer = isValid(_fbh)
  2427. ? m_frameBuffers[_fbh.idx]
  2428. : m_backBuffer
  2429. ;
  2430. FrameBufferVK& oldFrameBuffer = isValid(m_fbh)
  2431. ? m_frameBuffers[m_fbh.idx]
  2432. : m_backBuffer
  2433. ;
  2434. if (NULL == oldFrameBuffer.m_nwh
  2435. && m_fbh.idx != _fbh.idx)
  2436. {
  2437. oldFrameBuffer.resolve();
  2438. for (uint8_t ii = 0, num = oldFrameBuffer.m_num; ii < num; ++ii)
  2439. {
  2440. TextureVK& texture = m_textures[oldFrameBuffer.m_texture[ii].idx];
  2441. texture.setImageMemoryBarrier(m_commandBuffer, texture.m_sampledLayout);
  2442. if (VK_NULL_HANDLE != texture.m_singleMsaaImage)
  2443. {
  2444. texture.setImageMemoryBarrier(m_commandBuffer, texture.m_sampledLayout, true);
  2445. }
  2446. }
  2447. if (isValid(oldFrameBuffer.m_depth) )
  2448. {
  2449. TextureVK& texture = m_textures[oldFrameBuffer.m_depth.idx];
  2450. const bool writeOnly = 0 != (texture.m_flags&BGFX_TEXTURE_RT_WRITE_ONLY);
  2451. if (!writeOnly)
  2452. {
  2453. texture.setImageMemoryBarrier(m_commandBuffer, texture.m_sampledLayout);
  2454. }
  2455. }
  2456. }
  2457. if (NULL == newFrameBuffer.m_nwh)
  2458. {
  2459. for (uint8_t ii = 0, num = newFrameBuffer.m_num; ii < num; ++ii)
  2460. {
  2461. TextureVK& texture = m_textures[newFrameBuffer.m_texture[ii].idx];
  2462. texture.setImageMemoryBarrier(
  2463. m_commandBuffer
  2464. , VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
  2465. );
  2466. }
  2467. if (isValid(newFrameBuffer.m_depth) )
  2468. {
  2469. TextureVK& texture = m_textures[newFrameBuffer.m_depth.idx];
  2470. texture.setImageMemoryBarrier(
  2471. m_commandBuffer
  2472. , VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
  2473. );
  2474. }
  2475. newFrameBuffer.acquire(m_commandBuffer);
  2476. }
  2477. if (_acquire)
  2478. {
  2479. int64_t start = bx::getHPCounter();
  2480. newFrameBuffer.acquire(m_commandBuffer);
  2481. int64_t now = bx::getHPCounter();
  2482. if (NULL != newFrameBuffer.m_nwh)
  2483. {
  2484. m_presentElapsed += now - start;
  2485. }
  2486. }
  2487. m_fbh = _fbh;
  2488. }
  2489. void setDebugWireframe(bool _wireframe)
  2490. {
  2491. const bool wireframe = m_deviceFeatures.fillModeNonSolid && _wireframe;
  2492. if (m_wireframe != wireframe)
  2493. {
  2494. m_wireframe = wireframe;
  2495. m_pipelineStateCache.invalidate();
  2496. }
  2497. }
  2498. void setBlendState(VkPipelineColorBlendStateCreateInfo& _desc, uint64_t _state, uint32_t _rgba = 0)
  2499. {
  2500. VkPipelineColorBlendAttachmentState* bas = const_cast<VkPipelineColorBlendAttachmentState*>(_desc.pAttachments);
  2501. uint8_t writeMask = 0;
  2502. writeMask |= (_state & BGFX_STATE_WRITE_R) ? VK_COLOR_COMPONENT_R_BIT : 0;
  2503. writeMask |= (_state & BGFX_STATE_WRITE_G) ? VK_COLOR_COMPONENT_G_BIT : 0;
  2504. writeMask |= (_state & BGFX_STATE_WRITE_B) ? VK_COLOR_COMPONENT_B_BIT : 0;
  2505. writeMask |= (_state & BGFX_STATE_WRITE_A) ? VK_COLOR_COMPONENT_A_BIT : 0;
  2506. bas->blendEnable = !!(BGFX_STATE_BLEND_MASK & _state);
  2507. {
  2508. const uint32_t blend = uint32_t( (_state & BGFX_STATE_BLEND_MASK ) >> BGFX_STATE_BLEND_SHIFT);
  2509. const uint32_t equation = uint32_t( (_state & BGFX_STATE_BLEND_EQUATION_MASK) >> BGFX_STATE_BLEND_EQUATION_SHIFT);
  2510. const uint32_t srcRGB = (blend ) & 0xf;
  2511. const uint32_t dstRGB = (blend >> 4) & 0xf;
  2512. const uint32_t srcA = (blend >> 8) & 0xf;
  2513. const uint32_t dstA = (blend >> 12) & 0xf;
  2514. const uint32_t equRGB = (equation ) & 0x7;
  2515. const uint32_t equA = (equation >> 3) & 0x7;
  2516. bas->srcColorBlendFactor = s_blendFactor[srcRGB][0];
  2517. bas->dstColorBlendFactor = s_blendFactor[dstRGB][0];
  2518. bas->colorBlendOp = s_blendEquation[equRGB];
  2519. bas->srcAlphaBlendFactor = s_blendFactor[srcA][1];
  2520. bas->dstAlphaBlendFactor = s_blendFactor[dstA][1];
  2521. bas->alphaBlendOp = s_blendEquation[equA];
  2522. bas->colorWriteMask = writeMask;
  2523. }
  2524. const FrameBufferVK& frameBuffer = isValid(m_fbh)
  2525. ? m_frameBuffers[m_fbh.idx]
  2526. : m_backBuffer
  2527. ;
  2528. const uint32_t numAttachments = NULL == frameBuffer.m_nwh
  2529. ? frameBuffer.m_num
  2530. : 1
  2531. ;
  2532. if (!!(BGFX_STATE_BLEND_INDEPENDENT & _state)
  2533. && m_deviceFeatures.independentBlend )
  2534. {
  2535. for (uint32_t ii = 1, rgba = _rgba; ii < numAttachments; ++ii, rgba >>= 11)
  2536. {
  2537. ++bas;
  2538. bas->blendEnable = 0 != (rgba & 0x7ff);
  2539. const uint32_t src = (rgba ) & 0xf;
  2540. const uint32_t dst = (rgba >> 4) & 0xf;
  2541. const uint32_t equation = (rgba >> 8) & 0x7;
  2542. bas->srcColorBlendFactor = s_blendFactor[src][0];
  2543. bas->dstColorBlendFactor = s_blendFactor[dst][0];
  2544. bas->colorBlendOp = s_blendEquation[equation];
  2545. bas->srcAlphaBlendFactor = s_blendFactor[src][1];
  2546. bas->dstAlphaBlendFactor = s_blendFactor[dst][1];
  2547. bas->alphaBlendOp = s_blendEquation[equation];
  2548. bas->colorWriteMask = writeMask;
  2549. }
  2550. }
  2551. else
  2552. {
  2553. for (uint32_t ii = 1; ii < numAttachments; ++ii)
  2554. {
  2555. bx::memCopy(&bas[ii], bas, sizeof(VkPipelineColorBlendAttachmentState) );
  2556. }
  2557. }
  2558. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
  2559. _desc.pNext = NULL;
  2560. _desc.flags = 0;
  2561. _desc.logicOpEnable = VK_FALSE;
  2562. _desc.logicOp = VK_LOGIC_OP_CLEAR;
  2563. _desc.attachmentCount = numAttachments;
  2564. _desc.blendConstants[0] = 0.0f;
  2565. _desc.blendConstants[1] = 0.0f;
  2566. _desc.blendConstants[2] = 0.0f;
  2567. _desc.blendConstants[3] = 0.0f;
  2568. }
  2569. void setRasterizerState(VkPipelineRasterizationStateCreateInfo& _desc, uint64_t _state, bool _wireframe = false)
  2570. {
  2571. const uint32_t cull = (_state&BGFX_STATE_CULL_MASK) >> BGFX_STATE_CULL_SHIFT;
  2572. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
  2573. _desc.pNext = NULL;
  2574. _desc.flags = 0;
  2575. _desc.depthClampEnable = m_deviceFeatures.depthClamp && m_depthClamp;
  2576. _desc.rasterizerDiscardEnable = VK_FALSE;
  2577. _desc.polygonMode = m_deviceFeatures.fillModeNonSolid && _wireframe
  2578. ? VK_POLYGON_MODE_LINE
  2579. : VK_POLYGON_MODE_FILL
  2580. ;
  2581. _desc.cullMode = s_cullMode[cull];
  2582. _desc.frontFace = (_state&BGFX_STATE_FRONT_CCW) ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE;
  2583. _desc.depthBiasEnable = VK_FALSE;
  2584. _desc.depthBiasConstantFactor = 0.0f;
  2585. _desc.depthBiasClamp = 0.0f;
  2586. _desc.depthBiasSlopeFactor = 0.0f;
  2587. _desc.lineWidth = 1.0f;
  2588. }
  2589. void setConservativeRasterizerState(VkPipelineRasterizationConservativeStateCreateInfoEXT& _desc, uint64_t _state)
  2590. {
  2591. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT;
  2592. _desc.pNext = NULL;
  2593. _desc.flags = 0;
  2594. _desc.conservativeRasterizationMode = (_state&BGFX_STATE_CONSERVATIVE_RASTER)
  2595. ? VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT
  2596. : VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT
  2597. ;
  2598. _desc.extraPrimitiveOverestimationSize = 0.0f;
  2599. }
  2600. void setLineRasterizerState(VkPipelineRasterizationLineStateCreateInfoEXT& _desc, uint64_t _state)
  2601. {
  2602. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
  2603. _desc.pNext = NULL;
  2604. _desc.lineRasterizationMode = (_state & BGFX_STATE_LINEAA)
  2605. ? VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT
  2606. : VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT
  2607. ;
  2608. _desc.stippledLineEnable = VK_FALSE;
  2609. _desc.lineStippleFactor = 0;
  2610. _desc.lineStipplePattern = 0;
  2611. }
  2612. void setDepthStencilState(VkPipelineDepthStencilStateCreateInfo& _desc, uint64_t _state, uint64_t _stencil = 0)
  2613. {
  2614. const uint32_t fstencil = unpackStencil(0, _stencil);
  2615. uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
  2616. _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
  2617. _desc.pNext = NULL;
  2618. _desc.flags = 0;
  2619. _desc.depthTestEnable = 0 != func;
  2620. _desc.depthWriteEnable = !!(BGFX_STATE_WRITE_Z & _state);
  2621. _desc.depthCompareOp = s_cmpFunc[func];
  2622. _desc.depthBoundsTestEnable = VK_FALSE;
  2623. _desc.stencilTestEnable = 0 != _stencil;
  2624. uint32_t bstencil = unpackStencil(1, _stencil);
  2625. uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
  2626. bstencil = frontAndBack ? bstencil : fstencil;
  2627. _desc.front.failOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_FAIL_S_MASK) >> BGFX_STENCIL_OP_FAIL_S_SHIFT];
  2628. _desc.front.passOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_PASS_Z_MASK) >> BGFX_STENCIL_OP_PASS_Z_SHIFT];
  2629. _desc.front.depthFailOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_FAIL_Z_MASK) >> BGFX_STENCIL_OP_FAIL_Z_SHIFT];
  2630. _desc.front.compareOp = s_cmpFunc[(fstencil & BGFX_STENCIL_TEST_MASK) >> BGFX_STENCIL_TEST_SHIFT];
  2631. _desc.front.compareMask = UINT32_MAX;
  2632. _desc.front.writeMask = UINT32_MAX;
  2633. _desc.front.reference = 0;
  2634. _desc.back.failOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_FAIL_S_MASK) >> BGFX_STENCIL_OP_FAIL_S_SHIFT];
  2635. _desc.back.passOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_PASS_Z_MASK) >> BGFX_STENCIL_OP_PASS_Z_SHIFT];
  2636. _desc.back.depthFailOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_FAIL_Z_MASK) >> BGFX_STENCIL_OP_FAIL_Z_SHIFT];
  2637. _desc.back.compareOp = s_cmpFunc[(bstencil&BGFX_STENCIL_TEST_MASK) >> BGFX_STENCIL_TEST_SHIFT];
  2638. _desc.back.compareMask = UINT32_MAX;
  2639. _desc.back.writeMask = UINT32_MAX;
  2640. _desc.back.reference = 0;
  2641. _desc.minDepthBounds = 0.0f;
  2642. _desc.maxDepthBounds = 1.0f;
  2643. }
  2644. void setInputLayout(VkPipelineVertexInputStateCreateInfo& _vertexInputState, uint8_t _numStream, const VertexLayout** _layout, const ProgramVK& _program, uint8_t _numInstanceData)
  2645. {
  2646. _vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
  2647. _vertexInputState.pNext = NULL;
  2648. _vertexInputState.flags = 0;
  2649. _vertexInputState.vertexBindingDescriptionCount = 0;
  2650. _vertexInputState.vertexAttributeDescriptionCount = 0;
  2651. uint16_t unsettedAttr[Attrib::Count];
  2652. bx::memCopy(unsettedAttr, _program.m_vsh->m_attrMask, sizeof(uint16_t) * Attrib::Count);
  2653. for (uint8_t stream = 0; stream < _numStream; ++stream)
  2654. {
  2655. VertexLayout layout;
  2656. bx::memCopy(&layout, _layout[stream], sizeof(VertexLayout) );
  2657. const uint16_t* attrMask = _program.m_vsh->m_attrMask;
  2658. for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
  2659. {
  2660. uint16_t mask = attrMask[ii];
  2661. uint16_t attr = (layout.m_attributes[ii] & mask);
  2662. layout.m_attributes[ii] = attr == 0 || attr == UINT16_MAX ? UINT16_MAX : attr;
  2663. if (unsettedAttr[ii] && attr != UINT16_MAX)
  2664. {
  2665. unsettedAttr[ii] = 0;
  2666. }
  2667. }
  2668. fillVertexLayout(_program.m_vsh, _vertexInputState, layout);
  2669. }
  2670. for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
  2671. {
  2672. if (0 < unsettedAttr[ii])
  2673. {
  2674. uint32_t numAttribs = _vertexInputState.vertexAttributeDescriptionCount;
  2675. VkVertexInputAttributeDescription* inputAttrib = const_cast<VkVertexInputAttributeDescription*>(_vertexInputState.pVertexAttributeDescriptions + numAttribs);
  2676. inputAttrib->location = _program.m_vsh->m_attrRemap[ii];
  2677. inputAttrib->binding = 0;
  2678. inputAttrib->format = VK_FORMAT_R32G32B32_SFLOAT;
  2679. inputAttrib->offset = 0;
  2680. _vertexInputState.vertexAttributeDescriptionCount++;
  2681. }
  2682. }
  2683. if (0 < _numInstanceData)
  2684. {
  2685. fillInstanceBinding(_program.m_vsh, _vertexInputState, _numInstanceData);
  2686. }
  2687. }
  2688. VkResult getRenderPass(uint8_t _num, const VkFormat* _formats, const VkImageAspectFlags* _aspects, const bool* _resolve, VkSampleCountFlagBits _samples, ::VkRenderPass* _renderPass)
  2689. {
  2690. VkResult result = VK_SUCCESS;
  2691. if (VK_SAMPLE_COUNT_1_BIT == _samples)
  2692. {
  2693. _resolve = NULL;
  2694. }
  2695. bx::HashMurmur2A hash;
  2696. hash.begin();
  2697. hash.add(_samples);
  2698. hash.add(_formats, sizeof(VkFormat) * _num);
  2699. if (NULL != _resolve)
  2700. {
  2701. hash.add(_resolve, sizeof(bool) * _num);
  2702. }
  2703. uint32_t hashKey = hash.end();
  2704. VkRenderPass renderPass = m_renderPassCache.find(hashKey);
  2705. if (VK_NULL_HANDLE != renderPass)
  2706. {
  2707. *_renderPass = renderPass;
  2708. return result;
  2709. }
  2710. VkAttachmentDescription ad[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS * 2];
  2711. for (uint8_t ii = 0; ii < (_num * 2); ++ii)
  2712. {
  2713. ad[ii].flags = 0;
  2714. ad[ii].format = VK_FORMAT_UNDEFINED;
  2715. ad[ii].samples = _samples;
  2716. ad[ii].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
  2717. ad[ii].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  2718. ad[ii].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  2719. ad[ii].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  2720. ad[ii].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2721. ad[ii].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2722. }
  2723. VkAttachmentReference colorAr[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  2724. VkAttachmentReference resolveAr[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  2725. VkAttachmentReference depthAr;
  2726. uint32_t numColorAr = 0;
  2727. uint32_t numResolveAr = 0;
  2728. colorAr[0].attachment = VK_ATTACHMENT_UNUSED;
  2729. colorAr[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2730. resolveAr[0].attachment = VK_ATTACHMENT_UNUSED;
  2731. resolveAr[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2732. depthAr.attachment = VK_ATTACHMENT_UNUSED;
  2733. depthAr.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  2734. for (uint8_t ii = 0; ii < _num; ++ii)
  2735. {
  2736. ad[ii].format = _formats[ii];
  2737. if (_aspects[ii] & VK_IMAGE_ASPECT_COLOR_BIT)
  2738. {
  2739. colorAr[numColorAr].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2740. colorAr[numColorAr].attachment = ii;
  2741. resolveAr[numColorAr].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  2742. resolveAr[numColorAr].attachment = VK_ATTACHMENT_UNUSED;
  2743. if (NULL != _resolve
  2744. && _resolve[ii])
  2745. {
  2746. const uint32_t resolve = _num + numResolveAr;
  2747. ad[resolve].format = _formats[ii];
  2748. ad[resolve].samples = VK_SAMPLE_COUNT_1_BIT;
  2749. ad[resolve].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  2750. resolveAr[numColorAr].attachment = resolve;
  2751. numResolveAr++;
  2752. }
  2753. numColorAr++;
  2754. }
  2755. else if (_aspects[ii] & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) )
  2756. {
  2757. ad[ii].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
  2758. ad[ii].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
  2759. ad[ii].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  2760. ad[ii].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  2761. depthAr.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  2762. depthAr.attachment = ii;
  2763. }
  2764. }
  2765. VkSubpassDescription sd[1];
  2766. sd[0].flags = 0;
  2767. sd[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  2768. sd[0].inputAttachmentCount = 0;
  2769. sd[0].pInputAttachments = NULL;
  2770. sd[0].colorAttachmentCount = bx::max<uint32_t>(numColorAr, 1);
  2771. sd[0].pColorAttachments = colorAr;
  2772. sd[0].pResolveAttachments = resolveAr;
  2773. sd[0].pDepthStencilAttachment = &depthAr;
  2774. sd[0].preserveAttachmentCount = 0;
  2775. sd[0].pPreserveAttachments = NULL;
  2776. const VkPipelineStageFlags graphicsStages = 0
  2777. | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
  2778. | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
  2779. | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
  2780. | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
  2781. | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
  2782. | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
  2783. | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
  2784. ;
  2785. const VkPipelineStageFlags outsideStages = 0
  2786. | graphicsStages
  2787. | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
  2788. | VK_PIPELINE_STAGE_TRANSFER_BIT
  2789. ;
  2790. VkSubpassDependency dep[2];
  2791. dep[0].srcSubpass = VK_SUBPASS_EXTERNAL;
  2792. dep[0].dstSubpass = 0;
  2793. dep[0].srcStageMask = outsideStages;
  2794. dep[0].dstStageMask = graphicsStages;
  2795. dep[0].srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
  2796. dep[0].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
  2797. dep[0].dependencyFlags = 0;
  2798. dep[1].srcSubpass = BX_COUNTOF(sd)-1;
  2799. dep[1].dstSubpass = VK_SUBPASS_EXTERNAL;
  2800. dep[1].srcStageMask = graphicsStages;
  2801. dep[1].dstStageMask = outsideStages;
  2802. dep[1].srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
  2803. dep[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
  2804. dep[1].dependencyFlags = 0;
  2805. VkRenderPassCreateInfo rpi;
  2806. rpi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  2807. rpi.pNext = NULL;
  2808. rpi.flags = 0;
  2809. rpi.attachmentCount = _num + numResolveAr;
  2810. rpi.pAttachments = ad;
  2811. rpi.subpassCount = BX_COUNTOF(sd);
  2812. rpi.pSubpasses = sd;
  2813. rpi.dependencyCount = BX_COUNTOF(dep);
  2814. rpi.pDependencies = dep;
  2815. result = vkCreateRenderPass(m_device, &rpi, m_allocatorCb, &renderPass);
  2816. if (VK_SUCCESS != result)
  2817. {
  2818. BX_TRACE("Create render pass error: vkCreateRenderPass failed %d: %s.", result, getName(result) );
  2819. return result;
  2820. }
  2821. m_renderPassCache.add(hashKey, renderPass);
  2822. *_renderPass = renderPass;
  2823. return result;
  2824. }
  2825. VkResult getRenderPass(uint8_t _num, const Attachment* _attachments, ::VkRenderPass* _renderPass)
  2826. {
  2827. VkFormat formats[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  2828. VkImageAspectFlags aspects[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  2829. VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
  2830. for (uint8_t ii = 0; ii < _num; ++ii)
  2831. {
  2832. const TextureVK& texture = m_textures[_attachments[ii].handle.idx];
  2833. formats[ii] = texture.m_format;
  2834. aspects[ii] = texture.m_aspectMask;
  2835. samples = texture.m_sampler.Sample;
  2836. }
  2837. return getRenderPass(_num, formats, aspects, NULL, samples, _renderPass);
  2838. }
  2839. VkResult getRenderPass(const SwapChainVK& swapChain, ::VkRenderPass* _renderPass)
  2840. {
  2841. const VkFormat formats[2] =
  2842. {
  2843. swapChain.m_sci.imageFormat,
  2844. swapChain.m_backBufferDepthStencil.m_format
  2845. };
  2846. const VkImageAspectFlags aspects[2] =
  2847. {
  2848. VK_IMAGE_ASPECT_COLOR_BIT,
  2849. swapChain.m_backBufferDepthStencil.m_aspectMask
  2850. };
  2851. const bool resolve[2] =
  2852. {
  2853. swapChain.m_supportsManualResolve ? false : true,
  2854. false
  2855. };
  2856. const VkSampleCountFlagBits samples = swapChain.m_sampler.Sample;
  2857. return getRenderPass(BX_COUNTOF(formats), formats, aspects, resolve, samples, _renderPass);
  2858. }
  2859. VkSampler getSampler(uint32_t _flags, VkFormat _format, const float _palette[][4])
  2860. {
  2861. uint32_t index = ((_flags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT);
  2862. index = bx::min<uint32_t>(BGFX_CONFIG_MAX_COLOR_PALETTE - 1, index);
  2863. _flags &= BGFX_SAMPLER_BITS_MASK;
  2864. _flags &= ~(m_deviceFeatures.samplerAnisotropy ? 0 : (BGFX_SAMPLER_MIN_ANISOTROPIC | BGFX_SAMPLER_MAG_ANISOTROPIC) );
  2865. // Force both min+max anisotropic, can't be set individually.
  2866. _flags |= 0 != (_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC) )
  2867. ? BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC
  2868. : 0
  2869. ;
  2870. const float* rgba = NULL == _palette
  2871. ? NULL
  2872. : _palette[index]
  2873. ;
  2874. const bool needColor = true
  2875. && needBorderColor(_flags)
  2876. && NULL != rgba
  2877. && m_borderColorSupport
  2878. ;
  2879. uint32_t hashKey;
  2880. VkSampler sampler = VK_NULL_HANDLE;
  2881. if (!needColor)
  2882. {
  2883. bx::HashMurmur2A hash;
  2884. hash.begin();
  2885. hash.add(_flags);
  2886. hash.add(-1);
  2887. hash.add(VK_FORMAT_UNDEFINED);
  2888. hashKey = hash.end();
  2889. sampler = m_samplerCache.find(hashKey);
  2890. }
  2891. else
  2892. {
  2893. bx::HashMurmur2A hash;
  2894. hash.begin();
  2895. hash.add(_flags);
  2896. hash.add(index);
  2897. hash.add(_format);
  2898. hashKey = hash.end();
  2899. const uint32_t colorHashKey = m_samplerBorderColorCache.find(hashKey);
  2900. const uint32_t newColorHashKey = bx::hash<bx::HashMurmur2A>(rgba, sizeof(float) * 4);
  2901. if (newColorHashKey == colorHashKey)
  2902. {
  2903. sampler = m_samplerCache.find(hashKey);
  2904. }
  2905. else
  2906. {
  2907. m_samplerBorderColorCache.add(hashKey, newColorHashKey);
  2908. }
  2909. }
  2910. if (VK_NULL_HANDLE != sampler)
  2911. {
  2912. return sampler;
  2913. }
  2914. const uint32_t cmpFunc = (_flags&BGFX_SAMPLER_COMPARE_MASK)>>BGFX_SAMPLER_COMPARE_SHIFT;
  2915. const float maxLodBias = m_deviceProperties.limits.maxSamplerLodBias;
  2916. const float lodBias = bx::clamp(float(BGFX_CONFIG_MIP_LOD_BIAS), -maxLodBias, maxLodBias);
  2917. VkSamplerCreateInfo sci;
  2918. sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
  2919. sci.pNext = NULL;
  2920. sci.flags = 0;
  2921. sci.magFilter = _flags & BGFX_SAMPLER_MAG_POINT ? VK_FILTER_NEAREST : VK_FILTER_LINEAR;
  2922. sci.minFilter = _flags & BGFX_SAMPLER_MIN_POINT ? VK_FILTER_NEAREST : VK_FILTER_LINEAR;
  2923. sci.mipmapMode = _flags & BGFX_SAMPLER_MIP_POINT ? VK_SAMPLER_MIPMAP_MODE_NEAREST : VK_SAMPLER_MIPMAP_MODE_LINEAR;
  2924. sci.addressModeU = s_textureAddress[(_flags&BGFX_SAMPLER_U_MASK)>>BGFX_SAMPLER_U_SHIFT];
  2925. sci.addressModeV = s_textureAddress[(_flags&BGFX_SAMPLER_V_MASK)>>BGFX_SAMPLER_V_SHIFT];
  2926. sci.addressModeW = s_textureAddress[(_flags&BGFX_SAMPLER_W_MASK)>>BGFX_SAMPLER_W_SHIFT];
  2927. sci.mipLodBias = lodBias;
  2928. sci.anisotropyEnable = !!(_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC | BGFX_SAMPLER_MAG_ANISOTROPIC) );
  2929. sci.maxAnisotropy = m_maxAnisotropy;
  2930. sci.compareEnable = 0 != cmpFunc;
  2931. sci.compareOp = s_cmpFunc[cmpFunc];
  2932. sci.minLod = 0.0f;
  2933. sci.maxLod = VK_LOD_CLAMP_NONE;
  2934. sci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
  2935. sci.unnormalizedCoordinates = VK_FALSE;
  2936. VkSamplerCustomBorderColorCreateInfoEXT cbcci;
  2937. if (needColor)
  2938. {
  2939. cbcci.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
  2940. cbcci.pNext = NULL;
  2941. cbcci.format = _format;
  2942. bx::memCopy(cbcci.customBorderColor.float32, rgba, sizeof(cbcci.customBorderColor.float32) );
  2943. sci.pNext = &cbcci;
  2944. sci.borderColor = VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
  2945. }
  2946. VK_CHECK(vkCreateSampler(m_device, &sci, m_allocatorCb, &sampler) );
  2947. m_samplerCache.add(hashKey, sampler);
  2948. return sampler;
  2949. }
  2950. VkImageView getCachedImageView(TextureHandle _handle, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, bool _stencil = false)
  2951. {
  2952. const TextureVK& texture = m_textures[_handle.idx];
  2953. _stencil = _stencil && !!(texture.m_aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT);
  2954. bx::HashMurmur2A hash;
  2955. hash.begin();
  2956. hash.add(_handle.idx);
  2957. hash.add(_mip);
  2958. hash.add(_numMips);
  2959. hash.add(_type);
  2960. hash.add(_stencil);
  2961. uint32_t hashKey = hash.end();
  2962. VkImageView* viewCached = m_imageViewCache.find(hashKey);
  2963. if (NULL != viewCached)
  2964. {
  2965. return *viewCached;
  2966. }
  2967. const VkImageAspectFlags aspectMask = 0
  2968. | VK_IMAGE_ASPECT_COLOR_BIT
  2969. | ( _stencil ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT)
  2970. ;
  2971. VkImageView view;
  2972. VK_CHECK(texture.createView(0, texture.m_numSides, _mip, _numMips, _type, aspectMask, false, &view) );
  2973. m_imageViewCache.add(hashKey, view, _handle.idx);
  2974. return view;
  2975. }
  2976. VkPipeline getPipeline(ProgramHandle _program)
  2977. {
  2978. ProgramVK& program = m_program[_program.idx];
  2979. bx::HashMurmur2A murmur;
  2980. murmur.begin();
  2981. murmur.add(program.m_vsh->m_hash);
  2982. const uint32_t hash = murmur.end();
  2983. VkPipeline pipeline = m_pipelineStateCache.find(hash);
  2984. if (VK_NULL_HANDLE != pipeline)
  2985. {
  2986. return pipeline;
  2987. }
  2988. VkComputePipelineCreateInfo cpci;
  2989. cpci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
  2990. cpci.pNext = NULL;
  2991. cpci.flags = 0;
  2992. cpci.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
  2993. cpci.stage.pNext = NULL;
  2994. cpci.stage.flags = 0;
  2995. cpci.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
  2996. cpci.stage.module = program.m_vsh->m_module;
  2997. cpci.stage.pName = "main";
  2998. cpci.stage.pSpecializationInfo = NULL;
  2999. cpci.layout = program.m_pipelineLayout;
  3000. cpci.basePipelineHandle = VK_NULL_HANDLE;
  3001. cpci.basePipelineIndex = 0;
  3002. VK_CHECK(vkCreateComputePipelines(m_device, m_pipelineCache, 1, &cpci, m_allocatorCb, &pipeline) );
  3003. m_pipelineStateCache.add(hash, pipeline);
  3004. return pipeline;
  3005. }
  3006. VkPipeline getPipeline(uint64_t _state, uint64_t _stencil, uint8_t _numStreams, const VertexLayout** _layouts, ProgramHandle _program, uint8_t _numInstanceData)
  3007. {
  3008. ProgramVK& program = m_program[_program.idx];
  3009. _state &= 0
  3010. | BGFX_STATE_WRITE_MASK
  3011. | BGFX_STATE_DEPTH_TEST_MASK
  3012. | BGFX_STATE_BLEND_MASK
  3013. | BGFX_STATE_BLEND_EQUATION_MASK
  3014. | (g_caps.supported & BGFX_CAPS_BLEND_INDEPENDENT ? BGFX_STATE_BLEND_INDEPENDENT : 0)
  3015. | BGFX_STATE_BLEND_ALPHA_TO_COVERAGE
  3016. | BGFX_STATE_CULL_MASK
  3017. | BGFX_STATE_FRONT_CCW
  3018. | BGFX_STATE_MSAA
  3019. | (m_lineAASupport ? BGFX_STATE_LINEAA : 0)
  3020. | (g_caps.supported & BGFX_CAPS_CONSERVATIVE_RASTER ? BGFX_STATE_CONSERVATIVE_RASTER : 0)
  3021. | BGFX_STATE_PT_MASK
  3022. ;
  3023. _stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, ~BGFX_STENCIL_FUNC_REF_MASK);
  3024. VertexLayout layout;
  3025. if (0 < _numStreams)
  3026. {
  3027. bx::memCopy(&layout, _layouts[0], sizeof(VertexLayout) );
  3028. const uint16_t* attrMask = program.m_vsh->m_attrMask;
  3029. for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
  3030. {
  3031. uint16_t mask = attrMask[ii];
  3032. uint16_t attr = (layout.m_attributes[ii] & mask);
  3033. layout.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr;
  3034. }
  3035. }
  3036. const FrameBufferVK& frameBuffer = isValid(m_fbh)
  3037. ? m_frameBuffers[m_fbh.idx]
  3038. : m_backBuffer
  3039. ;
  3040. bx::HashMurmur2A murmur;
  3041. murmur.begin();
  3042. murmur.add(_state);
  3043. murmur.add(_stencil);
  3044. murmur.add(program.m_vsh->m_hash);
  3045. murmur.add(program.m_vsh->m_attrMask, sizeof(program.m_vsh->m_attrMask) );
  3046. if (NULL != program.m_fsh)
  3047. {
  3048. murmur.add(program.m_fsh->m_hash);
  3049. }
  3050. for (uint8_t ii = 0; ii < _numStreams; ++ii)
  3051. {
  3052. murmur.add(_layouts[ii]->m_hash);
  3053. }
  3054. murmur.add(layout.m_attributes, sizeof(layout.m_attributes) );
  3055. murmur.add(_numInstanceData);
  3056. murmur.add(frameBuffer.m_renderPass);
  3057. const uint32_t hash = murmur.end();
  3058. VkPipeline pipeline = m_pipelineStateCache.find(hash);
  3059. if (VK_NULL_HANDLE != pipeline)
  3060. {
  3061. return pipeline;
  3062. }
  3063. VkPipelineColorBlendAttachmentState blendAttachmentState[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  3064. VkPipelineColorBlendStateCreateInfo colorBlendState;
  3065. colorBlendState.pAttachments = blendAttachmentState;
  3066. setBlendState(colorBlendState, _state);
  3067. VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
  3068. inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
  3069. inputAssemblyState.pNext = NULL;
  3070. inputAssemblyState.flags = 0;
  3071. inputAssemblyState.topology = s_primInfo[(_state&BGFX_STATE_PT_MASK) >> BGFX_STATE_PT_SHIFT].m_topology;
  3072. inputAssemblyState.primitiveRestartEnable = VK_FALSE;
  3073. VkPipelineRasterizationStateCreateInfo rasterizationState;
  3074. setRasterizerState(rasterizationState, _state, m_wireframe);
  3075. VkBaseInStructure* nextRasterizationState = (VkBaseInStructure*)&rasterizationState;
  3076. VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeRasterizationState;
  3077. if (s_extension[Extension::EXT_conservative_rasterization].m_supported)
  3078. {
  3079. nextRasterizationState->pNext = (VkBaseInStructure*)&conservativeRasterizationState;
  3080. nextRasterizationState = (VkBaseInStructure*)&conservativeRasterizationState;
  3081. setConservativeRasterizerState(conservativeRasterizationState, _state);
  3082. }
  3083. VkPipelineRasterizationLineStateCreateInfoEXT lineRasterizationState;
  3084. if (m_lineAASupport)
  3085. {
  3086. nextRasterizationState->pNext = (VkBaseInStructure*)&lineRasterizationState;
  3087. nextRasterizationState = (VkBaseInStructure*)&lineRasterizationState;
  3088. setLineRasterizerState(lineRasterizationState, _state);
  3089. }
  3090. VkPipelineDepthStencilStateCreateInfo depthStencilState;
  3091. setDepthStencilState(depthStencilState, _state, _stencil);
  3092. VkVertexInputBindingDescription inputBinding[BGFX_CONFIG_MAX_VERTEX_STREAMS + 1];
  3093. VkVertexInputAttributeDescription inputAttrib[Attrib::Count + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
  3094. VkPipelineVertexInputStateCreateInfo vertexInputState;
  3095. vertexInputState.pVertexBindingDescriptions = inputBinding;
  3096. vertexInputState.pVertexAttributeDescriptions = inputAttrib;
  3097. setInputLayout(vertexInputState, _numStreams, _layouts, program, _numInstanceData);
  3098. const VkDynamicState dynamicStates[] =
  3099. {
  3100. VK_DYNAMIC_STATE_VIEWPORT,
  3101. VK_DYNAMIC_STATE_SCISSOR,
  3102. VK_DYNAMIC_STATE_BLEND_CONSTANTS,
  3103. VK_DYNAMIC_STATE_STENCIL_REFERENCE,
  3104. };
  3105. VkPipelineDynamicStateCreateInfo dynamicState;
  3106. dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
  3107. dynamicState.pNext = NULL;
  3108. dynamicState.flags = 0;
  3109. dynamicState.dynamicStateCount = BX_COUNTOF(dynamicStates);
  3110. dynamicState.pDynamicStates = dynamicStates;
  3111. VkPipelineShaderStageCreateInfo shaderStages[2];
  3112. shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
  3113. shaderStages[0].pNext = NULL;
  3114. shaderStages[0].flags = 0;
  3115. shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
  3116. shaderStages[0].module = program.m_vsh->m_module;
  3117. shaderStages[0].pName = "main";
  3118. shaderStages[0].pSpecializationInfo = NULL;
  3119. if (NULL != program.m_fsh)
  3120. {
  3121. shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
  3122. shaderStages[1].pNext = NULL;
  3123. shaderStages[1].flags = 0;
  3124. shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
  3125. shaderStages[1].module = program.m_fsh->m_module;
  3126. shaderStages[1].pName = "main";
  3127. shaderStages[1].pSpecializationInfo = NULL;
  3128. }
  3129. VkPipelineViewportStateCreateInfo viewportState;
  3130. viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
  3131. viewportState.pNext = NULL;
  3132. viewportState.flags = 0;
  3133. viewportState.viewportCount = 1;
  3134. viewportState.pViewports = NULL;
  3135. viewportState.scissorCount = 1;
  3136. viewportState.pScissors = NULL;
  3137. VkPipelineMultisampleStateCreateInfo multisampleState;
  3138. multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
  3139. multisampleState.pNext = NULL;
  3140. multisampleState.flags = 0;
  3141. multisampleState.rasterizationSamples = frameBuffer.m_sampler.Sample;
  3142. multisampleState.sampleShadingEnable = VK_FALSE;
  3143. multisampleState.minSampleShading = 0.0f;
  3144. multisampleState.pSampleMask = NULL;
  3145. multisampleState.alphaToCoverageEnable = !!(BGFX_STATE_BLEND_ALPHA_TO_COVERAGE & _state);
  3146. multisampleState.alphaToOneEnable = VK_FALSE;
  3147. VkGraphicsPipelineCreateInfo graphicsPipeline;
  3148. graphicsPipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
  3149. graphicsPipeline.pNext = NULL;
  3150. graphicsPipeline.flags = 0;
  3151. graphicsPipeline.stageCount = NULL == program.m_fsh ? 1 : 2;
  3152. graphicsPipeline.pStages = shaderStages;
  3153. graphicsPipeline.pVertexInputState = &vertexInputState;
  3154. graphicsPipeline.pInputAssemblyState = &inputAssemblyState;
  3155. graphicsPipeline.pTessellationState = NULL;
  3156. graphicsPipeline.pViewportState = &viewportState;
  3157. graphicsPipeline.pRasterizationState = &rasterizationState;
  3158. graphicsPipeline.pMultisampleState = &multisampleState;
  3159. graphicsPipeline.pDepthStencilState = &depthStencilState;
  3160. graphicsPipeline.pColorBlendState = &colorBlendState;
  3161. graphicsPipeline.pDynamicState = &dynamicState;
  3162. graphicsPipeline.layout = program.m_pipelineLayout;
  3163. graphicsPipeline.renderPass = frameBuffer.m_renderPass;
  3164. graphicsPipeline.subpass = 0;
  3165. graphicsPipeline.basePipelineHandle = VK_NULL_HANDLE;
  3166. graphicsPipeline.basePipelineIndex = 0;
  3167. uint32_t length = g_callback->cacheReadSize(hash);
  3168. bool cached = length > 0;
  3169. void* cachedData = NULL;
  3170. VkPipelineCacheCreateInfo pcci;
  3171. pcci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
  3172. pcci.pNext = NULL;
  3173. pcci.flags = 0;
  3174. pcci.initialDataSize = 0;
  3175. pcci.pInitialData = NULL;
  3176. if (cached)
  3177. {
  3178. cachedData = bx::alloc(g_allocator, length);
  3179. if (g_callback->cacheRead(hash, cachedData, length) )
  3180. {
  3181. BX_TRACE("Loading cached pipeline state (size %d).", length);
  3182. bx::MemoryReader reader(cachedData, length);
  3183. pcci.initialDataSize = (size_t)reader.remaining();
  3184. pcci.pInitialData = reader.getDataPtr();
  3185. }
  3186. }
  3187. VkPipelineCache cache;
  3188. VK_CHECK(vkCreatePipelineCache(m_device, &pcci, m_allocatorCb, &cache) );
  3189. VK_CHECK(vkCreateGraphicsPipelines(
  3190. m_device
  3191. , cache
  3192. , 1
  3193. , &graphicsPipeline
  3194. , m_allocatorCb
  3195. , &pipeline
  3196. ) );
  3197. m_pipelineStateCache.add(hash, pipeline);
  3198. size_t dataSize;
  3199. VK_CHECK(vkGetPipelineCacheData(m_device, cache, &dataSize, NULL) );
  3200. if (0 < dataSize)
  3201. {
  3202. if (length < dataSize)
  3203. {
  3204. cachedData = bx::realloc(g_allocator, cachedData, dataSize);
  3205. }
  3206. VK_CHECK(vkGetPipelineCacheData(m_device, cache, &dataSize, cachedData) );
  3207. g_callback->cacheWrite(hash, cachedData, (uint32_t)dataSize);
  3208. }
  3209. VK_CHECK(vkMergePipelineCaches(m_device, m_pipelineCache, 1, &cache) );
  3210. vkDestroy(cache);
  3211. if (NULL != cachedData)
  3212. {
  3213. bx::free(g_allocator, cachedData);
  3214. }
  3215. return pipeline;
  3216. }
  3217. VkDescriptorSet getDescriptorSet(const ProgramVK& program, const RenderBind& renderBind, const ScratchBufferVK& scratchBuffer, const float _palette[][4])
  3218. {
  3219. VkDescriptorSet descriptorSet;
  3220. VkDescriptorSetAllocateInfo dsai;
  3221. dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
  3222. dsai.pNext = NULL;
  3223. dsai.descriptorPool = m_descriptorPool;
  3224. dsai.descriptorSetCount = 1;
  3225. dsai.pSetLayouts = &program.m_descriptorSetLayout;
  3226. VK_CHECK(vkAllocateDescriptorSets(m_device, &dsai, &descriptorSet) );
  3227. VkDescriptorImageInfo imageInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  3228. VkDescriptorBufferInfo bufferInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  3229. constexpr uint32_t kMaxDescriptorSets = 2 * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS + 2;
  3230. VkWriteDescriptorSet wds[kMaxDescriptorSets] = {};
  3231. uint32_t wdsCount = 0;
  3232. uint32_t bufferCount = 0;
  3233. uint32_t imageCount = 0;
  3234. for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage)
  3235. {
  3236. const Binding& bind = renderBind.m_bind[stage];
  3237. const BindInfo& bindInfo = program.m_bindInfo[stage];
  3238. if (kInvalidHandle != bind.m_idx
  3239. && isValid(bindInfo.uniformHandle) )
  3240. {
  3241. switch (bind.m_type)
  3242. {
  3243. case Binding::Image:
  3244. {
  3245. const bool isImageDescriptor = BindType::Image == bindInfo.type;
  3246. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3247. wds[wdsCount].pNext = NULL;
  3248. wds[wdsCount].dstSet = descriptorSet;
  3249. wds[wdsCount].dstBinding = bindInfo.binding;
  3250. wds[wdsCount].dstArrayElement = 0;
  3251. wds[wdsCount].descriptorCount = 1;
  3252. wds[wdsCount].descriptorType = isImageDescriptor
  3253. ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
  3254. : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
  3255. ;
  3256. wds[wdsCount].pImageInfo = NULL;
  3257. wds[wdsCount].pBufferInfo = NULL;
  3258. wds[wdsCount].pTexelBufferView = NULL;
  3259. const TextureVK& texture = m_textures[bind.m_idx];
  3260. VkImageViewType type = texture.m_type;
  3261. if (UINT32_MAX != bindInfo.index)
  3262. {
  3263. type = program.m_textures[bindInfo.index].type;
  3264. }
  3265. else if (type == VK_IMAGE_VIEW_TYPE_CUBE
  3266. || type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
  3267. {
  3268. type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
  3269. }
  3270. BX_ASSERT(
  3271. texture.m_currentImageLayout == texture.m_sampledLayout
  3272. , "Mismatching image layout. Texture currently used as a framebuffer attachment?"
  3273. );
  3274. imageInfo[imageCount].imageLayout = texture.m_sampledLayout;
  3275. imageInfo[imageCount].sampler = VK_NULL_HANDLE;
  3276. imageInfo[imageCount].imageView = getCachedImageView(
  3277. { bind.m_idx }
  3278. , bind.m_mip
  3279. , 1
  3280. , type
  3281. );
  3282. wds[wdsCount].pImageInfo = &imageInfo[imageCount];
  3283. ++imageCount;
  3284. ++wdsCount;
  3285. }
  3286. break;
  3287. case Binding::VertexBuffer:
  3288. case Binding::IndexBuffer:
  3289. {
  3290. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3291. wds[wdsCount].pNext = NULL;
  3292. wds[wdsCount].dstSet = descriptorSet;
  3293. wds[wdsCount].dstBinding = bindInfo.binding;
  3294. wds[wdsCount].dstArrayElement = 0;
  3295. wds[wdsCount].descriptorCount = 1;
  3296. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
  3297. wds[wdsCount].pImageInfo = NULL;
  3298. wds[wdsCount].pBufferInfo = NULL;
  3299. wds[wdsCount].pTexelBufferView = NULL;
  3300. const BufferVK& sb = bind.m_type == Binding::VertexBuffer
  3301. ? m_vertexBuffers[bind.m_idx]
  3302. : m_indexBuffers[bind.m_idx]
  3303. ;
  3304. bufferInfo[bufferCount].buffer = sb.m_buffer;
  3305. bufferInfo[bufferCount].offset = 0;
  3306. bufferInfo[bufferCount].range = sb.m_size;
  3307. wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount];
  3308. ++bufferCount;
  3309. ++wdsCount;
  3310. }
  3311. break;
  3312. case Binding::Texture:
  3313. {
  3314. TextureVK& texture = m_textures[bind.m_idx];
  3315. const uint32_t samplerFlags = 0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags)
  3316. ? bind.m_samplerFlags
  3317. : (uint32_t)texture.m_flags
  3318. ;
  3319. const bool sampleStencil = !!(samplerFlags & BGFX_SAMPLER_SAMPLE_STENCIL);
  3320. VkSampler sampler = getSampler(samplerFlags, texture.m_format, _palette);
  3321. const VkImageViewType type = UINT32_MAX == bindInfo.index
  3322. ? texture.m_type
  3323. : program.m_textures[bindInfo.index].type
  3324. ;
  3325. BX_ASSERT(
  3326. texture.m_currentImageLayout == texture.m_sampledLayout
  3327. , "Mismatching image layout. Texture currently used as a framebuffer attachment?"
  3328. );
  3329. imageInfo[imageCount].imageLayout = texture.m_sampledLayout;
  3330. imageInfo[imageCount].sampler = sampler;
  3331. imageInfo[imageCount].imageView = getCachedImageView(
  3332. { bind.m_idx }
  3333. , 0
  3334. , texture.m_numMips
  3335. , type
  3336. , sampleStencil
  3337. );
  3338. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3339. wds[wdsCount].pNext = NULL;
  3340. wds[wdsCount].dstSet = descriptorSet;
  3341. wds[wdsCount].dstBinding = bindInfo.binding;
  3342. wds[wdsCount].dstArrayElement = 0;
  3343. wds[wdsCount].descriptorCount = 1;
  3344. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
  3345. wds[wdsCount].pImageInfo = &imageInfo[imageCount];
  3346. wds[wdsCount].pBufferInfo = NULL;
  3347. wds[wdsCount].pTexelBufferView = NULL;
  3348. ++wdsCount;
  3349. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3350. wds[wdsCount].pNext = NULL;
  3351. wds[wdsCount].dstSet = descriptorSet;
  3352. wds[wdsCount].dstBinding = bindInfo.samplerBinding;
  3353. wds[wdsCount].dstArrayElement = 0;
  3354. wds[wdsCount].descriptorCount = 1;
  3355. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
  3356. wds[wdsCount].pImageInfo = &imageInfo[imageCount];
  3357. wds[wdsCount].pBufferInfo = NULL;
  3358. wds[wdsCount].pTexelBufferView = NULL;
  3359. ++wdsCount;
  3360. ++imageCount;
  3361. }
  3362. break;
  3363. }
  3364. }
  3365. }
  3366. const uint32_t vsize = program.m_vsh->m_size;
  3367. const uint32_t fsize = NULL != program.m_fsh ? program.m_fsh->m_size : 0;
  3368. if (vsize > 0)
  3369. {
  3370. bufferInfo[bufferCount].buffer = scratchBuffer.m_buffer;
  3371. bufferInfo[bufferCount].offset = 0;
  3372. bufferInfo[bufferCount].range = vsize;
  3373. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3374. wds[wdsCount].pNext = NULL;
  3375. wds[wdsCount].dstSet = descriptorSet;
  3376. wds[wdsCount].dstBinding = program.m_vsh->m_uniformBinding;
  3377. wds[wdsCount].dstArrayElement = 0;
  3378. wds[wdsCount].descriptorCount = 1;
  3379. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  3380. wds[wdsCount].pImageInfo = NULL;
  3381. wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount];
  3382. wds[wdsCount].pTexelBufferView = NULL;
  3383. ++wdsCount;
  3384. ++bufferCount;
  3385. }
  3386. if (fsize > 0)
  3387. {
  3388. bufferInfo[bufferCount].buffer = scratchBuffer.m_buffer;
  3389. bufferInfo[bufferCount].offset = 0;
  3390. bufferInfo[bufferCount].range = fsize;
  3391. wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  3392. wds[wdsCount].pNext = NULL;
  3393. wds[wdsCount].dstSet = descriptorSet;
  3394. wds[wdsCount].dstBinding = program.m_fsh->m_uniformBinding;
  3395. wds[wdsCount].dstArrayElement = 0;
  3396. wds[wdsCount].descriptorCount = 1;
  3397. wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  3398. wds[wdsCount].pImageInfo = NULL;
  3399. wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount];
  3400. wds[wdsCount].pTexelBufferView = NULL;
  3401. ++wdsCount;
  3402. ++bufferCount;
  3403. }
  3404. vkUpdateDescriptorSets(m_device, wdsCount, wds, 0, NULL);
  3405. VkDescriptorSet temp = descriptorSet;
  3406. release(temp);
  3407. return descriptorSet;
  3408. }
  3409. bool isSwapChainReadable(const SwapChainVK& _swapChain)
  3410. {
  3411. return true
  3412. && NULL != _swapChain.m_nwh
  3413. && _swapChain.m_needPresent
  3414. && _swapChain.m_supportsReadback
  3415. && bimg::imageConvert(bimg::TextureFormat::BGRA8, bimg::TextureFormat::Enum(_swapChain.m_colorFormat) )
  3416. ;
  3417. }
  3418. typedef void (*SwapChainReadFunc)(void* /*src*/, uint32_t /*width*/, uint32_t /*height*/, uint32_t /*pitch*/, const void* /*userData*/);
  3419. bool readSwapChain(const SwapChainVK& _swapChain, VkBuffer _buffer, DeviceMemoryAllocationVK _memory, SwapChainReadFunc _func, const void* _userData = NULL)
  3420. {
  3421. if (isSwapChainReadable(_swapChain) )
  3422. {
  3423. // source for the copy is the last rendered swapchain image
  3424. const VkImage image = _swapChain.m_backBufferColorImage[_swapChain.m_backBufferColorIdx];
  3425. const VkImageLayout layout = _swapChain.m_backBufferColorImageLayout[_swapChain.m_backBufferColorIdx];
  3426. const uint32_t width = _swapChain.m_sci.imageExtent.width;
  3427. const uint32_t height = _swapChain.m_sci.imageExtent.height;
  3428. ReadbackVK readback;
  3429. readback.create(image, width, height, _swapChain.m_colorFormat);
  3430. const uint32_t pitch = readback.pitch();
  3431. readback.copyImageToBuffer(m_commandBuffer, _buffer, layout, VK_IMAGE_ASPECT_COLOR_BIT);
  3432. // stall for commandbuffer to finish
  3433. kick(true);
  3434. uint8_t* src;
  3435. VK_CHECK(vkMapMemory(m_device, _memory.mem, _memory.offset, _memory.size, 0, (void**)&src) );
  3436. if (_swapChain.m_colorFormat == TextureFormat::RGBA8)
  3437. {
  3438. bimg::imageSwizzleBgra8(src, pitch, width, height, src, pitch);
  3439. _func(src, width, height, pitch, _userData);
  3440. }
  3441. else if (_swapChain.m_colorFormat == TextureFormat::BGRA8)
  3442. {
  3443. _func(src, width, height, pitch, _userData);
  3444. }
  3445. else
  3446. {
  3447. const uint8_t dstBpp = bimg::getBitsPerPixel(bimg::TextureFormat::BGRA8);
  3448. const uint32_t dstPitch = width * dstBpp / 8;
  3449. const uint32_t dstSize = height * dstPitch;
  3450. void* dst = bx::alloc(g_allocator, dstSize);
  3451. bimg::imageConvert(g_allocator, dst, bimg::TextureFormat::BGRA8, src, bimg::TextureFormat::Enum(_swapChain.m_colorFormat), width, height, 1);
  3452. _func(dst, width, height, dstPitch, _userData);
  3453. bx::free(g_allocator, dst);
  3454. }
  3455. vkUnmapMemory(m_device, _memory.mem);
  3456. readback.destroy();
  3457. return true;
  3458. }
  3459. return false;
  3460. }
  3461. void capture()
  3462. {
  3463. if (m_captureSize > 0)
  3464. {
  3465. m_backBuffer.resolve();
  3466. auto callback = [](void* _src, uint32_t /*_width*/, uint32_t _height, uint32_t _pitch, const void* /*_userData*/)
  3467. {
  3468. const uint32_t size = _height * _pitch;
  3469. g_callback->captureFrame(_src, size);
  3470. };
  3471. readSwapChain(m_backBuffer.m_swapChain, m_captureBuffer, m_captureMemory, callback);
  3472. }
  3473. }
  3474. bool isVisible(Frame* _render, OcclusionQueryHandle _handle, bool _visible)
  3475. {
  3476. return _visible == (0 != _render->m_occlusion[_handle.idx]);
  3477. }
  3478. void commit(UniformBuffer& _uniformBuffer)
  3479. {
  3480. _uniformBuffer.reset();
  3481. for (;;)
  3482. {
  3483. uint32_t opcode = _uniformBuffer.read();
  3484. if (UniformType::End == opcode)
  3485. {
  3486. break;
  3487. }
  3488. uint8_t type;
  3489. uint16_t loc;
  3490. uint16_t num;
  3491. uint16_t copy;
  3492. UniformBuffer::decodeOpcode(opcode, type, loc, num, copy);
  3493. const char* data;
  3494. if (copy)
  3495. {
  3496. data = _uniformBuffer.read(g_uniformTypeSize[type]*num);
  3497. }
  3498. else
  3499. {
  3500. UniformHandle handle;
  3501. bx::memCopy(&handle, _uniformBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) );
  3502. data = (const char*)m_uniforms[handle.idx];
  3503. }
  3504. switch (type)
  3505. {
  3506. case UniformType::Mat3:
  3507. case UniformType::Mat3|kUniformFragmentBit:
  3508. {
  3509. float* value = (float*)data;
  3510. for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9)
  3511. {
  3512. Matrix4 mtx;
  3513. mtx.un.val[ 0] = value[0];
  3514. mtx.un.val[ 1] = value[1];
  3515. mtx.un.val[ 2] = value[2];
  3516. mtx.un.val[ 3] = 0.0f;
  3517. mtx.un.val[ 4] = value[3];
  3518. mtx.un.val[ 5] = value[4];
  3519. mtx.un.val[ 6] = value[5];
  3520. mtx.un.val[ 7] = 0.0f;
  3521. mtx.un.val[ 8] = value[6];
  3522. mtx.un.val[ 9] = value[7];
  3523. mtx.un.val[10] = value[8];
  3524. mtx.un.val[11] = 0.0f;
  3525. setShaderUniform(uint8_t(type), loc, &mtx.un.val[0], 3);
  3526. }
  3527. }
  3528. break;
  3529. case UniformType::Sampler:
  3530. case UniformType::Sampler|kUniformFragmentBit:
  3531. // do nothing, but VkDescriptorSetImageInfo would be set before drawing
  3532. break;
  3533. case UniformType::Vec4:
  3534. case UniformType::Vec4 | kUniformFragmentBit:
  3535. case UniformType::Mat4:
  3536. case UniformType::Mat4 | kUniformFragmentBit:
  3537. {
  3538. setShaderUniform(uint8_t(type), loc, data, num);
  3539. }
  3540. break;
  3541. case UniformType::End:
  3542. break;
  3543. default:
  3544. BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy);
  3545. break;
  3546. }
  3547. }
  3548. }
  3549. void clearQuad(const Rect& _rect, const Clear& _clear, const float _palette[][4])
  3550. {
  3551. VkClearRect rect[1];
  3552. rect[0].rect.offset.x = _rect.m_x;
  3553. rect[0].rect.offset.y = _rect.m_y;
  3554. rect[0].rect.extent.width = _rect.m_width;
  3555. rect[0].rect.extent.height = _rect.m_height;
  3556. rect[0].baseArrayLayer = 0;
  3557. rect[0].layerCount = 1;
  3558. uint32_t numMrt;
  3559. bgfx::TextureFormat::Enum mrtFormat[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  3560. VkImageAspectFlags depthAspectMask;
  3561. const FrameBufferVK& fb = isValid(m_fbh)
  3562. ? m_frameBuffers[m_fbh.idx]
  3563. : m_backBuffer
  3564. ;
  3565. if (NULL == fb.m_nwh)
  3566. {
  3567. numMrt = fb.m_num;
  3568. for (uint8_t ii = 0; ii < fb.m_num; ++ii)
  3569. {
  3570. mrtFormat[ii] = bgfx::TextureFormat::Enum(m_textures[fb.m_texture[ii].idx].m_requestedFormat);
  3571. }
  3572. depthAspectMask = isValid(fb.m_depth) ? m_textures[fb.m_depth.idx].m_aspectMask : 0;
  3573. rect[0].layerCount = fb.m_attachment[0].numLayers;
  3574. }
  3575. else
  3576. {
  3577. numMrt = 1;
  3578. mrtFormat[0] = fb.m_swapChain.m_colorFormat;
  3579. depthAspectMask = fb.m_swapChain.m_backBufferDepthStencil.m_aspectMask;
  3580. }
  3581. VkClearAttachment attachments[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS + 1];
  3582. uint32_t mrt = 0;
  3583. if (BGFX_CLEAR_COLOR & _clear.m_flags)
  3584. {
  3585. for (uint32_t ii = 0; ii < numMrt; ++ii)
  3586. {
  3587. attachments[mrt].colorAttachment = mrt;
  3588. attachments[mrt].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  3589. VkClearColorValue& clearValue = attachments[mrt].clearValue.color;
  3590. const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(mrtFormat[ii]) );
  3591. const bx::EncodingType::Enum type = bx::EncodingType::Enum(blockInfo.encoding);
  3592. if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)
  3593. {
  3594. const uint8_t index = bx::min<uint8_t>(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[ii]);
  3595. switch (type)
  3596. {
  3597. case bx::EncodingType::Int:
  3598. case bx::EncodingType::Uint:
  3599. clearValue.int32[0] = int32_t(_palette[index][0]);
  3600. clearValue.int32[1] = int32_t(_palette[index][1]);
  3601. clearValue.int32[2] = int32_t(_palette[index][2]);
  3602. clearValue.int32[3] = int32_t(_palette[index][3]);
  3603. break;
  3604. default:
  3605. bx::memCopy(&clearValue.float32, _palette[index], sizeof(clearValue.float32) );
  3606. break;
  3607. }
  3608. }
  3609. else
  3610. {
  3611. switch (type)
  3612. {
  3613. case bx::EncodingType::Int:
  3614. case bx::EncodingType::Uint:
  3615. clearValue.uint32[0] = _clear.m_index[0];
  3616. clearValue.uint32[1] = _clear.m_index[1];
  3617. clearValue.uint32[2] = _clear.m_index[2];
  3618. clearValue.uint32[3] = _clear.m_index[3];
  3619. break;
  3620. default:
  3621. bx::unpackRgba8(clearValue.float32, _clear.m_index);
  3622. break;
  3623. }
  3624. }
  3625. ++mrt;
  3626. }
  3627. }
  3628. depthAspectMask &= 0
  3629. | (_clear.m_flags & BGFX_CLEAR_DEPTH ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
  3630. | (_clear.m_flags & BGFX_CLEAR_STENCIL ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)
  3631. ;
  3632. if (0 != depthAspectMask)
  3633. {
  3634. attachments[mrt].colorAttachment = VK_ATTACHMENT_UNUSED;
  3635. // The above is meaningless and not required by the spec, but Khronos
  3636. // Validation Layer has a conditional jump depending on this, even
  3637. // without VK_IMAGE_ASPECT_COLOR_BIT set. Valgrind found this.
  3638. attachments[mrt].aspectMask = depthAspectMask;
  3639. attachments[mrt].clearValue.depthStencil.stencil = _clear.m_stencil;
  3640. attachments[mrt].clearValue.depthStencil.depth = _clear.m_depth;
  3641. ++mrt;
  3642. }
  3643. if (mrt > 0)
  3644. {
  3645. vkCmdClearAttachments(m_commandBuffer, mrt, attachments, BX_COUNTOF(rect), rect);
  3646. }
  3647. }
  3648. void kick(bool _finishAll = false)
  3649. {
  3650. m_cmd.kick(_finishAll);
  3651. VK_CHECK(m_cmd.alloc(&m_commandBuffer) );
  3652. m_cmd.finish(_finishAll);
  3653. }
  3654. int32_t selectMemoryType(uint32_t _memoryTypeBits, uint32_t _propertyFlags, int32_t _startIndex = 0) const
  3655. {
  3656. for (int32_t ii = _startIndex, num = m_memoryProperties.memoryTypeCount; ii < num; ++ii)
  3657. {
  3658. const VkMemoryType& memType = m_memoryProperties.memoryTypes[ii];
  3659. if ( (0 != ( (1<<ii) & _memoryTypeBits) )
  3660. && ( (memType.propertyFlags & _propertyFlags) == _propertyFlags) )
  3661. {
  3662. return ii;
  3663. }
  3664. }
  3665. BX_TRACE("Failed to find memory that supports flags 0x%08x.", _propertyFlags);
  3666. return -1;
  3667. }
  3668. VkResult allocateMemory(const VkMemoryRequirements* requirements, VkMemoryPropertyFlags propertyFlags, DeviceMemoryAllocationVK* memory, bool _forcePrivateDeviceAllocation)
  3669. {
  3670. BGFX_PROFILER_SCOPE("RendererContextVK::allocateMemory", kColorResource);
  3671. // Forcing the use of a private device allocation for a certain memory allocation
  3672. // can be desirable when memory mapping the allocation. A memory allocation
  3673. // can only be mapped once. So handing out multiple subregions of one bigger
  3674. // allocation can lead to problems, when they get mapped multiple times.
  3675. // Right now, with the LRU system, we are still only handing out the full
  3676. // memory allocation, and never subregions of it, so it's impossible right
  3677. // now to map a single allocation multiple times.
  3678. // The argument is there to indicate this, but it's ignored right now, for the above
  3679. // reason: any cached memory is fine, as long as we don't partition it.
  3680. BX_UNUSED(_forcePrivateDeviceAllocation);
  3681. {
  3682. // Check LRU cache.
  3683. int memoryType = selectMemoryType(requirements->memoryTypeBits, propertyFlags, 0);
  3684. bool found = m_memoryLru.find(bx::narrowCast<uint32_t>(requirements->size), memoryType, memory);
  3685. if (found)
  3686. {
  3687. return VK_SUCCESS;
  3688. }
  3689. }
  3690. VkMemoryAllocateInfo ma;
  3691. ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
  3692. ma.pNext = NULL;
  3693. ma.allocationSize = requirements->size;
  3694. VkResult result = VK_ERROR_UNKNOWN;
  3695. int32_t searchIndex = -1;
  3696. do
  3697. {
  3698. searchIndex++;
  3699. searchIndex = selectMemoryType(requirements->memoryTypeBits, propertyFlags, searchIndex);
  3700. if (searchIndex >= 0)
  3701. {
  3702. BGFX_PROFILER_SCOPE("vkAllocateMemory", kColorResource);
  3703. ma.memoryTypeIndex = searchIndex;
  3704. memory->memoryTypeIndex = searchIndex;
  3705. memory->size = bx::narrowCast<uint32_t>(ma.allocationSize);
  3706. memory->offset = 0;
  3707. result = vkAllocateMemory(m_device, &ma, m_allocatorCb, &memory->mem);
  3708. }
  3709. }
  3710. while (result != VK_SUCCESS
  3711. && searchIndex >= 0);
  3712. return result;
  3713. }
  3714. VkResult createHostBuffer(uint32_t _size, VkMemoryPropertyFlags _flags, ::VkBuffer* _buffer, DeviceMemoryAllocationVK* _memory, bool _forcePrivateDeviceAllocation, const void* _data = NULL)
  3715. {
  3716. BGFX_PROFILER_SCOPE("createHostBuffer", kColorResource);
  3717. VkResult result = VK_SUCCESS;
  3718. VkBufferCreateInfo bci;
  3719. bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  3720. bci.pNext = NULL;
  3721. bci.flags = 0;
  3722. bci.size = _size;
  3723. bci.queueFamilyIndexCount = 0;
  3724. bci.pQueueFamilyIndices = NULL;
  3725. bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  3726. bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
  3727. result = vkCreateBuffer(m_device, &bci, m_allocatorCb, _buffer);
  3728. if (VK_SUCCESS != result)
  3729. {
  3730. BX_TRACE("Create host buffer error: vkCreateBuffer failed %d: %s.", result, getName(result) );
  3731. return result;
  3732. }
  3733. VkMemoryRequirements mr;
  3734. vkGetBufferMemoryRequirements(m_device, *_buffer, &mr);
  3735. result = allocateMemory(&mr, _flags, _memory, _forcePrivateDeviceAllocation);
  3736. if (VK_SUCCESS != result
  3737. && (_flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) )
  3738. {
  3739. result = allocateMemory(&mr, _flags & ~VK_MEMORY_PROPERTY_HOST_CACHED_BIT, _memory, _forcePrivateDeviceAllocation);
  3740. }
  3741. if (VK_SUCCESS != result)
  3742. {
  3743. BX_TRACE("Create host buffer error: vkAllocateMemory failed %d: %s.", result, getName(result) );
  3744. return result;
  3745. }
  3746. result = vkBindBufferMemory(m_device, *_buffer, _memory->mem, _memory->offset);
  3747. if (VK_SUCCESS != result)
  3748. {
  3749. BX_TRACE("Create host buffer error: vkBindBufferMemory failed %d: %s.", result, getName(result) );
  3750. return result;
  3751. }
  3752. if (_data != NULL)
  3753. {
  3754. BGFX_PROFILER_SCOPE("map and copy data", kColorResource);
  3755. void* dst;
  3756. result = vkMapMemory(m_device, _memory->mem, _memory->offset, _size, 0, &dst);
  3757. if (VK_SUCCESS != result)
  3758. {
  3759. BX_TRACE("Create host buffer error: vkMapMemory failed %d: %s.", result, getName(result) );
  3760. return result;
  3761. }
  3762. bx::memCopy(dst, _data, _size);
  3763. vkUnmapMemory(m_device, _memory->mem);
  3764. }
  3765. return result;
  3766. }
  3767. VkResult createStagingBuffer(uint32_t _size, ::VkBuffer* _buffer, DeviceMemoryAllocationVK* _memory, const void* _data = NULL)
  3768. {
  3769. const VkMemoryPropertyFlags flags = 0
  3770. | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
  3771. | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
  3772. ;
  3773. return createHostBuffer(_size, flags, _buffer, _memory, false, _data);
  3774. }
  3775. StagingBufferVK allocFromScratchStagingBuffer(uint32_t _size, uint32_t _align, const void* _data = NULL)
  3776. {
  3777. BGFX_PROFILER_SCOPE("allocFromScratchStagingBuffer", kColorResource);
  3778. StagingBufferVK result;
  3779. ScratchBufferVK &scratch = m_scratchStagingBuffer[m_cmd.m_currentFrameInFlight];
  3780. if (_size <= BGFX_CONFIG_MAX_STAGING_SIZE_FOR_SCRATCH_BUFFER)
  3781. {
  3782. const uint32_t scratchOffset = scratch.alloc(_size, _align);
  3783. if (UINT32_MAX != scratchOffset)
  3784. {
  3785. result.m_isFromScratch = true;
  3786. result.m_deviceMem = scratch.m_deviceMem;
  3787. result.m_size = _size;
  3788. result.m_offset = scratchOffset;
  3789. result.m_buffer = scratch.m_buffer;
  3790. result.m_data = scratch.m_data + result.m_offset;
  3791. if (_data != NULL)
  3792. {
  3793. BGFX_PROFILER_SCOPE("copy to scratch", kColorResource);
  3794. bx::memCopy(result.m_data, _data, _size);
  3795. }
  3796. return result;
  3797. }
  3798. }
  3799. // Not enough space or too big, we will create a new staging buffer on the spot.
  3800. VK_CHECK(createStagingBuffer(_size, &result.m_buffer, &result.m_deviceMem, _data));
  3801. result.m_isFromScratch = false;
  3802. result.m_offset = 0;
  3803. result.m_size = _size;
  3804. result.m_data = NULL;
  3805. return result;
  3806. }
  3807. VkResult createReadbackBuffer(uint32_t _size, ::VkBuffer* _buffer, DeviceMemoryAllocationVK* _memory)
  3808. {
  3809. const VkMemoryPropertyFlags flags = 0
  3810. | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
  3811. | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
  3812. | VK_MEMORY_PROPERTY_HOST_CACHED_BIT
  3813. ;
  3814. return createHostBuffer(_size, flags, _buffer, _memory, true, NULL);
  3815. }
  3816. VkAllocationCallbacks* m_allocatorCb;
  3817. VkDebugReportCallbackEXT m_debugReportCallback;
  3818. VkInstance m_instance;
  3819. VkPhysicalDevice m_physicalDevice;
  3820. uint32_t m_instanceApiVersion;
  3821. VkPhysicalDeviceProperties m_deviceProperties;
  3822. VkPhysicalDeviceMemoryProperties m_memoryProperties;
  3823. VkPhysicalDeviceFeatures m_deviceFeatures;
  3824. bool m_lineAASupport;
  3825. bool m_borderColorSupport;
  3826. bool m_timerQuerySupport;
  3827. FrameBufferVK m_backBuffer;
  3828. TextureFormat::Enum m_swapChainFormats[TextureFormat::Count];
  3829. uint16_t m_numWindows;
  3830. FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
  3831. int64_t m_presentElapsed;
  3832. MemoryLruVK m_memoryLru;
  3833. ScratchBufferVK m_scratchBuffer[BGFX_CONFIG_MAX_FRAME_LATENCY];
  3834. ScratchBufferVK m_scratchStagingBuffer[BGFX_CONFIG_MAX_FRAME_LATENCY];
  3835. uint32_t m_numFramesInFlight;
  3836. CommandQueueVK m_cmd;
  3837. VkCommandBuffer m_commandBuffer;
  3838. VkDevice m_device;
  3839. uint32_t m_globalQueueFamily;
  3840. VkQueue m_globalQueue;
  3841. VkDescriptorPool m_descriptorPool;
  3842. VkPipelineCache m_pipelineCache;
  3843. TimerQueryVK m_gpuTimer;
  3844. OcclusionQueryVK m_occlusionQuery;
  3845. void* m_renderDocDll;
  3846. void* m_vulkan1Dll;
  3847. IndexBufferVK m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
  3848. VertexBufferVK m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
  3849. ShaderVK m_shaders[BGFX_CONFIG_MAX_SHADERS];
  3850. ProgramVK m_program[BGFX_CONFIG_MAX_PROGRAMS];
  3851. TextureVK m_textures[BGFX_CONFIG_MAX_TEXTURES];
  3852. VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS];
  3853. FrameBufferVK m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS];
  3854. void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
  3855. Matrix4 m_predefinedUniforms[PredefinedUniform::Count];
  3856. UniformRegistry m_uniformReg;
  3857. StateCacheT<VkPipeline> m_pipelineStateCache;
  3858. StateCacheT<VkDescriptorSetLayout> m_descriptorSetLayoutCache;
  3859. StateCacheT<VkRenderPass> m_renderPassCache;
  3860. StateCacheT<VkSampler> m_samplerCache;
  3861. StateCacheT<uint32_t> m_samplerBorderColorCache;
  3862. StateCacheLru<VkImageView, 1024> m_imageViewCache;
  3863. Resolution m_resolution;
  3864. float m_maxAnisotropy;
  3865. bool m_depthClamp;
  3866. bool m_wireframe;
  3867. VkBuffer m_captureBuffer;
  3868. DeviceMemoryAllocationVK m_captureMemory;
  3869. uint32_t m_captureSize;
  3870. TextVideoMem m_textVideoMem;
  3871. uint8_t m_fsScratch[64<<10];
  3872. uint8_t m_vsScratch[64<<10];
  3873. FrameBufferHandle m_fbh;
  3874. };
  3875. static RendererContextVK* s_renderVK;
  3876. RendererContextI* rendererCreate(const Init& _init)
  3877. {
  3878. s_renderVK = BX_NEW(g_allocator, RendererContextVK);
  3879. if (!s_renderVK->init(_init) )
  3880. {
  3881. bx::deleteObject(g_allocator, s_renderVK);
  3882. s_renderVK = NULL;
  3883. }
  3884. return s_renderVK;
  3885. }
  3886. void rendererDestroy()
  3887. {
  3888. s_renderVK->shutdown();
  3889. bx::deleteObject(g_allocator, s_renderVK);
  3890. s_renderVK = NULL;
  3891. }
  3892. #define VK_DESTROY_FUNC(_name) \
  3893. void vkDestroy(Vk##_name& _obj) \
  3894. { \
  3895. if (VK_NULL_HANDLE != _obj) \
  3896. { \
  3897. BGFX_PROFILER_SCOPE("vkDestroy" #_name, kColorResource); \
  3898. vkDestroy##_name(s_renderVK->m_device, _obj.vk, s_renderVK->m_allocatorCb); \
  3899. _obj = VK_NULL_HANDLE; \
  3900. } \
  3901. } \
  3902. void release(Vk##_name& _obj) \
  3903. { \
  3904. s_renderVK->release(_obj); \
  3905. }
  3906. VK_DESTROY
  3907. #undef VK_DESTROY_FUNC
  3908. void vkDestroy(VkDeviceMemory& _obj)
  3909. {
  3910. if (VK_NULL_HANDLE != _obj)
  3911. {
  3912. BGFX_PROFILER_SCOPE("vkFreeMemory", kColorResource);
  3913. vkFreeMemory(s_renderVK->m_device, _obj.vk, s_renderVK->m_allocatorCb);
  3914. _obj = VK_NULL_HANDLE;
  3915. }
  3916. }
  3917. void vkDestroy(VkSurfaceKHR& _obj)
  3918. {
  3919. if (VK_NULL_HANDLE != _obj)
  3920. {
  3921. BGFX_PROFILER_SCOPE("vkDestroySurfaceKHR", kColorResource);
  3922. vkDestroySurfaceKHR(s_renderVK->m_instance, _obj.vk, s_renderVK->m_allocatorCb);
  3923. _obj = VK_NULL_HANDLE;
  3924. }
  3925. }
  3926. void vkDestroy(VkDescriptorSet& _obj)
  3927. {
  3928. if (VK_NULL_HANDLE != _obj)
  3929. {
  3930. BGFX_PROFILER_SCOPE("vkFreeDescriptorSets", kColorResource);
  3931. vkFreeDescriptorSets(s_renderVK->m_device, s_renderVK->m_descriptorPool, 1, &_obj);
  3932. _obj = VK_NULL_HANDLE;
  3933. }
  3934. }
  3935. void release(VkDeviceMemory& _obj)
  3936. {
  3937. s_renderVK->release(_obj);
  3938. }
  3939. void release(VkSurfaceKHR& _obj)
  3940. {
  3941. s_renderVK->release(_obj);
  3942. }
  3943. void release(VkDescriptorSet& _obj)
  3944. {
  3945. s_renderVK->release(_obj);
  3946. }
  3947. void MemoryLruVK::recycle(DeviceMemoryAllocationVK &_alloc)
  3948. {
  3949. if (MAX_ENTRIES == lru.getNumHandles())
  3950. {
  3951. // Evict LRU
  3952. uint16_t handle = lru.getBack();
  3953. DeviceMemoryAllocationVK &alloc = entries[handle];
  3954. totalSizeCached -= alloc.size;
  3955. release(alloc.mem);
  3956. // Touch slot and overwrite
  3957. lru.touch(handle);
  3958. alloc = _alloc;
  3959. } else
  3960. {
  3961. uint16_t handle = lru.alloc();
  3962. entries[handle] = _alloc;
  3963. }
  3964. totalSizeCached += _alloc.size;
  3965. while (totalSizeCached > BGFX_CONFIG_MAX_BYTES_CACHED_DEVICE_MEMORY_ALLOCATIONS)
  3966. {
  3967. BX_ASSERT(lru.getNumHandles() > 0, "Memory badly counted.");
  3968. uint16_t handle = lru.getBack();
  3969. DeviceMemoryAllocationVK &alloc = entries[handle];
  3970. totalSizeCached -= alloc.size;
  3971. release(alloc.mem);
  3972. lru.free(handle);
  3973. }
  3974. }
  3975. bool MemoryLruVK::find(uint32_t _size, int32_t _memoryTypeIndex, DeviceMemoryAllocationVK *_alloc)
  3976. {
  3977. BGFX_PROFILER_SCOPE("MemoryLruVK::find", kColorResource);
  3978. // Find best fit.
  3979. uint16_t slot;
  3980. {
  3981. int16_t bestIdx = MAX_ENTRIES;
  3982. uint32_t bestWaste = 0xffff'ffff;
  3983. slot = lru.getFront();
  3984. while (UINT16_MAX != slot)
  3985. {
  3986. DeviceMemoryAllocationVK &alloc = entries[slot];
  3987. if (alloc.memoryTypeIndex == _memoryTypeIndex)
  3988. {
  3989. // 50% waste allowed, otherwise we'll just allocate a new one.
  3990. // This is to prevent we trash this cache of useful allocations
  3991. // with a handful of tiny allocations.
  3992. if (alloc.size >= _size && _size * 2 >= alloc.size)
  3993. {
  3994. uint32_t waste = bx::narrowCast<uint32_t>(alloc.size - _size);
  3995. if (waste < bestWaste)
  3996. {
  3997. bestIdx = slot;
  3998. bestWaste = waste;
  3999. if (waste == 0)
  4000. {
  4001. break;
  4002. }
  4003. }
  4004. }
  4005. }
  4006. slot = lru.getNext(slot);
  4007. }
  4008. slot = bestIdx;
  4009. }
  4010. if (MAX_ENTRIES != slot)
  4011. {
  4012. *_alloc = entries[slot];
  4013. lru.free(slot);
  4014. totalSizeCached -= _alloc->size;
  4015. return true;
  4016. } else {
  4017. return false;
  4018. }
  4019. }
  4020. void MemoryLruVK::evictAll()
  4021. {
  4022. uint16_t slot = lru.getFront();
  4023. while (slot != UINT16_MAX)
  4024. {
  4025. release(entries[slot].mem);
  4026. slot = lru.getNext(slot);
  4027. }
  4028. lru.reset();
  4029. totalSizeCached = 0;
  4030. }
  4031. void ScratchBufferVK::create(uint32_t _size, uint32_t _count, VkBufferUsageFlags usage, uint32_t _align)
  4032. {
  4033. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  4034. const VkDevice device = s_renderVK->m_device;
  4035. const uint32_t entrySize = bx::strideAlign(_size, _align);
  4036. const uint32_t totalSize = entrySize * _count;
  4037. VkBufferCreateInfo bci;
  4038. bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  4039. bci.pNext = NULL;
  4040. bci.flags = 0;
  4041. bci.size = totalSize;
  4042. bci.usage = usage;
  4043. bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  4044. bci.queueFamilyIndexCount = 0;
  4045. bci.pQueueFamilyIndices = NULL;
  4046. VK_CHECK(vkCreateBuffer(
  4047. device
  4048. , &bci
  4049. , allocatorCb
  4050. , &m_buffer
  4051. ) );
  4052. VkMemoryRequirements mr;
  4053. vkGetBufferMemoryRequirements(
  4054. device
  4055. , m_buffer
  4056. , &mr
  4057. );
  4058. VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  4059. VkResult result = s_renderVK->allocateMemory(&mr, flags, &m_deviceMem, true);
  4060. if (VK_SUCCESS != result)
  4061. {
  4062. flags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  4063. VK_CHECK(s_renderVK->allocateMemory(&mr, flags, &m_deviceMem, true) );
  4064. }
  4065. m_size = (uint32_t)mr.size;
  4066. m_pos = 0;
  4067. m_align = _align;
  4068. VK_CHECK(vkBindBufferMemory(device, m_buffer, m_deviceMem.mem, m_deviceMem.offset) );
  4069. VK_CHECK(vkMapMemory(device, m_deviceMem.mem, m_deviceMem.offset, m_size, 0, (void**)&m_data) );
  4070. }
  4071. void ScratchBufferVK::createUniform(uint32_t _size, uint32_t _count)
  4072. {
  4073. const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.limits;
  4074. const uint32_t align = uint32_t(deviceLimits.minUniformBufferOffsetAlignment);
  4075. create(_size, _count, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, align);
  4076. }
  4077. void ScratchBufferVK::createStaging(uint32_t _size)
  4078. {
  4079. const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.limits;
  4080. const uint32_t align = uint32_t(deviceLimits.optimalBufferCopyOffsetAlignment);
  4081. create(_size, 1, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, align);
  4082. }
  4083. void ScratchBufferVK::destroy()
  4084. {
  4085. vkUnmapMemory(s_renderVK->m_device, m_deviceMem.mem);
  4086. s_renderVK->release(m_buffer);
  4087. s_renderVK->recycleMemory(m_deviceMem);
  4088. }
  4089. uint32_t ScratchBufferVK::alloc(uint32_t _size, uint32_t _minAlign)
  4090. {
  4091. const uint32_t align = bx::uint32_lcm(m_align, _minAlign);
  4092. const uint32_t dstOffset = bx::strideAlign(m_pos, align);
  4093. if (dstOffset + _size <= m_size)
  4094. {
  4095. m_pos = dstOffset + _size;
  4096. return dstOffset;
  4097. }
  4098. return UINT32_MAX;
  4099. }
  4100. uint32_t ScratchBufferVK::write(const void* _data, uint32_t _size, uint32_t _minAlign)
  4101. {
  4102. uint32_t dstOffset = alloc(_size, _minAlign);
  4103. BX_ASSERT(dstOffset != UINT32_MAX, "Not enough space on ScratchBuffer left to allocate %u bytes with alignment %u.", _size, _minAlign);
  4104. if (_size > 0)
  4105. {
  4106. bx::memCopy(&m_data[dstOffset], _data, _size);
  4107. }
  4108. return dstOffset;
  4109. }
  4110. void ScratchBufferVK::flush(bool _reset)
  4111. {
  4112. const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.limits;
  4113. VkDevice device = s_renderVK->m_device;
  4114. const uint32_t align = uint32_t(deviceLimits.nonCoherentAtomSize);
  4115. const uint32_t size = bx::min(bx::strideAlign(m_pos, align), m_size);
  4116. VkMappedMemoryRange range;
  4117. range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
  4118. range.pNext = NULL;
  4119. range.memory = m_deviceMem.mem;
  4120. range.offset = m_deviceMem.offset;
  4121. range.size = size;
  4122. VK_CHECK(vkFlushMappedMemoryRanges(device, 1, &range) );
  4123. if (_reset)
  4124. {
  4125. m_pos = 0;
  4126. }
  4127. }
  4128. void BufferVK::create(VkCommandBuffer _commandBuffer, uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride)
  4129. {
  4130. BX_UNUSED(_stride);
  4131. m_size = _size;
  4132. m_flags = _flags;
  4133. m_dynamic = NULL == _data;
  4134. const bool storage = m_flags & BGFX_BUFFER_COMPUTE_READ_WRITE;
  4135. const bool indirect = m_flags & BGFX_BUFFER_DRAW_INDIRECT;
  4136. VkBufferCreateInfo bci;
  4137. bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  4138. bci.pNext = NULL;
  4139. bci.flags = 0;
  4140. bci.size = _size;
  4141. bci.usage = 0
  4142. | (_vertex ? VK_BUFFER_USAGE_VERTEX_BUFFER_BIT : VK_BUFFER_USAGE_INDEX_BUFFER_BIT)
  4143. | (storage || indirect ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : 0)
  4144. | (indirect ? VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT : 0)
  4145. | VK_BUFFER_USAGE_TRANSFER_DST_BIT
  4146. ;
  4147. bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  4148. bci.queueFamilyIndexCount = 0;
  4149. bci.pQueueFamilyIndices = NULL;
  4150. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  4151. const VkDevice device = s_renderVK->m_device;
  4152. VK_CHECK(vkCreateBuffer(device, &bci, allocatorCb, &m_buffer) );
  4153. VkMemoryRequirements mr;
  4154. vkGetBufferMemoryRequirements(device, m_buffer, &mr);
  4155. VK_CHECK(s_renderVK->allocateMemory(&mr, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &m_deviceMem, false) );
  4156. VK_CHECK(vkBindBufferMemory(device, m_buffer, m_deviceMem.mem, m_deviceMem.offset) );
  4157. if (!m_dynamic)
  4158. {
  4159. update(_commandBuffer, 0, _size, _data);
  4160. }
  4161. }
  4162. void BufferVK::update(VkCommandBuffer _commandBuffer, uint32_t _offset, uint32_t _size, void* _data, bool _discard)
  4163. {
  4164. BGFX_PROFILER_SCOPE("BufferVK::update", kColorFrame);
  4165. BX_UNUSED(_discard);
  4166. StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(_size, 8, _data);
  4167. VkBufferCopy region;
  4168. region.srcOffset = stagingBuffer.m_offset;
  4169. region.dstOffset = _offset;
  4170. region.size = _size;
  4171. vkCmdCopyBuffer(_commandBuffer, stagingBuffer.m_buffer, m_buffer, 1, &region);
  4172. setMemoryBarrier(
  4173. _commandBuffer
  4174. , VK_PIPELINE_STAGE_TRANSFER_BIT
  4175. , VK_PIPELINE_STAGE_TRANSFER_BIT
  4176. );
  4177. if (!stagingBuffer.m_isFromScratch)
  4178. {
  4179. s_renderVK->release(stagingBuffer.m_buffer);
  4180. s_renderVK->recycleMemory(stagingBuffer.m_deviceMem);
  4181. }
  4182. }
  4183. void BufferVK::destroy()
  4184. {
  4185. if (VK_NULL_HANDLE != m_buffer)
  4186. {
  4187. s_renderVK->release(m_buffer);
  4188. s_renderVK->recycleMemory(m_deviceMem);
  4189. m_dynamic = false;
  4190. }
  4191. }
  4192. void VertexBufferVK::create(VkCommandBuffer _commandBuffer, uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle, uint16_t _flags)
  4193. {
  4194. BufferVK::create(_commandBuffer, _size, _data, _flags, true);
  4195. m_layoutHandle = _layoutHandle;
  4196. }
  4197. void ShaderVK::create(const Memory* _mem)
  4198. {
  4199. bx::MemoryReader reader(_mem->data, _mem->size);
  4200. bx::ErrorAssert err;
  4201. uint32_t magic;
  4202. bx::read(&reader, magic, &err);
  4203. VkShaderStageFlagBits shaderStage = VK_SHADER_STAGE_ALL;
  4204. if (isShaderType(magic, 'C') )
  4205. {
  4206. shaderStage = VK_SHADER_STAGE_COMPUTE_BIT;
  4207. }
  4208. else if (isShaderType(magic, 'F') )
  4209. {
  4210. shaderStage = VK_SHADER_STAGE_FRAGMENT_BIT;
  4211. }
  4212. else if (isShaderType(magic, 'V') )
  4213. {
  4214. shaderStage = VK_SHADER_STAGE_VERTEX_BIT;
  4215. }
  4216. const bool fragment = isShaderType(magic, 'F');
  4217. uint32_t hashIn;
  4218. bx::read(&reader, hashIn, &err);
  4219. uint32_t hashOut;
  4220. if (isShaderVerLess(magic, 6) )
  4221. {
  4222. hashOut = hashIn;
  4223. }
  4224. else
  4225. {
  4226. bx::read(&reader, hashOut, &err);
  4227. }
  4228. uint16_t count;
  4229. bx::read(&reader, count, &err);
  4230. m_numPredefined = 0;
  4231. m_numUniforms = count;
  4232. m_numTextures = 0;
  4233. m_oldBindingModel = isShaderVerLess(magic, 11);
  4234. BX_TRACE("%s Shader consts %d"
  4235. , getShaderTypeName(magic)
  4236. , count
  4237. );
  4238. uint8_t fragmentBit = fragment ? kUniformFragmentBit : 0;
  4239. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++ii)
  4240. {
  4241. m_bindInfo[ii].uniformHandle = BGFX_INVALID_HANDLE;
  4242. m_bindInfo[ii].type = BindType::Count;
  4243. m_bindInfo[ii].binding = 0;
  4244. m_bindInfo[ii].samplerBinding = 0;
  4245. m_bindInfo[ii].index = UINT32_MAX;
  4246. }
  4247. if (0 < count)
  4248. {
  4249. for (uint32_t ii = 0; ii < count; ++ii)
  4250. {
  4251. uint8_t nameSize = 0;
  4252. bx::read(&reader, nameSize, &err);
  4253. char name[256];
  4254. bx::read(&reader, &name, nameSize, &err);
  4255. name[nameSize] = '\0';
  4256. uint8_t type = 0;
  4257. bx::read(&reader, type, &err);
  4258. uint8_t num;
  4259. bx::read(&reader, num, &err);
  4260. uint16_t regIndex;
  4261. bx::read(&reader, regIndex, &err);
  4262. uint16_t regCount;
  4263. bx::read(&reader, regCount, &err);
  4264. const bool hasTexData = !isShaderVerLess(magic, 8);
  4265. const bool hasTexFormat = !isShaderVerLess(magic, 10);
  4266. uint8_t texComponent = 0;
  4267. uint8_t texDimension = 0;
  4268. uint16_t texFormat = 0;
  4269. if (hasTexData)
  4270. {
  4271. bx::read(&reader, texComponent, &err);
  4272. bx::read(&reader, texDimension, &err);
  4273. }
  4274. if (hasTexFormat)
  4275. {
  4276. bx::read(&reader, texFormat, &err);
  4277. }
  4278. const char* kind = "invalid";
  4279. BX_UNUSED(num, texComponent, texFormat);
  4280. auto textureDimensionToViewType = [](TextureDimension::Enum dimension)
  4281. {
  4282. switch (dimension)
  4283. {
  4284. case TextureDimension::Dimension1D: return VK_IMAGE_VIEW_TYPE_1D;
  4285. case TextureDimension::Dimension2D: return VK_IMAGE_VIEW_TYPE_2D;
  4286. case TextureDimension::Dimension2DArray: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
  4287. case TextureDimension::DimensionCube: return VK_IMAGE_VIEW_TYPE_CUBE;
  4288. case TextureDimension::DimensionCubeArray: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
  4289. case TextureDimension::Dimension3D: return VK_IMAGE_VIEW_TYPE_3D;
  4290. default: return VK_IMAGE_VIEW_TYPE_MAX_ENUM;
  4291. }
  4292. };
  4293. if (UINT16_MAX != regIndex)
  4294. {
  4295. PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
  4296. if (PredefinedUniform::Count != predefined)
  4297. {
  4298. kind = "predefined";
  4299. m_predefined[m_numPredefined].m_loc = regIndex;
  4300. m_predefined[m_numPredefined].m_count = regCount;
  4301. m_predefined[m_numPredefined].m_type = uint8_t(predefined|fragmentBit);
  4302. m_numPredefined++;
  4303. }
  4304. else if (UniformType::End == (~kUniformMask & type) )
  4305. {
  4306. // regCount is used for descriptor type
  4307. const bool isBuffer = idToDescriptorType(regCount) == DescriptorType::StorageBuffer;
  4308. if (0 == regIndex)
  4309. {
  4310. continue;
  4311. }
  4312. const uint8_t reverseShift = m_oldBindingModel
  4313. ? (fragment ? kSpirvOldFragmentShift : 0) + (isBuffer ? kSpirvOldBufferShift : kSpirvOldImageShift)
  4314. : kSpirvBindShift;
  4315. const uint16_t stage = regIndex - reverseShift; // regIndex is used for buffer binding index
  4316. m_bindInfo[stage].type = isBuffer ? BindType::Buffer : BindType::Image;
  4317. m_bindInfo[stage].uniformHandle = { 0 };
  4318. m_bindInfo[stage].binding = regIndex;
  4319. if (!isBuffer)
  4320. {
  4321. const VkImageViewType viewType = hasTexData
  4322. ? textureDimensionToViewType(idToTextureDimension(texDimension) )
  4323. : VK_IMAGE_VIEW_TYPE_MAX_ENUM
  4324. ;
  4325. if (VK_IMAGE_VIEW_TYPE_MAX_ENUM != viewType)
  4326. {
  4327. m_bindInfo[stage].index = m_numTextures;
  4328. m_textures[m_numTextures].type = viewType;
  4329. m_numTextures++;
  4330. }
  4331. }
  4332. kind = "storage";
  4333. }
  4334. else if (UniformType::Sampler == (~kUniformMask & type) )
  4335. {
  4336. const uint8_t reverseShift = m_oldBindingModel
  4337. ? (fragment ? kSpirvOldFragmentShift : 0) + kSpirvOldTextureShift
  4338. : kSpirvBindShift;
  4339. const uint16_t stage = regIndex - reverseShift; // regIndex is used for image/sampler binding index
  4340. const UniformRegInfo* info = s_renderVK->m_uniformReg.find(name);
  4341. BX_ASSERT(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
  4342. m_bindInfo[stage].uniformHandle = info->m_handle;
  4343. m_bindInfo[stage].type = BindType::Sampler;
  4344. m_bindInfo[stage].binding = regIndex;
  4345. m_bindInfo[stage].samplerBinding = regIndex + kSpirvSamplerShift;
  4346. const VkImageViewType viewType = hasTexData
  4347. ? textureDimensionToViewType(idToTextureDimension(texDimension) )
  4348. : VK_IMAGE_VIEW_TYPE_MAX_ENUM
  4349. ;
  4350. if (VK_IMAGE_VIEW_TYPE_MAX_ENUM != viewType)
  4351. {
  4352. m_bindInfo[stage].index = m_numTextures;
  4353. m_textures[m_numTextures].type = viewType;
  4354. m_numTextures++;
  4355. }
  4356. kind = "sampler";
  4357. }
  4358. else
  4359. {
  4360. const UniformRegInfo* info = s_renderVK->m_uniformReg.find(name);
  4361. BX_ASSERT(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
  4362. if (NULL != info)
  4363. {
  4364. if (NULL == m_constantBuffer)
  4365. {
  4366. m_constantBuffer = UniformBuffer::create(1024);
  4367. }
  4368. kind = "user";
  4369. m_constantBuffer->writeUniformHandle(type|fragmentBit, regIndex, info->m_handle, regCount);
  4370. }
  4371. }
  4372. }
  4373. BX_TRACE("\t%s: %s (%s), r.index %3d, r.count %2d, r.texComponent %1d, r.texDimension %1d"
  4374. , kind
  4375. , name
  4376. , getUniformTypeName(UniformType::Enum(type&~kUniformMask) )
  4377. , regIndex
  4378. , regCount
  4379. , texComponent
  4380. , texDimension
  4381. );
  4382. BX_UNUSED(kind);
  4383. }
  4384. if (NULL != m_constantBuffer)
  4385. {
  4386. m_constantBuffer->finish();
  4387. }
  4388. }
  4389. uint32_t shaderSize;
  4390. bx::read(&reader, shaderSize, &err);
  4391. const void* code = reader.getDataPtr();
  4392. bx::skip(&reader, shaderSize+1);
  4393. m_code = alloc(shaderSize);
  4394. bx::memCopy(m_code->data, code, shaderSize);
  4395. VkShaderModuleCreateInfo smci;
  4396. smci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
  4397. smci.pNext = NULL;
  4398. smci.flags = 0;
  4399. smci.codeSize = m_code->size;
  4400. smci.pCode = (const uint32_t*)m_code->data;
  4401. VK_CHECK(vkCreateShaderModule(
  4402. s_renderVK->m_device
  4403. , &smci
  4404. , s_renderVK->m_allocatorCb
  4405. , &m_module
  4406. ) );
  4407. bx::memSet(m_attrMask, 0, sizeof(m_attrMask) );
  4408. bx::memSet(m_attrRemap, 0, sizeof(m_attrRemap) );
  4409. bx::read(&reader, m_numAttrs, &err);
  4410. for (uint8_t ii = 0; ii < m_numAttrs; ++ii)
  4411. {
  4412. uint16_t id;
  4413. bx::read(&reader, id, &err);
  4414. Attrib::Enum attr = idToAttrib(id);
  4415. if (Attrib::Count != attr)
  4416. {
  4417. m_attrMask[attr] = UINT16_MAX;
  4418. m_attrRemap[attr] = ii;
  4419. }
  4420. }
  4421. bx::HashMurmur2A murmur;
  4422. murmur.begin();
  4423. murmur.add(hashIn);
  4424. murmur.add(hashOut);
  4425. murmur.add(m_code->data, m_code->size);
  4426. murmur.add(m_numAttrs);
  4427. murmur.add(m_attrMask, m_numAttrs);
  4428. murmur.add(m_attrRemap, m_numAttrs);
  4429. m_hash = murmur.end();
  4430. bx::read(&reader, m_size, &err);
  4431. // fill binding description with uniform information
  4432. uint16_t bidx = 0;
  4433. if (m_size > 0)
  4434. {
  4435. m_uniformBinding = fragment ? (m_oldBindingModel ? kSpirvOldFragmentBinding : kSpirvFragmentBinding) : 0;
  4436. VkDescriptorSetLayoutBinding& binding = m_bindings[bidx];
  4437. binding.stageFlags = shaderStage;
  4438. binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  4439. binding.binding = m_uniformBinding;
  4440. binding.pImmutableSamplers = NULL;
  4441. binding.descriptorCount = 1;
  4442. bidx++;
  4443. }
  4444. for (uint32_t ii = 0; ii < BX_COUNTOF(m_bindInfo); ++ii)
  4445. {
  4446. switch (m_bindInfo[ii].type)
  4447. {
  4448. case BindType::Buffer:
  4449. case BindType::Image:
  4450. {
  4451. VkDescriptorSetLayoutBinding& binding = m_bindings[bidx];
  4452. binding.stageFlags = shaderStage;
  4453. binding.descriptorType = BindType::Buffer == m_bindInfo[ii].type
  4454. ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
  4455. : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
  4456. ;
  4457. binding.binding = m_bindInfo[ii].binding;
  4458. binding.pImmutableSamplers = NULL;
  4459. binding.descriptorCount = 1;
  4460. bidx++;
  4461. }
  4462. break;
  4463. case BindType::Sampler:
  4464. {
  4465. VkDescriptorSetLayoutBinding& textureBinding = m_bindings[bidx];
  4466. textureBinding.stageFlags = shaderStage;
  4467. textureBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
  4468. textureBinding.binding = m_bindInfo[ii].binding;
  4469. textureBinding.pImmutableSamplers = NULL;
  4470. textureBinding.descriptorCount = 1;
  4471. bidx++;
  4472. VkDescriptorSetLayoutBinding& samplerBinding = m_bindings[bidx];
  4473. samplerBinding.stageFlags = shaderStage;
  4474. samplerBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
  4475. samplerBinding.binding = m_bindInfo[ii].samplerBinding;
  4476. samplerBinding.pImmutableSamplers = NULL;
  4477. samplerBinding.descriptorCount = 1;
  4478. bidx++;
  4479. }
  4480. break;
  4481. default:
  4482. break;
  4483. }
  4484. }
  4485. m_numBindings = bidx;
  4486. }
  4487. void ShaderVK::destroy()
  4488. {
  4489. if (NULL != m_constantBuffer)
  4490. {
  4491. UniformBuffer::destroy(m_constantBuffer);
  4492. m_constantBuffer = NULL;
  4493. }
  4494. m_numPredefined = 0;
  4495. if (NULL != m_code)
  4496. {
  4497. release(m_code);
  4498. m_code = NULL;
  4499. m_hash = 0;
  4500. }
  4501. if (VK_NULL_HANDLE != m_module)
  4502. {
  4503. vkDestroy(m_module);
  4504. }
  4505. }
  4506. void ProgramVK::create(const ShaderVK* _vsh, const ShaderVK* _fsh)
  4507. {
  4508. BX_ASSERT(NULL != _vsh->m_code, "Vertex shader doesn't exist.");
  4509. m_vsh = _vsh;
  4510. bx::memCopy(
  4511. &m_predefined[0]
  4512. , _vsh->m_predefined
  4513. , _vsh->m_numPredefined * sizeof(PredefinedUniform)
  4514. );
  4515. m_numPredefined = _vsh->m_numPredefined;
  4516. if (NULL != _fsh)
  4517. {
  4518. BX_ASSERT(NULL != _fsh->m_code, "Fragment shader doesn't exist.");
  4519. m_fsh = _fsh;
  4520. bx::memCopy(
  4521. &m_predefined[m_numPredefined]
  4522. , _fsh->m_predefined
  4523. , _fsh->m_numPredefined * sizeof(PredefinedUniform)
  4524. );
  4525. m_numPredefined += _fsh->m_numPredefined;
  4526. }
  4527. m_numTextures = 0;
  4528. for (uint8_t stage = 0; stage < BX_COUNTOF(m_bindInfo); ++stage)
  4529. {
  4530. const ShaderVK* shader = NULL;
  4531. if (isValid(m_vsh->m_bindInfo[stage].uniformHandle) )
  4532. {
  4533. shader = _vsh;
  4534. BX_ASSERT(false
  4535. || NULL == m_fsh
  4536. || !isValid(m_fsh->m_bindInfo[stage].uniformHandle)
  4537. || !(m_vsh->m_oldBindingModel || m_fsh->m_oldBindingModel)
  4538. , "Shared vertex/fragment bindings require shader binary version >= 11."
  4539. );
  4540. }
  4541. else if (NULL != m_fsh
  4542. && isValid(m_fsh->m_bindInfo[stage].uniformHandle) )
  4543. {
  4544. shader = _fsh;
  4545. }
  4546. if (NULL != shader)
  4547. {
  4548. m_bindInfo[stage] = shader->m_bindInfo[stage];
  4549. uint32_t& index = m_bindInfo[stage].index;
  4550. if (UINT32_MAX != index)
  4551. {
  4552. m_textures[m_numTextures] = shader->m_textures[index];
  4553. index = m_numTextures;
  4554. m_numTextures++;
  4555. }
  4556. }
  4557. }
  4558. // create exact pipeline layout
  4559. m_descriptorSetLayout = VK_NULL_HANDLE;
  4560. uint32_t numBindings = m_vsh->m_numBindings + (m_fsh ? m_fsh->m_numBindings : 0);
  4561. if (0 < numBindings)
  4562. {
  4563. // generate descriptor set layout hash
  4564. bx::HashMurmur2A murmur;
  4565. murmur.begin();
  4566. murmur.add(m_vsh->m_bindings, sizeof(VkDescriptorSetLayoutBinding) * m_vsh->m_numBindings);
  4567. if (NULL != m_fsh)
  4568. {
  4569. murmur.add(m_fsh->m_bindings, sizeof(VkDescriptorSetLayoutBinding) * m_fsh->m_numBindings);
  4570. }
  4571. uint32_t descriptorSetLayoutHash = murmur.end();
  4572. m_descriptorSetLayout = s_renderVK->m_descriptorSetLayoutCache.find(descriptorSetLayoutHash);
  4573. if (VK_NULL_HANDLE == m_descriptorSetLayout)
  4574. {
  4575. VkDescriptorSetLayoutBinding bindings[2 * BX_COUNTOF(ShaderVK::m_bindings)];
  4576. bx::memCopy(
  4577. bindings
  4578. , m_vsh->m_bindings
  4579. , sizeof(VkDescriptorSetLayoutBinding) * m_vsh->m_numBindings
  4580. );
  4581. numBindings = m_vsh->m_numBindings;
  4582. if (NULL != m_fsh)
  4583. {
  4584. for (uint16_t ii = 0; ii < m_fsh->m_numBindings; ii++)
  4585. {
  4586. const VkDescriptorSetLayoutBinding& fsBinding = m_fsh->m_bindings[ii];
  4587. uint16_t vsBindingIdx = UINT16_MAX;
  4588. for (uint16_t jj = 0; jj < m_vsh->m_numBindings; jj++)
  4589. {
  4590. if (fsBinding.binding == bindings[jj].binding)
  4591. {
  4592. vsBindingIdx = jj;
  4593. break;
  4594. }
  4595. }
  4596. if (UINT16_MAX != vsBindingIdx)
  4597. {
  4598. BX_ASSERT(
  4599. bindings[vsBindingIdx].descriptorType == fsBinding.descriptorType
  4600. , "Mismatching descriptor types. Shaders compiled with different versions of shaderc?"
  4601. );
  4602. bindings[vsBindingIdx].stageFlags |= fsBinding.stageFlags;
  4603. }
  4604. else
  4605. {
  4606. bindings[numBindings] = fsBinding;
  4607. numBindings++;
  4608. }
  4609. }
  4610. }
  4611. VkDescriptorSetLayoutCreateInfo dslci;
  4612. dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
  4613. dslci.pNext = NULL;
  4614. dslci.flags = 0;
  4615. dslci.bindingCount = numBindings;
  4616. dslci.pBindings = bindings;
  4617. VK_CHECK(vkCreateDescriptorSetLayout(
  4618. s_renderVK->m_device
  4619. , &dslci
  4620. , s_renderVK->m_allocatorCb
  4621. , &m_descriptorSetLayout
  4622. ) );
  4623. s_renderVK->m_descriptorSetLayoutCache.add(descriptorSetLayoutHash, m_descriptorSetLayout);
  4624. }
  4625. }
  4626. VkPipelineLayoutCreateInfo plci;
  4627. plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
  4628. plci.pNext = NULL;
  4629. plci.flags = 0;
  4630. plci.pushConstantRangeCount = 0;
  4631. plci.pPushConstantRanges = NULL;
  4632. plci.setLayoutCount = (m_descriptorSetLayout == VK_NULL_HANDLE ? 0 : 1);
  4633. plci.pSetLayouts = &m_descriptorSetLayout;
  4634. VK_CHECK(vkCreatePipelineLayout(
  4635. s_renderVK->m_device
  4636. , &plci
  4637. , s_renderVK->m_allocatorCb
  4638. , &m_pipelineLayout
  4639. ) );
  4640. }
  4641. void ProgramVK::destroy()
  4642. {
  4643. s_renderVK->release(m_pipelineLayout);
  4644. m_numPredefined = 0;
  4645. m_vsh = NULL;
  4646. m_fsh = NULL;
  4647. }
  4648. VkResult TimerQueryVK::init()
  4649. {
  4650. BGFX_PROFILER_SCOPE("TimerQueryVK::init", kColorFrame);
  4651. VkResult result = VK_SUCCESS;
  4652. const VkDevice device = s_renderVK->m_device;
  4653. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4654. const uint32_t count = m_control.m_size * 2;
  4655. VkQueryPoolCreateInfo qpci;
  4656. qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
  4657. qpci.pNext = NULL;
  4658. qpci.flags = 0;
  4659. qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
  4660. qpci.queryCount = count;
  4661. qpci.pipelineStatistics = 0;
  4662. result = vkCreateQueryPool(device, &qpci, s_renderVK->m_allocatorCb, &m_queryPool);
  4663. if (VK_SUCCESS != result)
  4664. {
  4665. BX_TRACE("Create timer query error: vkCreateQueryPool failed %d: %s.", result, getName(result) );
  4666. return result;
  4667. }
  4668. vkCmdResetQueryPool(commandBuffer, m_queryPool, 0, count);
  4669. const uint32_t size = count * sizeof(uint64_t);
  4670. result = s_renderVK->createReadbackBuffer(size, &m_readback, &m_readbackMemory);
  4671. if (VK_SUCCESS != result)
  4672. {
  4673. return result;
  4674. }
  4675. result = vkMapMemory(device, m_readbackMemory.mem, m_readbackMemory.offset, VK_WHOLE_SIZE, 0, (void**)&m_queryResult);
  4676. if (VK_SUCCESS != result)
  4677. {
  4678. BX_TRACE("Create timer query error: vkMapMemory failed %d: %s.", result, getName(result) );
  4679. return result;
  4680. }
  4681. m_frequency = uint64_t(1000000000.0 / double(s_renderVK->m_deviceProperties.limits.timestampPeriod) );
  4682. for (uint32_t ii = 0; ii < BX_COUNTOF(m_result); ++ii)
  4683. {
  4684. m_result[ii].reset();
  4685. }
  4686. m_control.reset();
  4687. return result;
  4688. }
  4689. void TimerQueryVK::shutdown()
  4690. {
  4691. vkDestroy(m_queryPool);
  4692. vkDestroy(m_readback);
  4693. vkUnmapMemory(s_renderVK->m_device, m_readbackMemory.mem);
  4694. s_renderVK->recycleMemory(m_readbackMemory);
  4695. }
  4696. uint32_t TimerQueryVK::begin(uint32_t _resultIdx, uint32_t _frameNum)
  4697. {
  4698. BGFX_PROFILER_SCOPE("TimerQueryVK::begin", kColorFrame);
  4699. while (0 == m_control.reserve(1) )
  4700. {
  4701. m_control.consume(1);
  4702. }
  4703. Result& result = m_result[_resultIdx];
  4704. ++result.m_pending;
  4705. const uint32_t idx = m_control.m_current;
  4706. Query& query = m_query[idx];
  4707. query.m_resultIdx = _resultIdx;
  4708. query.m_ready = false;
  4709. query.m_frameNum = _frameNum;
  4710. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4711. const uint32_t offset = idx * 2 + 0;
  4712. vkCmdResetQueryPool(commandBuffer, m_queryPool, offset, 2);
  4713. vkCmdWriteTimestamp(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, m_queryPool, offset + 0);
  4714. m_control.commit(1);
  4715. return idx;
  4716. }
  4717. void TimerQueryVK::end(uint32_t _idx)
  4718. {
  4719. BGFX_PROFILER_SCOPE("TimerQueryVK::end", kColorFrame);
  4720. Query& query = m_query[_idx];
  4721. query.m_ready = true;
  4722. query.m_completed = s_renderVK->m_cmd.m_submitted + s_renderVK->m_cmd.m_numFramesInFlight;
  4723. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4724. const uint32_t offset = _idx * 2 + 0;
  4725. vkCmdWriteTimestamp(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, m_queryPool, offset + 1);
  4726. vkCmdCopyQueryPoolResults(
  4727. commandBuffer
  4728. , m_queryPool
  4729. , offset
  4730. , 2
  4731. , m_readback
  4732. , offset * sizeof(uint64_t)
  4733. , sizeof(uint64_t)
  4734. , VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT
  4735. );
  4736. setMemoryBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT);
  4737. while (update() )
  4738. {
  4739. }
  4740. }
  4741. bool TimerQueryVK::update()
  4742. {
  4743. if (0 != m_control.available() )
  4744. {
  4745. uint32_t idx = m_control.m_read;
  4746. Query& query = m_query[idx];
  4747. if (!query.m_ready)
  4748. {
  4749. return false;
  4750. }
  4751. if (query.m_completed > s_renderVK->m_cmd.m_submitted)
  4752. {
  4753. return false;
  4754. }
  4755. m_control.consume(1);
  4756. Result& result = m_result[query.m_resultIdx];
  4757. --result.m_pending;
  4758. result.m_frameNum = query.m_frameNum;
  4759. uint32_t offset = idx * 2;
  4760. result.m_begin = m_queryResult[offset+0];
  4761. result.m_end = m_queryResult[offset+1];
  4762. return true;
  4763. }
  4764. return false;
  4765. }
  4766. VkResult OcclusionQueryVK::init()
  4767. {
  4768. BGFX_PROFILER_SCOPE("OcclusionQueryVK::init", kColorFrame);
  4769. VkResult result = VK_SUCCESS;
  4770. const VkDevice device = s_renderVK->m_device;
  4771. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4772. const uint32_t count = BX_COUNTOF(m_handle);
  4773. VkQueryPoolCreateInfo qpci;
  4774. qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
  4775. qpci.pNext = NULL;
  4776. qpci.flags = 0;
  4777. qpci.queryType = VK_QUERY_TYPE_OCCLUSION;
  4778. qpci.queryCount = count;
  4779. qpci.pipelineStatistics = 0;
  4780. result = vkCreateQueryPool(device, &qpci, s_renderVK->m_allocatorCb, &m_queryPool);
  4781. if (VK_SUCCESS != result)
  4782. {
  4783. BX_TRACE("Create occlusion query error: vkCreateQueryPool failed %d: %s.", result, getName(result) );
  4784. return result;
  4785. }
  4786. vkCmdResetQueryPool(commandBuffer, m_queryPool, 0, count);
  4787. const uint32_t size = count * sizeof(uint32_t);
  4788. result = s_renderVK->createReadbackBuffer(size, &m_readback, &m_readbackMemory);
  4789. if (VK_SUCCESS != result)
  4790. {
  4791. return result;
  4792. }
  4793. result = vkMapMemory(device, m_readbackMemory.mem, m_readbackMemory.offset, VK_WHOLE_SIZE, 0, (void**)&m_queryResult);
  4794. if (VK_SUCCESS != result)
  4795. {
  4796. BX_TRACE("Create occlusion query error: vkMapMemory failed %d: %s.", result, getName(result) );
  4797. return result;
  4798. }
  4799. m_control.reset();
  4800. return result;
  4801. }
  4802. void OcclusionQueryVK::shutdown()
  4803. {
  4804. vkDestroy(m_queryPool);
  4805. vkDestroy(m_readback);
  4806. vkUnmapMemory(s_renderVK->m_device, m_readbackMemory.mem);
  4807. s_renderVK->recycleMemory(m_readbackMemory);
  4808. }
  4809. void OcclusionQueryVK::begin(OcclusionQueryHandle _handle)
  4810. {
  4811. BGFX_PROFILER_SCOPE("OcclusionQueryVK::shutdown", kColorFrame);
  4812. m_control.reserve(1);
  4813. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4814. m_handle[m_control.m_current] = _handle;
  4815. vkCmdBeginQuery(commandBuffer, m_queryPool, _handle.idx, 0);
  4816. }
  4817. void OcclusionQueryVK::end()
  4818. {
  4819. BGFX_PROFILER_SCOPE("OcclusionQueryVK::end", kColorFrame);
  4820. const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4821. const OcclusionQueryHandle handle = m_handle[m_control.m_current];
  4822. vkCmdEndQuery(commandBuffer, m_queryPool, handle.idx);
  4823. m_control.commit(1);
  4824. }
  4825. void OcclusionQueryVK::flush(Frame* _render)
  4826. {
  4827. BGFX_PROFILER_SCOPE("OcclusionQueryVK::flush", kColorFrame);
  4828. if (0 < m_control.available() )
  4829. {
  4830. VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer;
  4831. const uint32_t size = m_control.m_size;
  4832. // need to copy each result individually because VK_QUERY_RESULT_WAIT_BIT causes
  4833. // vkWaitForFences to hang indefinitely if we copy all results (including unavailable ones)
  4834. for (uint32_t ii = 0, num = m_control.available(); ii < num; ++ii)
  4835. {
  4836. const OcclusionQueryHandle& handle = m_handle[(m_control.m_read + ii) % size];
  4837. if (isValid(handle) )
  4838. {
  4839. vkCmdCopyQueryPoolResults(
  4840. commandBuffer
  4841. , m_queryPool
  4842. , handle.idx
  4843. , 1
  4844. , m_readback
  4845. , handle.idx * sizeof(uint32_t)
  4846. , sizeof(uint32_t)
  4847. , VK_QUERY_RESULT_WAIT_BIT
  4848. );
  4849. }
  4850. }
  4851. setMemoryBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT);
  4852. s_renderVK->kick(true);
  4853. commandBuffer = s_renderVK->m_commandBuffer;
  4854. // resetting in the new command buffer prevents a false positive validation layer error
  4855. const uint32_t count = BX_COUNTOF(m_handle);
  4856. vkCmdResetQueryPool(commandBuffer, m_queryPool, 0, count);
  4857. resolve(_render);
  4858. }
  4859. }
  4860. void OcclusionQueryVK::resolve(Frame* _render)
  4861. {
  4862. while (0 != m_control.available() )
  4863. {
  4864. OcclusionQueryHandle handle = m_handle[m_control.m_read];
  4865. if (isValid(handle) )
  4866. {
  4867. _render->m_occlusion[handle.idx] = m_queryResult[handle.idx];
  4868. }
  4869. m_control.consume(1);
  4870. }
  4871. }
  4872. void OcclusionQueryVK::invalidate(OcclusionQueryHandle _handle)
  4873. {
  4874. const uint32_t size = m_control.m_size;
  4875. for (uint32_t ii = 0, num = m_control.available(); ii < num; ++ii)
  4876. {
  4877. OcclusionQueryHandle& handle = m_handle[(m_control.m_read + ii) % size];
  4878. if (handle.idx == _handle.idx)
  4879. {
  4880. handle.idx = bgfx::kInvalidHandle;
  4881. }
  4882. }
  4883. }
  4884. void ReadbackVK::create(VkImage _image, uint32_t _width, uint32_t _height, TextureFormat::Enum _format)
  4885. {
  4886. m_image = _image;
  4887. m_width = _width;
  4888. m_height = _height;
  4889. m_format = _format;
  4890. }
  4891. void ReadbackVK::destroy()
  4892. {
  4893. m_image = VK_NULL_HANDLE;
  4894. }
  4895. uint32_t ReadbackVK::pitch(uint8_t _mip) const
  4896. {
  4897. uint32_t mipWidth = bx::uint32_max(1, m_width >> _mip);
  4898. uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_format) );
  4899. return mipWidth * bpp / 8;
  4900. }
  4901. void ReadbackVK::copyImageToBuffer(VkCommandBuffer _commandBuffer, VkBuffer _buffer, VkImageLayout _layout, VkImageAspectFlags _aspect, uint8_t _mip) const
  4902. {
  4903. BGFX_PROFILER_SCOPE("ReadbackVK::copyImageToBuffer", kColorFrame);
  4904. uint32_t mipWidth = bx::uint32_max(1, m_width >> _mip);
  4905. uint32_t mipHeight = bx::uint32_max(1, m_height >> _mip);
  4906. setImageMemoryBarrier(
  4907. _commandBuffer
  4908. , m_image
  4909. , _aspect
  4910. , _layout
  4911. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  4912. , _mip
  4913. , 1
  4914. , 0
  4915. , 1
  4916. );
  4917. VkBufferImageCopy bic;
  4918. bic.bufferOffset = 0;
  4919. bic.bufferRowLength = mipWidth;
  4920. bic.bufferImageHeight = mipHeight;
  4921. bic.imageSubresource.aspectMask = _aspect;
  4922. bic.imageSubresource.mipLevel = _mip;
  4923. bic.imageSubresource.baseArrayLayer = 0;
  4924. bic.imageSubresource.layerCount = 1;
  4925. bic.imageOffset = { 0, 0, 0 };
  4926. bic.imageExtent = { mipWidth, mipHeight, 1 };
  4927. vkCmdCopyImageToBuffer(
  4928. _commandBuffer
  4929. , m_image
  4930. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  4931. , _buffer
  4932. , 1
  4933. , &bic
  4934. );
  4935. // Make changes to the buffer visible to the host
  4936. setMemoryBarrier(
  4937. _commandBuffer
  4938. , VK_PIPELINE_STAGE_TRANSFER_BIT
  4939. , VK_PIPELINE_STAGE_HOST_BIT
  4940. );
  4941. setImageMemoryBarrier(
  4942. _commandBuffer
  4943. , m_image
  4944. , _aspect
  4945. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  4946. , _layout
  4947. , _mip
  4948. , 1
  4949. , 0
  4950. , 1
  4951. );
  4952. }
  4953. void ReadbackVK::readback(VkDeviceMemory _memory, VkDeviceSize _offset, void* _data, uint8_t _mip) const
  4954. {
  4955. BGFX_PROFILER_SCOPE("ReadbackVK::readback", kColorResource);
  4956. if (m_image == VK_NULL_HANDLE)
  4957. {
  4958. return;
  4959. }
  4960. uint32_t mipHeight = bx::uint32_max(1, m_height >> _mip);
  4961. uint32_t rowPitch = pitch(_mip);
  4962. uint8_t* src;
  4963. VK_CHECK(vkMapMemory(s_renderVK->m_device, _memory, 0, VK_WHOLE_SIZE, 0, (void**)&src) );
  4964. src += _offset;
  4965. uint8_t* dst = (uint8_t*)_data;
  4966. for (uint32_t yy = 0; yy < mipHeight; ++yy)
  4967. {
  4968. bx::memCopy(dst, src, rowPitch);
  4969. src += rowPitch;
  4970. dst += rowPitch;
  4971. }
  4972. vkUnmapMemory(s_renderVK->m_device, _memory);
  4973. }
  4974. VkResult TextureVK::create(VkCommandBuffer _commandBuffer, uint32_t _width, uint32_t _height, uint64_t _flags, VkFormat _format)
  4975. {
  4976. BGFX_PROFILER_SCOPE("TextureVK::create", kColorResource);
  4977. BX_ASSERT(0 != (_flags & BGFX_TEXTURE_RT_MASK), "");
  4978. _flags |= BGFX_TEXTURE_RT_WRITE_ONLY;
  4979. m_flags = _flags;
  4980. m_width = _width;
  4981. m_height = _height;
  4982. m_depth = 1;
  4983. m_numLayers = 1;
  4984. m_requestedFormat = uint8_t(bimg::TextureFormat::Count);
  4985. m_textureFormat = uint8_t(bimg::TextureFormat::Count);
  4986. m_format = _format;
  4987. m_components = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
  4988. m_aspectMask = getAspectMask(m_format);
  4989. m_sampler = s_msaa[bx::uint32_satsub( (m_flags & BGFX_TEXTURE_RT_MSAA_MASK) >> BGFX_TEXTURE_RT_MSAA_SHIFT, 1)];
  4990. m_type = VK_IMAGE_VIEW_TYPE_2D;
  4991. m_numMips = 1;
  4992. m_numSides = 1;
  4993. VkResult result = createImages(_commandBuffer);
  4994. if (VK_SUCCESS == result)
  4995. {
  4996. const VkImageLayout layout = 0 != (m_aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) )
  4997. ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
  4998. : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
  4999. ;
  5000. setImageMemoryBarrier(_commandBuffer, layout);
  5001. }
  5002. return result;
  5003. }
  5004. VkResult TextureVK::createImages(VkCommandBuffer _commandBuffer)
  5005. {
  5006. BGFX_PROFILER_SCOPE("TextureVK::createImages", kColorResource);
  5007. VkResult result = VK_SUCCESS;
  5008. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  5009. const VkDevice device = s_renderVK->m_device;
  5010. if (m_sampler.Count > 1)
  5011. {
  5012. BX_ASSERT(VK_IMAGE_VIEW_TYPE_3D != m_type, "Can't create multisample 3D image.");
  5013. BX_ASSERT(m_numMips <= 1, "Can't create multisample image with mip chain.");
  5014. }
  5015. // create texture and allocate its device memory
  5016. VkImageCreateInfo ici;
  5017. ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
  5018. ici.pNext = NULL;
  5019. ici.flags = 0
  5020. | (VK_IMAGE_VIEW_TYPE_CUBE == m_type
  5021. ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
  5022. : 0
  5023. )
  5024. | (VK_IMAGE_VIEW_TYPE_3D == m_type
  5025. ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR
  5026. : 0
  5027. )
  5028. ;
  5029. ici.pQueueFamilyIndices = NULL;
  5030. ici.queueFamilyIndexCount = 0;
  5031. ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  5032. ici.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  5033. ici.usage = 0
  5034. | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
  5035. | VK_IMAGE_USAGE_TRANSFER_DST_BIT
  5036. | VK_IMAGE_USAGE_SAMPLED_BIT
  5037. | (m_flags & BGFX_TEXTURE_RT_MASK
  5038. ? (m_aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
  5039. ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
  5040. : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
  5041. : 0
  5042. )
  5043. | (m_flags & BGFX_TEXTURE_COMPUTE_WRITE ? VK_IMAGE_USAGE_STORAGE_BIT : 0)
  5044. ;
  5045. ici.format = m_format;
  5046. ici.samples = m_sampler.Sample;
  5047. ici.mipLevels = m_numMips;
  5048. ici.arrayLayers = m_numSides;
  5049. ici.extent.width = m_width;
  5050. ici.extent.height = m_height;
  5051. ici.extent.depth = m_depth;
  5052. ici.imageType = VK_IMAGE_VIEW_TYPE_3D == m_type
  5053. ? VK_IMAGE_TYPE_3D
  5054. : VK_IMAGE_TYPE_2D
  5055. ;
  5056. ici.tiling = VK_IMAGE_TILING_OPTIMAL;
  5057. result = vkCreateImage(device, &ici, allocatorCb, &m_textureImage);
  5058. if (VK_SUCCESS != result)
  5059. {
  5060. BX_TRACE("Create texture image error: vkCreateImage failed %d: %s.", result, getName(result) );
  5061. return result;
  5062. }
  5063. VkMemoryRequirements imageMemReq;
  5064. vkGetImageMemoryRequirements(device, m_textureImage, &imageMemReq);
  5065. result = s_renderVK->allocateMemory(&imageMemReq, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &m_textureDeviceMem, false);
  5066. if (VK_SUCCESS != result)
  5067. {
  5068. BX_TRACE("Create texture image error: allocateMemory failed %d: %s.", result, getName(result) );
  5069. return result;
  5070. }
  5071. result = vkBindImageMemory(device, m_textureImage, m_textureDeviceMem.mem, m_textureDeviceMem.offset);
  5072. if (VK_SUCCESS != result)
  5073. {
  5074. BX_TRACE("Create texture image error: vkBindImageMemory failed %d: %s.", result, getName(result) );
  5075. return result;
  5076. }
  5077. m_sampledLayout = m_flags & BGFX_TEXTURE_COMPUTE_WRITE
  5078. ? VK_IMAGE_LAYOUT_GENERAL
  5079. : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
  5080. ;
  5081. const bool needResolve = true
  5082. && 1 < m_sampler.Count
  5083. && 0 != (ici.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
  5084. && 0 == (m_flags & BGFX_TEXTURE_MSAA_SAMPLE)
  5085. && 0 == (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY)
  5086. ;
  5087. if (needResolve)
  5088. {
  5089. VkImageCreateInfo ici_resolve = ici;
  5090. ici_resolve.samples = s_msaa[0].Sample;
  5091. ici_resolve.usage &= ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
  5092. ici_resolve.flags &= ~VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
  5093. result = vkCreateImage(device, &ici_resolve, allocatorCb, &m_singleMsaaImage);
  5094. if (VK_SUCCESS != result)
  5095. {
  5096. BX_TRACE("Create texture image error: vkCreateImage failed %d: %s.", result, getName(result) );
  5097. return result;
  5098. }
  5099. VkMemoryRequirements imageMemReq_resolve;
  5100. vkGetImageMemoryRequirements(device, m_singleMsaaImage, &imageMemReq_resolve);
  5101. result = s_renderVK->allocateMemory(&imageMemReq_resolve, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &m_singleMsaaDeviceMem, false);
  5102. if (VK_SUCCESS != result)
  5103. {
  5104. BX_TRACE("Create texture image error: allocateMemory failed %d: %s.", result, getName(result) );
  5105. return result;
  5106. }
  5107. result = vkBindImageMemory(device, m_singleMsaaImage, m_singleMsaaDeviceMem.mem, m_singleMsaaDeviceMem.offset);
  5108. if (VK_SUCCESS != result)
  5109. {
  5110. BX_TRACE("Create texture image error: vkBindImageMemory failed %d: %s.", result, getName(result) );
  5111. return result;
  5112. }
  5113. setImageMemoryBarrier(_commandBuffer, m_sampledLayout, true);
  5114. }
  5115. return result;
  5116. }
  5117. void* TextureVK::create(VkCommandBuffer _commandBuffer, const Memory* _mem, uint64_t _flags, uint8_t _skip)
  5118. {
  5119. BGFX_PROFILER_SCOPE("TextureVK::create", kColorResource);
  5120. bimg::ImageContainer imageContainer;
  5121. if (bimg::imageParse(imageContainer, _mem->data, _mem->size) )
  5122. {
  5123. const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(imageContainer.m_format);
  5124. const uint8_t startLod = bx::min<uint8_t>(_skip, imageContainer.m_numMips - 1);
  5125. bimg::TextureInfo ti;
  5126. bimg::imageGetSize(
  5127. &ti
  5128. , uint16_t(imageContainer.m_width >> startLod)
  5129. , uint16_t(imageContainer.m_height >> startLod)
  5130. , uint16_t(imageContainer.m_depth >> startLod)
  5131. , imageContainer.m_cubeMap
  5132. , 1 < imageContainer.m_numMips
  5133. , imageContainer.m_numLayers
  5134. , imageContainer.m_format
  5135. );
  5136. ti.numMips = bx::min<uint8_t>(imageContainer.m_numMips - startLod, ti.numMips);
  5137. m_flags = _flags;
  5138. m_width = ti.width;
  5139. m_height = ti.height;
  5140. m_depth = ti.depth;
  5141. m_numLayers = ti.numLayers;
  5142. m_requestedFormat = uint8_t(imageContainer.m_format);
  5143. m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) );
  5144. m_format = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) )
  5145. ? s_textureFormat[m_textureFormat].m_fmtDsv
  5146. : (m_flags & BGFX_TEXTURE_SRGB) ? s_textureFormat[m_textureFormat].m_fmtSrgb : s_textureFormat[m_textureFormat].m_fmt
  5147. ;
  5148. m_components = s_textureFormat[m_textureFormat].m_mapping;
  5149. const bool convert = m_textureFormat != m_requestedFormat;
  5150. const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) );
  5151. m_aspectMask = getAspectMask(m_format);
  5152. m_sampler = s_msaa[bx::uint32_satsub( (m_flags & BGFX_TEXTURE_RT_MSAA_MASK) >> BGFX_TEXTURE_RT_MSAA_SHIFT, 1)];
  5153. if (imageContainer.m_cubeMap)
  5154. {
  5155. m_type = imageContainer.m_numLayers > 1
  5156. ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
  5157. : VK_IMAGE_VIEW_TYPE_CUBE
  5158. ;
  5159. }
  5160. else if (imageContainer.m_depth > 1)
  5161. {
  5162. m_type = VK_IMAGE_VIEW_TYPE_3D;
  5163. }
  5164. else if (imageContainer.m_numLayers > 1)
  5165. {
  5166. m_type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
  5167. }
  5168. else
  5169. {
  5170. m_type = VK_IMAGE_VIEW_TYPE_2D;
  5171. }
  5172. m_numMips = ti.numMips;
  5173. m_numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1);
  5174. const uint16_t numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1);
  5175. const uint32_t numSrd = numSides * ti.numMips;
  5176. uint32_t kk = 0;
  5177. const bool compressed = bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) );
  5178. const bool swizzle = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE);
  5179. const bool writeOnly = 0 != (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY);
  5180. const bool computeWrite = 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE);
  5181. const bool renderTarget = 0 != (m_flags & BGFX_TEXTURE_RT_MASK);
  5182. const bool blit = 0 != (m_flags & BGFX_TEXTURE_BLIT_DST);
  5183. BX_UNUSED(swizzle, writeOnly, computeWrite, renderTarget, blit);
  5184. BX_TRACE(
  5185. "Texture %3d: %s (requested: %s), %dx%dx%d%s RT[%c], BO[%c], CW[%c]%s."
  5186. , (int)(this - s_renderVK->m_textures)
  5187. , getName( (TextureFormat::Enum)m_textureFormat)
  5188. , getName( (TextureFormat::Enum)m_requestedFormat)
  5189. , ti.width
  5190. , ti.height
  5191. , ti.depth
  5192. , imageContainer.m_cubeMap ? "x6" : ""
  5193. , renderTarget ? 'x' : ' '
  5194. , writeOnly ? 'x' : ' '
  5195. , computeWrite ? 'x' : ' '
  5196. , swizzle ? " (swizzle BGRA8 -> RGBA8)" : ""
  5197. );
  5198. VK_CHECK(createImages(_commandBuffer) );
  5199. // decode images
  5200. struct ImageInfo
  5201. {
  5202. uint8_t* data;
  5203. uint32_t width;
  5204. uint32_t height;
  5205. uint32_t depth;
  5206. uint32_t pitch;
  5207. uint32_t slice;
  5208. uint32_t size;
  5209. uint32_t mipLevel;
  5210. uint32_t layer;
  5211. };
  5212. ImageInfo* imageInfos = (ImageInfo*)bx::alloc(g_allocator, sizeof(ImageInfo) * numSrd);
  5213. bx::memSet(imageInfos, 0, sizeof(ImageInfo) * numSrd);
  5214. uint32_t alignment = 1; // tightly aligned buffer
  5215. for (uint16_t side = 0; side < numSides; ++side)
  5216. {
  5217. for (uint8_t lod = 0; lod < ti.numMips; ++lod)
  5218. {
  5219. bimg::ImageMip mip;
  5220. if (bimg::imageGetRawData(imageContainer, side, lod + startLod, _mem->data, _mem->size, mip) )
  5221. {
  5222. if (convert)
  5223. {
  5224. const uint32_t pitch = bx::strideAlign(bx::max<uint32_t>(mip.m_width, 4) * bpp / 8, alignment);
  5225. const uint32_t slice = bx::strideAlign(bx::max<uint32_t>(mip.m_height, 4) * pitch, alignment);
  5226. const uint32_t size = slice * mip.m_depth;
  5227. uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, size);
  5228. bimg::imageDecodeToBgra8(
  5229. g_allocator
  5230. , temp
  5231. , mip.m_data
  5232. , mip.m_width
  5233. , mip.m_height
  5234. , pitch
  5235. , mip.m_format
  5236. );
  5237. imageInfos[kk].data = temp;
  5238. imageInfos[kk].width = mip.m_width;
  5239. imageInfos[kk].height = mip.m_height;
  5240. imageInfos[kk].depth = mip.m_depth;
  5241. imageInfos[kk].pitch = pitch;
  5242. imageInfos[kk].slice = slice;
  5243. imageInfos[kk].size = size;
  5244. imageInfos[kk].mipLevel = lod;
  5245. imageInfos[kk].layer = side;
  5246. }
  5247. else if (compressed)
  5248. {
  5249. const uint32_t pitch = bx::strideAlign( (mip.m_width / blockInfo.blockWidth) * mip.m_blockSize, alignment);
  5250. const uint32_t slice = bx::strideAlign( (mip.m_height / blockInfo.blockHeight) * pitch, alignment);
  5251. const uint32_t size = slice * mip.m_depth;
  5252. uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, size);
  5253. bimg::imageCopy(
  5254. temp
  5255. , mip.m_height / blockInfo.blockHeight
  5256. , (mip.m_width / blockInfo.blockWidth) * mip.m_blockSize
  5257. , mip.m_depth
  5258. , mip.m_data
  5259. , pitch
  5260. );
  5261. imageInfos[kk].data = temp;
  5262. imageInfos[kk].width = mip.m_width;
  5263. imageInfos[kk].height = mip.m_height;
  5264. imageInfos[kk].depth = mip.m_depth;
  5265. imageInfos[kk].pitch = pitch;
  5266. imageInfos[kk].slice = slice;
  5267. imageInfos[kk].size = size;
  5268. imageInfos[kk].mipLevel = lod;
  5269. imageInfos[kk].layer = side;
  5270. }
  5271. else
  5272. {
  5273. const uint32_t pitch = bx::strideAlign(mip.m_width * mip.m_bpp / 8, alignment);
  5274. const uint32_t slice = bx::strideAlign(mip.m_height * pitch, alignment);
  5275. const uint32_t size = slice * mip.m_depth;
  5276. uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, size);
  5277. bimg::imageCopy(
  5278. temp
  5279. , mip.m_height
  5280. , mip.m_width * mip.m_bpp / 8
  5281. , mip.m_depth
  5282. , mip.m_data
  5283. , pitch
  5284. );
  5285. imageInfos[kk].data = temp;
  5286. imageInfos[kk].width = mip.m_width;
  5287. imageInfos[kk].height = mip.m_height;
  5288. imageInfos[kk].depth = mip.m_depth;
  5289. imageInfos[kk].pitch = pitch;
  5290. imageInfos[kk].slice = slice;
  5291. imageInfos[kk].size = size;
  5292. imageInfos[kk].mipLevel = lod;
  5293. imageInfos[kk].layer = side;
  5294. }
  5295. }
  5296. ++kk;
  5297. }
  5298. }
  5299. uint32_t totalMemSize = 0;
  5300. VkBufferImageCopy* bufferCopyInfo = (VkBufferImageCopy*)bx::alloc(g_allocator, sizeof(VkBufferImageCopy) * numSrd);
  5301. for (uint32_t ii = 0; ii < numSrd; ++ii)
  5302. {
  5303. const uint32_t idealWidth = bx::max<uint32_t>(1, m_width >> imageInfos[ii].mipLevel);
  5304. const uint32_t idealHeight = bx::max<uint32_t>(1, m_height >> imageInfos[ii].mipLevel);
  5305. bufferCopyInfo[ii].bufferOffset = totalMemSize;
  5306. bufferCopyInfo[ii].bufferRowLength = 0; // assume that image data are tightly aligned
  5307. bufferCopyInfo[ii].bufferImageHeight = 0; // assume that image data are tightly aligned
  5308. bufferCopyInfo[ii].imageSubresource.aspectMask = m_aspectMask;
  5309. bufferCopyInfo[ii].imageSubresource.mipLevel = imageInfos[ii].mipLevel;
  5310. bufferCopyInfo[ii].imageSubresource.baseArrayLayer = imageInfos[ii].layer;
  5311. bufferCopyInfo[ii].imageSubresource.layerCount = 1;
  5312. bufferCopyInfo[ii].imageOffset = { 0, 0, 0 };
  5313. bufferCopyInfo[ii].imageExtent = { idealWidth, idealHeight, imageInfos[ii].depth };
  5314. totalMemSize += imageInfos[ii].size;
  5315. }
  5316. if (totalMemSize > 0)
  5317. {
  5318. const VkDevice device = s_renderVK->m_device;
  5319. const bimg::ImageBlockInfo &dstBlockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat));
  5320. StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(totalMemSize, dstBlockInfo.blockSize);
  5321. uint8_t* mappedMemory;
  5322. if (!stagingBuffer.m_isFromScratch)
  5323. {
  5324. VK_CHECK(vkMapMemory(
  5325. device
  5326. , stagingBuffer.m_deviceMem.mem
  5327. , stagingBuffer.m_deviceMem.offset
  5328. , totalMemSize
  5329. , 0
  5330. , (void**)&mappedMemory
  5331. ) );
  5332. }
  5333. else
  5334. {
  5335. mappedMemory = stagingBuffer.m_data;
  5336. }
  5337. // copy image to staging buffer
  5338. for (uint32_t ii = 0; ii < numSrd; ++ii)
  5339. {
  5340. bx::memCopy(mappedMemory, imageInfos[ii].data, imageInfos[ii].size);
  5341. mappedMemory += imageInfos[ii].size;
  5342. bufferCopyInfo[ii].bufferOffset += stagingBuffer.m_offset;
  5343. BX_ASSERT(
  5344. bx::uint32_mod(bx::narrowCast<uint32_t>(bufferCopyInfo[ii].bufferOffset), dstBlockInfo.blockSize) == 0
  5345. , "Alignment for subimage %u is not aligned correctly (%u)."
  5346. , ii, bufferCopyInfo[ii].bufferOffset, dstBlockInfo.blockSize
  5347. );
  5348. }
  5349. if (!stagingBuffer.m_isFromScratch)
  5350. {
  5351. vkUnmapMemory(device, stagingBuffer.m_deviceMem.mem);
  5352. }
  5353. copyBufferToTexture(_commandBuffer, stagingBuffer.m_buffer, numSrd, bufferCopyInfo);
  5354. if (!stagingBuffer.m_isFromScratch)
  5355. {
  5356. s_renderVK->release(stagingBuffer.m_buffer);
  5357. s_renderVK->recycleMemory(stagingBuffer.m_deviceMem);
  5358. }
  5359. }
  5360. else
  5361. {
  5362. setImageMemoryBarrier(_commandBuffer, m_sampledLayout);
  5363. }
  5364. bx::free(g_allocator, bufferCopyInfo);
  5365. for (uint32_t ii = 0; ii < numSrd; ++ii)
  5366. {
  5367. bx::free(g_allocator, imageInfos[ii].data);
  5368. }
  5369. bx::free(g_allocator, imageInfos);
  5370. m_readback.create(m_textureImage, m_width, m_height, TextureFormat::Enum(m_textureFormat) );
  5371. }
  5372. return m_directAccessPtr;
  5373. }
  5374. void TextureVK::destroy()
  5375. {
  5376. BGFX_PROFILER_SCOPE("TextureVK::destroy", kColorResource);
  5377. m_readback.destroy();
  5378. if (VK_NULL_HANDLE != m_textureImage)
  5379. {
  5380. s_renderVK->release(m_textureImage);
  5381. s_renderVK->recycleMemory(m_textureDeviceMem);
  5382. }
  5383. if (VK_NULL_HANDLE != m_singleMsaaImage)
  5384. {
  5385. s_renderVK->release(m_singleMsaaImage);
  5386. s_renderVK->recycleMemory(m_singleMsaaDeviceMem);
  5387. }
  5388. m_currentImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  5389. m_currentSingleMsaaImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  5390. }
  5391. 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)
  5392. {
  5393. BGFX_PROFILER_SCOPE("TextureVK::update", kColorResource);
  5394. const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) );
  5395. const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) );
  5396. uint32_t rectpitch = _rect.m_width * bpp / 8;
  5397. uint32_t slicepitch = rectpitch * _rect.m_height;
  5398. uint32_t align = blockInfo.blockSize;
  5399. if (bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ) )
  5400. {
  5401. rectpitch = (_rect.m_width / blockInfo.blockWidth ) * blockInfo.blockSize;
  5402. slicepitch = (_rect.m_height / blockInfo.blockHeight) * rectpitch;
  5403. }
  5404. const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch;
  5405. const uint32_t size = UINT16_MAX == _pitch ? slicepitch * _depth: _rect.m_height * _pitch * _depth;
  5406. const bool convert = m_textureFormat != m_requestedFormat;
  5407. VkBufferImageCopy region;
  5408. region.bufferOffset = 0;
  5409. region.bufferRowLength = (_pitch == UINT16_MAX ? 0 : _pitch * 8 / bpp);
  5410. region.bufferImageHeight = 0;
  5411. region.imageSubresource.aspectMask = m_aspectMask;
  5412. region.imageSubresource.mipLevel = _mip;
  5413. region.imageSubresource.baseArrayLayer = 0;
  5414. region.imageSubresource.layerCount = 1;
  5415. region.imageOffset = { _rect.m_x, _rect.m_y, 0 };
  5416. region.imageExtent = { _rect.m_width, _rect.m_height, _depth };
  5417. uint8_t* data = _mem->data;
  5418. uint8_t* temp = NULL;
  5419. if (convert)
  5420. {
  5421. temp = (uint8_t*)bx::alloc(g_allocator, slicepitch);
  5422. bimg::imageDecodeToBgra8(g_allocator, temp, data, _rect.m_width, _rect.m_height, srcpitch, bimg::TextureFormat::Enum(m_requestedFormat));
  5423. data = temp;
  5424. region.imageExtent =
  5425. {
  5426. bx::max(1u, m_width >> _mip),
  5427. bx::max(1u, m_height >> _mip),
  5428. _depth,
  5429. };
  5430. }
  5431. StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(size, align, data);
  5432. region.bufferOffset += stagingBuffer.m_offset;
  5433. BX_ASSERT(region.bufferOffset % align == 0,
  5434. "Alignment for image (mip %u, z %u) is not aligned correctly (%u).",
  5435. _mip, _z, region.bufferOffset, align);
  5436. if (VK_IMAGE_VIEW_TYPE_3D == m_type)
  5437. {
  5438. region.imageOffset.z = _z;
  5439. }
  5440. else if (VK_IMAGE_VIEW_TYPE_CUBE == m_type
  5441. || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == m_type)
  5442. {
  5443. region.imageSubresource.baseArrayLayer = _z * 6 + _side;
  5444. }
  5445. else
  5446. {
  5447. region.imageSubresource.baseArrayLayer = _z;
  5448. }
  5449. copyBufferToTexture(_commandBuffer, stagingBuffer.m_buffer, 1, &region);
  5450. if (!stagingBuffer.m_isFromScratch)
  5451. {
  5452. s_renderVK->release(stagingBuffer.m_buffer);
  5453. s_renderVK->recycleMemory(stagingBuffer.m_deviceMem);
  5454. }
  5455. if (NULL != temp)
  5456. {
  5457. bx::free(g_allocator, temp);
  5458. }
  5459. }
  5460. void TextureVK::resolve(VkCommandBuffer _commandBuffer, uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip)
  5461. {
  5462. BGFX_PROFILER_SCOPE("TextureVK::resolve", kColorResource);
  5463. const bool needResolve = VK_NULL_HANDLE != m_singleMsaaImage;
  5464. const bool needMipGen = true
  5465. && !needResolve
  5466. && 0 != (m_flags & BGFX_TEXTURE_RT_MASK)
  5467. && 0 == (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY)
  5468. && (_mip + 1) < m_numMips
  5469. && 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS)
  5470. ;
  5471. const VkImageLayout oldLayout = m_currentImageLayout;
  5472. const VkImageLayout oldSingleMsaaLayout = m_currentSingleMsaaImageLayout;
  5473. const uint32_t numLayers = false
  5474. || m_type == VK_IMAGE_VIEW_TYPE_CUBE
  5475. || m_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
  5476. ? m_numSides
  5477. : _numLayers
  5478. ;
  5479. if (needResolve)
  5480. {
  5481. setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
  5482. setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
  5483. VkImageResolve resolve;
  5484. resolve.srcOffset.x = 0;
  5485. resolve.srcOffset.y = 0;
  5486. resolve.srcOffset.z = 0;
  5487. resolve.dstOffset.x = 0;
  5488. resolve.dstOffset.y = 0;
  5489. resolve.dstOffset.z = 0;
  5490. resolve.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  5491. resolve.srcSubresource.mipLevel = _mip;
  5492. resolve.srcSubresource.baseArrayLayer = _layer;
  5493. resolve.srcSubresource.layerCount = numLayers;
  5494. resolve.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  5495. resolve.dstSubresource.mipLevel = _mip;
  5496. resolve.dstSubresource.baseArrayLayer = _layer;
  5497. resolve.dstSubresource.layerCount = numLayers;
  5498. resolve.extent.width = m_width;
  5499. resolve.extent.height = m_height;
  5500. resolve.extent.depth = 1;
  5501. vkCmdResolveImage(
  5502. _commandBuffer
  5503. , m_textureImage
  5504. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5505. , m_singleMsaaImage
  5506. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5507. , 1
  5508. , &resolve
  5509. );
  5510. }
  5511. if (needMipGen)
  5512. {
  5513. BGFX_PROFILER_SCOPE("TextureVK::resolve genMipmaps", kColorResource);
  5514. setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
  5515. int32_t mipWidth = bx::max<int32_t>(int32_t(m_width) >> _mip, 1);
  5516. int32_t mipHeight = bx::max<int32_t>(int32_t(m_height) >> _mip, 1);
  5517. const VkFilter filter = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) )
  5518. ? VK_FILTER_NEAREST
  5519. : VK_FILTER_LINEAR
  5520. ;
  5521. VkImageBlit blit;
  5522. blit.srcOffsets[0] = { 0, 0, 0 };
  5523. blit.srcOffsets[1] = { mipWidth, mipHeight, 1 };
  5524. blit.srcSubresource.aspectMask = m_aspectMask;
  5525. blit.srcSubresource.mipLevel = 0;
  5526. blit.srcSubresource.baseArrayLayer = _layer;
  5527. blit.srcSubresource.layerCount = numLayers;
  5528. blit.dstOffsets[0] = { 0, 0, 0 };
  5529. blit.dstOffsets[1] = { mipWidth, mipHeight, 1 };
  5530. blit.dstSubresource.aspectMask = m_aspectMask;
  5531. blit.dstSubresource.mipLevel = 0;
  5532. blit.dstSubresource.baseArrayLayer = _layer;
  5533. blit.dstSubresource.layerCount = numLayers;
  5534. for (uint32_t i = _mip + 1; i < m_numMips; i++)
  5535. {
  5536. BGFX_PROFILER_SCOPE("mipmap", kColorResource);
  5537. blit.srcOffsets[1] = { mipWidth, mipHeight, 1 };
  5538. blit.srcSubresource.mipLevel = i - 1;
  5539. mipWidth = bx::uint32_max(mipWidth >> 1, 1);
  5540. mipHeight = bx::uint32_max(mipHeight >> 1, 1);
  5541. blit.dstOffsets[1] = { mipWidth, mipHeight, 1 };
  5542. blit.dstSubresource.mipLevel = i;
  5543. vk::setImageMemoryBarrier(
  5544. _commandBuffer
  5545. , m_textureImage
  5546. , m_aspectMask
  5547. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5548. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5549. , blit.srcSubresource.mipLevel
  5550. , 1
  5551. , _layer
  5552. , numLayers
  5553. );
  5554. vkCmdBlitImage(
  5555. _commandBuffer
  5556. , m_textureImage
  5557. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5558. , m_textureImage
  5559. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5560. , 1
  5561. , &blit
  5562. , filter
  5563. );
  5564. }
  5565. vk::setImageMemoryBarrier(
  5566. _commandBuffer
  5567. , m_textureImage
  5568. , m_aspectMask
  5569. , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  5570. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5571. , _mip
  5572. , m_numMips - _mip - 1
  5573. , _layer
  5574. , numLayers
  5575. );
  5576. }
  5577. setImageMemoryBarrier(_commandBuffer, oldLayout);
  5578. setImageMemoryBarrier(_commandBuffer, oldSingleMsaaLayout, true);
  5579. }
  5580. void TextureVK::copyBufferToTexture(VkCommandBuffer _commandBuffer, VkBuffer _stagingBuffer, uint32_t _bufferImageCopyCount, VkBufferImageCopy* _bufferImageCopy)
  5581. {
  5582. BGFX_PROFILER_SCOPE("TextureVK::copyBufferToTexture", kColorResource);
  5583. const VkImageLayout oldLayout = m_currentImageLayout == VK_IMAGE_LAYOUT_UNDEFINED
  5584. ? m_sampledLayout
  5585. : m_currentImageLayout
  5586. ;
  5587. setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
  5588. bimg::TextureFormat::Enum format = bimg::TextureFormat::Enum(m_textureFormat);
  5589. const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(format);
  5590. for (uint32_t ii = 0; ii < _bufferImageCopyCount; ++ii)
  5591. {
  5592. BX_ASSERT(
  5593. bx::uint32_mod(bx::narrowCast<uint32_t>(_bufferImageCopy[ii].bufferOffset), blockInfo.blockSize) == 0
  5594. , "Misaligned texture of type %s to offset %u, which is not a multiple of %u."
  5595. , bimg::getName(format), _bufferImageCopy[ii].bufferOffset, blockInfo.blockSize
  5596. );
  5597. }
  5598. BX_UNUSED(blockInfo);
  5599. vkCmdCopyBufferToImage(
  5600. _commandBuffer
  5601. , _stagingBuffer
  5602. , m_textureImage
  5603. , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  5604. , _bufferImageCopyCount
  5605. , _bufferImageCopy
  5606. );
  5607. setImageMemoryBarrier(_commandBuffer, oldLayout);
  5608. }
  5609. VkImageLayout TextureVK::setImageMemoryBarrier(VkCommandBuffer _commandBuffer, VkImageLayout _newImageLayout, bool _singleMsaaImage)
  5610. {
  5611. if (_singleMsaaImage && VK_NULL_HANDLE == m_singleMsaaImage)
  5612. {
  5613. return VK_IMAGE_LAYOUT_UNDEFINED;
  5614. }
  5615. VkImageLayout& currentLayout = _singleMsaaImage
  5616. ? m_currentSingleMsaaImageLayout
  5617. : m_currentImageLayout
  5618. ;
  5619. const VkImageLayout oldLayout = currentLayout;
  5620. if (currentLayout == _newImageLayout)
  5621. {
  5622. return oldLayout;
  5623. }
  5624. const VkImage image = _singleMsaaImage
  5625. ? m_singleMsaaImage
  5626. : m_textureImage
  5627. ;
  5628. vk::setImageMemoryBarrier(
  5629. _commandBuffer
  5630. , image
  5631. , m_aspectMask
  5632. , currentLayout
  5633. , _newImageLayout
  5634. );
  5635. currentLayout = _newImageLayout;
  5636. return oldLayout;
  5637. }
  5638. VkResult TextureVK::createView(uint32_t _layer, uint32_t _numLayers, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, VkImageAspectFlags _aspectMask, bool _renderTarget, ::VkImageView* _view) const
  5639. {
  5640. VkResult result = VK_SUCCESS;
  5641. if (VK_IMAGE_VIEW_TYPE_3D == m_type)
  5642. {
  5643. BX_ASSERT(false
  5644. || !_renderTarget
  5645. || !(m_aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) )
  5646. , "3D image can't be a depth attachment"
  5647. );
  5648. }
  5649. if (VK_IMAGE_VIEW_TYPE_CUBE == _type
  5650. || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == _type)
  5651. {
  5652. BX_ASSERT(_numLayers % 6 == 0, "");
  5653. BX_ASSERT(
  5654. VK_IMAGE_VIEW_TYPE_3D != m_type
  5655. , "3D image can't be aliased as a cube texture"
  5656. );
  5657. }
  5658. VkImageViewCreateInfo viewInfo;
  5659. viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
  5660. viewInfo.pNext = NULL;
  5661. viewInfo.flags = 0;
  5662. viewInfo.image = ((VK_NULL_HANDLE != m_singleMsaaImage) && !_renderTarget)
  5663. ? m_singleMsaaImage
  5664. : m_textureImage
  5665. ;
  5666. viewInfo.viewType = _type;
  5667. viewInfo.format = m_format;
  5668. viewInfo.components = m_components;
  5669. viewInfo.subresourceRange.aspectMask = m_aspectMask & _aspectMask;
  5670. viewInfo.subresourceRange.baseMipLevel = _mip;
  5671. viewInfo.subresourceRange.levelCount = _numMips;
  5672. viewInfo.subresourceRange.baseArrayLayer = _layer;
  5673. viewInfo.subresourceRange.layerCount = 1;
  5674. if (VK_IMAGE_VIEW_TYPE_2D != _type
  5675. && VK_IMAGE_VIEW_TYPE_3D != _type)
  5676. {
  5677. viewInfo.subresourceRange.layerCount = VK_IMAGE_VIEW_TYPE_CUBE == _type
  5678. ? 6
  5679. : _numLayers
  5680. ;
  5681. }
  5682. VkImageView view = VK_NULL_HANDLE;
  5683. result = vkCreateImageView(
  5684. s_renderVK->m_device
  5685. , &viewInfo
  5686. , s_renderVK->m_allocatorCb
  5687. , &view
  5688. );
  5689. if (VK_SUCCESS != result)
  5690. {
  5691. BX_TRACE("Create texture view error: vkCreateImageView failed %d: %s.", result, getName(result) );
  5692. return result;
  5693. }
  5694. *_view = view;
  5695. return result;
  5696. }
  5697. VkImageAspectFlags TextureVK::getAspectMask(VkFormat _format)
  5698. {
  5699. switch (_format)
  5700. {
  5701. case VK_FORMAT_S8_UINT:
  5702. return VK_IMAGE_ASPECT_STENCIL_BIT;
  5703. break;
  5704. case VK_FORMAT_D16_UNORM:
  5705. case VK_FORMAT_X8_D24_UNORM_PACK32:
  5706. case VK_FORMAT_D32_SFLOAT:
  5707. return VK_IMAGE_ASPECT_DEPTH_BIT;
  5708. case VK_FORMAT_D16_UNORM_S8_UINT:
  5709. case VK_FORMAT_D24_UNORM_S8_UINT:
  5710. case VK_FORMAT_D32_SFLOAT_S8_UINT:
  5711. return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
  5712. default:
  5713. return VK_IMAGE_ASPECT_COLOR_BIT;
  5714. }
  5715. }
  5716. VkResult SwapChainVK::create(VkCommandBuffer _commandBuffer, void* _nwh, const Resolution& _resolution, TextureFormat::Enum _depthFormat)
  5717. {
  5718. struct ErrorState
  5719. {
  5720. enum Enum
  5721. {
  5722. Default,
  5723. SurfaceCreated,
  5724. SwapChainCreated,
  5725. AttachmentsCreated
  5726. };
  5727. };
  5728. ErrorState::Enum errorState = ErrorState::Default;
  5729. VkResult result = VK_SUCCESS;
  5730. if (NULL == _nwh)
  5731. {
  5732. return result;
  5733. }
  5734. m_nwh = _nwh;
  5735. m_resolution = _resolution;
  5736. m_depthFormat = TextureFormat::Count == _depthFormat ? TextureFormat::D24S8 : _depthFormat;
  5737. m_queue = s_renderVK->m_globalQueue;
  5738. result = createSurface();
  5739. if (VK_SUCCESS != result)
  5740. {
  5741. BX_TRACE("Create swap chain error: creating surface failed %d: %s.", result, getName(result) );
  5742. goto error;
  5743. }
  5744. errorState = ErrorState::SurfaceCreated;
  5745. {
  5746. m_sci.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
  5747. m_sci.pNext = NULL;
  5748. m_sci.flags = 0;
  5749. m_sci.imageArrayLayers = 1;
  5750. m_sci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
  5751. m_sci.queueFamilyIndexCount = 0;
  5752. m_sci.pQueueFamilyIndices = NULL;
  5753. m_sci.preTransform = BX_ENABLED(BX_PLATFORM_NX)
  5754. ? VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR
  5755. : VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
  5756. ;
  5757. m_sci.oldSwapchain = VK_NULL_HANDLE;
  5758. for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii)
  5759. {
  5760. m_backBufferColorImage[ii] = VK_NULL_HANDLE;
  5761. m_backBufferColorImageView[ii] = VK_NULL_HANDLE;
  5762. m_backBufferFrameBuffer[ii] = VK_NULL_HANDLE;
  5763. m_backBufferFence[ii] = VK_NULL_HANDLE;
  5764. m_presentDoneSemaphore[ii] = VK_NULL_HANDLE;
  5765. m_renderDoneSemaphore[ii] = VK_NULL_HANDLE;
  5766. }
  5767. m_lastImageRenderedSemaphore = VK_NULL_HANDLE;
  5768. m_lastImageAcquiredSemaphore = VK_NULL_HANDLE;
  5769. result = createSwapChain();
  5770. if (VK_SUCCESS != result)
  5771. {
  5772. BX_TRACE("Create swap chain error: creating swapchain and image views failed %d: %s", result, getName(result) );
  5773. goto error;
  5774. }
  5775. }
  5776. errorState = ErrorState::SwapChainCreated;
  5777. {
  5778. result = createAttachments(_commandBuffer);
  5779. if (VK_SUCCESS != result)
  5780. {
  5781. BX_TRACE("Create swap chain error: creating MSAA/depth attachments failed %d: %s.", result, getName(result) );
  5782. goto error;
  5783. }
  5784. }
  5785. errorState = ErrorState::AttachmentsCreated;
  5786. {
  5787. result = createFrameBuffer();
  5788. if (VK_SUCCESS != result)
  5789. {
  5790. BX_TRACE("Create swap chain error: creating frame buffers failed %d: %s.", result, getName(result) );
  5791. goto error;
  5792. }
  5793. }
  5794. return VK_SUCCESS;
  5795. error:
  5796. BX_TRACE("errorState %d", errorState);
  5797. switch (errorState)
  5798. {
  5799. case ErrorState::AttachmentsCreated:
  5800. releaseAttachments();
  5801. [[fallthrough]];
  5802. case ErrorState::SwapChainCreated:
  5803. releaseSwapChain();
  5804. [[fallthrough]];
  5805. case ErrorState::SurfaceCreated:
  5806. releaseSurface();
  5807. [[fallthrough]];
  5808. case ErrorState::Default:
  5809. break;
  5810. };
  5811. return VK_SUCCESS != result
  5812. ? result
  5813. : VK_ERROR_INITIALIZATION_FAILED
  5814. ;
  5815. }
  5816. void SwapChainVK::destroy()
  5817. {
  5818. if (VK_NULL_HANDLE != m_swapChain)
  5819. {
  5820. releaseFrameBuffer();
  5821. releaseAttachments();
  5822. releaseSwapChain();
  5823. releaseSurface();
  5824. // can't delay-delete the surface, since there can only be one swapchain per surface
  5825. // new framebuffer with the same window would get an error at swapchain creation
  5826. s_renderVK->kick(true);
  5827. }
  5828. m_nwh = NULL;
  5829. }
  5830. void SwapChainVK::update(VkCommandBuffer _commandBuffer, void* _nwh, const Resolution& _resolution)
  5831. {
  5832. BGFX_PROFILER_SCOPE("SwapChainVK::update", kColorFrame);
  5833. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  5834. m_lastImageRenderedSemaphore = VK_NULL_HANDLE;
  5835. m_lastImageAcquiredSemaphore = VK_NULL_HANDLE;
  5836. const uint64_t recreateSurfaceMask = BGFX_RESET_HIDPI;
  5837. const uint64_t recreateSwapchainMask = BGFX_RESET_VSYNC | BGFX_RESET_SRGB_BACKBUFFER;
  5838. const uint64_t recreateAttachmentsMask = BGFX_RESET_MSAA_MASK;
  5839. const bool recreateSurface = false
  5840. || m_needToRecreateSurface
  5841. || m_nwh != _nwh
  5842. || (m_resolution.reset & recreateSurfaceMask) != (_resolution.reset & recreateSurfaceMask)
  5843. ;
  5844. const bool recreateSwapchain = false
  5845. || m_needToRecreateSwapchain
  5846. || m_resolution.format != _resolution.format
  5847. || m_resolution.width != _resolution.width
  5848. || m_resolution.height != _resolution.height
  5849. || (m_resolution.reset & recreateSwapchainMask) != (_resolution.reset & recreateSwapchainMask)
  5850. || recreateSurface
  5851. ;
  5852. const bool recreateAttachments = false
  5853. || (m_resolution.reset & recreateAttachmentsMask) != (_resolution.reset & recreateAttachmentsMask)
  5854. || recreateSwapchain
  5855. ;
  5856. m_nwh = _nwh;
  5857. m_resolution = _resolution;
  5858. if (recreateAttachments)
  5859. {
  5860. releaseFrameBuffer();
  5861. releaseAttachments();
  5862. if (recreateSwapchain)
  5863. {
  5864. releaseSwapChain();
  5865. if (recreateSurface)
  5866. {
  5867. m_sci.oldSwapchain = VK_NULL_HANDLE;
  5868. releaseSurface();
  5869. s_renderVK->kick(true);
  5870. _commandBuffer = s_renderVK->m_commandBuffer;
  5871. VkResult result = createSurface();
  5872. if (VK_SUCCESS != result)
  5873. {
  5874. BX_TRACE("Surface lost.");
  5875. return;
  5876. }
  5877. }
  5878. VkSurfaceCapabilitiesKHR surfaceCapabilities;
  5879. VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, m_surface, &surfaceCapabilities) );
  5880. const uint32_t width = bx::clamp<uint32_t>(
  5881. m_resolution.width
  5882. , surfaceCapabilities.minImageExtent.width
  5883. , surfaceCapabilities.maxImageExtent.width
  5884. );
  5885. const uint32_t height = bx::clamp<uint32_t>(
  5886. m_resolution.height
  5887. , surfaceCapabilities.minImageExtent.height
  5888. , surfaceCapabilities.maxImageExtent.height
  5889. );
  5890. // swapchain can't have size 0
  5891. // on some platforms this happens when minimized
  5892. if (width == 0
  5893. || height == 0)
  5894. {
  5895. m_sci.oldSwapchain = VK_NULL_HANDLE;
  5896. s_renderVK->kick(true);
  5897. return;
  5898. }
  5899. VK_CHECK(createSwapChain() );
  5900. }
  5901. VK_CHECK(createAttachments(_commandBuffer) );
  5902. VK_CHECK(createFrameBuffer() );
  5903. }
  5904. }
  5905. VkResult SwapChainVK::createSurface()
  5906. {
  5907. BGFX_PROFILER_SCOPE("SwapChainVK::createSurface", kColorFrame);
  5908. VkResult result = VK_ERROR_EXTENSION_NOT_PRESENT;
  5909. const VkInstance instance = s_renderVK->m_instance;
  5910. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  5911. #if BX_PLATFORM_WINDOWS
  5912. {
  5913. if (NULL != vkCreateWin32SurfaceKHR)
  5914. {
  5915. VkWin32SurfaceCreateInfoKHR sci;
  5916. sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
  5917. sci.pNext = NULL;
  5918. sci.flags = 0;
  5919. sci.hinstance = (HINSTANCE)GetModuleHandle(NULL);
  5920. sci.hwnd = (HWND)m_nwh;
  5921. result = vkCreateWin32SurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  5922. BX_WARN(VK_SUCCESS == result, "vkCreateWin32SurfaceKHR failed %d: %s.", result, getName(result) );
  5923. }
  5924. }
  5925. #elif BX_PLATFORM_ANDROID
  5926. {
  5927. if (NULL != vkCreateAndroidSurfaceKHR)
  5928. {
  5929. VkAndroidSurfaceCreateInfoKHR sci;
  5930. sci.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
  5931. sci.pNext = NULL;
  5932. sci.flags = 0;
  5933. sci.window = (ANativeWindow*)m_nwh;
  5934. result = vkCreateAndroidSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  5935. BX_WARN(VK_SUCCESS == result, "vkCreateAndroidSurfaceKHR failed %d: %s.", result, getName(result) );
  5936. }
  5937. }
  5938. #elif BX_PLATFORM_LINUX
  5939. {
  5940. if (g_platformData.type == bgfx::NativeWindowHandleType::Wayland)
  5941. {
  5942. if (s_extension[Extension::KHR_wayland_surface].m_supported
  5943. && NULL != vkCreateWaylandSurfaceKHR
  5944. )
  5945. {
  5946. BX_TRACE("Attempting Wayland surface creation.");
  5947. VkWaylandSurfaceCreateInfoKHR sci;
  5948. sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
  5949. sci.pNext = NULL;
  5950. sci.flags = 0;
  5951. sci.display = (wl_display*)g_platformData.ndt;
  5952. sci.surface = (wl_surface*)m_nwh;
  5953. result = vkCreateWaylandSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  5954. BX_WARN(VK_SUCCESS == result, "vkCreateWaylandSurfaceKHR failed %d: %s.", result, getName(result) );
  5955. }
  5956. }
  5957. else
  5958. {
  5959. if (s_extension[Extension::KHR_xlib_surface].m_supported
  5960. && NULL != vkCreateXlibSurfaceKHR
  5961. )
  5962. {
  5963. BX_TRACE("Attempting Xlib surface creation.");
  5964. VkXlibSurfaceCreateInfoKHR sci;
  5965. sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
  5966. sci.pNext = NULL;
  5967. sci.flags = 0;
  5968. sci.dpy = (Display*)g_platformData.ndt;
  5969. sci.window = (Window)m_nwh;
  5970. result = vkCreateXlibSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  5971. BX_WARN(VK_SUCCESS == result, "vkCreateXlibSurfaceKHR failed %d: %s.", result, getName(result) );
  5972. }
  5973. if (VK_SUCCESS != result
  5974. && s_extension[Extension::KHR_xcb_surface].m_supported
  5975. && NULL != vkCreateXcbSurfaceKHR
  5976. )
  5977. {
  5978. void* xcbdll = bx::dlopen("libX11-xcb.so.1");
  5979. if (NULL != xcbdll)
  5980. {
  5981. BX_TRACE("Attempting XCB surface creation.");
  5982. typedef xcb_connection_t* (*PFN_XGETXCBCONNECTION)(Display*);
  5983. PFN_XGETXCBCONNECTION XGetXCBConnection = (PFN_XGETXCBCONNECTION)bx::dlsym(xcbdll, "XGetXCBConnection");
  5984. VkXcbSurfaceCreateInfoKHR sci;
  5985. sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
  5986. sci.pNext = NULL;
  5987. sci.flags = 0;
  5988. sci.connection = XGetXCBConnection( (Display*)g_platformData.ndt);
  5989. sci.window = bx::narrowCast<xcb_window_t>(uintptr_t(m_nwh) );
  5990. result = vkCreateXcbSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
  5991. BX_WARN(VK_SUCCESS == result, "vkCreateXcbSurfaceKHR failed %d: %s.", result, getName(result) );
  5992. bx::dlclose(xcbdll);
  5993. }
  5994. }
  5995. }
  5996. }
  5997. #elif BX_PLATFORM_OSX
  5998. {
  5999. if (NULL != vkCreateMacOSSurfaceMVK)
  6000. {
  6001. NSWindow* window = (NSWindow*)(m_nwh);
  6002. CAMetalLayer* layer = (CAMetalLayer*)(m_nwh);
  6003. if ([window isKindOfClass:[NSWindow class]])
  6004. {
  6005. NSView *contentView = (NSView *)window.contentView;
  6006. layer = [CAMetalLayer layer];
  6007. [contentView setWantsLayer : YES];
  6008. [contentView setLayer : layer];
  6009. }
  6010. else if ([layer isKindOfClass:[CAMetalLayer class]])
  6011. {
  6012. NSView *contentView = (NSView *)layer.delegate;
  6013. window = contentView.window;
  6014. }
  6015. else
  6016. {
  6017. BX_WARN(0, "Unable to create MoltenVk surface. Please set platform data window to an NSWindow or CAMetalLayer");
  6018. return result;
  6019. }
  6020. if (m_resolution.reset & BGFX_RESET_HIDPI)
  6021. {
  6022. layer.contentsScale = [window backingScaleFactor];
  6023. }
  6024. VkMacOSSurfaceCreateInfoMVK sci;
  6025. sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
  6026. sci.pNext = NULL;
  6027. sci.flags = 0;
  6028. sci.pView = (__bridge void*)layer;
  6029. result = vkCreateMacOSSurfaceMVK(instance, &sci, allocatorCb, &m_surface);
  6030. BX_WARN(VK_SUCCESS == result, "vkCreateMacOSSurfaceMVK failed %d: %s.", result, getName(result) );
  6031. }
  6032. }
  6033. #elif BX_PLATFORM_NX
  6034. if (NULL != vkCreateViSurfaceNN)
  6035. {
  6036. VkViSurfaceCreateInfoNN sci;
  6037. sci.sType = VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN;
  6038. sci.pNext = NULL;
  6039. sci.flags = 0;
  6040. sci.window = m_nwh;
  6041. result = vkCreateViSurfaceNN(instance, &sci, allocatorCb, &m_surface);
  6042. BX_WARN(VK_SUCCESS == result, "vkCreateViSurfaceNN failed %d: %s.", result, getName(result) );
  6043. }
  6044. #else
  6045. # error "Figure out KHR surface..."
  6046. #endif // BX_PLATFORM_
  6047. m_needToRecreateSurface = false;
  6048. if (VK_SUCCESS != result)
  6049. {
  6050. BX_TRACE("Create surface error: vkCreate[Platform]SurfaceKHR failed %d: %s.", result, getName(result) );
  6051. return result;
  6052. }
  6053. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  6054. const uint32_t queueFamily = s_renderVK->m_globalQueueFamily;
  6055. VkBool32 surfaceSupported;
  6056. result = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamily, m_surface, &surfaceSupported);
  6057. if (VK_SUCCESS != result
  6058. || !surfaceSupported)
  6059. {
  6060. BX_TRACE("Create surface error: Presentation to the given surface not supported.");
  6061. return VK_ERROR_INITIALIZATION_FAILED;
  6062. }
  6063. return result;
  6064. }
  6065. void SwapChainVK::releaseSurface()
  6066. {
  6067. release(m_surface);
  6068. }
  6069. VkResult SwapChainVK::createSwapChain()
  6070. {
  6071. BGFX_PROFILER_SCOPE("SwapChainVK::createSwapchain", kColorFrame);
  6072. VkResult result = VK_SUCCESS;
  6073. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  6074. const VkDevice device = s_renderVK->m_device;
  6075. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  6076. // Waiting for the device to be idle seems to get rid of VK_DEVICE_LOST
  6077. // upon resizing the window quickly. See:
  6078. // - https://github.com/mpv-player/mpv/issues/8360
  6079. // - https://github.com/bkaradzic/bgfx/issues/3227
  6080. result = vkDeviceWaitIdle(device);
  6081. BX_WARN(VK_SUCCESS == result, "Create swapchain error: vkDeviceWaitIdle() failed: %d: %s", result, getName(result));
  6082. VkSurfaceCapabilitiesKHR surfaceCapabilities;
  6083. result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, m_surface, &surfaceCapabilities);
  6084. if (VK_SUCCESS != result)
  6085. {
  6086. BX_TRACE("Create swapchain error: vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed %d: %s.", result, getName(result) );
  6087. return result;
  6088. }
  6089. const uint32_t minSwapBufferCount = bx::max<uint32_t>(surfaceCapabilities.minImageCount, 2);
  6090. const uint32_t maxSwapBufferCount = surfaceCapabilities.maxImageCount == 0
  6091. ? kMaxBackBuffers
  6092. : bx::min<uint32_t>(surfaceCapabilities.maxImageCount, kMaxBackBuffers)
  6093. ;
  6094. if (minSwapBufferCount > maxSwapBufferCount)
  6095. {
  6096. BX_TRACE("Create swapchain error: Incompatible swapchain image count (min: %d, max: %d, MaxBackBuffers: %d)."
  6097. , minSwapBufferCount
  6098. , maxSwapBufferCount
  6099. , kMaxBackBuffers
  6100. );
  6101. return VK_ERROR_INITIALIZATION_FAILED;
  6102. }
  6103. const uint32_t swapBufferCount = bx::clamp<uint32_t>(m_resolution.numBackBuffers, minSwapBufferCount, maxSwapBufferCount);
  6104. const VkColorSpaceKHR surfaceColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
  6105. const bool srgb = !!(m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER);
  6106. m_colorFormat = findSurfaceFormat(m_resolution.format, surfaceColorSpace, srgb);
  6107. if (TextureFormat::Count == m_colorFormat)
  6108. {
  6109. BX_TRACE("Create swapchain error: Unable to find surface format (srgb: %d).", srgb);
  6110. return VK_ERROR_INITIALIZATION_FAILED;
  6111. }
  6112. const VkFormat surfaceFormat = srgb
  6113. ? s_textureFormat[m_colorFormat].m_fmtSrgb
  6114. : s_textureFormat[m_colorFormat].m_fmt
  6115. ;
  6116. const uint32_t width = bx::clamp<uint32_t>(
  6117. m_resolution.width
  6118. , surfaceCapabilities.minImageExtent.width
  6119. , surfaceCapabilities.maxImageExtent.width
  6120. );
  6121. const uint32_t height = bx::clamp<uint32_t>(
  6122. m_resolution.height
  6123. , surfaceCapabilities.minImageExtent.height
  6124. , surfaceCapabilities.maxImageExtent.height
  6125. );
  6126. if (width != m_resolution.width || height != m_resolution.height)
  6127. {
  6128. BX_TRACE("Clamped swapchain resolution from %dx%d to %dx%d"
  6129. , m_resolution.width
  6130. , m_resolution.height
  6131. , width
  6132. , height
  6133. );
  6134. }
  6135. VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
  6136. if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)
  6137. {
  6138. compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
  6139. }
  6140. else if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR)
  6141. {
  6142. compositeAlpha = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
  6143. }
  6144. else if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR)
  6145. {
  6146. compositeAlpha = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR;
  6147. }
  6148. const VkImageUsageFlags imageUsageMask = 0
  6149. | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
  6150. | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
  6151. | VK_IMAGE_USAGE_TRANSFER_DST_BIT
  6152. ;
  6153. const VkImageUsageFlags imageUsage = surfaceCapabilities.supportedUsageFlags & imageUsageMask;
  6154. m_supportsReadback = 0 != (imageUsage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
  6155. m_supportsManualResolve = 0 != (imageUsage & VK_IMAGE_USAGE_TRANSFER_DST_BIT);
  6156. const bool vsync = !!(m_resolution.reset & BGFX_RESET_VSYNC);
  6157. uint32_t presentModeIdx = findPresentMode(vsync);
  6158. if (UINT32_MAX == presentModeIdx)
  6159. {
  6160. BX_TRACE("Create swapchain error: Unable to find present mode (vsync: %d).", vsync);
  6161. return VK_ERROR_INITIALIZATION_FAILED;
  6162. }
  6163. m_sci.surface = m_surface;
  6164. m_sci.minImageCount = swapBufferCount;
  6165. m_sci.imageFormat = surfaceFormat;
  6166. m_sci.imageColorSpace = surfaceColorSpace;
  6167. m_sci.imageExtent.width = width;
  6168. m_sci.imageExtent.height = height;
  6169. m_sci.imageUsage = imageUsage;
  6170. m_sci.compositeAlpha = compositeAlpha;
  6171. m_sci.presentMode = s_presentMode[presentModeIdx].mode;
  6172. m_sci.clipped = VK_FALSE;
  6173. result = vkCreateSwapchainKHR(device, &m_sci, allocatorCb, &m_swapChain);
  6174. if (VK_SUCCESS != result)
  6175. {
  6176. BX_TRACE("Create swapchain error: vkCreateSwapchainKHR failed %d: %s.", result, getName(result) );
  6177. return result;
  6178. }
  6179. m_sci.oldSwapchain = m_swapChain;
  6180. result = vkGetSwapchainImagesKHR(device, m_swapChain, &m_numSwapChainImages, NULL);
  6181. if (VK_SUCCESS != result)
  6182. {
  6183. BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR failed %d: %s.", result, getName(result) );
  6184. return result;
  6185. }
  6186. BX_TRACE("Create swapchain numSwapChainImages %d, minImageCount %d, BX_COUNTOF(m_backBufferColorImage) %d"
  6187. , m_numSwapChainImages
  6188. , m_sci.minImageCount
  6189. , BX_COUNTOF(m_backBufferColorImage)
  6190. );
  6191. if (m_numSwapChainImages < m_sci.minImageCount)
  6192. {
  6193. BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR: numSwapchainImages %d < minImageCount %d."
  6194. , m_numSwapChainImages
  6195. , m_sci.minImageCount
  6196. );
  6197. return VK_ERROR_INITIALIZATION_FAILED;
  6198. }
  6199. if (m_numSwapChainImages > BX_COUNTOF(m_backBufferColorImage) )
  6200. {
  6201. BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR: numSwapchainImages %d > countof(m_backBufferColorImage) %d."
  6202. , m_numSwapChainImages
  6203. , BX_COUNTOF(m_backBufferColorImage)
  6204. );
  6205. return VK_ERROR_INITIALIZATION_FAILED;
  6206. }
  6207. result = vkGetSwapchainImagesKHR(device, m_swapChain, &m_numSwapChainImages, &m_backBufferColorImage[0]);
  6208. if (VK_SUCCESS != result && VK_INCOMPLETE != result)
  6209. {
  6210. BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR failed %d: %s."
  6211. , result
  6212. , getName(result)
  6213. );
  6214. return result;
  6215. }
  6216. VkImageViewCreateInfo ivci;
  6217. ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
  6218. ivci.pNext = NULL;
  6219. ivci.flags = 0;
  6220. ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
  6221. ivci.format = m_sci.imageFormat;
  6222. ivci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
  6223. ivci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
  6224. ivci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
  6225. ivci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
  6226. ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  6227. ivci.subresourceRange.baseMipLevel = 0;
  6228. ivci.subresourceRange.levelCount = 1;
  6229. ivci.subresourceRange.baseArrayLayer = 0;
  6230. ivci.subresourceRange.layerCount = 1;
  6231. for (uint32_t ii = 0; ii < m_numSwapChainImages; ++ii)
  6232. {
  6233. ivci.image = m_backBufferColorImage[ii];
  6234. result = vkCreateImageView(device, &ivci, allocatorCb, &m_backBufferColorImageView[ii]);
  6235. if (VK_SUCCESS != result)
  6236. {
  6237. BX_TRACE("Create swapchain error: vkCreateImageView failed %d: %s.", result, getName(result) );
  6238. return result;
  6239. }
  6240. m_backBufferColorImageLayout[ii] = VK_IMAGE_LAYOUT_UNDEFINED;
  6241. }
  6242. BX_TRACE("Successfully created swapchain (%dx%d) with %d images.", width, height, m_numSwapChainImages);
  6243. VkSemaphoreCreateInfo sci;
  6244. sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
  6245. sci.pNext = NULL;
  6246. sci.flags = 0;
  6247. // We will make a fully filled pool of semaphores and cycle through those.
  6248. // This is to make sure we have enough, even in the case where there are
  6249. // more frames in flight than images on the swapchain.
  6250. for (uint32_t ii = 0; ii < kMaxBackBuffers; ++ii)
  6251. {
  6252. if (VK_SUCCESS != vkCreateSemaphore(device, &sci, allocatorCb, &m_presentDoneSemaphore[ii])
  6253. || VK_SUCCESS != vkCreateSemaphore(device, &sci, allocatorCb, &m_renderDoneSemaphore[ii]) )
  6254. {
  6255. BX_TRACE("Create swapchain error: vkCreateSemaphore failed %d: %s.", result, getName(result) );
  6256. return result;
  6257. }
  6258. }
  6259. m_backBufferColorIdx = 0;
  6260. m_currentSemaphore = 0;
  6261. m_needPresent = false;
  6262. m_needToRecreateSwapchain = false;
  6263. return result;
  6264. }
  6265. void SwapChainVK::releaseSwapChain()
  6266. {
  6267. BGFX_PROFILER_SCOPE("SwapChainVK::releaseSwapChain", kColorFrame);
  6268. for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii)
  6269. {
  6270. release(m_backBufferColorImageView[ii]);
  6271. m_backBufferFence[ii] = VK_NULL_HANDLE;
  6272. }
  6273. for (uint32_t ii = 0; ii < kMaxBackBuffers; ++ii)
  6274. {
  6275. release(m_presentDoneSemaphore[ii]);
  6276. release(m_renderDoneSemaphore[ii]);
  6277. }
  6278. release(m_swapChain);
  6279. }
  6280. VkResult SwapChainVK::createAttachments(VkCommandBuffer _commandBuffer)
  6281. {
  6282. BGFX_PROFILER_SCOPE("SwapChainVK::createAttachments", kColorFrame);
  6283. VkResult result = VK_SUCCESS;
  6284. const uint32_t samplerIndex = (m_resolution.reset & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT;
  6285. const uint64_t textureFlags = (uint64_t(samplerIndex + 1) << BGFX_TEXTURE_RT_MSAA_SHIFT) | BGFX_TEXTURE_RT | BGFX_TEXTURE_RT_WRITE_ONLY;
  6286. m_sampler = s_msaa[samplerIndex];
  6287. const uint16_t requiredCaps = m_sampler.Count > 1
  6288. ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA
  6289. : BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
  6290. ;
  6291. // the spec guarantees that at least one of D24S8 and D32FS8 is supported
  6292. VkFormat depthFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
  6293. if (g_caps.formats[m_depthFormat] & requiredCaps)
  6294. {
  6295. depthFormat = s_textureFormat[m_depthFormat].m_fmtDsv;
  6296. }
  6297. else if (g_caps.formats[TextureFormat::D24S8] & requiredCaps)
  6298. {
  6299. depthFormat = s_textureFormat[TextureFormat::D24S8].m_fmtDsv;
  6300. }
  6301. result = m_backBufferDepthStencil.create(
  6302. _commandBuffer
  6303. , m_sci.imageExtent.width
  6304. , m_sci.imageExtent.height
  6305. , textureFlags
  6306. , depthFormat
  6307. );
  6308. if (VK_SUCCESS != result)
  6309. {
  6310. BX_TRACE("Create swapchain error: creating depth stencil image failed %d: %s.", result, getName(result) );
  6311. return result;
  6312. }
  6313. result = m_backBufferDepthStencil.createView(0, 1, 0, 1, VK_IMAGE_VIEW_TYPE_2D, m_backBufferDepthStencil.m_aspectMask, true, &m_backBufferDepthStencilImageView);
  6314. if (VK_SUCCESS != result)
  6315. {
  6316. BX_TRACE("Create swapchain error: creating depth stencil image view failed %d: %s.", result, getName(result) );
  6317. return result;
  6318. }
  6319. if (m_sampler.Count > 1)
  6320. {
  6321. result = m_backBufferColorMsaa.create(
  6322. _commandBuffer
  6323. , m_sci.imageExtent.width
  6324. , m_sci.imageExtent.height
  6325. , textureFlags
  6326. , m_sci.imageFormat
  6327. );
  6328. if (VK_SUCCESS != result)
  6329. {
  6330. BX_TRACE("Create swapchain error: creating MSAA color image failed %d: %s.", result, getName(result) );
  6331. return result;
  6332. }
  6333. result = m_backBufferColorMsaa.createView(0, 1, 0, 1, VK_IMAGE_VIEW_TYPE_2D, m_backBufferColorMsaa.m_aspectMask, true, &m_backBufferColorMsaaImageView);
  6334. if (VK_SUCCESS != result)
  6335. {
  6336. BX_TRACE("Create swapchain error: creating MSAA color image view failed %d: %s.", result, getName(result) );
  6337. return result;
  6338. }
  6339. }
  6340. return result;
  6341. }
  6342. void SwapChainVK::releaseAttachments()
  6343. {
  6344. BGFX_PROFILER_SCOPE("SwapChainVK::releaseAttachments", kColorFrame);
  6345. release(m_backBufferDepthStencilImageView);
  6346. release(m_backBufferColorMsaaImageView);
  6347. m_backBufferDepthStencil.destroy();
  6348. m_backBufferColorMsaa.destroy();
  6349. }
  6350. VkResult SwapChainVK::createFrameBuffer()
  6351. {
  6352. BGFX_PROFILER_SCOPE("SwapChainVK::createFrameBuffer", kColorFrame);
  6353. VkResult result = VK_SUCCESS;
  6354. const VkDevice device = s_renderVK->m_device;
  6355. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  6356. VkRenderPass renderPass;
  6357. result = s_renderVK->getRenderPass(*this, &renderPass);
  6358. if (VK_SUCCESS != result)
  6359. {
  6360. return result;
  6361. }
  6362. for (uint32_t ii = 0; ii < m_numSwapChainImages; ++ii)
  6363. {
  6364. uint32_t numAttachments = 2;
  6365. ::VkImageView attachments[3] =
  6366. {
  6367. m_sampler.Count > 1
  6368. ? m_backBufferColorMsaaImageView
  6369. : m_backBufferColorImageView[ii],
  6370. m_backBufferDepthStencilImageView,
  6371. };
  6372. if (m_sampler.Count > 1 && !m_supportsManualResolve)
  6373. {
  6374. attachments[numAttachments++] = m_backBufferColorImageView[ii];
  6375. }
  6376. VkFramebufferCreateInfo fci;
  6377. fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
  6378. fci.pNext = NULL;
  6379. fci.flags = 0;
  6380. fci.renderPass = renderPass;
  6381. fci.attachmentCount = numAttachments;
  6382. fci.pAttachments = attachments;
  6383. fci.width = m_sci.imageExtent.width;
  6384. fci.height = m_sci.imageExtent.height;
  6385. fci.layers = 1;
  6386. result = vkCreateFramebuffer(device, &fci, allocatorCb, &m_backBufferFrameBuffer[ii]);
  6387. if (VK_SUCCESS != result)
  6388. {
  6389. return result;
  6390. }
  6391. }
  6392. return result;
  6393. }
  6394. void SwapChainVK::releaseFrameBuffer()
  6395. {
  6396. for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii)
  6397. {
  6398. release(m_backBufferFrameBuffer[ii]);
  6399. }
  6400. }
  6401. uint32_t SwapChainVK::findPresentMode(bool _vsync)
  6402. {
  6403. BGFX_PROFILER_SCOPE("SwapChainVK::findPresentMode", kColorFrame);
  6404. VkResult result = VK_SUCCESS;
  6405. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  6406. uint32_t numPresentModes;
  6407. result = vkGetPhysicalDeviceSurfacePresentModesKHR(
  6408. physicalDevice
  6409. , m_surface
  6410. , &numPresentModes
  6411. , NULL
  6412. );
  6413. if (VK_SUCCESS != result)
  6414. {
  6415. BX_TRACE("findPresentMode error: vkGetPhysicalDeviceSurfacePresentModesKHR failed %d: %s.", result, getName(result) );
  6416. return UINT32_MAX;
  6417. }
  6418. VkPresentModeKHR presentModes[16];
  6419. numPresentModes = bx::min<uint32_t>(numPresentModes, BX_COUNTOF(presentModes) );
  6420. result = vkGetPhysicalDeviceSurfacePresentModesKHR(
  6421. physicalDevice
  6422. , m_surface
  6423. , &numPresentModes
  6424. , presentModes
  6425. );
  6426. if (VK_SUCCESS != result)
  6427. {
  6428. BX_TRACE("findPresentMode error: vkGetPhysicalDeviceSurfacePresentModesKHR failed %d: %s.", result, getName(result) );
  6429. return UINT32_MAX;
  6430. }
  6431. uint32_t idx = UINT32_MAX;
  6432. for (uint32_t ii = 0; ii < BX_COUNTOF(s_presentMode) && UINT32_MAX == idx; ++ii)
  6433. {
  6434. for (uint32_t jj = 0; jj < numPresentModes; ++jj)
  6435. {
  6436. const PresentMode& pm = s_presentMode[ii];
  6437. if (pm.mode == presentModes[jj]
  6438. && pm.vsync == _vsync)
  6439. {
  6440. idx = ii;
  6441. break;
  6442. }
  6443. }
  6444. }
  6445. if (UINT32_MAX == idx)
  6446. {
  6447. idx = 0;
  6448. BX_TRACE("Present mode not found! Defaulting to %s.", s_presentMode[idx].name);
  6449. }
  6450. return idx;
  6451. }
  6452. TextureFormat::Enum SwapChainVK::findSurfaceFormat(TextureFormat::Enum _format, VkColorSpaceKHR _colorSpace, bool _srgb)
  6453. {
  6454. BGFX_PROFILER_SCOPE("SwapChainVK::findSurfaceFormat", kColorFrame);
  6455. VkResult result = VK_SUCCESS;
  6456. TextureFormat::Enum selectedFormat = TextureFormat::Count;
  6457. const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice;
  6458. uint32_t numSurfaceFormats;
  6459. result = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &numSurfaceFormats, NULL);
  6460. if (VK_SUCCESS != result)
  6461. {
  6462. BX_TRACE("findSurfaceFormat error: vkGetPhysicalDeviceSurfaceFormatsKHR failed %d: %s.", result, getName(result) );
  6463. return selectedFormat;
  6464. }
  6465. VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)bx::alloc(g_allocator, numSurfaceFormats * sizeof(VkSurfaceFormatKHR) );
  6466. result = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats);
  6467. if (VK_SUCCESS != result)
  6468. {
  6469. BX_TRACE("findSurfaceFormat error: vkGetPhysicalDeviceSurfaceFormatsKHR failed %d: %s.", result, getName(result) );
  6470. bx::free(g_allocator, surfaceFormats);
  6471. return selectedFormat;
  6472. }
  6473. const TextureFormat::Enum requestedFormats[] =
  6474. {
  6475. _format,
  6476. TextureFormat::BGRA8,
  6477. TextureFormat::RGBA8,
  6478. };
  6479. for (uint32_t ii = 0; ii < BX_COUNTOF(requestedFormats) && TextureFormat::Count == selectedFormat; ii++)
  6480. {
  6481. const TextureFormat::Enum requested = requestedFormats[ii];
  6482. const VkFormat requestedVkFormat = _srgb
  6483. ? s_textureFormat[requested].m_fmtSrgb
  6484. : s_textureFormat[requested].m_fmt
  6485. ;
  6486. for (uint32_t jj = 0; jj < numSurfaceFormats; jj++)
  6487. {
  6488. if (_colorSpace == surfaceFormats[jj].colorSpace
  6489. && requestedVkFormat == surfaceFormats[jj].format)
  6490. {
  6491. selectedFormat = requested;
  6492. if (0 != ii
  6493. && s_renderVK->m_swapChainFormats[_format] != selectedFormat)
  6494. {
  6495. s_renderVK->m_swapChainFormats[_format] = selectedFormat;
  6496. BX_TRACE(
  6497. "findSurfaceFormat: Surface format %s not found! Defaulting to %s."
  6498. , bimg::getName(bimg::TextureFormat::Enum(_format) )
  6499. , bimg::getName(bimg::TextureFormat::Enum(selectedFormat) )
  6500. );
  6501. }
  6502. break;
  6503. }
  6504. }
  6505. }
  6506. bx::free(g_allocator, surfaceFormats);
  6507. if (TextureFormat::Count == selectedFormat)
  6508. {
  6509. BX_TRACE("findSurfaceFormat error: No supported surface format found.");
  6510. }
  6511. return selectedFormat;
  6512. }
  6513. bool SwapChainVK::acquire(VkCommandBuffer _commandBuffer)
  6514. {
  6515. BGFX_PROFILER_SCOPE("SwapChainVK::acquire", kColorFrame);
  6516. if (VK_NULL_HANDLE == m_swapChain
  6517. || m_needToRecreateSwapchain)
  6518. {
  6519. return false;
  6520. }
  6521. if (!m_needPresent)
  6522. {
  6523. const VkDevice device = s_renderVK->m_device;
  6524. m_lastImageAcquiredSemaphore = m_presentDoneSemaphore[m_currentSemaphore];
  6525. m_lastImageRenderedSemaphore = m_renderDoneSemaphore[m_currentSemaphore];
  6526. m_currentSemaphore = (m_currentSemaphore + 1) % kMaxBackBuffers;
  6527. VkResult result;
  6528. {
  6529. BGFX_PROFILER_SCOPE("vkAcquireNextImageKHR", kColorFrame);
  6530. result = vkAcquireNextImageKHR(
  6531. device
  6532. , m_swapChain
  6533. , UINT64_MAX
  6534. , m_lastImageAcquiredSemaphore
  6535. , VK_NULL_HANDLE
  6536. , &m_backBufferColorIdx
  6537. );
  6538. }
  6539. if (result != VK_SUCCESS)
  6540. {
  6541. BX_TRACE("vkAcquireNextImageKHR(...): result = %s", getName(result));
  6542. }
  6543. switch (result)
  6544. {
  6545. case VK_SUCCESS:
  6546. break;
  6547. case VK_ERROR_SURFACE_LOST_KHR:
  6548. m_needToRecreateSurface = true;
  6549. m_needToRecreateSwapchain = true;
  6550. return false;
  6551. case VK_ERROR_OUT_OF_DATE_KHR:
  6552. case VK_SUBOPTIMAL_KHR:
  6553. m_needToRecreateSwapchain = true;
  6554. return false;
  6555. default:
  6556. BX_ASSERT(VK_SUCCESS == result, "vkAcquireNextImageKHR(...); VK error 0x%x: %s", result, getName(result) );
  6557. return false;
  6558. }
  6559. if (VK_NULL_HANDLE != m_backBufferFence[m_backBufferColorIdx])
  6560. {
  6561. BGFX_PROFILER_SCOPE("vkWaitForFences", kColorFrame);
  6562. VK_CHECK(vkWaitForFences(
  6563. device
  6564. , 1
  6565. , &m_backBufferFence[m_backBufferColorIdx]
  6566. , VK_TRUE
  6567. , UINT64_MAX
  6568. ) );
  6569. }
  6570. transitionImage(_commandBuffer);
  6571. m_needPresent = true;
  6572. }
  6573. return true;
  6574. }
  6575. void SwapChainVK::present()
  6576. {
  6577. BGFX_PROFILER_SCOPE("SwapChainVk::present", kColorFrame);
  6578. if (VK_NULL_HANDLE != m_swapChain
  6579. && m_needPresent)
  6580. {
  6581. VkPresentInfoKHR pi;
  6582. pi.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
  6583. pi.pNext = NULL;
  6584. pi.waitSemaphoreCount = 1;
  6585. pi.pWaitSemaphores = &m_lastImageRenderedSemaphore;
  6586. pi.swapchainCount = 1;
  6587. pi.pSwapchains = &m_swapChain;
  6588. pi.pImageIndices = &m_backBufferColorIdx;
  6589. pi.pResults = NULL;
  6590. VkResult result;
  6591. {
  6592. BGFX_PROFILER_SCOPE("vkQueuePresentHKR", kColorFrame);
  6593. result = vkQueuePresentKHR(m_queue, &pi);
  6594. }
  6595. if (result != VK_SUCCESS)
  6596. {
  6597. BX_TRACE("vkQueuePresentKHR(...): result = %s", getName(result));
  6598. }
  6599. switch (result)
  6600. {
  6601. case VK_ERROR_SURFACE_LOST_KHR:
  6602. m_needToRecreateSurface = true;
  6603. m_needToRecreateSwapchain = true;
  6604. break;
  6605. case VK_ERROR_OUT_OF_DATE_KHR:
  6606. case VK_SUBOPTIMAL_KHR:
  6607. m_needToRecreateSwapchain = true;
  6608. break;
  6609. default:
  6610. BX_ASSERT(VK_SUCCESS == result, "vkQueuePresentKHR(...); VK error 0x%x: %s", result, getName(result) );
  6611. break;
  6612. }
  6613. m_needPresent = false;
  6614. m_lastImageRenderedSemaphore = VK_NULL_HANDLE;
  6615. }
  6616. }
  6617. void SwapChainVK::transitionImage(VkCommandBuffer _commandBuffer)
  6618. {
  6619. VkImageLayout& layout = m_backBufferColorImageLayout[m_backBufferColorIdx];
  6620. const bool toPresent = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout;
  6621. const VkImageLayout newLayout = toPresent
  6622. ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
  6623. : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
  6624. ;
  6625. layout = toPresent ? layout : VK_IMAGE_LAYOUT_UNDEFINED;
  6626. setImageMemoryBarrier(
  6627. _commandBuffer
  6628. , m_backBufferColorImage[m_backBufferColorIdx]
  6629. , VK_IMAGE_ASPECT_COLOR_BIT
  6630. , layout
  6631. , newLayout
  6632. );
  6633. layout = newLayout;
  6634. }
  6635. void FrameBufferVK::create(uint8_t _num, const Attachment* _attachment)
  6636. {
  6637. BGFX_PROFILER_SCOPE("FrameBufferVK::create", kColorFrame);
  6638. m_numTh = _num;
  6639. bx::memCopy(m_attachment, _attachment, sizeof(Attachment) * _num);
  6640. postReset();
  6641. }
  6642. VkResult FrameBufferVK::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat)
  6643. {
  6644. BGFX_PROFILER_SCOPE("FrameBufferVK::create", kColorFrame);
  6645. VkResult result = VK_SUCCESS;
  6646. Resolution resolution = s_renderVK->m_resolution;
  6647. resolution.format = TextureFormat::Count == _format ? resolution.format : _format;
  6648. resolution.width = _width;
  6649. resolution.height = _height;
  6650. if (_denseIdx != UINT16_MAX)
  6651. {
  6652. resolution.reset &= ~BGFX_RESET_MSAA_MASK;
  6653. }
  6654. result = m_swapChain.create(s_renderVK->m_commandBuffer, _nwh, resolution, _depthFormat);
  6655. if (VK_SUCCESS != result)
  6656. {
  6657. return result;
  6658. }
  6659. result = s_renderVK->getRenderPass(m_swapChain, &m_renderPass);
  6660. if (VK_SUCCESS != result)
  6661. {
  6662. return result;
  6663. }
  6664. m_denseIdx = _denseIdx;
  6665. m_nwh = _nwh;
  6666. m_width = m_swapChain.m_sci.imageExtent.width;
  6667. m_height = m_swapChain.m_sci.imageExtent.height;
  6668. m_sampler = m_swapChain.m_sampler;
  6669. return result;
  6670. }
  6671. void FrameBufferVK::preReset()
  6672. {
  6673. BGFX_PROFILER_SCOPE("FrameBufferVK::preReset", kColorFrame);
  6674. if (VK_NULL_HANDLE != m_framebuffer)
  6675. {
  6676. s_renderVK->release(m_framebuffer);
  6677. for (uint8_t ii = 0; ii < m_numTh; ++ii)
  6678. {
  6679. s_renderVK->release(m_textureImageViews[ii]);
  6680. }
  6681. }
  6682. }
  6683. void FrameBufferVK::postReset()
  6684. {
  6685. BGFX_PROFILER_SCOPE("FrameBufferVK::postReset", kColorFrame);
  6686. if (m_numTh > 0)
  6687. {
  6688. const VkDevice device = s_renderVK->m_device;
  6689. const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb;
  6690. VK_CHECK(s_renderVK->getRenderPass(m_numTh, m_attachment, &m_renderPass) );
  6691. m_depth = BGFX_INVALID_HANDLE;
  6692. m_num = 0;
  6693. for (uint8_t ii = 0; ii < m_numTh; ++ii)
  6694. {
  6695. const Attachment& at = m_attachment[ii];
  6696. const TextureVK& texture = s_renderVK->m_textures[at.handle.idx];
  6697. VK_CHECK(texture.createView(
  6698. at.layer
  6699. , at.numLayers
  6700. , at.mip
  6701. , 1
  6702. , at.numLayers > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D
  6703. , texture.m_aspectMask
  6704. , true
  6705. , &m_textureImageViews[ii]
  6706. ) );
  6707. if (texture.m_aspectMask & VK_IMAGE_ASPECT_COLOR_BIT)
  6708. {
  6709. m_texture[m_num] = at.handle;
  6710. m_num++;
  6711. }
  6712. else if (texture.m_aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) )
  6713. {
  6714. m_depth = at.handle;
  6715. }
  6716. }
  6717. const TextureVK& firstTexture = s_renderVK->m_textures[m_attachment[0].handle.idx];
  6718. m_width = bx::uint32_max(firstTexture.m_width >> m_attachment[0].mip, 1);
  6719. m_height = bx::uint32_max(firstTexture.m_height >> m_attachment[0].mip, 1);
  6720. m_sampler = firstTexture.m_sampler;
  6721. VkFramebufferCreateInfo fci;
  6722. fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
  6723. fci.pNext = NULL;
  6724. fci.flags = 0;
  6725. fci.renderPass = m_renderPass;
  6726. fci.attachmentCount = m_numTh;
  6727. fci.pAttachments = &m_textureImageViews[0];
  6728. fci.width = m_width;
  6729. fci.height = m_height;
  6730. fci.layers = m_attachment[0].numLayers;
  6731. VK_CHECK(vkCreateFramebuffer(device, &fci, allocatorCb, &m_framebuffer) );
  6732. m_currentFramebuffer = m_framebuffer;
  6733. }
  6734. }
  6735. void FrameBufferVK::update(VkCommandBuffer _commandBuffer, const Resolution& _resolution)
  6736. {
  6737. BGFX_PROFILER_SCOPE("FrameBufferVK::update", kColorResource);
  6738. m_swapChain.update(_commandBuffer, m_nwh, _resolution);
  6739. VK_CHECK(s_renderVK->getRenderPass(m_swapChain, &m_renderPass) );
  6740. // Don't believe the passed Resolution, as the Vulkan driver might have
  6741. // specified another resolution, which we had to obey.
  6742. m_width = m_swapChain.m_sci.imageExtent.width;
  6743. m_height = m_swapChain.m_sci.imageExtent.height;
  6744. m_sampler = m_swapChain.m_sampler;
  6745. }
  6746. void FrameBufferVK::resolve()
  6747. {
  6748. if (!m_needResolve)
  6749. {
  6750. return;
  6751. }
  6752. BGFX_PROFILER_SCOPE("FrameBufferVK::resolve", kColorFrame);
  6753. if (NULL == m_nwh)
  6754. {
  6755. for (uint32_t ii = 0; ii < m_numTh; ++ii)
  6756. {
  6757. const Attachment& at = m_attachment[ii];
  6758. if (isValid(at.handle) )
  6759. {
  6760. TextureVK& texture = s_renderVK->m_textures[at.handle.idx];
  6761. texture.resolve(s_renderVK->m_commandBuffer, at.resolve, at.layer, at.numLayers, at.mip);
  6762. }
  6763. }
  6764. }
  6765. else if (isRenderable()
  6766. && m_sampler.Count > 1
  6767. && m_swapChain.m_supportsManualResolve)
  6768. {
  6769. m_swapChain.m_backBufferColorMsaa.m_singleMsaaImage = m_swapChain.m_backBufferColorImage[m_swapChain.m_backBufferColorIdx];
  6770. m_swapChain.m_backBufferColorMsaa.m_currentSingleMsaaImageLayout = m_swapChain.m_backBufferColorImageLayout[m_swapChain.m_backBufferColorIdx];
  6771. m_swapChain.m_backBufferColorMsaa.resolve(s_renderVK->m_commandBuffer, 0, 0, 1, 0);
  6772. m_swapChain.m_backBufferColorMsaa.m_singleMsaaImage = VK_NULL_HANDLE;
  6773. m_swapChain.m_backBufferColorMsaa.m_currentSingleMsaaImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  6774. }
  6775. m_needResolve = false;
  6776. }
  6777. uint16_t FrameBufferVK::destroy()
  6778. {
  6779. BGFX_PROFILER_SCOPE("FrameBufferVK::destroy", kColorFrame);
  6780. preReset();
  6781. if (NULL != m_nwh)
  6782. {
  6783. m_swapChain.destroy();
  6784. m_nwh = NULL;
  6785. m_needPresent = false;
  6786. }
  6787. m_numTh = 0;
  6788. m_num = 0;
  6789. m_depth = BGFX_INVALID_HANDLE;
  6790. m_needResolve = false;
  6791. uint16_t denseIdx = m_denseIdx;
  6792. m_denseIdx = UINT16_MAX;
  6793. return denseIdx;
  6794. }
  6795. bool FrameBufferVK::acquire(VkCommandBuffer _commandBuffer)
  6796. {
  6797. BGFX_PROFILER_SCOPE("FrameBufferVK::acquire", kColorFrame);
  6798. bool acquired = true;
  6799. if (NULL != m_nwh)
  6800. {
  6801. acquired = m_swapChain.acquire(_commandBuffer);
  6802. m_needPresent = m_swapChain.m_needPresent;
  6803. m_currentFramebuffer = m_swapChain.m_backBufferFrameBuffer[m_swapChain.m_backBufferColorIdx];
  6804. }
  6805. m_needResolve = true;
  6806. return acquired;
  6807. }
  6808. void FrameBufferVK::present()
  6809. {
  6810. BGFX_PROFILER_SCOPE("FrameBufferVK::present", kColorFrame);
  6811. m_swapChain.present();
  6812. m_needPresent = false;
  6813. }
  6814. bool FrameBufferVK::isRenderable() const
  6815. {
  6816. return false
  6817. || (NULL == m_nwh)
  6818. || m_swapChain.m_needPresent
  6819. ;
  6820. }
  6821. VkResult CommandQueueVK::init(uint32_t _queueFamily, VkQueue _queue, uint32_t _numFramesInFlight)
  6822. {
  6823. m_queueFamily = _queueFamily;
  6824. m_queue = _queue;
  6825. m_numFramesInFlight = bx::clamp<uint32_t>(_numFramesInFlight, 1, BGFX_CONFIG_MAX_FRAME_LATENCY);
  6826. m_activeCommandBuffer = VK_NULL_HANDLE;
  6827. m_consumeIndex = 0;
  6828. return reset();
  6829. }
  6830. VkResult CommandQueueVK::reset()
  6831. {
  6832. shutdown();
  6833. m_currentFrameInFlight = 0;
  6834. m_consumeIndex = 0;
  6835. m_numSignalSemaphores = 0;
  6836. m_numWaitSemaphores = 0;
  6837. m_activeCommandBuffer = VK_NULL_HANDLE;
  6838. m_currentFence = VK_NULL_HANDLE;
  6839. m_completedFence = VK_NULL_HANDLE;
  6840. m_submitted = 0;
  6841. VkCommandPoolCreateInfo cpci;
  6842. cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
  6843. cpci.pNext = NULL;
  6844. cpci.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
  6845. cpci.queueFamilyIndex = m_queueFamily;
  6846. VkCommandBufferAllocateInfo cbai;
  6847. cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
  6848. cbai.pNext = NULL;
  6849. cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
  6850. cbai.commandBufferCount = 1;
  6851. VkFenceCreateInfo fci;
  6852. fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
  6853. fci.pNext = NULL;
  6854. fci.flags = VK_FENCE_CREATE_SIGNALED_BIT;
  6855. VkResult result = VK_SUCCESS;
  6856. for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii)
  6857. {
  6858. result = vkCreateCommandPool(
  6859. s_renderVK->m_device
  6860. , &cpci
  6861. , s_renderVK->m_allocatorCb
  6862. , &m_commandList[ii].m_commandPool
  6863. );
  6864. if (VK_SUCCESS != result)
  6865. {
  6866. BX_TRACE("Create command queue error: vkCreateCommandPool failed %d: %s.", result, getName(result) );
  6867. return result;
  6868. }
  6869. cbai.commandPool = m_commandList[ii].m_commandPool;
  6870. result = vkAllocateCommandBuffers(
  6871. s_renderVK->m_device
  6872. , &cbai
  6873. , &m_commandList[ii].m_commandBuffer
  6874. );
  6875. if (VK_SUCCESS != result)
  6876. {
  6877. BX_TRACE("Create command queue error: vkAllocateCommandBuffers failed %d: %s.", result, getName(result) );
  6878. return result;
  6879. }
  6880. result = vkCreateFence(
  6881. s_renderVK->m_device
  6882. , &fci
  6883. , s_renderVK->m_allocatorCb
  6884. , &m_commandList[ii].m_fence
  6885. );
  6886. if (VK_SUCCESS != result)
  6887. {
  6888. BX_TRACE("Create command queue error: vkCreateFence failed %d: %s.", result, getName(result) );
  6889. return result;
  6890. }
  6891. }
  6892. return result;
  6893. }
  6894. void CommandQueueVK::shutdown()
  6895. {
  6896. kick(true);
  6897. finish(true);
  6898. for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii)
  6899. {
  6900. vkDestroy(m_commandList[ii].m_fence);
  6901. m_commandList[ii].m_commandBuffer = VK_NULL_HANDLE;
  6902. vkDestroy(m_commandList[ii].m_commandPool);
  6903. }
  6904. }
  6905. VkResult CommandQueueVK::alloc(VkCommandBuffer* _commandBuffer)
  6906. {
  6907. BGFX_PROFILER_SCOPE("CommandQueueVK::alloc", kColorResource);
  6908. VkResult result = VK_SUCCESS;
  6909. if (m_activeCommandBuffer == VK_NULL_HANDLE)
  6910. {
  6911. const VkDevice device = s_renderVK->m_device;
  6912. CommandList& commandList = m_commandList[m_currentFrameInFlight];
  6913. {
  6914. BGFX_PROFILER_SCOPE("vkWaitForFences", kColorFrame);
  6915. result = vkWaitForFences(device, 1, &commandList.m_fence, VK_TRUE, UINT64_MAX);
  6916. }
  6917. if (VK_SUCCESS != result)
  6918. {
  6919. BX_TRACE("Allocate command buffer error: vkWaitForFences failed %d: %s.", result, getName(result) );
  6920. return result;
  6921. }
  6922. result = vkResetCommandPool(device, commandList.m_commandPool, 0);
  6923. if (VK_SUCCESS != result)
  6924. {
  6925. BX_TRACE("Allocate command buffer error: vkResetCommandPool failed %d: %s.", result, getName(result) );
  6926. return result;
  6927. }
  6928. VkCommandBufferBeginInfo cbi;
  6929. cbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
  6930. cbi.pNext = NULL;
  6931. cbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
  6932. cbi.pInheritanceInfo = NULL;
  6933. result = vkBeginCommandBuffer(commandList.m_commandBuffer, &cbi);
  6934. if (VK_SUCCESS != result)
  6935. {
  6936. BX_TRACE("Allocate command buffer error: vkBeginCommandBuffer failed %d: %s.", result, getName(result) );
  6937. return result;
  6938. }
  6939. m_activeCommandBuffer = commandList.m_commandBuffer;
  6940. m_currentFence = commandList.m_fence;
  6941. }
  6942. if (NULL != _commandBuffer)
  6943. {
  6944. *_commandBuffer = m_activeCommandBuffer;
  6945. }
  6946. return result;
  6947. }
  6948. void CommandQueueVK::addWaitSemaphore(VkSemaphore _semaphore, VkPipelineStageFlags _waitFlags)
  6949. {
  6950. BX_ASSERT(m_numWaitSemaphores < BX_COUNTOF(m_waitSemaphores), "Too many wait semaphores.");
  6951. m_waitSemaphores[m_numWaitSemaphores] = _semaphore;
  6952. m_waitSemaphoreStages[m_numWaitSemaphores] = _waitFlags;
  6953. m_numWaitSemaphores++;
  6954. }
  6955. void CommandQueueVK::addSignalSemaphore(VkSemaphore _semaphore)
  6956. {
  6957. BX_ASSERT(m_numSignalSemaphores < BX_COUNTOF(m_signalSemaphores), "Too many signal semaphores.");
  6958. m_signalSemaphores[m_numSignalSemaphores] = _semaphore;
  6959. m_numSignalSemaphores++;
  6960. }
  6961. void CommandQueueVK::kick(bool _wait)
  6962. {
  6963. BGFX_PROFILER_SCOPE("CommandQueueVK::kick", kColorDraw);
  6964. if (VK_NULL_HANDLE != m_activeCommandBuffer)
  6965. {
  6966. const VkDevice device = s_renderVK->m_device;
  6967. setMemoryBarrier(
  6968. m_activeCommandBuffer
  6969. , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
  6970. , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
  6971. );
  6972. VK_CHECK(vkEndCommandBuffer(m_activeCommandBuffer) );
  6973. m_completedFence = m_currentFence;
  6974. m_currentFence = VK_NULL_HANDLE;
  6975. VK_CHECK(vkResetFences(device, 1, &m_completedFence) );
  6976. VkSubmitInfo si;
  6977. si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  6978. si.pNext = NULL;
  6979. si.waitSemaphoreCount = m_numWaitSemaphores;
  6980. si.pWaitSemaphores = &m_waitSemaphores[0];
  6981. si.pWaitDstStageMask = m_waitSemaphoreStages;
  6982. si.commandBufferCount = 1;
  6983. si.pCommandBuffers = &m_activeCommandBuffer;
  6984. si.signalSemaphoreCount = m_numSignalSemaphores;
  6985. si.pSignalSemaphores = &m_signalSemaphores[0];
  6986. m_numWaitSemaphores = 0;
  6987. m_numSignalSemaphores = 0;
  6988. {
  6989. BGFX_PROFILER_SCOPE("CommandQueueVK::kick vkQueueSubmit", kColorDraw);
  6990. VK_CHECK(vkQueueSubmit(m_queue, 1, &si, m_completedFence) );
  6991. }
  6992. if (_wait)
  6993. {
  6994. BGFX_PROFILER_SCOPE("CommandQueue::kick vkWaitForFences", kColorDraw);
  6995. VK_CHECK(vkWaitForFences(device, 1, &m_completedFence, VK_TRUE, UINT64_MAX) );
  6996. }
  6997. m_activeCommandBuffer = VK_NULL_HANDLE;
  6998. m_currentFrameInFlight = (m_currentFrameInFlight + 1) % m_numFramesInFlight;
  6999. m_submitted++;
  7000. }
  7001. }
  7002. void CommandQueueVK::finish(bool _finishAll)
  7003. {
  7004. BGFX_PROFILER_SCOPE("CommandQueueVK::finish", kColorDraw);
  7005. if (_finishAll)
  7006. {
  7007. for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii)
  7008. {
  7009. consume();
  7010. }
  7011. m_consumeIndex = m_currentFrameInFlight;
  7012. }
  7013. else
  7014. {
  7015. consume();
  7016. }
  7017. }
  7018. void CommandQueueVK::release(uint64_t _handle, VkObjectType _type)
  7019. {
  7020. Resource resource;
  7021. resource.m_type = _type;
  7022. resource.m_handle = _handle;
  7023. m_release[m_currentFrameInFlight].push_back(resource);
  7024. }
  7025. void CommandQueueVK::recycleMemory(DeviceMemoryAllocationVK _mem)
  7026. {
  7027. m_recycleAllocs[m_currentFrameInFlight].push_back(_mem);
  7028. }
  7029. void CommandQueueVK::consume()
  7030. {
  7031. BGFX_PROFILER_SCOPE("CommandQueueVK::consume", kColorResource);
  7032. m_consumeIndex = (m_consumeIndex + 1) % m_numFramesInFlight;
  7033. for (DeviceMemoryAllocationVK &alloc : m_recycleAllocs[m_consumeIndex])
  7034. {
  7035. s_renderVK->m_memoryLru.recycle(alloc);
  7036. }
  7037. m_recycleAllocs[m_consumeIndex].clear();
  7038. for (const Resource& resource : m_release[m_consumeIndex])
  7039. {
  7040. switch (resource.m_type)
  7041. {
  7042. case VK_OBJECT_TYPE_BUFFER: destroy<VkBuffer >(resource.m_handle); break;
  7043. case VK_OBJECT_TYPE_IMAGE_VIEW: destroy<VkImageView >(resource.m_handle); break;
  7044. case VK_OBJECT_TYPE_IMAGE: destroy<VkImage >(resource.m_handle); break;
  7045. case VK_OBJECT_TYPE_FRAMEBUFFER: destroy<VkFramebuffer >(resource.m_handle); break;
  7046. case VK_OBJECT_TYPE_PIPELINE_LAYOUT: destroy<VkPipelineLayout >(resource.m_handle); break;
  7047. case VK_OBJECT_TYPE_PIPELINE: destroy<VkPipeline >(resource.m_handle); break;
  7048. case VK_OBJECT_TYPE_DESCRIPTOR_SET: destroy<VkDescriptorSet >(resource.m_handle); break;
  7049. case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT: destroy<VkDescriptorSetLayout>(resource.m_handle); break;
  7050. case VK_OBJECT_TYPE_RENDER_PASS: destroy<VkRenderPass >(resource.m_handle); break;
  7051. case VK_OBJECT_TYPE_SAMPLER: destroy<VkSampler >(resource.m_handle); break;
  7052. case VK_OBJECT_TYPE_SEMAPHORE: destroy<VkSemaphore >(resource.m_handle); break;
  7053. case VK_OBJECT_TYPE_SURFACE_KHR: destroy<VkSurfaceKHR >(resource.m_handle); break;
  7054. case VK_OBJECT_TYPE_SWAPCHAIN_KHR: destroy<VkSwapchainKHR >(resource.m_handle); break;
  7055. case VK_OBJECT_TYPE_DEVICE_MEMORY: destroy<VkDeviceMemory >(resource.m_handle); break;
  7056. default:
  7057. BX_ASSERT(false, "Invalid resource type: %d", resource.m_type);
  7058. break;
  7059. }
  7060. }
  7061. m_release[m_consumeIndex].clear();
  7062. }
  7063. void RendererContextVK::submitBlit(BlitState& _bs, uint16_t _view)
  7064. {
  7065. BGFX_PROFILER_SCOPE("RendererContextVK::submitBlit", kColorFrame);
  7066. VkImageLayout srcLayouts[BGFX_CONFIG_MAX_BLIT_ITEMS];
  7067. VkImageLayout dstLayouts[BGFX_CONFIG_MAX_BLIT_ITEMS];
  7068. BlitState bs0 = _bs;
  7069. while (bs0.hasItem(_view) )
  7070. {
  7071. uint16_t item = bs0.m_item;
  7072. const BlitItem& blit = bs0.advance();
  7073. TextureVK& src = m_textures[blit.m_src.idx];
  7074. TextureVK& dst = m_textures[blit.m_dst.idx];
  7075. srcLayouts[item] = VK_NULL_HANDLE != src.m_singleMsaaImage ? src.m_currentSingleMsaaImageLayout : src.m_currentImageLayout;
  7076. dstLayouts[item] = dst.m_currentImageLayout;
  7077. }
  7078. bs0 = _bs;
  7079. while (bs0.hasItem(_view) )
  7080. {
  7081. const BlitItem& blit = bs0.advance();
  7082. TextureVK& src = m_textures[blit.m_src.idx];
  7083. TextureVK& dst = m_textures[blit.m_dst.idx];
  7084. src.setImageMemoryBarrier(
  7085. m_commandBuffer
  7086. , blit.m_src.idx == blit.m_dst.idx ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
  7087. , VK_NULL_HANDLE != src.m_singleMsaaImage
  7088. );
  7089. if (blit.m_src.idx != blit.m_dst.idx)
  7090. {
  7091. dst.setImageMemoryBarrier(m_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
  7092. }
  7093. const uint16_t srcSamples = VK_NULL_HANDLE != src.m_singleMsaaImage ? 1 : src.m_sampler.Count;
  7094. const uint16_t dstSamples = dst.m_sampler.Count;
  7095. BX_UNUSED(srcSamples, dstSamples);
  7096. BX_ASSERT(
  7097. srcSamples == dstSamples
  7098. , "Mismatching texture sample count (%d != %d)."
  7099. , srcSamples
  7100. , dstSamples
  7101. );
  7102. VkImageCopy copyInfo;
  7103. copyInfo.srcSubresource.aspectMask = src.m_aspectMask;
  7104. copyInfo.srcSubresource.mipLevel = blit.m_srcMip;
  7105. copyInfo.srcSubresource.baseArrayLayer = 0;
  7106. copyInfo.srcSubresource.layerCount = 1;
  7107. copyInfo.srcOffset.x = blit.m_srcX;
  7108. copyInfo.srcOffset.y = blit.m_srcY;
  7109. copyInfo.srcOffset.z = 0;
  7110. copyInfo.dstSubresource.aspectMask = dst.m_aspectMask;
  7111. copyInfo.dstSubresource.mipLevel = blit.m_dstMip;
  7112. copyInfo.dstSubresource.baseArrayLayer = 0;
  7113. copyInfo.dstSubresource.layerCount = 1;
  7114. copyInfo.dstOffset.x = blit.m_dstX;
  7115. copyInfo.dstOffset.y = blit.m_dstY;
  7116. copyInfo.dstOffset.z = 0;
  7117. copyInfo.extent.width = blit.m_width;
  7118. copyInfo.extent.height = blit.m_height;
  7119. copyInfo.extent.depth = 1;
  7120. const uint32_t depth = bx::max<uint32_t>(1, blit.m_depth);
  7121. if (VK_IMAGE_VIEW_TYPE_3D == src.m_type)
  7122. {
  7123. BX_ASSERT(VK_IMAGE_VIEW_TYPE_3D == dst.m_type, "Can't blit between 2D and 3D image.");
  7124. copyInfo.srcOffset.z = blit.m_srcZ;
  7125. copyInfo.dstOffset.z = blit.m_dstZ;
  7126. copyInfo.extent.depth = depth;
  7127. }
  7128. else
  7129. {
  7130. copyInfo.srcSubresource.baseArrayLayer = blit.m_srcZ;
  7131. copyInfo.dstSubresource.baseArrayLayer = blit.m_dstZ;
  7132. copyInfo.srcSubresource.layerCount = depth;
  7133. copyInfo.dstSubresource.layerCount = depth;
  7134. }
  7135. vkCmdCopyImage(
  7136. m_commandBuffer
  7137. , VK_NULL_HANDLE != src.m_singleMsaaImage ? src.m_singleMsaaImage : src.m_textureImage
  7138. , VK_NULL_HANDLE != src.m_singleMsaaImage ? src.m_currentSingleMsaaImageLayout : src.m_currentImageLayout
  7139. , dst.m_textureImage
  7140. , dst.m_currentImageLayout
  7141. , 1
  7142. , &copyInfo
  7143. );
  7144. setMemoryBarrier(
  7145. m_commandBuffer
  7146. , VK_PIPELINE_STAGE_TRANSFER_BIT
  7147. , VK_PIPELINE_STAGE_TRANSFER_BIT
  7148. );
  7149. }
  7150. while (_bs.hasItem(_view) )
  7151. {
  7152. uint16_t item = _bs.m_item;
  7153. const BlitItem& blit = _bs.advance();
  7154. TextureVK& src = m_textures[blit.m_src.idx];
  7155. TextureVK& dst = m_textures[blit.m_dst.idx];
  7156. src.setImageMemoryBarrier(m_commandBuffer, srcLayouts[item], VK_NULL_HANDLE != src.m_singleMsaaImage);
  7157. dst.setImageMemoryBarrier(m_commandBuffer, dstLayouts[item]);
  7158. }
  7159. }
  7160. void RendererContextVK::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
  7161. {
  7162. BX_UNUSED(_clearQuad);
  7163. if (updateResolution(_render->m_resolution) )
  7164. {
  7165. return;
  7166. }
  7167. if (_render->m_capture)
  7168. {
  7169. renderDocTriggerCapture();
  7170. }
  7171. BGFX_VK_PROFILER_BEGIN_LITERAL("rendererSubmit", kColorView);
  7172. int64_t timeBegin = bx::getHPCounter();
  7173. int64_t captureElapsed = 0;
  7174. uint32_t frameQueryIdx = UINT32_MAX;
  7175. if (m_timerQuerySupport)
  7176. {
  7177. frameQueryIdx = m_gpuTimer.begin(BGFX_CONFIG_MAX_VIEWS, _render->m_frameNum);
  7178. }
  7179. if (0 < _render->m_iboffset)
  7180. {
  7181. BGFX_PROFILER_SCOPE("bgfx/Update transient index buffer", kColorResource);
  7182. TransientIndexBuffer* ib = _render->m_transientIb;
  7183. m_indexBuffers[ib->handle.idx].update(m_commandBuffer, 0, _render->m_iboffset, ib->data);
  7184. }
  7185. if (0 < _render->m_vboffset)
  7186. {
  7187. BGFX_PROFILER_SCOPE("bgfx/Update transient vertex buffer", kColorResource);
  7188. TransientVertexBuffer* vb = _render->m_transientVb;
  7189. m_vertexBuffers[vb->handle.idx].update(m_commandBuffer, 0, _render->m_vboffset, vb->data);
  7190. }
  7191. _render->sort();
  7192. RenderDraw currentState;
  7193. currentState.clear();
  7194. currentState.m_stateFlags = BGFX_STATE_NONE;
  7195. currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
  7196. static ViewState viewState;
  7197. viewState.reset(_render);
  7198. bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);
  7199. setDebugWireframe(wireframe);
  7200. ProgramHandle currentProgram = BGFX_INVALID_HANDLE;
  7201. bool hasPredefined = false;
  7202. VkPipeline currentPipeline = VK_NULL_HANDLE;
  7203. VkDescriptorSet currentDescriptorSet = VK_NULL_HANDLE;
  7204. uint32_t currentBindHash = 0;
  7205. uint32_t descriptorSetCount = 0;
  7206. VkIndexType currentIndexFormat = VK_INDEX_TYPE_MAX_ENUM;
  7207. SortKey key;
  7208. uint16_t view = UINT16_MAX;
  7209. FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };
  7210. BlitState bs(_render);
  7211. uint64_t blendFactor = UINT64_MAX;
  7212. bool wasCompute = false;
  7213. bool viewHasScissor = false;
  7214. bool restoreScissor = false;
  7215. Rect viewScissorRect;
  7216. viewScissorRect.clear();
  7217. bool isFrameBufferValid = false;
  7218. uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {};
  7219. uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {};
  7220. uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {};
  7221. uint32_t statsNumIndices = 0;
  7222. uint32_t statsKeyType[2] = {};
  7223. const uint64_t f0 = BGFX_STATE_BLEND_FACTOR;
  7224. const uint64_t f1 = BGFX_STATE_BLEND_INV_FACTOR;
  7225. const uint64_t f2 = BGFX_STATE_BLEND_FACTOR<<4;
  7226. const uint64_t f3 = BGFX_STATE_BLEND_INV_FACTOR<<4;
  7227. ScratchBufferVK& scratchBuffer = m_scratchBuffer[m_cmd.m_currentFrameInFlight];
  7228. ScratchBufferVK& scratchStagingBuffer = m_scratchStagingBuffer[m_cmd.m_currentFrameInFlight];
  7229. setMemoryBarrier(
  7230. m_commandBuffer
  7231. , VK_PIPELINE_STAGE_TRANSFER_BIT
  7232. , VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
  7233. );
  7234. VkRenderPassBeginInfo rpbi;
  7235. rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
  7236. rpbi.pNext = NULL;
  7237. rpbi.clearValueCount = 0;
  7238. rpbi.pClearValues = NULL;
  7239. bool beginRenderPass = false;
  7240. Profiler<TimerQueryVK> profiler(
  7241. _render
  7242. , m_gpuTimer
  7243. , s_viewName
  7244. , m_timerQuerySupport
  7245. );
  7246. m_occlusionQuery.flush(_render);
  7247. if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
  7248. {
  7249. viewState.m_rect = _render->m_view[0].m_rect;
  7250. int32_t numItems = _render->m_numRenderItems;
  7251. for (int32_t item = 0; item < numItems;)
  7252. {
  7253. const uint64_t encodedKey = _render->m_sortKeys[item];
  7254. const bool isCompute = key.decode(encodedKey, _render->m_viewRemap);
  7255. statsKeyType[isCompute]++;
  7256. const bool viewChanged = 0
  7257. || key.m_view != view
  7258. || item == numItems
  7259. ;
  7260. const uint32_t itemIdx = _render->m_sortValues[item];
  7261. const RenderItem& renderItem = _render->m_renderItem[itemIdx];
  7262. const RenderBind& renderBind = _render->m_renderItemBind[itemIdx];
  7263. ++item;
  7264. if (viewChanged)
  7265. {
  7266. if (beginRenderPass)
  7267. {
  7268. vkCmdEndRenderPass(m_commandBuffer);
  7269. beginRenderPass = false;
  7270. }
  7271. view = key.m_view;
  7272. currentProgram = BGFX_INVALID_HANDLE;
  7273. hasPredefined = false;
  7274. if (item > 1)
  7275. {
  7276. profiler.end();
  7277. }
  7278. BGFX_VK_PROFILER_END();
  7279. setViewType(view, " ");
  7280. BGFX_VK_PROFILER_BEGIN(view, kColorView);
  7281. profiler.begin(view);
  7282. if (_render->m_view[view].m_fbh.idx != fbh.idx)
  7283. {
  7284. fbh = _render->m_view[view].m_fbh;
  7285. setFrameBuffer(fbh);
  7286. }
  7287. const FrameBufferVK& fb = isValid(m_fbh)
  7288. ? m_frameBuffers[m_fbh.idx]
  7289. : m_backBuffer
  7290. ;
  7291. isFrameBufferValid = fb.isRenderable();
  7292. if (isFrameBufferValid)
  7293. {
  7294. viewState.m_rect = _render->m_view[view].m_rect;
  7295. Rect rect = _render->m_view[view].m_rect;
  7296. Rect scissorRect = _render->m_view[view].m_scissor;
  7297. viewHasScissor = !scissorRect.isZero();
  7298. viewScissorRect = viewHasScissor ? scissorRect : rect;
  7299. restoreScissor = false;
  7300. // Clamp the rect to what's valid according to Vulkan.
  7301. rect.m_width = bx::min(rect.m_width, bx::narrowCast<uint16_t>(fb.m_width) - rect.m_x);
  7302. rect.m_height = bx::min(rect.m_height, bx::narrowCast<uint16_t>(fb.m_height) - rect.m_y);
  7303. if (_render->m_view[view].m_rect.m_width != rect.m_width
  7304. || _render->m_view[view].m_rect.m_height != rect.m_height)
  7305. {
  7306. BX_TRACE("Clamp render pass from %dx%d to %dx%d"
  7307. , _render->m_view[view].m_rect.m_width
  7308. , _render->m_view[view].m_rect.m_height
  7309. , rect.m_width
  7310. , rect.m_height
  7311. );
  7312. }
  7313. rpbi.framebuffer = fb.m_currentFramebuffer;
  7314. rpbi.renderPass = fb.m_renderPass;
  7315. rpbi.renderArea.offset.x = rect.m_x;
  7316. rpbi.renderArea.offset.y = rect.m_y;
  7317. rpbi.renderArea.extent.width = rect.m_width;
  7318. rpbi.renderArea.extent.height = rect.m_height;
  7319. VkViewport vp;
  7320. vp.x = float(rect.m_x);
  7321. vp.y = float(rect.m_y + rect.m_height);
  7322. vp.width = float(rect.m_width);
  7323. vp.height = -float(rect.m_height);
  7324. vp.minDepth = 0.0f;
  7325. vp.maxDepth = 1.0f;
  7326. vkCmdSetViewport(m_commandBuffer, 0, 1, &vp);
  7327. VkRect2D rc;
  7328. rc.offset.x = viewScissorRect.m_x;
  7329. rc.offset.y = viewScissorRect.m_y;
  7330. rc.extent.width = viewScissorRect.m_width;
  7331. rc.extent.height = viewScissorRect.m_height;
  7332. vkCmdSetScissor(m_commandBuffer, 0, 1, &rc);
  7333. const Clear& clr = _render->m_view[view].m_clear;
  7334. if (BGFX_CLEAR_NONE != clr.m_flags)
  7335. {
  7336. vkCmdBeginRenderPass(m_commandBuffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
  7337. Rect clearRect = rect;
  7338. clearRect.setIntersect(rect, viewScissorRect);
  7339. clearQuad(clearRect, clr, _render->m_colorPalette);
  7340. vkCmdEndRenderPass(m_commandBuffer);
  7341. }
  7342. submitBlit(bs, view);
  7343. }
  7344. }
  7345. if (isCompute)
  7346. {
  7347. if (!wasCompute)
  7348. {
  7349. wasCompute = true;
  7350. currentBindHash = 0;
  7351. BGFX_VK_PROFILER_END();
  7352. setViewType(view, "C");
  7353. BGFX_VK_PROFILER_BEGIN(view, kColorCompute);
  7354. }
  7355. // renderpass external subpass dependencies handle graphics -> compute and compute -> graphics
  7356. // but not compute -> compute (possibly also across views if they contain no draw calls)
  7357. setMemoryBarrier(
  7358. m_commandBuffer
  7359. , VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
  7360. , VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
  7361. );
  7362. const RenderCompute& compute = renderItem.compute;
  7363. const VkPipeline pipeline = getPipeline(key.m_program);
  7364. if (currentPipeline != pipeline)
  7365. {
  7366. currentPipeline = pipeline;
  7367. vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
  7368. }
  7369. bool constantsChanged = false;
  7370. if (compute.m_uniformBegin < compute.m_uniformEnd
  7371. || currentProgram.idx != key.m_program.idx)
  7372. {
  7373. rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd);
  7374. currentProgram = key.m_program;
  7375. ProgramVK& program = m_program[currentProgram.idx];
  7376. UniformBuffer* vcb = program.m_vsh->m_constantBuffer;
  7377. if (NULL != vcb)
  7378. {
  7379. commit(*vcb);
  7380. }
  7381. hasPredefined = 0 < program.m_numPredefined;
  7382. constantsChanged = true;
  7383. }
  7384. const ProgramVK& program = m_program[currentProgram.idx];
  7385. if (constantsChanged
  7386. || hasPredefined)
  7387. {
  7388. viewState.setPredefined<4>(this, view, program, _render, compute);
  7389. }
  7390. if (VK_NULL_HANDLE != program.m_descriptorSetLayout)
  7391. {
  7392. const uint32_t vsize = program.m_vsh->m_size;
  7393. uint32_t numOffset = 0;
  7394. uint32_t offset = 0;
  7395. if (constantsChanged
  7396. || hasPredefined)
  7397. {
  7398. if (vsize > 0)
  7399. {
  7400. offset = scratchBuffer.write(m_vsScratch, vsize);
  7401. ++numOffset;
  7402. }
  7403. }
  7404. bx::HashMurmur2A hash;
  7405. hash.begin();
  7406. hash.add(program.m_descriptorSetLayout);
  7407. hash.add(renderBind.m_bind, sizeof(renderBind.m_bind) );
  7408. hash.add(vsize);
  7409. hash.add(0);
  7410. const uint32_t bindHash = hash.end();
  7411. if (currentBindHash != bindHash)
  7412. {
  7413. currentBindHash = bindHash;
  7414. currentDescriptorSet = getDescriptorSet(
  7415. program
  7416. , renderBind
  7417. , scratchBuffer
  7418. , _render->m_colorPalette
  7419. );
  7420. descriptorSetCount++;
  7421. }
  7422. vkCmdBindDescriptorSets(
  7423. m_commandBuffer
  7424. , VK_PIPELINE_BIND_POINT_COMPUTE
  7425. , program.m_pipelineLayout
  7426. , 0
  7427. , 1
  7428. , &currentDescriptorSet
  7429. , numOffset
  7430. , &offset
  7431. );
  7432. }
  7433. if (isValid(compute.m_indirectBuffer) )
  7434. {
  7435. const VertexBufferVK& vb = m_vertexBuffers[compute.m_indirectBuffer.idx];
  7436. uint32_t numDrawIndirect = UINT32_MAX == compute.m_numIndirect
  7437. ? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  7438. : compute.m_numIndirect
  7439. ;
  7440. uint32_t args = compute.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
  7441. for (uint32_t ii = 0; ii < numDrawIndirect; ++ii)
  7442. {
  7443. vkCmdDispatchIndirect(m_commandBuffer, vb.m_buffer, args);
  7444. args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
  7445. }
  7446. }
  7447. else
  7448. {
  7449. vkCmdDispatch(m_commandBuffer, compute.m_numX, compute.m_numY, compute.m_numZ);
  7450. }
  7451. continue;
  7452. }
  7453. const RenderDraw& draw = renderItem.draw;
  7454. rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd);
  7455. const bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY);
  7456. {
  7457. const bool occluded = true
  7458. && isValid(draw.m_occlusionQuery)
  7459. && !hasOcclusionQuery
  7460. && !isVisible(_render, draw.m_occlusionQuery, 0 != (draw.m_submitFlags & BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) )
  7461. ;
  7462. if (occluded
  7463. || !isFrameBufferValid
  7464. || 0 == draw.m_streamMask
  7465. || _render->m_frameCache.isZeroArea(viewScissorRect, draw.m_scissor) )
  7466. {
  7467. continue;
  7468. }
  7469. }
  7470. const uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags;
  7471. currentState.m_stateFlags = draw.m_stateFlags;
  7472. if (!beginRenderPass)
  7473. {
  7474. if (wasCompute)
  7475. {
  7476. wasCompute = false;
  7477. currentBindHash = 0;
  7478. }
  7479. BGFX_VK_PROFILER_END();
  7480. setViewType(view, " ");
  7481. BGFX_VK_PROFILER_BEGIN(view, kColorDraw);
  7482. vkCmdBeginRenderPass(m_commandBuffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
  7483. beginRenderPass = true;
  7484. currentProgram = BGFX_INVALID_HANDLE;
  7485. currentState.m_scissor = !draw.m_scissor;
  7486. }
  7487. if (0 != draw.m_streamMask)
  7488. {
  7489. const bool bindAttribs = hasVertexStreamChanged(currentState, draw);
  7490. currentState.m_streamMask = draw.m_streamMask;
  7491. currentState.m_instanceDataBuffer = draw.m_instanceDataBuffer;
  7492. currentState.m_instanceDataOffset = draw.m_instanceDataOffset;
  7493. currentState.m_instanceDataStride = draw.m_instanceDataStride;
  7494. const VertexLayout* layouts[BGFX_CONFIG_MAX_VERTEX_STREAMS];
  7495. VkBuffer streamBuffers[BGFX_CONFIG_MAX_VERTEX_STREAMS + 1];
  7496. VkDeviceSize streamOffsets[BGFX_CONFIG_MAX_VERTEX_STREAMS + 1];
  7497. uint8_t numStreams = 0;
  7498. uint32_t numVertices = draw.m_numVertices;
  7499. if (UINT8_MAX != draw.m_streamMask)
  7500. {
  7501. for (uint32_t idx = 0, streamMask = draw.m_streamMask
  7502. ; 0 != streamMask
  7503. ; streamMask >>= 1, idx += 1, ++numStreams
  7504. )
  7505. {
  7506. const uint32_t ntz = bx::uint32_cnttz(streamMask);
  7507. streamMask >>= ntz;
  7508. idx += ntz;
  7509. currentState.m_stream[idx] = draw.m_stream[idx];
  7510. const VertexBufferHandle handle = draw.m_stream[idx].m_handle;
  7511. const VertexBufferVK& vb = m_vertexBuffers[handle.idx];
  7512. const uint16_t decl = isValid(draw.m_stream[idx].m_layoutHandle)
  7513. ? draw.m_stream[idx].m_layoutHandle.idx
  7514. : vb.m_layoutHandle.idx
  7515. ;
  7516. const VertexLayout& layout = m_vertexLayouts[decl];
  7517. const uint32_t stride = layout.m_stride;
  7518. streamBuffers[numStreams] = m_vertexBuffers[handle.idx].m_buffer;
  7519. streamOffsets[numStreams] = draw.m_stream[idx].m_startVertex * stride;
  7520. layouts[numStreams] = &layout;
  7521. numVertices = bx::uint32_min(UINT32_MAX == draw.m_numVertices
  7522. ? vb.m_size/stride
  7523. : draw.m_numVertices
  7524. , numVertices
  7525. );
  7526. }
  7527. }
  7528. if (bindAttribs)
  7529. {
  7530. uint32_t numVertexBuffers = numStreams;
  7531. if (isValid(draw.m_instanceDataBuffer) )
  7532. {
  7533. streamOffsets[numVertexBuffers] = draw.m_instanceDataOffset;
  7534. streamBuffers[numVertexBuffers] = m_vertexBuffers[draw.m_instanceDataBuffer.idx].m_buffer;
  7535. numVertexBuffers++;
  7536. }
  7537. if (0 < numVertexBuffers)
  7538. {
  7539. vkCmdBindVertexBuffers(
  7540. m_commandBuffer
  7541. , 0
  7542. , numVertexBuffers
  7543. , &streamBuffers[0]
  7544. , streamOffsets
  7545. );
  7546. }
  7547. }
  7548. const VkPipeline pipeline =
  7549. getPipeline(draw.m_stateFlags
  7550. , draw.m_stencil
  7551. , numStreams
  7552. , layouts
  7553. , key.m_program
  7554. , uint8_t(draw.m_instanceDataStride/16)
  7555. );
  7556. if (currentPipeline != pipeline)
  7557. {
  7558. currentPipeline = pipeline;
  7559. vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
  7560. }
  7561. const bool hasStencil = 0 != draw.m_stencil;
  7562. if (hasStencil
  7563. && currentState.m_stencil != draw.m_stencil)
  7564. {
  7565. currentState.m_stencil = draw.m_stencil;
  7566. const uint32_t fstencil = unpackStencil(0, draw.m_stencil);
  7567. const uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
  7568. vkCmdSetStencilReference(m_commandBuffer, VK_STENCIL_FRONT_AND_BACK, ref);
  7569. }
  7570. const bool hasFactor = 0
  7571. || f0 == (draw.m_stateFlags & f0)
  7572. || f1 == (draw.m_stateFlags & f1)
  7573. || f2 == (draw.m_stateFlags & f2)
  7574. || f3 == (draw.m_stateFlags & f3)
  7575. ;
  7576. if (hasFactor
  7577. && blendFactor != draw.m_rgba)
  7578. {
  7579. blendFactor = draw.m_rgba;
  7580. float bf[4];
  7581. bf[0] = ( (draw.m_rgba>>24) )/255.0f;
  7582. bf[1] = ( (draw.m_rgba>>16)&0xff)/255.0f;
  7583. bf[2] = ( (draw.m_rgba>> 8)&0xff)/255.0f;
  7584. bf[3] = ( (draw.m_rgba )&0xff)/255.0f;
  7585. vkCmdSetBlendConstants(m_commandBuffer, bf);
  7586. }
  7587. const uint16_t scissor = draw.m_scissor;
  7588. if (currentState.m_scissor != scissor)
  7589. {
  7590. currentState.m_scissor = scissor;
  7591. if (UINT16_MAX == scissor)
  7592. {
  7593. if (restoreScissor
  7594. || viewHasScissor)
  7595. {
  7596. restoreScissor = false;
  7597. VkRect2D rc;
  7598. rc.offset.x = viewScissorRect.m_x;
  7599. rc.offset.y = viewScissorRect.m_y;
  7600. rc.extent.width = viewScissorRect.m_width;
  7601. rc.extent.height = viewScissorRect.m_height;
  7602. vkCmdSetScissor(m_commandBuffer, 0, 1, &rc);
  7603. }
  7604. }
  7605. else
  7606. {
  7607. restoreScissor = true;
  7608. Rect scissorRect;
  7609. scissorRect.setIntersect(viewScissorRect, _render->m_frameCache.m_rectCache.m_cache[scissor]);
  7610. VkRect2D rc;
  7611. rc.offset.x = scissorRect.m_x;
  7612. rc.offset.y = scissorRect.m_y;
  7613. rc.extent.width = scissorRect.m_width;
  7614. rc.extent.height = scissorRect.m_height;
  7615. vkCmdSetScissor(m_commandBuffer, 0, 1, &rc);
  7616. }
  7617. }
  7618. bool constantsChanged = false;
  7619. if (draw.m_uniformBegin < draw.m_uniformEnd
  7620. || currentProgram.idx != key.m_program.idx
  7621. || BGFX_STATE_ALPHA_REF_MASK & changedFlags)
  7622. {
  7623. currentProgram = key.m_program;
  7624. ProgramVK& program = m_program[currentProgram.idx];
  7625. UniformBuffer* vcb = program.m_vsh->m_constantBuffer;
  7626. if (NULL != vcb)
  7627. {
  7628. commit(*vcb);
  7629. }
  7630. if (NULL != program.m_fsh)
  7631. {
  7632. UniformBuffer* fcb = program.m_fsh->m_constantBuffer;
  7633. if (NULL != fcb)
  7634. {
  7635. commit(*fcb);
  7636. }
  7637. }
  7638. hasPredefined = 0 < program.m_numPredefined;
  7639. constantsChanged = true;
  7640. }
  7641. const ProgramVK& program = m_program[currentProgram.idx];
  7642. if (hasPredefined)
  7643. {
  7644. uint32_t ref = (draw.m_stateFlags & BGFX_STATE_ALPHA_REF_MASK) >> BGFX_STATE_ALPHA_REF_SHIFT;
  7645. viewState.m_alphaRef = ref / 255.0f;
  7646. viewState.setPredefined<4>(this, view, program, _render, draw);
  7647. }
  7648. if (VK_NULL_HANDLE != program.m_descriptorSetLayout)
  7649. {
  7650. const uint32_t vsize = program.m_vsh->m_size;
  7651. const uint32_t fsize = NULL != program.m_fsh ? program.m_fsh->m_size : 0;
  7652. uint32_t numOffset = 0;
  7653. uint32_t offsets[2] = { 0, 0 };
  7654. if (constantsChanged
  7655. || hasPredefined)
  7656. {
  7657. if (vsize > 0)
  7658. {
  7659. offsets[numOffset++] = scratchBuffer.write(m_vsScratch, vsize);
  7660. }
  7661. if (fsize > 0)
  7662. {
  7663. offsets[numOffset++] = scratchBuffer.write(m_fsScratch, fsize);
  7664. }
  7665. }
  7666. bx::HashMurmur2A hash;
  7667. hash.begin();
  7668. hash.add(program.m_descriptorSetLayout);
  7669. hash.add(renderBind.m_bind, sizeof(renderBind.m_bind) );
  7670. hash.add(vsize);
  7671. hash.add(fsize);
  7672. const uint32_t bindHash = hash.end();
  7673. if (currentBindHash != bindHash)
  7674. {
  7675. currentBindHash = bindHash;
  7676. currentDescriptorSet = getDescriptorSet(
  7677. program
  7678. , renderBind
  7679. , scratchBuffer
  7680. , _render->m_colorPalette
  7681. );
  7682. descriptorSetCount++;
  7683. }
  7684. vkCmdBindDescriptorSets(
  7685. m_commandBuffer
  7686. , VK_PIPELINE_BIND_POINT_GRAPHICS
  7687. , program.m_pipelineLayout
  7688. , 0
  7689. , 1
  7690. , &currentDescriptorSet
  7691. , numOffset
  7692. , offsets
  7693. );
  7694. }
  7695. VkBuffer bufferIndirect = VK_NULL_HANDLE;
  7696. VkBuffer bufferNumIndirect = VK_NULL_HANDLE;
  7697. uint32_t numDrawIndirect = 0;
  7698. uint32_t bufferOffsetIndirect = 0;
  7699. uint32_t bufferNumOffsetIndirect = 0;
  7700. if (isValid(draw.m_indirectBuffer) )
  7701. {
  7702. const VertexBufferVK& vb = m_vertexBuffers[draw.m_indirectBuffer.idx];
  7703. bufferIndirect = vb.m_buffer;
  7704. numDrawIndirect = UINT32_MAX == draw.m_numIndirect
  7705. ? vb.m_size / BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  7706. : draw.m_numIndirect
  7707. ;
  7708. bufferOffsetIndirect = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
  7709. if (isValid(draw.m_numIndirectBuffer) )
  7710. {
  7711. bufferNumIndirect = m_indexBuffers[draw.m_numIndirectBuffer.idx].m_buffer;
  7712. bufferNumOffsetIndirect = draw.m_numIndirectIndex * sizeof(uint32_t);
  7713. }
  7714. }
  7715. if (hasOcclusionQuery)
  7716. {
  7717. m_occlusionQuery.begin(draw.m_occlusionQuery);
  7718. }
  7719. const uint8_t primIndex = uint8_t((draw.m_stateFlags & BGFX_STATE_PT_MASK) >> BGFX_STATE_PT_SHIFT);
  7720. const PrimInfo& prim = s_primInfo[primIndex];
  7721. uint32_t numPrimsSubmitted = 0;
  7722. uint32_t numIndices = 0;
  7723. if (!isValid(draw.m_indexBuffer) )
  7724. {
  7725. numPrimsSubmitted = numVertices / prim.m_div - prim.m_sub;
  7726. if (isValid(draw.m_indirectBuffer) )
  7727. {
  7728. if (isValid(draw.m_numIndirectBuffer) )
  7729. {
  7730. vkCmdDrawIndirectCountKHR(
  7731. m_commandBuffer
  7732. , bufferIndirect
  7733. , bufferOffsetIndirect
  7734. , bufferNumIndirect
  7735. , bufferNumOffsetIndirect
  7736. , numDrawIndirect
  7737. , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  7738. );
  7739. }
  7740. else
  7741. {
  7742. vkCmdDrawIndirect(
  7743. m_commandBuffer
  7744. , bufferIndirect
  7745. , bufferOffsetIndirect
  7746. , numDrawIndirect
  7747. , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  7748. );
  7749. }
  7750. }
  7751. else
  7752. {
  7753. vkCmdDraw(
  7754. m_commandBuffer
  7755. , numVertices
  7756. , draw.m_numInstances
  7757. , 0
  7758. , 0
  7759. );
  7760. }
  7761. }
  7762. else
  7763. {
  7764. const bool isIndex16 = draw.isIndex16();
  7765. const uint32_t indexSize = isIndex16 ? 2 : 4;
  7766. const VkIndexType indexFormat = isIndex16 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32;
  7767. const BufferVK& ib = m_indexBuffers[draw.m_indexBuffer.idx];
  7768. numIndices = UINT32_MAX == draw.m_numIndices
  7769. ? ib.m_size / indexSize
  7770. : draw.m_numIndices
  7771. ;
  7772. numPrimsSubmitted = numIndices / prim.m_div - prim.m_sub;
  7773. if (currentState.m_indexBuffer.idx != draw.m_indexBuffer.idx
  7774. || currentIndexFormat != indexFormat)
  7775. {
  7776. currentState.m_indexBuffer = draw.m_indexBuffer;
  7777. currentIndexFormat = indexFormat;
  7778. vkCmdBindIndexBuffer(
  7779. m_commandBuffer
  7780. , m_indexBuffers[draw.m_indexBuffer.idx].m_buffer
  7781. , 0
  7782. , indexFormat
  7783. );
  7784. }
  7785. if (isValid(draw.m_indirectBuffer) )
  7786. {
  7787. if (isValid(draw.m_numIndirectBuffer) )
  7788. {
  7789. vkCmdDrawIndexedIndirectCountKHR(
  7790. m_commandBuffer
  7791. , bufferIndirect
  7792. , bufferOffsetIndirect
  7793. , bufferNumIndirect
  7794. , bufferNumOffsetIndirect
  7795. , numDrawIndirect
  7796. , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  7797. );
  7798. }
  7799. else
  7800. {
  7801. vkCmdDrawIndexedIndirect(
  7802. m_commandBuffer
  7803. , bufferIndirect
  7804. , bufferOffsetIndirect
  7805. , numDrawIndirect
  7806. , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
  7807. );
  7808. }
  7809. }
  7810. else
  7811. {
  7812. vkCmdDrawIndexed(
  7813. m_commandBuffer
  7814. , numIndices
  7815. , draw.m_numInstances
  7816. , draw.m_startIndex
  7817. , 0
  7818. , 0
  7819. );
  7820. }
  7821. }
  7822. uint32_t numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
  7823. statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
  7824. statsNumPrimsRendered[primIndex] += numPrimsRendered;
  7825. statsNumInstances[primIndex] += draw.m_numInstances;
  7826. statsNumIndices += numIndices;
  7827. if (hasOcclusionQuery)
  7828. {
  7829. m_occlusionQuery.end();
  7830. }
  7831. }
  7832. }
  7833. if (beginRenderPass)
  7834. {
  7835. vkCmdEndRenderPass(m_commandBuffer);
  7836. beginRenderPass = false;
  7837. }
  7838. if (wasCompute)
  7839. {
  7840. setViewType(view, "C");
  7841. BGFX_VK_PROFILER_END();
  7842. BGFX_VK_PROFILER_BEGIN(view, kColorCompute);
  7843. }
  7844. submitBlit(bs, BGFX_CONFIG_MAX_VIEWS);
  7845. if (0 < _render->m_numRenderItems)
  7846. {
  7847. captureElapsed = -bx::getHPCounter();
  7848. capture();
  7849. captureElapsed += bx::getHPCounter();
  7850. profiler.end();
  7851. }
  7852. }
  7853. BGFX_VK_PROFILER_END();
  7854. int64_t timeEnd = bx::getHPCounter();
  7855. int64_t frameTime = timeEnd - timeBegin;
  7856. static int64_t min = frameTime;
  7857. static int64_t max = frameTime;
  7858. min = bx::min<int64_t>(min, frameTime);
  7859. max = bx::max<int64_t>(max, frameTime);
  7860. static uint32_t maxGpuLatency = 0;
  7861. static double maxGpuElapsed = 0.0f;
  7862. double elapsedGpuMs = 0.0;
  7863. static int64_t presentMin = m_presentElapsed;
  7864. static int64_t presentMax = m_presentElapsed;
  7865. presentMin = bx::min<int64_t>(presentMin, m_presentElapsed);
  7866. presentMax = bx::max<int64_t>(presentMax, m_presentElapsed);
  7867. if (UINT32_MAX != frameQueryIdx)
  7868. {
  7869. m_gpuTimer.end(frameQueryIdx);
  7870. const TimerQueryVK::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS];
  7871. double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency);
  7872. elapsedGpuMs = (result.m_end - result.m_begin) * toGpuMs;
  7873. maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed;
  7874. maxGpuLatency = bx::uint32_imax(maxGpuLatency, result.m_pending-1);
  7875. }
  7876. maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1);
  7877. const int64_t timerFreq = bx::getHPFrequency();
  7878. VkPhysicalDeviceMemoryBudgetPropertiesEXT dmbp;
  7879. dmbp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
  7880. dmbp.pNext = NULL;
  7881. int64_t gpuMemoryAvailable = -INT64_MAX;
  7882. int64_t gpuMemoryUsed = -INT64_MAX;
  7883. if (s_extension[Extension::EXT_memory_budget].m_supported)
  7884. {
  7885. VkPhysicalDeviceMemoryProperties2 pdmp2;
  7886. pdmp2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
  7887. pdmp2.pNext = &dmbp;
  7888. vkGetPhysicalDeviceMemoryProperties2KHR(m_physicalDevice, &pdmp2);
  7889. gpuMemoryAvailable = 0;
  7890. gpuMemoryUsed = 0;
  7891. for (uint32_t ii = 0; ii < m_memoryProperties.memoryHeapCount; ++ii)
  7892. {
  7893. if (!!(m_memoryProperties.memoryHeaps[ii].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) )
  7894. {
  7895. gpuMemoryAvailable += dmbp.heapBudget[ii];
  7896. gpuMemoryUsed += dmbp.heapUsage[ii];
  7897. }
  7898. }
  7899. }
  7900. Stats& perfStats = _render->m_perfStats;
  7901. perfStats.cpuTimeBegin = timeBegin;
  7902. perfStats.cpuTimeEnd = timeEnd;
  7903. perfStats.cpuTimerFreq = timerFreq;
  7904. const TimerQueryVK::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS];
  7905. perfStats.gpuTimeBegin = result.m_begin;
  7906. perfStats.gpuTimeEnd = result.m_end;
  7907. perfStats.gpuTimerFreq = m_gpuTimer.m_frequency;
  7908. perfStats.numDraw = statsKeyType[0];
  7909. perfStats.numCompute = statsKeyType[1];
  7910. perfStats.numBlit = _render->m_numBlitItems;
  7911. perfStats.maxGpuLatency = maxGpuLatency;
  7912. perfStats.gpuFrameNum = result.m_frameNum;
  7913. bx::memCopy(perfStats.numPrims, statsNumPrimsRendered, sizeof(perfStats.numPrims) );
  7914. perfStats.gpuMemoryMax = gpuMemoryAvailable;
  7915. perfStats.gpuMemoryUsed = gpuMemoryUsed;
  7916. if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
  7917. {
  7918. BGFX_VK_PROFILER_BEGIN_LITERAL("debugstats", kColorFrame);
  7919. TextVideoMem& tvm = m_textVideoMem;
  7920. static int64_t next = timeEnd;
  7921. if (timeEnd >= next)
  7922. {
  7923. next = timeEnd + timerFreq;
  7924. double freq = double(timerFreq);
  7925. double toMs = 1000.0 / freq;
  7926. tvm.clear();
  7927. uint16_t pos = 0;
  7928. tvm.printf(0, pos++, BGFX_CONFIG_DEBUG ? 0x8c : 0x8f
  7929. , " %s / " BX_COMPILER_NAME
  7930. " / " BX_CPU_NAME
  7931. " / " BX_ARCH_NAME
  7932. " / " BX_PLATFORM_NAME
  7933. " / Version 1.%d.%d (commit: " BGFX_REV_SHA1 ")"
  7934. , getRendererName()
  7935. , BGFX_API_VERSION
  7936. , BGFX_REV_NUMBER
  7937. );
  7938. const VkPhysicalDeviceProperties& pdp = m_deviceProperties;
  7939. tvm.printf(0, pos++, 0x8f, " Device: %s (%s)"
  7940. , pdp.deviceName
  7941. , getName(pdp.deviceType)
  7942. );
  7943. if (0 <= gpuMemoryAvailable && 0 <= gpuMemoryUsed)
  7944. {
  7945. for (uint32_t ii = 0; ii < m_memoryProperties.memoryHeapCount; ++ii)
  7946. {
  7947. char budget[16];
  7948. bx::prettify(budget, BX_COUNTOF(budget), dmbp.heapBudget[ii]);
  7949. char usage[16];
  7950. bx::prettify(usage, BX_COUNTOF(usage), dmbp.heapUsage[ii]);
  7951. const bool local = (!!(m_memoryProperties.memoryHeaps[ii].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) );
  7952. tvm.printf(0, pos++, 0x8f, " Memory %d %s - Budget: %12s, Usage: %12s"
  7953. , ii
  7954. , local ? "(local) " : "(non-local)"
  7955. , budget
  7956. , usage
  7957. );
  7958. }
  7959. }
  7960. pos = 10;
  7961. tvm.printf(10, pos++, 0x8b, " Frame: % 7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS"
  7962. , double(frameTime)*toMs
  7963. , double(min)*toMs
  7964. , double(max)*toMs
  7965. , freq/frameTime
  7966. );
  7967. tvm.printf(10, pos++, 0x8b, " Present: % 7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] "
  7968. , double(m_presentElapsed)*toMs
  7969. , double(presentMin)*toMs
  7970. , double(presentMax)*toMs
  7971. );
  7972. const uint32_t msaa = (m_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT;
  7973. tvm.printf(10, pos++, 0x8b, " Reset flags: [%c] vsync, [%c] MSAAx%d, [%c] MaxAnisotropy "
  7974. , !!(m_resolution.reset&BGFX_RESET_VSYNC) ? '\xfe' : ' '
  7975. , 0 != msaa ? '\xfe' : ' '
  7976. , 1<<msaa
  7977. , !!(m_resolution.reset&BGFX_RESET_MAXANISOTROPY) ? '\xfe' : ' '
  7978. );
  7979. double elapsedCpuMs = double(frameTime)*toMs;
  7980. tvm.printf(10, pos++, 0x8b, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] %c GPU %7.4f [ms] (latency %d) "
  7981. , _render->m_numRenderItems
  7982. , statsKeyType[0]
  7983. , statsKeyType[1]
  7984. , elapsedCpuMs
  7985. , elapsedCpuMs > maxGpuElapsed ? '>' : '<'
  7986. , maxGpuElapsed
  7987. , maxGpuLatency
  7988. );
  7989. for (uint32_t ii = 0; ii < Topology::Count; ++ii)
  7990. {
  7991. tvm.printf(10, pos++, 0x8b, " %9s: %7d (#inst: %5d), submitted: %7d "
  7992. , getName(Topology::Enum(ii) )
  7993. , statsNumPrimsRendered[ii]
  7994. , statsNumInstances[ii]
  7995. , statsNumPrimsSubmitted[ii]
  7996. );
  7997. }
  7998. if (NULL != m_renderDocDll)
  7999. {
  8000. tvm.printf(tvm.m_width-27, 0, 0x4f, " [F11 - RenderDoc capture] ");
  8001. }
  8002. tvm.printf(10, pos++, 0x8b, " Indices: %7d ", statsNumIndices);
  8003. tvm.printf(10, pos++, 0x8b, " DVB size: %7d ", _render->m_vboffset);
  8004. tvm.printf(10, pos++, 0x8b, " DIB size: %7d ", _render->m_iboffset);
  8005. pos++;
  8006. tvm.printf(10, pos++, 0x8b, " Occlusion queries: %3d ", m_occlusionQuery.m_control.available() );
  8007. pos++;
  8008. tvm.printf(10, pos++, 0x8b, " State cache: ");
  8009. tvm.printf(10, pos++, 0x8b, " PSO | DSL | DS ");
  8010. tvm.printf(10, pos++, 0x8b, " %6d | %6d | %6d "
  8011. , m_pipelineStateCache.getCount()
  8012. , m_descriptorSetLayoutCache.getCount()
  8013. , descriptorSetCount
  8014. );
  8015. pos++;
  8016. double captureMs = double(captureElapsed)*toMs;
  8017. tvm.printf(10, pos++, 0x8b, " Capture: %7.4f [ms] ", captureMs);
  8018. uint8_t attr[2] = { 0x8c, 0x8a };
  8019. uint8_t attrIndex = _render->m_waitSubmit < _render->m_waitRender;
  8020. tvm.printf(10, pos++, attr[attrIndex&1], " Submit wait: %7.4f [ms] ", _render->m_waitSubmit*toMs);
  8021. tvm.printf(10, pos++, attr[(attrIndex+1)&1], " Render wait: %7.4f [ms] ", _render->m_waitRender*toMs);
  8022. min = frameTime;
  8023. max = frameTime;
  8024. presentMin = m_presentElapsed;
  8025. presentMax = m_presentElapsed;
  8026. }
  8027. blit(this, _textVideoMemBlitter, tvm);
  8028. BGFX_VK_PROFILER_END();
  8029. }
  8030. else if (_render->m_debug & BGFX_DEBUG_TEXT)
  8031. {
  8032. BGFX_VK_PROFILER_BEGIN_LITERAL("debugtext", kColorFrame);
  8033. blit(this, _textVideoMemBlitter, _render->m_textVideoMem);
  8034. BGFX_VK_PROFILER_END();
  8035. }
  8036. m_presentElapsed = 0;
  8037. {
  8038. BGFX_PROFILER_SCOPE("scratchBuffer::flush", kColorResource);
  8039. scratchBuffer.flush();
  8040. }
  8041. {
  8042. BGFX_PROFILER_SCOPE("scratchStagingBuffer::flush", kColorResource);
  8043. scratchStagingBuffer.flush();
  8044. }
  8045. for (uint16_t ii = 0; ii < m_numWindows; ++ii)
  8046. {
  8047. FrameBufferVK& fb = isValid(m_windows[ii])
  8048. ? m_frameBuffers[m_windows[ii].idx]
  8049. : m_backBuffer
  8050. ;
  8051. if (fb.m_needPresent)
  8052. {
  8053. fb.resolve();
  8054. fb.m_swapChain.transitionImage(m_commandBuffer);
  8055. m_cmd.addWaitSemaphore(fb.m_swapChain.m_lastImageAcquiredSemaphore, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
  8056. m_cmd.addSignalSemaphore(fb.m_swapChain.m_lastImageRenderedSemaphore);
  8057. fb.m_swapChain.m_lastImageAcquiredSemaphore = VK_NULL_HANDLE;
  8058. fb.m_swapChain.m_backBufferFence[fb.m_swapChain.m_backBufferColorIdx] = m_cmd.m_currentFence;
  8059. }
  8060. }
  8061. kick();
  8062. }
  8063. } /* namespace vk */ } // namespace bgfx
  8064. #else
  8065. namespace bgfx { namespace vk
  8066. {
  8067. RendererContextI* rendererCreate(const Init& _init)
  8068. {
  8069. BX_UNUSED(_init);
  8070. return NULL;
  8071. }
  8072. void rendererDestroy()
  8073. {
  8074. }
  8075. } /* namespace vk */ } // namespace bgfx
  8076. #endif // BGFX_CONFIG_RENDERER_VULKAN